根据第一个字符将单列转换为 table
Convert a single column to a table based on first characters
我最近开始在 Excel 中使用 Essbase/SmartView 帮助进行报告。我正在尝试获取 Essbase 报告;它将我的项目层次结构的所有级别合并到一个列中 - 而不是将其转换为 table。 Essbase 似乎没有这个功能,所以我一直在尝试在 VBA 中弄清楚如何做到这一点。下面是我正在尝试做的事情以及我的宏的示例,该宏目前仅适用于在 table 中填充项目 ID 和预算。我是 VBA 的新手,所以我希望有人能为我指明正确的方向,告诉我如何接近第 1、2 和 3 级。我认为我最好的选择是某种基于查找的方法在前两个字符上,例如 "L2",但我很感谢您提供的任何指导。
当前
+-----------------+--------+
| Project | Budget |
+-----------------+--------+
| P1200 | 150 |
| P1400 | 200 |
| L3 Program 3 | 350 |
| P1100 | 250 |
| P1300 | 150 |
| L3 Program 2 | 400 |
| L2 Initiative 2 | 750 |
| P2200 | 300 |
| P2400 | 200 |
| P2600 | 300 |
| L3 Program 1 | 800 |
| L2 Initiative 1 | 800 |
| L1 Division | 1550 |
+-----------------+--------+
需要
+-------------+-----------------+--------------+---------+--------+
| L1 | L2 | L3 | Project | Budget |
+-------------+-----------------+--------------+---------+--------+
| L1 Division | L2 Initiative 2 | L3 Program 3 | P1200 | 150 |
| L1 Division | L2 Initiative 2 | L3 Program 3 | P1400 | 200 |
| L1 Division | L2 Initiative 2 | L3 Program 2 | P1100 | 250 |
| L1 Division | L2 Initiative 2 | L3 Program 2 | P1300 | 150 |
| L1 Division | L2 Initiative 1 | L3 Program 1 | P2200 | 300 |
| L1 Division | L2 Initiative 1 | L3 Program 1 | P2400 | 200 |
| L1 Division | L2 Initiative 1 | L3 Program 1 | P2600 | 300 |
+-------------+-----------------+--------------+---------+--------+
当前宏
Sub TabularView()
Dim esData As Worksheet
Dim tabView As Worksheet
Set esData = ThisWorkbook.Sheets("Sheet1")
Set tabview = ThisWorkbook.Sheets("TabularView")
rptLR = esData.Cells(Rows.Count, 1).End(xlUp).Row + 1
y = 2
For x = 9 to rptLR 'Data starts in row 9
If Left(esData.Cells(x, 1).Text, 1) = "P" Then
tabView.Cells(y,4) = esData.Cells(x,1)
tabView.Cells(y,5) = esData.Cells(x,2)
y = y + 1
End If
Next x
End Sub
见下方代码,注释中解释:
Sub TabularView()
Dim esData As Worksheet
Dim tabView As Worksheet
Set esData = ThisWorkbook.Sheets("Sheet1")
Set tabview = ThisWorkbook.Sheets("TabularView")
rptLR = esData.Cells(Rows.Count, 1).End(xlUp).Row + 1
y = 2
dim L1, L2, L3 as string
'My first suggestion is to work from the bottom up.
'This is because your data appear to be structured
'such that the details for level 1 2 and 3 only
'appear after the project code they apply to.
'(If you have any say on the structure, I would
'suggest rather reversing the order of the hierarchy
'on the sheet itself instep of looping backwards like this).
For x = rptLR to 9 step -1 'Data starts in row 9
' NOTE: Replace this series of If statements with a switch or case statement (whatever VBA has)
'The next thing to do is if you find an L, then store the name in memory so that we have it in future iterations
If Left(esData.Cells(x, 1).Text, 2) = "L1" Then
L1 = esData.Cells(x,1).value
End If
If Left(esData.Cells(x, 1).Text, 2) = "L2" Then
L2 = esData.Cells(x,1).value
End If
If Left(esData.Cells(x, 1).Text, 2) = "L3" Then
L3 = esData.Cells(x,1).value
End If
If Left(esData.Cells(x, 1).Text, 1) = "P" Then
'Finally, just use the L values we kept in memory in previous iterations
tabView.Cells(y,1) = L1
tabView.Cells(y,2) = L2
tabView.Cells(y,3) = L3
tabView.Cells(y,4) = esData.Cells(x,1)
tabView.Cells(y,5) = esData.Cells(x,2)
y = y + 1
End If
Next x
End Sub
我最近开始在 Excel 中使用 Essbase/SmartView 帮助进行报告。我正在尝试获取 Essbase 报告;它将我的项目层次结构的所有级别合并到一个列中 - 而不是将其转换为 table。 Essbase 似乎没有这个功能,所以我一直在尝试在 VBA 中弄清楚如何做到这一点。下面是我正在尝试做的事情以及我的宏的示例,该宏目前仅适用于在 table 中填充项目 ID 和预算。我是 VBA 的新手,所以我希望有人能为我指明正确的方向,告诉我如何接近第 1、2 和 3 级。我认为我最好的选择是某种基于查找的方法在前两个字符上,例如 "L2",但我很感谢您提供的任何指导。
当前
+-----------------+--------+
| Project | Budget |
+-----------------+--------+
| P1200 | 150 |
| P1400 | 200 |
| L3 Program 3 | 350 |
| P1100 | 250 |
| P1300 | 150 |
| L3 Program 2 | 400 |
| L2 Initiative 2 | 750 |
| P2200 | 300 |
| P2400 | 200 |
| P2600 | 300 |
| L3 Program 1 | 800 |
| L2 Initiative 1 | 800 |
| L1 Division | 1550 |
+-----------------+--------+
需要
+-------------+-----------------+--------------+---------+--------+
| L1 | L2 | L3 | Project | Budget |
+-------------+-----------------+--------------+---------+--------+
| L1 Division | L2 Initiative 2 | L3 Program 3 | P1200 | 150 |
| L1 Division | L2 Initiative 2 | L3 Program 3 | P1400 | 200 |
| L1 Division | L2 Initiative 2 | L3 Program 2 | P1100 | 250 |
| L1 Division | L2 Initiative 2 | L3 Program 2 | P1300 | 150 |
| L1 Division | L2 Initiative 1 | L3 Program 1 | P2200 | 300 |
| L1 Division | L2 Initiative 1 | L3 Program 1 | P2400 | 200 |
| L1 Division | L2 Initiative 1 | L3 Program 1 | P2600 | 300 |
+-------------+-----------------+--------------+---------+--------+
当前宏
Sub TabularView()
Dim esData As Worksheet
Dim tabView As Worksheet
Set esData = ThisWorkbook.Sheets("Sheet1")
Set tabview = ThisWorkbook.Sheets("TabularView")
rptLR = esData.Cells(Rows.Count, 1).End(xlUp).Row + 1
y = 2
For x = 9 to rptLR 'Data starts in row 9
If Left(esData.Cells(x, 1).Text, 1) = "P" Then
tabView.Cells(y,4) = esData.Cells(x,1)
tabView.Cells(y,5) = esData.Cells(x,2)
y = y + 1
End If
Next x
End Sub
见下方代码,注释中解释:
Sub TabularView()
Dim esData As Worksheet
Dim tabView As Worksheet
Set esData = ThisWorkbook.Sheets("Sheet1")
Set tabview = ThisWorkbook.Sheets("TabularView")
rptLR = esData.Cells(Rows.Count, 1).End(xlUp).Row + 1
y = 2
dim L1, L2, L3 as string
'My first suggestion is to work from the bottom up.
'This is because your data appear to be structured
'such that the details for level 1 2 and 3 only
'appear after the project code they apply to.
'(If you have any say on the structure, I would
'suggest rather reversing the order of the hierarchy
'on the sheet itself instep of looping backwards like this).
For x = rptLR to 9 step -1 'Data starts in row 9
' NOTE: Replace this series of If statements with a switch or case statement (whatever VBA has)
'The next thing to do is if you find an L, then store the name in memory so that we have it in future iterations
If Left(esData.Cells(x, 1).Text, 2) = "L1" Then
L1 = esData.Cells(x,1).value
End If
If Left(esData.Cells(x, 1).Text, 2) = "L2" Then
L2 = esData.Cells(x,1).value
End If
If Left(esData.Cells(x, 1).Text, 2) = "L3" Then
L3 = esData.Cells(x,1).value
End If
If Left(esData.Cells(x, 1).Text, 1) = "P" Then
'Finally, just use the L values we kept in memory in previous iterations
tabView.Cells(y,1) = L1
tabView.Cells(y,2) = L2
tabView.Cells(y,3) = L3
tabView.Cells(y,4) = esData.Cells(x,1)
tabView.Cells(y,5) = esData.Cells(x,2)
y = y + 1
End If
Next x
End Sub