使用 Power BI 根据其他列中的特定条件创建特定列(header 和 header 内的数据)
Using Power BI to create specifc columns (both headers and data within the header), based on specific conditions in other columns
我最初是从 VBA 开始的,有人建议我使用 PowerBI。
但是,如果我的问题可以通过 powerBI 解决,我真的不反对。
我有一个文件将定期发送,其中包含需要分组的特定信息。我正在尝试创建一个 VBA 宏来自动准备文件并使其适合在另一个工具中导入。
我有大约 40 列,但有时更少。列的位置有时会改变,因此我无法引用列位置(A,B,C ...)我必须寻找列名。
此外,我必须寻找一些特定的专栏。如果这些列有数据,我需要将每个案例的特定元素添加到之前连接的列中。
我在下面提供示例代码
这是一个虚拟数据描述:
| Client | ID | Info Superman | Info Product type | Spec 1 | Spec 2 | Spec a | Spec b | Info costumer type | Info facility type | Geography |
当“spec 1”、“spec 2”、“Spec a”或“Spec b”都没有值时,我需要按以下方式对数据进行分组(包括 headers):“Client”+ “超人”+Bravo+“信息客户类型”+信息设施类型“即 ClientSpermanBravoInfo
如果规格 1 或 2 有一个值:“客户”“超人”AlphaBravo“信息客户类型”“信息设施类型”
如果规格 1 或 2 以及规格 a 和 b 有值:“客户”“超人”AlphaAlphaBravo“信息客户类型”“信息设施类型”。
到目前为止,我有以下 VBA 代码,但使用 PowerBI 会提供更简单、更优雅的解决方案。我一直在寻找接近那个资源的资源,例如:https://powerbi.microsoft.com/en-us/blog/power-bi-desktop-april-update-feature-summary/ 以便以特定方式查询数据,并根据特定条件创建列,但我找不到解决方案。
Dim data
data = .Resize(.Rows.Count - 1).Offset(1).Value
End With
Dim result As Dictionary
Set result = New Dictionary
Dim i
For i = 1 To UBound(data, 1)
Select Case True
Case _
data(i, headers("Costumer")) = "" Or _
data(i, headers("Zone ")) = "" Or _
MsgBox "Empty row"
Exit For
Case _
data(i, headers("Spec A")) = "" And _
data(i, headers("Spec B")) = "" And _
data(i, headers("Spec_C ")) = "" And _
data(i, headers("Spec_D ")) = ""
result(result.Count) = _
q & "Costumer" & data(i, headers("Costumer”)) & _
q & "Alpha" & _
q & "Zone" & data(i, headers("Zone")) & _
q
Case _
data(i, headers("Spec_1")) = "" And _
data(i, headers("Spec_2")) = "" And _
data(i, headers("Spec_3")) = "" And _
data(i, headers("Spec_4")) = "" And _
data(i, headers("Spec_5")) = "" And _
data(i, headers("Spec_6")) = "" And _
data(i, headers("Spec_7")) = ""
result(result.Count) = _
q & "Costumer" & data(i, headers("Costumer")) & _
q & "Alphabet" & _
q & "Zone" & data(i, headers("Zone")) & _
q
Case Else
result(result.Count) = _
q & " Costumer" & data(i, headers("Costumer ")) &
q & "AlphabetAlpha" & _
q & " Zone " & data(i, headers("Zone")) & _
q
End Select
Next
' output result data to sheet 2
If result.Count = 0 Then
MsgBox "No result data for output"
Exit Sub
End If
With ThisWorkbook.Sheets(2)
.Cells.Delete
.Cells(1, 1).Resize(result.Count).Value = _
WorksheetFunction.Transpose(result.Items())
End With
MsgBox "Completed"
Sub TralaNome()
Const q = """"
' get source data table from sheet 1
With ThisWorkbook.Sheets(1).Cells(1, 1).CurrentRegion
' check if data exists
If .Rows.Count < 2 Or .Columns.Count < 2 Then
MsgBox "No data table"
Exit Sub
End If
' retrieve headers name and column numbers dictionary
Dim headers As Dictionary
Set headers = New Dictionary
Dim headCell
For Each headCell In .Rows(1).Cells
headers(headCell.Value) = headers.Count + 1
Next
' check mandatory headers
For Each headCell In Array(("Costumer", "ID", "Zone“, "Product Quali", "Spec A", "Spec B", "Spec_C", "Spec_D", "Spec_1", " Spec_2", " Spec_3", " Spec_4", " Spec_5", " Spec_6", " Spec_7", "Chiavetta", "Tipo_di _prodotto", "Unicorno_Cioccolato", “cacao tree“)
If Not headers.Exists(headCell) Then
MsgBox "Header '" & headCell & "' doesn't exists"
Exit Sub
End If
Next
Dim data
' retrieve table data
data = .Resize(.Rows.Count - 1).Offset(1).Value
End With
' process each row in table data
Dim result As Dictionary
Set result = New Dictionary
Dim i
For i = 1 To UBound(data, 1)
MsgBox "Empty row"
Exit For
result(result.Count) = _
q & "ID " & data(i, headers("ID ")) & _
q & " Tipo_di _prodotto " & data(i, headers("Tipo_di _prodotto")) & _
q & " Unicorno_Cioccolato " & data(i, headers("Unicorno_Cioccolato")) & _
q & " cacao tree " & data(i, headers("cacao tree "))&_qEnd Select
Next
' output result data to sheet 2
If result.Count = 0 Then
MsgBox "No result data for output"
Exit Sub
End If
With ThisWorkbook.Sheets(2)
.Cells.Delete
.Cells(1, 1).Resize(result.Count).Value = _
WorksheetFunction.Transpose(result.Items())
End With
MsgBox "Completed"
End Sub
Sub NewColumnNames()
Dim OrignialColumnNames As String
Dim a As Integer
Dim NewColumnNames As Integer
Spec A = Amber A
Spec_B = Amber B
Spec_C = Amber C
Spec_D = Amber D
Spec_1 = Zio_1
Spec_2 = Zio_2
Spec_3 = Zio_3
Spec_4 = Zio_4
Spec_5 = Zio_5
Spec_6 = Zio_6
Spec_7 = Zio_7
Noup_Start = Mip_F
Noup_End = Nip_D
Snouba = Snup_N
SnipChocolat = Choco_F
End Sub
如果您可以使用 PowerQuery 而不是 PowerBI 答案,如果数据被加载到 powerquery(数据 .... 来自 Table/Rage ... [x] 我的 table 有 headers) 然后添加一个简单的自定义列可能就可以了。
添加列...自定义列...使用类似于以下的公式;它根据该行中其他列的值使用 & 字符组合列,而不管这些列出现在何处或有多少列
= if [Spec 1]=null and [Spec 2]=null then [Client]&" "&[ID]&" "&[Info Superman] else
if [Spec 1]<>null and [Spec 2]<>null then [Info Product type]&" "&[Info Superman] else
null
然后您可以使用转换...分组依据...对该列进行分组,然后使用文件...关闭并加载...保存回工作簿...
我最初是从 VBA 开始的,有人建议我使用 PowerBI。 但是,如果我的问题可以通过 powerBI 解决,我真的不反对。
我有一个文件将定期发送,其中包含需要分组的特定信息。我正在尝试创建一个 VBA 宏来自动准备文件并使其适合在另一个工具中导入。
我有大约 40 列,但有时更少。列的位置有时会改变,因此我无法引用列位置(A,B,C ...)我必须寻找列名。
此外,我必须寻找一些特定的专栏。如果这些列有数据,我需要将每个案例的特定元素添加到之前连接的列中。
我在下面提供示例代码
这是一个虚拟数据描述:
| Client | ID | Info Superman | Info Product type | Spec 1 | Spec 2 | Spec a | Spec b | Info costumer type | Info facility type | Geography |
当“spec 1”、“spec 2”、“Spec a”或“Spec b”都没有值时,我需要按以下方式对数据进行分组(包括 headers):“Client”+ “超人”+Bravo+“信息客户类型”+信息设施类型“即 ClientSpermanBravoInfo
如果规格 1 或 2 有一个值:“客户”“超人”AlphaBravo“信息客户类型”“信息设施类型”
如果规格 1 或 2 以及规格 a 和 b 有值:“客户”“超人”AlphaAlphaBravo“信息客户类型”“信息设施类型”。
到目前为止,我有以下 VBA 代码,但使用 PowerBI 会提供更简单、更优雅的解决方案。我一直在寻找接近那个资源的资源,例如:https://powerbi.microsoft.com/en-us/blog/power-bi-desktop-april-update-feature-summary/ 以便以特定方式查询数据,并根据特定条件创建列,但我找不到解决方案。
Dim data
data = .Resize(.Rows.Count - 1).Offset(1).Value
End With
Dim result As Dictionary
Set result = New Dictionary
Dim i
For i = 1 To UBound(data, 1)
Select Case True
Case _
data(i, headers("Costumer")) = "" Or _
data(i, headers("Zone ")) = "" Or _
MsgBox "Empty row"
Exit For
Case _
data(i, headers("Spec A")) = "" And _
data(i, headers("Spec B")) = "" And _
data(i, headers("Spec_C ")) = "" And _
data(i, headers("Spec_D ")) = ""
result(result.Count) = _
q & "Costumer" & data(i, headers("Costumer”)) & _
q & "Alpha" & _
q & "Zone" & data(i, headers("Zone")) & _
q
Case _
data(i, headers("Spec_1")) = "" And _
data(i, headers("Spec_2")) = "" And _
data(i, headers("Spec_3")) = "" And _
data(i, headers("Spec_4")) = "" And _
data(i, headers("Spec_5")) = "" And _
data(i, headers("Spec_6")) = "" And _
data(i, headers("Spec_7")) = ""
result(result.Count) = _
q & "Costumer" & data(i, headers("Costumer")) & _
q & "Alphabet" & _
q & "Zone" & data(i, headers("Zone")) & _
q
Case Else
result(result.Count) = _
q & " Costumer" & data(i, headers("Costumer ")) &
q & "AlphabetAlpha" & _
q & " Zone " & data(i, headers("Zone")) & _
q
End Select
Next
' output result data to sheet 2
If result.Count = 0 Then
MsgBox "No result data for output"
Exit Sub
End If
With ThisWorkbook.Sheets(2)
.Cells.Delete
.Cells(1, 1).Resize(result.Count).Value = _
WorksheetFunction.Transpose(result.Items())
End With
MsgBox "Completed"
Sub TralaNome()
Const q = """"
' get source data table from sheet 1
With ThisWorkbook.Sheets(1).Cells(1, 1).CurrentRegion
' check if data exists
If .Rows.Count < 2 Or .Columns.Count < 2 Then
MsgBox "No data table"
Exit Sub
End If
' retrieve headers name and column numbers dictionary
Dim headers As Dictionary
Set headers = New Dictionary
Dim headCell
For Each headCell In .Rows(1).Cells
headers(headCell.Value) = headers.Count + 1
Next
' check mandatory headers
For Each headCell In Array(("Costumer", "ID", "Zone“, "Product Quali", "Spec A", "Spec B", "Spec_C", "Spec_D", "Spec_1", " Spec_2", " Spec_3", " Spec_4", " Spec_5", " Spec_6", " Spec_7", "Chiavetta", "Tipo_di _prodotto", "Unicorno_Cioccolato", “cacao tree“)
If Not headers.Exists(headCell) Then
MsgBox "Header '" & headCell & "' doesn't exists"
Exit Sub
End If
Next
Dim data
' retrieve table data
data = .Resize(.Rows.Count - 1).Offset(1).Value
End With
' process each row in table data
Dim result As Dictionary
Set result = New Dictionary
Dim i
For i = 1 To UBound(data, 1)
MsgBox "Empty row"
Exit For
result(result.Count) = _
q & "ID " & data(i, headers("ID ")) & _
q & " Tipo_di _prodotto " & data(i, headers("Tipo_di _prodotto")) & _
q & " Unicorno_Cioccolato " & data(i, headers("Unicorno_Cioccolato")) & _
q & " cacao tree " & data(i, headers("cacao tree "))&_qEnd Select
Next
' output result data to sheet 2
If result.Count = 0 Then
MsgBox "No result data for output"
Exit Sub
End If
With ThisWorkbook.Sheets(2)
.Cells.Delete
.Cells(1, 1).Resize(result.Count).Value = _
WorksheetFunction.Transpose(result.Items())
End With
MsgBox "Completed"
End Sub
Sub NewColumnNames()
Dim OrignialColumnNames As String
Dim a As Integer
Dim NewColumnNames As Integer
Spec A = Amber A
Spec_B = Amber B
Spec_C = Amber C
Spec_D = Amber D
Spec_1 = Zio_1
Spec_2 = Zio_2
Spec_3 = Zio_3
Spec_4 = Zio_4
Spec_5 = Zio_5
Spec_6 = Zio_6
Spec_7 = Zio_7
Noup_Start = Mip_F
Noup_End = Nip_D
Snouba = Snup_N
SnipChocolat = Choco_F
End Sub
如果您可以使用 PowerQuery 而不是 PowerBI 答案,如果数据被加载到 powerquery(数据 .... 来自 Table/Rage ... [x] 我的 table 有 headers) 然后添加一个简单的自定义列可能就可以了。
添加列...自定义列...使用类似于以下的公式;它根据该行中其他列的值使用 & 字符组合列,而不管这些列出现在何处或有多少列
= if [Spec 1]=null and [Spec 2]=null then [Client]&" "&[ID]&" "&[Info Superman] else
if [Spec 1]<>null and [Spec 2]<>null then [Info Product type]&" "&[Info Superman] else
null
然后您可以使用转换...分组依据...对该列进行分组,然后使用文件...关闭并加载...保存回工作簿...