VBA Excel return 来自其他 sheet 的值

VBA Excel return value from other sheet

请看这张图


为此,我使用 VBA 像这样

Sub TransformTbl()
   Dim i As Long, j As Long, cnt As Long

   With ActiveSheet
      .Range("G1:I1") = Array("Date", "Event", "Place")
      cnt = 1
      For j = 2 To 4     
         For i = 2 To 5   
            If Len(.Cells(i, j)) <> 0 Then
               cnt = cnt + 1
               .Cells(cnt, 7) = .Cells(1, j)  
               .Cells(cnt, 8) = .Cells(i, j)  
               .Cells(cnt, 9) = .Cells(i, 1)  
            End If
         Next i
      Next j
   End With
End Sub

但它在相同的 sheet 中工作。我怎样才能在 sheet B 的右边制作 table?但是 sheet A?

中的来源(左 table)
Sub TransformTbl()
   Dim i As Long, j As Long, cnt As Long, ShtB as worksheet, ShtA as Worksheet

   set ShtA = Thisworkbook.Sheets("sheet A")
   set ShtB = Thisworkbook.Sheets("sheet B") ' change to your sheet name

   With ShtA ' change to your sheet name
      ShtB.Range("G1:I1") = Array("Date", "Event", "Place")
      cnt = 1
      For j = 2 To 4     
         For i = 2 To 5   
            If Len(ShtA.Cells(i, j)) <> 0 Then
               cnt = cnt + 1
               ShtB.Cells(cnt, 7) = ShtA.Cells(1, j)  
               ShtB.Cells(cnt, 8) = ShtA.Cells(i, j)  
               ShtB.Cells(cnt, 9) = ShtA.Cells(i, 1)  
            End If
         Next i
      Next j
   End With
End Sub

你可以试试这个。未测试。

这里有一个稍微不同的方法,使用 UDF 作为 in-cell 函数来根据调用单元格的位置计算出应该显示哪个条目。

逻辑是输出 table 中的 nth 行将包含 nth non-blank 源中的条目 table。因此,如果我们定义一个 UDF,它可以计算出从 table 的哪一行调用它,那么它就可以确定源 table 中的哪个单元格包含 non-blank 条目行中显示。一旦我们知道单元格,那么我们也知道相应的日期和地点,因为它们分别是列和标题行。

UDF 的参数是 1) 包含事件的源 table 区域(不包括行标题和列标题)和 2) 位于列顶部的标题单元格称呼。调用单元格相对于标题单元格的相对位置给出了该行。标题单元格中的文本是 "Date"、"Event" 或 "Place" 之一,它告诉 UDF 要 return.

的数据
Option Explicit

Public Function GetEventData(EventTable As Range, ColumnHead As Range)
    Dim iEventNumber As Integer

    '// Calculate which row of the output table this has been called from.
    '// This gives the event number that we need to find in the table
    iEventNumber = Application.Caller.Row - ColumnHead.Row

    '// Check if the event number is bigger than the total possible
    '// number of events - there cannot be any event to return
    If iEventNumber > EventTable.Cells.Count Then
        GetEventData = ""
        Exit Function
    End If

    '// The event cell to be found in the event table
    Dim oEventCell As Range

    '// Control variables
    Dim iRow As Integer
    Dim icol As Integer

    Dim iEventCount As Integer
    iEventCount = 0

    '// Find the nth non-blank entry, where n
    '// is the row number of the caller in the
    '// ouptut table

    For icol = 1 To EventTable.Columns.Count
        For iRow = 1 To EventTable.Rows.Count

            '// Check if the cell contains data,
            '// if so increment the event count
            If Not IsEmpty(EventTable.Cells(iRow, icol)) Then
                iEventCount = iEventCount + 1

                '// After incrementing the count, check if this now
                '// matches the required event number
                If iEventCount = iEventNumber Then
                    Set oEventCell = EventTable.Cells(iRow, icol)
                    Exit For
                End If
            End If
        Next iRow

        '// Exit the loop if the cell has been found
        If Not oEventCell Is Nothing Then Exit For

    Next icol

    '// Check if there was no event found corresponding
    '// to this row number
    If oEventCell Is Nothing Then
        GetEventData = ""
        Exit Function
    End If

    '// Now check what data item we need to return,
    '// depending on the column heading
    Select Case ColumnHead.Value
    Case "Date"
        '// Return the date heading in the same column as the source data cell
        GetEventData = EventTable.Cells(0, oEventCell.Column - EventTable.Column + 1).Value

    Case "Event"
        '// Return the content of the event cell itself
        GetEventData = oEventCell.Value

    Case "Place"
        '// Return the place name from the same row as the source data cell
        GetEventData = EventTable.Cells(oEventCell.Row - EventTable.Row + 1, 0).Value

    Case Else
        '// Not recognised data item
        GetEventData = ColumnHead.Value & "?"

    End Select

End Function

这种方法的优点是只要输入区域中的任何条目发生更改,输出 table 就会更新,输入和输出 table 可以在不同的工作表甚至不同的工作簿中.您可以根据需要对任意数量的不同事件 table 使用相同的 UDF。

这是它在使用中的样子: