我有以下数据网格:
---------Header 1 Header 2 Header 3 Header 4
Row 1 x x x
Row 2 x x
Row 3 x
Row 4 x x x x
然后我有第二张表如下:
Row 1 Row 2 Row 3 Row 4
我希望第二张最终看起来像这样:
Row 1 Row 2 Row 3 Row 4
Header 1 Header 2 Header 3 Header 1
Header 3 Header 3 Header 2
Header 4 Header 3
. Header 4
忽略最后一段时间,我只是用它来正确格式化。
我一直在玩MATCH和INDEX几个小时,虽然我可以得到它的一部分,但我似乎无法将它们全部合作。
修改
我只使用'标题1'和'第1行'作为示例。实际数据分别是A列和第1行中的文本。此外,由于源数据将被修改,我宁愿有一些会自动更新第二张表。
答案 0 :(得分:0)
是否必须使用工作表函数?创建一个宏来做它会更简单(我已经做了一个例子)
编辑该函数以处理第1行中col a和列标题中的行标题,并将其更改为从“Source”表中读取并将结果写入“Output”表
Public Sub Example()
Dim Output As Worksheet
Dim Sheet As Worksheet
Dim Row As Integer
Dim Column As Integer
Set Sheet = ThisWorkbook.Worksheets("Source")
Set Output = ThisWorkbook.Worksheets("Output")
Output.Cells.Clear ' Since were going to rebuild the whole thing, just nuke it.
For Row = Sheet.UsedRange.Rows(Sheet.UsedRange.Rows.Count).Row To 2 Step -1
Output.Cells(1, Row - 1).Value = Sheet.Cells(Row, 1).Value
For Column = Sheet.UsedRange.Columns(Sheet.UsedRange.Columns.Count).Column To 1 Step -1
If Not IsEmpty(Sheet.Cells(Row, Column)) Then
Sheet.Cells(1, Column).Copy
Output.Cells(2, Row - 1).Insert xlShiftDown
End If
Next Column
Next Row
End Sub
我看了一下使用工作表函数进行的操作,并且正如其他人所说的那样,如果没有混合使用vba,那将会非常棘手。
如果将其添加到新模块,则可以将其作为工作簿功能进行访问。 (并不是说这是最好的方法,只是想去吧)
'Return The Column Header of the Nth Non-Blank Cell on Specified Row
Public Function NonBlankByIndex(ByVal Row As Integer, ByVal Index As Integer) As Range
Dim Sheet As Worksheet
Dim Column As Integer
Dim Result As Range
Set Sheet = ThisWorkbook.Worksheets("Source") ' Change to your source sheet's name
Set Result = Nothing
Column = 2 ' Skip 1 as its the header
Do
If Column > Sheet.UsedRange.Columns(Sheet.UsedRange.Columns.Count).Column Then
Exit Do
End If
If Sheet.Cells(Row, Column) = "" Then
Column = Column + 1
Else
If Index = 1 Then
Set Result = Sheet.Cells(1, Column)
Exit Do
Else
Column = Column + 1
Index = Index - 1
End If
End If
Loop
Set NonBlankByIndex = Result
End Function
答案 1 :(得分:0)
以下是使用VBA函数执行此操作的一种方法:
在“开发人员”选项卡中(*)单击“Visual Basic”,然后单击“插入”菜单,选择“模块”以插入新模块。然后粘贴以下代码:
Option Explicit
Public Function GetHeaderMatchingRow(RowText As String, _
SearchRange As Range, _
iHdrNo As Integer) As String
Dim rng As Range
Set rng = SearchRange
Dim cel As Range
'Get the Row to scan
Dim i As Long, rowOff As Long
For i = 2 To rng.Rows.Count
Set cel = rng.Cells(i, 1)
If cel.Value = RowText Then
rowOff = i
Exit For
End If
Next i
'Now, scan horizontally for the iHdrNo'th non-blank cell
Dim cnt As Integer
For i = 2 To rng.Columns.Count
Set cel = rng.Cells(rowOff, i)
If Not CStr(cel.Value) = "" Then
cnt = cnt + 1
If cnt = iHdrNo Then
GetHeaderMatchingRow = rng.Cells(1, i).Value
Exit Function
End If
End If
Next i
GetHeaderMatchingRow = ""
End Function
单击“Debug”菜单并选择“Compile VBAProject”。
现在返回Excel并在第一张工作表中定义命名范围以覆盖网格中的所有数据。 Row名称应该是此范围中的第一列,Header文本应该是其中的第一行。
现在转到第二张表并在每个输出单元格中输入这样的公式:
=GetHeaderMatchingRow(A$1, RowHeaderRange, 1)
其中First参数是它将尝试在范围的第一列中匹配的Row文本。我这里有“A $ 1”,因为在我的测试中,我的第二张表的列标题也是我第一张表中的行名,就像你的一样。
第二个参数是要搜索的范围(在这种情况下,我们之前定义的命名范围),第三个参数是它正在寻找的匹配的计数(第1,第2,第3等)。
请注意,第一个和第三个参数应根据输出的列和行进行更改。
答案 2 :(得分:0)
如果您对列表中的空白感到满意,请在sheet2中尝试此操作!A2:
!= IF(INDEX(Sheet 1中$ B $ 2:$ E $ 5 MATCH(A $ 1,工作表Sheet $ A $ 2:$ A $ 5,0),ROW() - 1)= “X”,INDEX(Sheet 1中!$ B $ 1:$ E $ 1,1,ROW() - 1), “”)
只需将公式复制到范围A2:D5
即可