[英]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: 在嵌套循环中,我们的想法是我们有两个集合应确保:
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.