excel 运行时错误438对象不支持使用set的此属性

vwoqyblh  于 2023-02-25  发布在  其他
关注(0)|答案(2)|浏览(431)

我有一个简单的脚本,它将一些变量声明为一个范围,但我得到了错误
运行时错误"438":
对象不支持此属性或方法
我错过了什么?

Sub copyId()

Dim numberID As Range, column As Range, pasteId As Range

Set column = Workbooks("Book4.xlsm").Worksheets(1).Columns("C")
Set pasteId = Workbooks("Book5.xlsx").Worksheets(1).Columns("A").xlUp

For Each numberID In column
    If numberID Like "########" Or numberID Like "#########" Then numberID.Copy Destination:=pasteId
Next numberID

End Sub
xytpbqjk

xytpbqjk1#

BigBen's answer已经识别了正确的拼写,但是这个特定错误(运行时错误号438)的 * 原因 * 通常是使用了 * 隐式后期绑定 *,这是不好的,因为它遵从了运行时错误,否则这些错误可以在编译时更早地被捕获。
Worksheets(1)之后的所有内容都是隐式后期绑定的:

Set pasteId = Workbooks("Book5.xlsx").Worksheets(1).Columns("A").xlUp

这意味着.Columns("A")调用是在运行时解决的,而对返回对象的.xlUp成员调用对编译器是完全不可见的,这就是将问题推迟到运行时解决的原因。
每当你输入一个点操作符(.),而编辑器没有给你一个可用成员的列表时,你就是在调用一个没有编译器安全网的成员,甚至Option Explicit也不能保存你:编译器会很高兴地说“这是一个变体,我们将在运行时计算出它的成员调用”,但这并不意味着您应该同样满意它。
通过引入对象变量,您可以为编译器提供它所缺少的推动力:

Dim book As Workbook
Set book = Application.Workbooks("Book5.xlsx") 'did the macro open this book? if so, you should already have a reference to it.

Dim sheet As Worksheet
Set sheet = book.Worksheets(1)

原因是,Sheets.Item属性返回一个Object,而这正是您使用Worksheets(1)调用的内容:Workbook.Worksheets属性返回Sheets对象,但Sheets.Item(其默认属性)返回Object,这意味着任何链接成员调用的解析都将推迟到运行时。
使用局部Worksheet类型的变量,编译器不再只看到Object;它知道Worksheet的成员是什么,所以Columns属性现在可以在编译时解析,类似地,Range.Columns产生一个Range对象,但是这里我们隐式地调用它隐藏的[_Default]属性(以"A"作为参数),并且返回一个Variant,其解析也延迟到运行时,因此我们引入另一个变量:

Dim columnA As Range
Set columnA = sheet.Columns("A")

现在这变成了一个 * 编译时 * 错误,因为当你输入.点时,xlUp不会被列出:

Set pasteId = ColumnA.xlUp

这是运行时错误438的编译时等价物。

x7yiwoj4

x7yiwoj42#

xlUpRange.End一起使用。然后,您需要确定循环 * 内部 * 的最后一个单元格:

For Each numberID In column
    If numberID Like "########" Or numberID Like "#########" Then 
        With Workbooks("Book5.xlsx").Worksheets(1)
            numberID.Copy Destination:=.Cells(.Rows.Count, "A").End(xlUp).Offset(1)
        End With
    End If
Next
    • 编辑**:

您(大概)不想遍历列中的每一个单元格......而是查找最后一行:

Dim sourceBook As Workbook
Set sourceBook = Workbooks("Book4.xlsm")

Dim destBook As Workbook
Set destBook = Workbooks("Book5.xlsx")

Dim sourceSheet As Worksheet
Set sourceSheet = sourceBook.Worksheets(1)

Dim destSheet As Worksheet
Set destSheet = destBook.Worksheets(1)

With sourceSheet
    Dim lastRow As Long
    lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
End With

Dim sourceCells As Range
Set sourceCells = sourceSheet.Range("C1:C" & lastRow)

For Each numberID in sourceCells
    If numberID Like "########" Or numberID Like "#########" Then 
        With destSheet
            numberID.Copy Destination:=.Cells(.Rows.Count, "A").End(xlUp).Offset(1)
        End With
    End If
Next

相关问题