根据行标题和单元格值返回列标题

时间:2012-07-12 18:57:49

标签: excel worksheet-function

我有以下数据网格:

         ---------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行中的文本。此外,由于源数据将被修改,我宁愿有一些会自动更新第二张表。

3 个答案:

答案 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

即可