我正在尝试从一个工作表中复制4个静态范围的单元格值,并将这些值粘贴到我动态构建的列表中包含的每个工作表的4个静态范围内的单元格中。
这是我的代码:
Sub retpsh()
Dim Home As Worksheet: Set Home = Worksheets("Home")
Dim s3 As Worksheet: Set s3 = Worksheets("Sheet3")
Dim s9 As Worksheet: Set s9 = Worksheets("Sheet9")
Dim s5 As Worksheet: Set s5 = Worksheets("Sheet5")
Dim s7 As Worksheet: Set s7 = Worksheets("Sheet7")
Dim Back As Worksheet: Set Back = Worksheets("Home Backstage")
Dim wsarray As Variant
Dim message As String: message = Back.Cells(18, 13)
Dim ws As Variant
If Back.Cells(18, 19) = 0 Then
If MsgBox("Nothing selected!", vbOKOnly) = vbOK Then Exit Sub
Else
If MsgBox(message + " Do you wish to continue?", vbYesNo) = vbNo Then Exit Sub
wsarray = Array(Back.Cells(18, 19)) 'Doesn't work properly
End If
For Each ws In wsarray
ws.Range("C2:C5", "C8:C11", "C13", "B18:C22") = Worksheets("Home Backstage").Range("B1:B4", "B6:B9", "B11", "B18:C22").Value '''''450 error with or without "Set" before line
Next ws
End Sub
首先,wsarray = Array(Back.Cells(18, 19))
不起作用,因为它不解析该单元格值,它将整个事物视为单个值(即"s3","s5","s7","s9"
或任何单元格值)。 Back.Cells(18, 19)
有一个公式,可根据" Home"上选择的4个选项构建列表。页。该公式将列表构建为以下16种组合中的任何一种:s3,s5,s7或s9。最终的单元格值如下:"s3"
或类似"s3","s7","s9"
。仅使用Dim wsarray()
或wsarray() =
不会改变行为。每当我使用wsarray()
而没有Array(...)
时,我都会收到'13' Type mismatch
错误。
其次,即使通过手动指定数组来绕过上述问题,我仍然会收到'450' Wrong number of arguments or invalid property assignment
错误。我知道设置一个范围与多个非连续的单元格=另一个范围设置相同的方式工作正常(例如Range("K15:C18","C29") = Range("C1:C4","C15")
),所以:
For
循环中不起作用?第三,For
循环中的语句需要完全限定的名称Worksheets("Home Backstage")
,并且不接受别名Back
。
For
不接受工作表别名Back
?For
循环是否在Dim
之前设置,因此在循环中需要Dim
?我知道我可以通过一堆If
语句解决所有这些问题,并参考" Home"上的4个选项中的每个选项的状态。页面,以确定要复制到哪些工作表,但我不喜欢这个想法。这似乎不是解决这个问题的正确方法,有一堆重复的代码,对谓词有轻微的改变,因此我希望使用数组。不过,我的问题更多是为什么"而且"怎么",但我感谢任何指导或解释都一样!
答案 0 :(得分:1)
您需要在单元格中输入实际的工作表名称:
sheet9,sheet7
将字符串或变量等同于变量名称不起作用,因此您需要遍历Split创建的数组并确保该表存在,然后使用它。
您不能使用具有两个以上单元格引用的范围。范围预计开始和结束。
Sub retpsh()
Dim Home As Worksheet: Set Home = Worksheets("Home")
Dim Back As Worksheet: Set Back = Worksheets("Home Backstage")
Dim wsarray() As String
Dim message As String: message = Back.Cells(18, 13)
Dim i As Long
If Back.Cells(18, 19) = 0 Then
If MsgBox("Nothing selected!", vbOKOnly) = vbOK Then Exit Sub
Else
If MsgBox(message + " Do you wish to continue?", vbYesNo) = vbNo Then Exit Sub
wsarray = Split(Back.Cells(18, 19).Value, ",")
End If
For i = LBound(wsarray) To UBound(wsarray)
If Not IsError(Application.Evaluate("'" & wsarray(i) & "'!A1")) Then
With Worksheets(wsarray(i))
.Range("C2:C5").Value = Back.Range("B1:B4").Value
.Range("C8:C11").Value = Back.Range("B6:B9").Value
.Range("C13").Value = Back.Range("B11").Value
.Range("B18:C22").Value = Back.Range("B18:C22").Value
End With
End If
Next i
End Sub
答案 1 :(得分:1)
这是另一个选项,非常类似于斯科特的选项,但是使用了更多的数组来处理你的范围:
Sub retpsh()
Dim Back As Worksheet: Set Back = Worksheets("Home Backstage")
Dim wsarray As Variant
Dim fromRangeArray As Variant
Dim toRangeArray As Variant
Dim message As String: message = Back.Cells(18, 13)
Dim ws As Variant
If Back.Cells(18, 19) = 0 Then
If MsgBox("Nothing selected!", vbOKOnly) = vbOK Then Exit Sub
Else
If MsgBox(message + " Do you wish to continue?", vbYesNo) = vbNo Then Exit Sub
wsarray = Split(Back.Cells(18, 19).Value, ",")
End If
'Could do this into a single multidimensional array if you are a sadist
fromRangeArray = Array("B1:B4", "B6:B9", "B11", "B18:C22")
toRangeArray = Array("C2:C5", "C8:C11", "C13", "B18:C22")
'loop through sheet names
For Each ws In wsarray
For rngIndex = 0 To UBound(fromRangeArray)
Sheets(ws).Range(toRangeArray(rngIndex)).Value = Back.Range(fromRangeArray(rngIndex)).Value
Next rngIndex
Next ws
End Sub