【问题标题】:VBA returns error 1004 while trying to copy worksheet to another workbook [duplicate]VBA 在尝试将工作表复制到另一个工作簿时返回错误 1004 [重复]
【发布时间】:2017-09-16 01:53:38
【问题描述】:

我有一个问题:尝试将工作表复制到另一个工作簿时出现错误(错误 1004)。 这是我的代码:

Sub CopyWorksheet()
Application.ScreenUpdating = False
Dim BonusRatesWB As Workbook
Dim appExcel  As Application

Set appExcel = New Application
appExcel.Visible = False
Set BonusRatesWB = appExcel.Workbooks.Open("D:\Documents\Overdraft\OVERDUE customers\HARD COLLECTION\Hard Collectors Bonus Calc\BonusRates\ProblemLoansOfficerBonusRates15Sep2017.xlsx")
With ThisWorkbook
    BonusRatesWB.Sheets(1).Copy After:=.Sheets(.Sheets.Count)
End With
BonusRatesWB.Close

appExcel.Quit
Application.ScreenUpdating = True

结束子

我认为我的对象变量有一些缺失/错误,但我无法弄清楚。帮助将不胜感激。 非常感谢。

【问题讨论】:

  • 你没有在 Dim 之后将 ThisWB 设置为任何内容
  • 您是否有充分的理由打开 Excel.Application 的 实例?
  • @DavidZemens 我想避免在代码运行时屏幕闪烁。我理解 ScreenUpdating=False 它仍然会打开新窗口。
  • Application.ScreenUpdating 控制屏幕“闪烁”。通常(可能有例外)打开工作簿将存在于 Excel 应用程序的 当前 实例中。一个新的“窗口”,但不是一个新的“应用程序”。我认为因为您在 Excel 的新实例中显式打开工作簿,所以您不能以这种方式复制它。您可以尝试在同一实例中打开吗?
  • @DavidZemens 当我尝试在同一个实例中打开它时它起作用了。但我不明白为什么它不适用于新实例。

标签: vba excel


【解决方案1】:

把 Dim 改成这个

Dim ThisWB As Workbook

然后添加:

Set ThisWB = ActiveWorkbook

您的ThisWorkbook 对象已声明但未赋值,要为对象赋值,您需要使用Set [object] = [value expression]

当且仅当 ThisWorkbook 在运行时是 ActiveWorkbook 时,此方法才有效。任何其他方案都将失败,因为您无法将不同的工作簿对象分配给ThisWorkbook 内置对象。

只需使用内置对象即可。您收到 1004 错误,因为您的 Sheets.Count 符合新打开的工作簿,而不是 ThisWorkbook,如果 BonusRatesWB.Sheets.Count > ThisWorkbook.Sheets.Count 将给出错误。为避免这种情况,总是将工作表、范围等限定为它们各自的父对象。下面使用With ThisWorkbook 块:

Sub CopyWorksheet()    
    Application.ScreenUpdating = False
    Dim BonusRatesWB As Workbook
    Dim appExcel  As Application

    Set appExcel = New Application
    appExcel.Visible = False
    Set BonusRatesWB = appExcel.Workbooks.Open("D:\Documents\Overdraft\OVERDUE customers\HARD COLLECTION\Hard Collectors Bonus Calc\BonusRates\ProblemLoansOfficerBonusRates15Sep2017.xlsx")
    With ThisWorkbook
        BonusRatesWB.Sheets(1).Copy After:=.Sheets(.Sheets.Count)
    End With
    BonusRatesWB.Close   

    appExcel.Quit
    Application.ScreenUpdating = True
End Sub

【讨论】:

  • 或者完全省略该声明并使用内置的 ThisWorkbook 对象——假设 OP 正在运行代码 来自 ActiveWorkbook 没有真正好的理由Dim 一个表示静态内置对象的变量,例如 ThisWorkbook ")
  • 我同意...我想过添加它,但想保持简单并向他展示你必须在 Dim 之后设置一个对象。
  • 感谢您的迅速答复。不幸的是,现在我收到错误 1004(应用程序定义或对象定义的错误)。
  • Dim 一个并不真正需要的变量会更简单:) 如果任何其他工作簿在运行时处于活动状态,您的代码实际上会因类型不匹配而失败。
  • @IvaBazhunaishvili 我已经确定了答案,我认为现在可以避免 1004。请参阅修改后的答案/解释。
【解决方案2】:

扩展 answer/revision ,似乎没有必要打开 Excel.Application 的新实例来打开/复制工作表(实际上这是您的 1004 错误的来源,见下文)。

在同一个实例中打开它,同时包含另一个答案:

Sub CopyWorksheet()    
    Application.ScreenUpdating = False
    Dim BonusRatesWB As Workbook
    Set BonusRatesWB = appExcel.Workbooks.Open("D:\Documents\Overdraft\OVERDUE customers\HARD COLLECTION\Hard Collectors Bonus Calc\BonusRates\ProblemLoansOfficerBonusRates15Sep2017.xlsx")
    With ThisWorkbook
        BonusRatesWB.Sheets(1).Copy After:=.Sheets(.Sheets.Count)
        BonusRatesWB.Close 
    End With
    Application.ScreenUpdating = True
End Sub

我认为您在两个不同的 Excel 应用程序中不会像这样 Copy 工作表,这似乎是 1004 错误的根源。

我不明白为什么它不能与新实例一起使用

This is by design limitation:

注意:您不能在单独的 Excel 实例中打开的工作簿之间移动或复制工作表。如果在单独的 Excel 实例中打开工作簿(例如,当您从 Windows SharePoint Services 站点打开该工作簿时可能会发生这种情况),请确保在同一 Excel 实例中打开该工作簿,而不是通过在打开对话框(文件选项卡,打开)。

如果您必须在新实例中打开,那么您可以使用this answer 中建议的解决方法,只需将工作表保存到新/临时文件,然后从 Excel 的原始实例中打开它,以便复制/粘贴。它的开销更大,但如果你需要这样做,那是唯一的方法。

【讨论】:

  • 非常感谢您的全面支持!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多