简体   繁体   English

复制粘贴多个范围的VBA

[英]Copy paste multiple ranges VBA

I'm trying to copy paste values from one workbook to another. 我正在尝试将粘贴值从一个工作簿复制到另一个工作簿。 I would like to specify multiple ranges so I can avoid using one variable for each range. 我想指定多个范围,因此可以避免为每个范围使用一个变量。 I use the below simplified code that doesn't work for me: 我使用以下对我不起作用的简化代码:

Sub Gather()

Dim y As Workbook

'## Setting variables ##
 Dim Contractual_flow_mat_C66_r460_470_c120_130_140 As Variant


'## Open Workbooks ##

  Set y = Workbooks.Open("Y")

'## Store values ##

    Contractual_flow_mat_C66_r460_470_c120_130_140 = y.Sheets("66").Range("P56:R57", "P62:R68", "P72:R74")

'## Input the values ##

    ThisWorkbook.Sheets("Denominator").Range("D48:F49", "D51:F57", "D59:F61") = Contractual_flow_mat_C66_r460_470_c120_130_140

'## Other ##

y.Close

End Sub

I get the error "Wrong number of arguments or invalid property assignment" on this row: 我在此行上收到错误“参数数量错误或属性分配无效”:

Contractual_flow_mat_C66_r460_470_c120_130_140 = y.Sheets("66").Range("P56:R57", "P62:R68", "P72:R74")

You don't need to use any variables at all other than to hold your source workbook reference: 除了保留源工作簿参考之外,您根本不需要使用任何变量:

Sub Gather()

  Dim y As Workbook
  Set y = Workbooks.Open("Y")

  ThisWorkbook.Sheets("Denominator").Range("D48:F49").Value2 = y.Sheets("66").Range("P56:R57").Value2
  ThisWorkbook.Sheets("Denominator").Range("D51:F57").Value2 = y.Sheets("66").Range("P62:R68").Value2
  ThisWorkbook.Sheets("Denominator").Range("D59:F61").Value2 = y.Sheets("66").Range("P72:R74").Value2

  y.Close

End Sub

Now, you can use variables, and you should, for your worksheet references. 现在,您可以使用变量,并且应该为工作表引用。 ThisWorkbook can change on you, especially when opening new workbooks: ThisWorkbook可能会因您而改变,尤其是在打开新工作簿时:

Sub Gather2()

  On Error GoTo ErrorHandler
  Dim destSheet As Worksheet
  Set destSheet = ThisWorkbook.Sheets("Denominator")

  Dim sourceBook As Workbook
  Set sourceBook = Workbooks.Open("Y")
  Dim sourceSheet As Worksheet
  Set sourceSheet = sourceBook.Sheets("66")

  destSheet.Range("D48:F49").Value2 = sourceSheet.Range("P56:R57").Value2
  destSheet.Range("D51:F57").Value2 = sourceSheet.Range("P62:R68").Value2
  destSheet.Range("D59:F61").Value2 = sourceSheet.Range("P72:R74").Value2

CleanExit:
  If Not sourceBook Is Nothing Then
    sourceBook.Close
  End If

  Exit Sub

ErrorHandler:
  MsgBox ("Failed to open workbook 'y'")
  Resume CleanExit

End Sub

I added a bit of error handling in there for you, just in case 'Y' doesn't exist. 我在其中为您添加了一些错误处理,以防万一'Y'不存在。

The next step is to add some variables for your actual range addresses so you can loop through them in case you ever need to copy more ranges, or if the ranges ever change (either source or destination). 下一步是为您的实际范围地址添加一些变量,以便在需要复制更多范围或范围发生更改(源或目标)的情况下可以遍历它们。

In general, your code should work one step further, if you declare the ranges like this: 通常,如果您声明这样的范围,则代码应该进一步工作:

With Worksheets(1)
    Set someSource = .Range("P56:R57, P62:R68, P72:R74")
End With

With Worksheets(2)
    Set someTarget = .Range("D48:F49, D51:F57, D59:F61")
End With

Thus, you need one less " per range. If you want to do it your way, the tricky part is to use the .Areas property of a Union of ranges and to loop through it. Thus, try like this: 因此,你需要一个都不能少" 。每范围内。如果你想要做你的方式,棘手的部分是使用.Areas范围的联盟,并通过其循环特性。因此,尝试这样的:

Sub TestMe()

    Dim someSource      As Range
    Dim someTarget      As Range
    Dim rng1            As Range
    Dim rng2            As Range

    With Worksheets(1)
        Set someSource = Union(.Range("P56:R57"), .Range("P62:R68"), .Range("P62:R68"))
    End With

    With Worksheets(2)
        'Without a Union(), but the same:
        Set someTarget = .Range("D48:F49, D51:F57, D59:F61")
    End With

    Dim cnt1 As Long
    Dim cnt2 As Long

    For Each rng1 In someSource.Areas
        cnt1 = cnt1 + 1
        For Each rng2 In someTarget.Areas
            cnt2 = cnt2 + 1
            If cnt1 = cnt2 Then
                rng2.Value = rng1.Value
            End If
        Next rng2
        cnt2 = 0
    Next rng1

End Sub

I have simplified the task, asking it to copy ranges from the first worksheet to the second one. 我简化了任务,要求它将范围从第一个工作表复制到第二个工作表。 In general it is quite the same. 通常情况是完全一样的。

In the nested loop, the idea is that we have two collections with which we should make sure, that: 在嵌套循环中,我们的想法是我们有两个集合应确保:

  • Area 1 from the worksheet(2).Values = Area 1 from worksheet(1).Values 工作表(2)中的区域1。值=工作表(1)中的区域1。值
  • Area 2 from the worksheet(2).Values = Area 2 from worksheet(1).Values 工作表(2)中的区域2.值=工作表(1)。值中的区域2
  • Area 3 from the worksheet(2).Values = Area 3 from worksheet(1).Values 工作表(2)中的区域3。值=工作表(1)中的区域3。值

Edit: And if you dislike the nested loops for their O(n^2) complexity, you may use the .Item(value) of the Areas for a linear one: 编辑:如果您不喜欢嵌套循环的O(n ^ 2)复杂性,则可以将.Item(value)用作线性.Item(value)

Dim cnt     As Long
For cnt = 1 To someSource.Areas.Count
    Debug.Print someSource.Areas.Item(cnt).Address
    Debug.Print someTarget.Areas.Item(cnt).Address
    someTarget.Areas.Item(cnt).Value = someSource.Areas.Item(cnt).Value
Next cnt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM