Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 返回用于查找某个范围的所有值的Excel宏_Vba_Excel - Fatal编程技术网

Vba 返回用于查找某个范围的所有值的Excel宏

Vba 返回用于查找某个范围的所有值的Excel宏,vba,excel,Vba,Excel,我知道标题看起来非常混乱,但这是我能做的最好的方式 为了进一步解释,我有一本工作手册和两张纸: 表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

我知道标题看起来非常混乱,但这是我能做的最好的方式

为了进一步解释,我有一本工作手册和两张纸:

  • 表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列复制和粘贴相应的范围


我不是一个宏专业人士,但这是我现在思想的方向。如果有人能理解这个枯燥的解释,并能帮上忙,那将是惊人的

我的理解是:类似于时间卡报表生成器,或者Sheet2中的任意名称和值列表,您希望将Sheet2转换并合并到数据透视表(如合并)中的Sheet1上(确定不能仅使用数据透视?)

纯VBA智能几年前我做了类似的事情(我的用例是上面提到的timecard报告):

  • 按您的姓名列对Sheet2进行排序
  • 使用
    lastrow=Range(“A”&Rows.Count).End(xlUp).row
    计算最后一行
  • 还要初始化一个行计数器(RCTR)和列计数器(CCTR),它将在写入输出表时进行迭代或重置
  • 从一个for next开始,一直到这个被称为Sheet2的已排序原始列表(
    FORN=1到lastrow…next n
  • 对于每一行,将
    Range(“A”&n)
    Range(“A”&n-1)
    进行比较,以确定何时出现新名称(您将覆盖此测试,并为第1行假定一个新名称)
  • 如果在步骤4中出现新名称,请将RCTR重置为2,并将CCTR迭代1,然后将该新名称复制到
    工作表(“Sheet1”)。单元格(1,CCTR)
    (列为当前列计数器,行为1)
  • 将数值复制到
    工作表(“Sheet1”).单元格(RCTR,CCTR)
    ,然后迭代RCTR
  • 循环到步骤5

  • 由于工作表已排序,我们只关心Sheet2中的name列何时更改,因此几乎可以忽略它在给定数据集中出现的次数。

    我建议循环检查工作表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
    

    我认为最简单的方法是使用集合/字典。我假设您在工作表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
    
    选项显式
    子检索数据()
    将wb设置为工作簿
    将ws_A设置为工作表
    将ws_B设置为工作表
    昏头
    昏暗的头侧立柱与立柱一样长
    暗淡的桌面开始时一样长
    作为对象的名称列表
    我想我会坚持多久
    将最后一行的宽度减到最长
    暗淡的下天冬氨酸和长的一样
    暗淡无光
    设置wb=ActiveWorkbook
    设置ws_A=wb.工作表(“工作表A”)
    设置ws_B=wb.工作表(“工作表B”)
    Set NameList=CreateObject(“Scripting.Dictionary”)
    与w_A
    HeaderRow=1'设置工作表A中的标题行
    TableColStart=1'在工作表A中设置起始列
    HeaderLastColumn=.Cells(HeaderRow,Columns.Count).End(xlToLeft).Column'获取您拥有的名称数
    对于i=TableColStart到HeaderLastColumn
    如果不存在NameList.Exists(UCase(.Cells(HeaderRow,i).Value)),则“检查字典中是否存在该名称
    NameList.Add UCase(.Cells(HeaderRow,i).Value),i'if不存在,则将名称记录为键,列号记录为字典中的值
    如果结束
    接下来我
    以
    与w_B
    ws_B_lastrow=.Cells(Rows.Count,1).End(xlUp).Row'获取工作表B中的数据数量
    对于每个数据,i=1到ws_B_lastrow
    NameCol=NameList(UCase(.Cells(i,1.Value))'从字典中获取名称在工作表A中的列
    如果名称为0,则“如果0”表示该名称不存在
    NextEntryline=ws_A.Cells(Rows.Count,NameCol).End(xlUp).Row+1'获取工作表A中特定名称的下一个输入行
    ws_A.Cells(NextEntryline,NameCol).Value=.Cells(i,2)'插入数据
    如果结束
    接下来我
    以
    端接头
    
    我建议您使用Excel表格和使用索引/匹配的Excel公式。谷歌Excel表格和索引:/Match。这里有几个链接可以帮助您开始。和我与这些网站没有任何联系。多年来,我从堆栈溢出中得到了很大的帮助,我正在努力向前推进。永远不要使用
    GoTo
    ,除非它在出现错误时立即落后于
    ,使用
    GoTo
    是一种非常糟糕的做法,可以通过否定此处的
    If
    语句来避免:
    If NameCol 0 Then…NextEntryline…End If
    。根据Peh建议编辑,以倡导良好的编码做法!!