Arrays VBA将静态范围复制/粘贴到动态生成的工作表数组中的静态范围

Arrays VBA将静态范围复制/粘贴到动态生成的工作表数组中的静态范围,arrays,excel,vba,Arrays,Excel,Vba,我试图从一个工作表中复制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 Wo

我试图从一个工作表中复制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”或任何单元格值)<代码>返回。单元格(18、19)
有一个公式,可以根据“主页”上选择的4个选项构建列表。该公式将列表构建为以下16种组合中的任意一种:s3、s5、s7或s9。最后的单元格值类似于:
“s3”
或类似于
“s3”、“s7”、“s9”
。仅使用
Dim wsarray()
wsarray()=
不会改变行为。每当我使用
wsarray()
而不使用
Array(…)
时,都会出现
'13'类型不匹配的错误

  • 这是一个动态定义数组维度的问题吗 首先
  • 如果没有,是否有方法将单元格值解析到数组中
  • 如果不是,如何在VBA中动态构建数组列表
  • 第二,即使通过手动指定数组来绕过上述问题,我仍然会得到一个
    '450'个错误的参数数或无效的属性分配
    错误。我知道用多个非连续单元格设置一个范围=另一个范围设置,同样的方法也可以正常工作(例如
    范围(“K15:C18”、“C29”)=范围(“C1:C4”、“C15”)
    ),因此:

  • 为什么该语法在
    For
    循环中不起作用
  • 第三,For
    循环中的
    语句需要完全限定的名称
    工作表(“Home Backstage”)
    ,并且不接受别名
    Back

  • 为什么
  • 不接受工作表别名
    Back
  • For
    循环是否在之前设置的
    Dim
    之外工作,因此需要在循环内设置
    Dim

  • 我知道我可以用一堆
    If
    语句来解决所有这些问题,并参考“主页”上4个选项中的每个选项的状态来确定要复制到哪些工作表,但我不喜欢这种想法。这似乎不是解决这个问题的正确方法,因为有一堆重复的代码,谓词略有更改,因此我希望使用数组。尽管如此,我的问题更多的是“为什么”而不是“如何”,但我仍然感谢任何指导或解释

    您需要在单元格中输入实际的图纸名称:

    sheet9,sheet7
    
    将字符串或变量等同于变量名是不起作用的,因此需要循环通过Split创建的数组,并确保工作表存在,然后使用它

    不能将范围与两个以上的单元格引用一起使用。Range需要一个开始和一个结束

    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
    

    您需要在单元格中输入实际的图纸名称:

    sheet9,sheet7
    
    将字符串或变量等同于变量名是不起作用的,因此需要循环通过Split创建的数组,并确保工作表存在,然后使用它

    不能将范围与两个以上的单元格引用一起使用。Range需要一个开始和一个结束

    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
    

    这里有另一个选项,与Scott的非常类似,但使用更多的数组来处理您的范围:

    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
    

    这里有另一个选项,与Scott的非常类似,但使用更多的数组来处理您的范围:

    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
    

    第一个问题:
    wsarray=Split(Back.Cells(18,19),“,”)
    第二个问题你需要分别处理每个区域,你不能给一个不连贯的区域分配一个不连贯的范围值。@Scott,你读过整篇文章了吗?我知道
    wsarray=Back.Cells(18,19)。Value
    不起作用,因此我提出了前3个问题。至于你评论的第二部分,为什么
    Range(“K15:C18”、“C29”)=Range(“C1:C4”、“C15”)
    单独运行时效果很好,但不在
    for
    循环中?请参见编辑,使用拆分。对于第二部分,您不能使用字符串来等同于vba变量名。你需要做一些不同的事情来循环工作表。@ScottCraner,我没有使用split,因为我认为它是一种字符串数据类型,并且会与
    For
    循环对变量数据类型的需求相冲突,但从未费心测试它。我很高兴地报告,在删除名称中的引号后,它的解析是正确的!谢谢至于断开的范围,不,它不起作用:
    范围(“K15:C18”、“C29”)
    不是断开的范围。放
    ?范围(“K15:C18”、“C29”)。在即时窗口中的地址
    ,您将获得
    $C$15:$K$29
    $K$15:$C$18,$C$29
    ,甚至在修复错误
    ws.Range(“C2:C5,C8:C11,C13,B18:C22”)。Value=Back.Range(“B1:B4,B6:B9,B11,B18:C22”)。Value
    没有任何作用。第一个问题:
    wsarray=Split(Back.Cells(18,19),“,”)
    第二个问题你需要分别处理每个区域,你不能将一个不连贯的区域值分配给一个不连贯的区域。@Scott,你看过整篇文章了吗?我知道
    wsarray=Back.Cells(18,19).Value不起作用,因此我提出了前3个问题。至于你评论的第二部分,为什么
    范围(“K15:C18”、“C29”)=范围(“C1:C4”、“C15”)
    如果单独运行,效果很好,但不在
    For
    循环中运行?请参见编辑,使用split。对于第二部分,您不能使用字符串来等同于vba变量名。您需要执行一些不同的操作来循环工作表。@ScottCraner,我没有使用split,因为我认为它是字符串数据类型,并且会使用c与
    For
    循环对变量数据类型的需求发生冲突,但从未费心测试它。我很高兴地报告,在删除名称中的引号后,它可以正确解析!谢谢!至于断开连接的范围,不,它不能