【问题标题】:Copy a sheet to a New workbook (of one sheet) without opening it将工作表复制到(一个工作表的)新工作簿而不打开它
【发布时间】:2019-03-14 18:45:36
【问题描述】:

我想将 ActiveWorkbook 中的工作表复制到新建工作簿。 新创建的工作簿将包含复制的工作表ONLY

我也不希望它在复制工作表时打开。我想将工作表静默复制到新创建的工作簿中。

如果我执行以下操作,则新创建的书有 3 张,而不仅仅是一张,并且在复印时会打开。它还问我是否想用宏保存它,而我只想复制 sheet1,所以不需要任何宏,如何解决它以满足我的需要?

ThisWorkbook.Sheets("Sheet1").Copy
ActiveWorkbook.SaveAs "C:\DestinationWb.xlsx", FileFormat:=51

【问题讨论】:

  • Sheet1 是否有 VBA 代码隐藏?如果是这样,文档模块(即相应的 VBA 项目组件)将与 Excel 工作表一起复制;如果您需要该代码,您想要的FileFormatxlOpenXMLWorkbookMacroEnabled51xlOpenXMLWorkbook 的基础值。我怀疑这可能是 Excel 一开始就警告使用宏保存它的原因。
  • 不,它不是,它只是一个表格,其中的文本在某些单元格等中使用颜色和日期格式格式化……但后面没有 vba。
  • 为什么不保持打开并提示是否关闭呢?它已经存在了,如果您要重新打开同一个文件,则无需关闭它...
  • Worksheet.Copy 创建新的目标工作簿并激活该工作簿 - 没有可打开的内容,如果您复制了工作表,无论您是否愿意,目标工作簿都将被打开......仍然可以关闭它只是为了提示用户是否要打开它是没有意义的。您正在与Worksheet.Copy 的副作用作斗争,这些副作用甚至允许您关闭创建的工作簿...
  • 查看documentation,并注意您可以使用VBA 中的Excel 对象模型与之交互的Workbook 对象只能作为Application.Workbooks 集合的元素存在:如果它是没有“打开”,就VBA而言它不存在。您可以想象使用 OpenXML 在没有 Excel 对象模型的情况下从头开始创建文件,但是由于您使用的是 VBA 并且您已经托管在 Excel 中,这样做没有什么意义,并且大大复杂化了应该是相当简单的事情.

标签: excel vba


【解决方案1】:

必须打开新创建的工作簿 - 否则您将如何保存它? - 但切换Application.ScreenUpdating 可能会促进您正在寻找的“无声”副本。切换Application.DisplayAlerts 也会根据需要抑制警报。

Application.ScreenUpdating = False
Application.DisplayAlerts = False

ThisWorkbook.Sheets("Sheet1").Copy
ActiveWorkbook.SaveAs FileName:="C:\DestinationWb.xlsx", FileFormat:=51
ActiveWorkbook.Close

Application.DisplayAlerts = True
Application.ScreenUpdating = True

【讨论】:

  • 谢谢,我明天下班试试,因为我现在没有工作簿。
  • 您好,我刚刚尝试了您提供的代码,它仍然打开书本大约 1-2 秒并关闭它。用户将清楚地看到这本书已打开。有没有其他方法,不是强制 sheet.copy 或者它是复制的唯一方法?
【解决方案2】:

您好,我刚刚尝试了您提供的代码,它仍然打开书本大约 1-2 秒并关闭它。用户将清楚地看到这本书已打开。有没有其他方法,而不是强制 sheet.copy 或者它是复制的唯一方法? – JustGreat 50 分钟前

在这种情况下我能想到的唯一方法是执行以下操作。

逻辑

  1. 使用.SaveCopyAs 方法保存现有工作簿的副本。你可以阅读更多关于.SaveCopyAsHERE
  2. 创建另一个 Excel 实例并将其隐藏
  3. 在该实例中打开副本
  4. 删除所有工作表,您想要的工作表除外。
  5. 保存并关闭,最后退出 Excel 实例。

代码

Sub Sample()
    Dim thisWb As Workbook

    '~~> New File Name
    Dim NewFile As String
    NewFile = "C:\Users\routs\Desktop\New folder\DestinationWb.xlsx"

    '~~> Sheets that you want to copy across
    Dim SheetToCopy As String
    SheetToCopy = "Sidd"

    Set thisWb = ThisWorkbook

    '~~> Save a copy of the current workbook to the new path
    thisWb.SaveCopyAs NewFile

    '~~> Create a new Excel instance and keep it hidden
    Dim tmpExcelApp As Object
    Dim ws As Object, thatWb As Object
    Set tmpExcelApp = CreateObject("Excel.Application")
    tmpExcelApp.Visible = False

    '~~> Open the copy file in hidden instance
    Set thatWb = tmpExcelApp.Workbooks.Open(NewFile)

    '~~> Delete all sheets except the one we copied
    tmpExcelApp.DisplayAlerts = False
    For Each ws In thatWb.Worksheets
        If ws.Name <> SheetToCopy Then ws.Delete
    Next ws
    tmpExcelApp.DisplayAlerts = True

    '~~> Save and close
    thatWb.Close (True)

    '~~> Quit Excel Instance
    tmpExcelApp.Quit

    MsgBox "Done"
End Sub

【讨论】:

  • 确实如此。相当迂回的方式,然后提示是否打开创建的工作簿仍然没有任何意义,但是是的,保存副本,然后删除除所需工作表之外的所有工作表,至少看起来像 OP 打算做的那样。可能希望在删除工作表时关闭计算;取决于里面的东西,否则这可能会很痛苦;-)
  • 我会使用 OleDb Drop Table 静默删除工作表,而不是在新实例中打开,但不幸的是 OleDb Drop Table 不会删除工作表。真希望……
  • 但是,是的,如果有公式引用其他工作表,OP 必须小心。不过可以在新实例中轻松处理:)
  • 对我来说工作得很好,但是当我尝试打开复制的文件时,Excel 说它无法打开,因为它无效或损坏,即使我复制了完全相同的代码。有什么建议吗?
  • @krobelusmeetsyndra:使用您正在使用的确切代码发布一个新问题。也可以随意添加对此问题的引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多