【问题标题】:Loop macro to copy user input range and paste to user input range in unknown open workbook循环宏以复制用户输入范围并粘贴到未知打开工作簿中的用户输入范围
【发布时间】:2018-01-28 14:14:12
【问题描述】:

我对 VBA 很陌生。几个星期以来,我一直在尝试开发一个模仿 Excel 中的 vlookup 和 hlookup 函数的代码。

我正在构建一个宏,用于将数据从一个工作簿复制并粘贴到另一个工作簿中。

数据将在源工作簿和目标工作簿的左侧列中具有参考值。

目标工作簿中的参考值与源工作簿中的参考值的顺序不同。

要复制的数据将位于距离参考值 4 列的位置。数据(连同参考值)可以是数千行和数百列的长度。

目标工作簿和源数据所在的工作簿都将打开。

用户将在源工作簿和目标工作簿中指定引用值的位置。

用户还将指定要复制的数据范围

所有数据都将被复制。

这是我一直在处理的示例文件。我的实际数据会远远大于这个。数据从这里复制过来:Original Workbook

然后将数据粘贴到此工作簿中。目标工作簿看起来很相似,但您可以看到参考数据的顺序不同:Destination Workbook

此外,在同一张工作表中成功循环后(粘贴范围是同一工作簿中的同一张工作表),我收到此错误: 我还收到“运行时错误 91。对象变量或未设置块变量。” 这是我到目前为止得到的:

> Sub copyv5input()
>  
> Dim wsSrc As Worksheet Dim wbSrc As Workbook Dim wsTgt As Worksheet
> Dim wbTgt As Workbook Dim vRng1 As Range Dim vNo As Range Dim rNum As
> Integer Dim vRef1 As Range Dim vRng2 As Range Dim vDest1 As Variant
> Dim vDest2 As Variant Dim vDest3 As Range Dim cNum As Integer Dim
> cNum2 As String Dim vNew2 As Range
> 
> rNum = 1 
> cNum = 1 
>     Set vRng1 = Application.InputBox("Select the range of reference data:", Type:=8)    '1
>     Set vRef1 = vRng1.Cells(rNum, cNum)     '1
>     
>     
>     
>     Set vRng2 = Application.InputBox("Select the reference data range for destination:", Type:=8)   '2
>      
>         
>    
>     Set vDest1 = vRng2.Find(what:=vRef1)    '2
>     Set vDest2 = Range(vDest1.Address)      '2
>     Set vDest3 = vDest2.Offset(0, 1).Resize(, 4)    '2
> 
> Do While vRef1 <> ""
> 
> Set vNo = vRef1.Offset(0, 4).Resize(, 4)    '1
>          
>          If vRef1 = vDest1 Then
>         
>             vNo.copy Destination:=vDest3
>         
>         
>          End If
>     
>     rNum = rNum + 1
>         
>             Set vRef1 = vRng1.Cells(rNum, cNum)
>             Set vDest1 = vRng2.Find(what:=vRef1)
>             Set vDest2 = Range(vDest1.Address)      '2
>             Set vDest3 = vDest2.Offset(0, 1).Resize(, 4)
>      Loop
>        
> 
> End Sub

提前致谢!

【问题讨论】:

    标签: excel vba loops object copy-paste


    【解决方案1】:

    您好,欢迎来到堆栈溢出, 恐怕你的问题有点难以理解(或者可能只是我)。希望我在正确的轨道上,但我认为你想要

    1. 选择要查找的值列表
    2. 选择一个范围,其中包含您要返回的这些值和列中的其他数据
    3. 将查找到的数据列添加到参考列表中

    您可以将 Application.WorksheetFunction 属性用于 vlookup,或者我会做的方式是遍历每个值以查找匹配项,然后在同一行但在另一列上返回该值。对于长数据列表,这可能会有点慢,但它很简单并且可以工作

     Sub copyv5input2()
    
    
     Dim vRng1 As Range
    
     Dim rNum As Integer
     Dim rNum2 As Integer
     Dim vRef1 As Range
     Dim vRng2 As Range
     Dim cNum As Integer
     Dim lookupV As String
     Dim foundR As Long
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
    End With
    
    Set vRng1 = Application.InputBox("Select the range of reference data:", Type:=8)
    Set vRng2 = Application.InputBox("Select the reference data range for destination:", Type:=8)   '2
    cNum = Application.InputBox("Select the column number you want to return from reference data:")
    
    
    For rNum = 1 To vRng1.Rows.Count
    
        lookupV = vRng1.Cells(rNum, 1).Value
        For rNum2 = 1 To vRng2.Rows.Count
            If vRng2.Cells(rNum2, 1) = lookupV Then
                vRng1.Cells(rNum, 1).Offset(0, 1) = vRng2.Cells(rNum2, cNum).Value
                foundR = foundR + 1
                GoTo 10
            End If
        Next rNum2
    10
    Next rNum
    
    With Application
        .ScreenUpdating = true
        .Calculation = xlCalculationAutomatic
    
    End With
    MsgBox "complete, " & foundR & " values returned", vbInformation, "auto lookup"
    
     End Sub
    

    【讨论】:

    • 谢谢大卫。很抱歉我没有正确传达这一点。我的代码中偏移的原因是因为数据从参考单元格开始 4 列。此外,这个想法是粘贴每一列数据,而不是仅仅选择一列数据。目标工作簿将具有相同的引用,但行顺序将不同。
    • 嗨,Jiggler,没问题,可能是我而不是你。所以要澄清一下,您是要返回多于一列(例如 4 然后 5 然后 6 等),还是只选择参考列。如果是这种情况,当您运行我的代码时,请在参考数据上选择整个表(第 1 到第 5 列),然后在下一个输入框中输入第 5 列。
    • 嗨@大卫怀亚特。我设法(最终)理解了你的代码。我通过删除“cNum”声明来修改它,然后在你的循环中添加一个“range.copy”对象变量然后presto!再次感谢
    • 很高兴听到,帮助
    【解决方案2】:

    欢迎来到 Stack Overflow!

    您可以通过 VBA 函数使用 Excel 工作表函数:Application.Worksheet

    例如,我有一个工作表函数:

    =VLOOKUP(D7,$A$2:$B$5,2,FALSE)
    

    ...所以在 VBA 中,我可以使用以下命令弹出一个具有相同结果的 MsgBox 对话框:

    MsgBox Application.WorksheetFunction.VLookup(Range("D7"), Range("$A$2:$B$5"), 2, False)
    

    更多信息:

    【讨论】:

    • 谢谢。但是,我不确定这会奏效,因为它不容易实现目标。正如我所说,我处理大量数据。如果我有 2000 行和 400 列的数据需要以不同的行顺序复制到不同的工作簿中,那么如果我在 vba 中使用 vlookup 函数,则需要多次运行此宏才能获得结果。您的建议将返回单列引用。在您的示例中,第 2 列。我需要循环 400 次以获取 400 列数据。复制粘贴宏不是更有效吗?再次感谢
    • 如果你要edit你的问题分享一个你有什么的例子,以及完成后它需要是什么样子,那将会很有帮助。 minimal reproducible example 有一些提示,还可以查看 Jon Skeet 的 Writing the perfect question(这个人在回答了 34,000 个问题后刚刚达到了 100 万个代表,所以他知道他在说什么......:-)
    猜你喜欢
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    相关资源
    最近更新 更多