VBA Excel从其他工作表返回值

VBA Excel从其他工作表返回值,excel,vba,ms-office,Excel,Vba,Ms Office,请看这张照片 对于这件事,我像这样使用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(.Ce

请看这张照片

对于这件事,我像这样使用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
但它在同一张纸上工作。我怎样才能把B页右边的桌子做好?但是来源在表A中留下了表格

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作为单元内函数,根据调用单元的位置确定应显示哪个条目

逻辑是,输出表中的第n行将包含源表中第n个非空条目的事件数据。因此,如果我们定义一个UDF,它可以计算出从表中的哪一行调用它,那么它可以确定源表中的哪个单元格包含要在该行中显示的非空条目。一旦我们知道了单元格,那么我们也知道了相应的日期和地点,因为它们分别是列和标题行

UDF的参数1是包含不包括行标题和列标题的事件的源表区域,2是位于进行调用的单元格上方列顶部的标题单元格。调用单元相对于标题单元的相对位置给出了行。标题单元格中的文本是日期、事件或地点之一,它告诉UDF要返回哪些数据

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
这种方法的优点是,一旦输入区域中的任何条目发生更改,输出表就会更新,输入和输出表可以位于不同的工作表甚至不同的工作簿中。您可以对任意多个不同的事件表使用相同的UDF

这是它在使用中的外观:


哇,谢谢你,我一定会更多地了解你的做法