Excel VBA:循环遍历单元格并将值复制到另一个工作簿

4

我已经花了数小时来尝试解决这个问题,但是没有找到有效的解决方案。

以下是我的问题描述

我想循环遍历一个工作簿中的某个单元格范围,并将值复制到另一个工作簿中。根据第一个工作簿中的当前列,我将值复制到第二个工作簿中的不同工作表中。当我执行代码时,总是出现运行时错误439:对象不支持此方法或属性

我的代码看起来差不多是这样的:

Sub trial()

Dim Group As Range
Dim Mat As Range
Dim CurCell_1 As Range
Dim CurCell_2 As Range

Application.ScreenUpdating = False

Set CurCell_1 = Range("B3") 'starting point in wb 1

For Each Group in Workbooks("My_WB_1").Worksheets("My_Sheet").Range("B4:P4")
    Set CurCell_2 = Range("B4") 'starting point in wb 2
    For Each Mat in Workbooks("My_WB_1").Worksheets("My_Sheet").Range("A5:A29")
        Set CurCell_1 = Cells(Mat.Row, Group.Column) 'Set current cell in the loop
        If Not IsEmpty(CurCell_1)
            Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).CurCell_2.Value = Workbooks("My_WB_1").Worksheets("My_Sheet").CurCell_1.Value 'Here it break with runtime error '438 object does not support this method or property
            CurCell_2 = CurCell_2.Offset(1,0) 'Move one cell down
        End If
    Next
Next

Application.ScreenUpdating = True

End Sub

我已经进行了详尽的研究,如果您使用明确的对象名称(工作表和范围),我知道如何将值从一个工作簿复制到另一个工作簿,但是我不知道为什么使用变量实现时它不起作用。我还在stackoverflow和Google上搜索过,但是没有找到类似的问题来回答我的问题。
所以我的问题是: 你能告诉我代码中的错误在哪里,或者是否有另一种更简单的方法使用不同的方式实现相同的效果吗?
这是我在这里的第一个问题,因此我希望我的代码格式、问题提出和提供的信息都没问题。如果有问题,请让我知道。
2个回答

11

5个注意事项...

1) 不需要这一行代码

Set CurCell_1 = Range("B3") 'wb 1中的起始点

由于你在循环内设置,所以此行代码是无意义的。

2) 你每次都在循环内进行设置

Set CurCell_2 = Range("B4")

为什么要这样做?这会简单地覆盖每个值。还有这个范围在哪个工作表中?(见第5点)

3)CurCell_2 是一个区域,正如JohnB所指出的那样,它不是一个方法。

Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).CurCell_2.Value = Workbooks("My_WB_1").Worksheets("My_Sheet").CurCell_1.Value

改为

CurCell_2.Value = CurCell_1.Value

4) 你不能仅通过设置“=”符号来分配范围

CurCell_2 = CurCell_2.Offset(1,0)

改为

Set CurCell_2 = CurCell_2.Offset(1,0)

5) 在处理两个或多个对象时,始终指定完整的声明,以减少混淆。你的代码也可以写成

Option Explicit

Sub trial()
    Dim wb1 As Workbook, wb2 As Workbook
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim Group As Range, Mat As Range
    Dim CurCell_1 As Range, CurCell_2 As Range

    Application.ScreenUpdating = False
    
    '~~> Change as applicable
    Set wb1 = Workbooks("My_WB_1")
    Set wb2 = Workbooks("My_WB_2")
    
    Set ws1 = wb1.Sheets("My_Sheet")
    Set ws2 = wb2.Sheets("Sheet2") '<~~ Change as required

    For Each Group In ws1.Range("B4:P4")
        '~~> Why this?
        Set CurCell_2 = ws2.Range("B4")
        For Each Mat In ws1.Range("A5:A29")
            Set CurCell_1 = ws1.Cells(Mat.Row, Group.Column)
            If Not IsEmpty(CurCell_1) Then
                CurCell_2.Value = CurCell_1.Value
                Set CurCell_2 = CurCell_2.Offset(1)
            End If
        Next
    Next

    Application.ScreenUpdating = True
End Sub

非常感谢!你的回答帮了我很多!我根据你的建议修改了我的代码,它立即按照预期运行!关于你提到的第二点:实际上你是对的,这个表格确实缺失了。如果我理解正确的话,那么一个范围指的是一个特定的单元格、工作表和工作簿,而不仅仅是一个单元格。但由于我在每个内部循环中使用Offset移动这个范围,所以我必须在外部循环中重置它。 - Patrick
如果我理解正确的话,那么“Range”指的是特定单元格、工作表和工作簿,而不仅仅是一个单元格。 不是的 :) “Range”代表一个单元格、一行、一列或包含一个或多个连续单元块的单元格选择,在工作表中。 - Siddharth Rout

2
Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).CurCell_2.Value

这样是行不通的,因为CurCell_2不是Worksheet的方法,而是一个变量。请替换为

Workbooks("My_WB_2").Worksheets(CStr(Group.Value)).Range("B4").Value

谢谢你的回答!听起来对我很有道理。 所以现在我清楚地明白了为什么会出现错误信息。但是如果结尾处的范围不总是Range("B4"),而是由变量CurCell_2定义的可变范围,你会如何编写代码呢? - Patrick
CurCell_2.Value = ...?或者类似于...Range(包含定义范围的字符串的变量)。Value = ... - JohnB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接