VBA Excel从其他工作表返回值

时间:2017-12-03 12:37:48

标签: excel vba excel-vba ms-office

请看这张图片

https://i.stack.imgur.com/iKToo.png


为此,我使用像这样的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中的来源(左表)?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

这是一种稍微不同的方法,使用UDF作为单元格函数来确定应根据调用单元格的位置显示哪个条目。

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

UDF的参数是1)包含事件的源表区域(不包括行和列标题)和2)进行调用的单元格上方列的顶部的标题单元格。调用单元相对于标题单元的相对位置给出了该行。标题单元格中的文本是&#34;日期&#34;,&#34;事件&#34;或&#34;放置&#34;,告诉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用于许多不同的事件表。

这就是它的用法:

enter image description here