我知道标题可能会让人感到困惑,但这是我最好的方法。
为了提供进一步的解释,我有一本书和两张纸:
表A在第1行中包含人名(A1,B1,C1等)。名称的数量会更改,有时更多,有时更少。
表B在A列中包含人名列表,在B列中包含值。例如:
A B
John 22
John 13
Sam 90
我需要一个宏,该宏查看工作表A中每一列的第一行中的值,然后返回,将所有匹配的值从工作表B中的列表粘贴到工作表A中的第二行。
它看起来像:
表A:
A B
John Sam
22 90
13
我没有时间测试任何东西,但我想我可以在B1:B [X]中粘贴一个公式,该公式查找名称在列表中出现的次数并找到其名称起始位置并将其用于复制并粘贴B列中的相应范围。
我不是Macro Pro,但这就是我现在的想法。如果有人能理解这种枯燥的解释并能提供帮助,那就太好了!
答案 0 :(得分:1)
我认为最简单的方法是使用集合/字典。我假设您在工作表A中的所有姓名都是唯一的。
Option Explicit
Sub RetrieveData()
Dim wb As Workbook
Dim ws_A As Worksheet
Dim ws_B As Worksheet
Dim HeaderRow As Long
Dim HeaderLastColumn As Long
Dim TableColStart As Long
Dim NameList As Object
Dim i As Long
Dim ws_B_lastrow As Long
Dim NextEntryline As Long
Dim NameCol As Long
Set wb = ActiveWorkbook
Set ws_A = wb.Worksheets("Sheet A")
Set ws_B = wb.Worksheets("Sheet B")
Set NameList = CreateObject("Scripting.Dictionary")
With ws_A
HeaderRow = 1 'set the header row in sheet A
TableColStart = 1 'Set start col in sheet A
HeaderLastColumn = .Cells(HeaderRow, Columns.Count).End(xlToLeft).Column 'Get number of NAMEs you have
For i = TableColStart To HeaderLastColumn
If Not NameList.Exists(UCase(.Cells(HeaderRow, i).Value)) Then 'check if the name exists in the dictionary
NameList.Add UCase(.Cells(HeaderRow, i).Value), i 'if does not exist record name as KEY and Column number as value in dictionary
End If
next i
End With
With ws_B
ws_B_lastrow = .Cells(Rows.Count, 1).End(xlUp).Row ' Get number of DATA you have in sheet B
For i = 1 To ws_B_lastrow 'for each data
NameCol = NameList(UCase(.Cells(i, 1).Value)) 'get the column where the name is in Sheet A from the dictionaary
If NameCol <> 0 Then 'if 0 means the name doesnt exists
NextEntryline = ws_A.Cells(Rows.Count, NameCol).End(xlUp).Row + 1 'get the next entry line of the particular name in sheet A
ws_A.Cells(NextEntryline, NameCol).Value = .Cells(i, 2) 'insert the data
End If
Next i
End With
End Sub
答案 1 :(得分:0)
我的理解方式:诸如时间卡报告生成器,或Sheet2中的名称和值的任意列表,并且您希望以类似数据透视表的合并方式将Sheet2转置并合并到Sheet1(确保您不能使用枢轴?)。
纯VBA明智的做法是,几年前我做了类似的事情(我的用例是上述的时间表报告):
lastrow = Range("A" & Rows.Count).End(xlUp).row
计算最后一行。For n = 1 To lastrow ... Next n
)。Range("A" & n)
与Range("A" & n-1)
进行比较,以确定何时出现新名称(您将覆盖此测试,并仅假设第1行使用新名称) 。Worksheets("Sheet1").Cells(1,CCTR)
(列是当前列计数器,行是1)。Worksheets("Sheet1").Cells(RCTR,CCTR)
中,然后迭代RCTR。由于对工作表进行了排序,因此我们只关心Sheet2中的名称列何时更改,因此几乎可以忽略它在给定数据集中出现了多少次。
答案 2 :(得分:0)
我建议遍历工作表B中的所有数据,将它们与工作表A中的第一行匹配,如果匹配,则将值写入匹配列中的下一个空闲行。
Option Explicit
Public Sub SortDataIntoSheetA()
Dim wsSrc As Worksheet
Set wsSrc = ThisWorkbook.Worksheets("Sheet B") 'define source worksheet
Dim wsDest As Worksheet
Set wsDest = ThisWorkbook.Worksheets("Sheet A") 'define destination worksheet
Dim LastSrcRow As Long
LastSrcRow = wsSrc.Cells(wsSrc.Rows.Count, "A").End(xlUp).Row 'find last used row in source
Dim DestCol As Long, LastDestRow As Long
Dim iRow As Long
For iRow = 1 To LastSrcRow 'loop throug all rows in source
DestCol = 0 'initialize
On Error Resume Next 'if next row throws error hide it
DestCol = WorksheetFunction.Match(wsSrc.Cells(iRow, "A").Value, wsDest.Rows(1), 0) 'find correct column
On Error GoTo 0 're-enable error reporting!!
'if nothing matched DestCol will still be 0
If DestCol > 0 Then
LastDestRow = wsDest.Cells(wsDest.Rows.Count, DestCol).End(xlUp).Row 'find last used row in destination column
wsDest.Cells(LastDestRow + 1, DestCol).Value = wsSrc.Cells(iRow, "B").Value 'write value
End If
Next iRow
End Sub