【问题标题】:Range.Paste - Object doesn't support this property or methodRange.Paste - 对象不支持此属性或方法
【发布时间】:2016-11-16 18:49:59
【问题描述】:

我有一个非常简单的程序,可以从一个工作簿复制一个范围并将其粘贴到另一个工作簿中;问题是,我在paste 行的标题中出现错误。

下面是代码:

Sub copypasta()
Dim x As Workbook
Dim y As Workbook

Set x = ActiveWorkbook
Set y = Workbooks.Open("F:\Target\FTB\FTB.xlsx")

x.Sheets(1).Range("A1").CurrentRegion.Copy

y.Sheets("DTR").Cells.Delete '<~~~No Error Here...?
y.Sheets("DTR").[a1].Paste   '<~~~Error Here

我觉得很奇怪,删除工作正常,但粘贴却不行。

看来我可能遗漏了粘贴方法的一些基础知识 - 有人可以解释一下我在这里遗漏了什么吗?

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    其他答案提供了使其工作的方法,但没有解释发生了什么。

    y.Sheets("DTR")
    

    确实应该是y.Worksheets("DTR"),因为Sheets 集合可以包含非工作表项,例如图表。

    不管怎样,SheetsWorksheets 集合的 Item 属性(这是任何集合类型的默认属性)都会产生一个 Object,这使得每个链接成员随后的调用,一个后期绑定调用。

    并且您不会在后期绑定调用中获得 IntelliSense,因为这些调用在运行时得到解决,根据定义:您可以在 @ 上调用 anything 987654336@,代码会顺利编译:

    Sub Test()
        Debug.Print ThisWorkbook.Worksheets(1).Whatever
    End Sub
    

    同:

    Sub Test()
        Debug.Print ThisWorkbook.Worksheets.Item(1).Whatever
    End Sub
    

    在运行时,如果 VBA 在检索到的对象的接口上找不到 Whatever 成员,则会引发运行时错误 438,“对象不支持此属性或方法”。

    后期绑定功能强大且非常有用,但它也会产生您不一定需要的开销。

    除了处理Object,当您知道特定类型是什么时,您可以返回的对象引用转换为特定类型 - 在这种情况下我们知道我们正在处理一个Worksheet 对象:

    Dim target As Worksheet
    Set target = y.Worksheets("DTR")
    

    现在您有了早期绑定Worksheet 对象引用,IntelliSense 可以指导您:

    如果您尝试调用虚假成员(例如target.Whatever),您将收到编译时错误而不是运行时错误。

    当你这样做时:

    target.[A1].Paste
    

    您再次使用后期绑定来检索A1 范围。相反,调用 Worksheet.Range 属性 getter 来检索早期绑定的 Range 对象 - 从那里你会看到当你输入 .paste 时,在 Paste 中没有 Paste 方法@对象:

    当您键入所有内容时,您会获得自动完成和工具提示:

    【讨论】:

      【解决方案2】:

      您可以使用 1 行代码在工作表(和工作簿)之间 CopyPaste Ranges,只需将您的代码替换为以下行:

      x.Sheets(1).Range("A1").CurrentRegion.Copy y.Sheets("DTR").[a1] 
      

      如果你想使用PasteSpecial方法,你必须分两行完成,但你需要在PasteSpecial之后添加一个参数,比如xlValues

      x.Sheets(1).Range("A1").CurrentRegion.Copy
      y.Sheets("DTR").[a1].PasteSpecial xlValues
      

      【讨论】:

      • 快速注意,如果您只是复制/粘贴值,避免复制/粘贴的替代方法是将两个范围设置为彼此相等:Range([destination range]).value = Range([origin range]).value
      • @BruceWayne ...带星号:Range 隐含指活动工作簿,以便在 destination 工作簿不是 源时工作 工作簿,Range 调用需要完全限定与 Worksheet 参考。在这种情况下,至少是 destination 范围。
      • @Mat'sMug - 是的,很棒的电话,尤其是当他从一张纸复制到另一张纸时,我忘了提到这一点。谢谢抓!所以,更具体地说,它应该是y.Sheets("DTR").[a1].Value = x.Sheets(1).Range("A1").Value
      【解决方案3】:

      改成y.Sheets("DTR").[a1].PasteSpecial

      Paste 不适用于范围,要粘贴范围,您必须使用 PasteSpecial。我相信默认情况下它会做所有事情,但您可以指定很多,请参阅here

      【讨论】:

      • 谢谢@tjb1。不幸的是,现在我遇到了一个运行时错误: Range 类的 PasteSpecial 方法失败
      【解决方案4】:

      您的原始代码存在两个问题。

      1. Cells.Delete 语句出现在 副本之后,但删除操作会清除剪贴板。

      2. Paste 方法是 Sheet 对象的成员,而不是 Range 对象。

      调整你的代码,变成:

      y.Sheets("DTR").Cells.Delete
      x.Sheets(1).Range("A1").CurrentRegion.Copy
      y.Sheets("DTR").Paste y.Sheets("DTR").[a1]
      

      【讨论】:

        猜你喜欢
        • 2013-10-05
        • 1970-01-01
        • 2015-07-02
        • 2019-04-09
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多