【问题标题】:Excel Workbook fails to open after updating and savingExcel 工作簿在更新和保存后无法打开
【发布时间】:2017-05-07 05:11:20
【问题描述】:

我有两本可以协同工作的工作簿。每周两次(通过 MS W10 任务计划程序和一个简单的 vbscript,运行 Excel 并将显示设置为“隐藏”),其中一个工作簿打开 (WB-A),执行 Web 查询,使用检索到的数据更新四个它的工作表,保存自己,然后打开另一个工作簿 (WB-B) 以开始进一步处理新数据。

这一切都很好地工作了一段时间。现在,在此更新过程完成后,我可以回到工作簿的唯一方法是如果我手动循环到另一个 Office 构建版本(通过“officec2rclient.exe /update user updatetoversion=16.0.XXXX.XXXX”,我一直在 1609 和 1610 之间切换)。

如果不这样做,Excel 会崩溃,我会看到错误消息告诉我 Excel 已“停止响应”。如果我先打开 Excel,然后尝试打开任一工作簿,有时我会看到一个错误,在关键警报 MsgBox 中只显示“400”。

最初我认为问题可能是由 WB-B 的重量引起的(磁盘上约 70mb,内存约 4GB),所以我开始着手解决它。我删除了所有无关的条件格式、命名范围和外部链接(到 WB-A)。这似乎有很大帮助,至少在加载时间上是这样。

乍一看,我似乎已经通过这些改进解决了这个问题。优化外部链接将调用次数减少了约 60%,并将整体内存使用量减少了约 50%。直到下一次预定的更新之后,我才意识到我还没有走出困境。

两个工作簿的相关细节

1) 它们包含表单按钮(控件)、条件格式、命名范围、公式,并且都支持宏。

2) 当它们无法打开时,它们会在应该出现按钮(控件)时失败(我相信工作簿正在完成其“计算”过程)。

3) 尝试在 Excel 中使用内置的“打开和修复”功能无法在与正常尝试完全相同的时刻加载任一工作簿。

4) 执行 Office365 的修复安装(快速和在线方法)无法解决问题。

5) 有其他时候我会去打开WB-B,每个单元格都被格式化为一个日期。删除“正常”的错误保存格式可以解决问题。

前一期

就在这开始发生之前,我收到了“The picture is too large and will be truncated”消息,因为自动更新过程似乎已经结束并保存了每个工作簿。在保存之前,我添加了Application.CutCopyMode = False,这似乎消除了该错误,因为我不再看到该弹出窗口。

后续步骤

我意识到我在每个工作簿中的条件格式和复杂公式是重大障碍,因此我再次鼓起勇气破解每个工作簿。我可以随意添加/删除 WB-B 中的所有按钮/条件格式,这样会很烦人(每次打开文件时都要处理),这是有可能的。

此时我唯一能想到的另一件事是将每个工作簿分成“一半”。

我可以看到分配给 WB-A 中的新工作簿的 4 或 5 张工作表,并且我可以限制 WB-B 中的工作表数量(目前它在每次更新期间添加一个新工作表,总计约 160 张工作表今天的)。限制 WB-B 中的工作表数量意味着我必须创建一个隐藏工作表,其中包含所有“截止后”工作表的相关数据,因为有依赖所述数据成功完成的 Subs。这些将被删除的工作表需要移动到新的工作簿中,因为它们在视觉上有助于整个工作簿的分析。

请求帮助

在我进入所有这些之前,我希望有人知道一些简单的 VBA,我可以使用它来解决所有这些问题。在我看来,Excel 必须缓存与这些工作簿相关的内容,但我无法找到任何相关信息。我的印象是使用Application.CutCopyMode = False 清除了剪贴板,但也许还有更多。

更新 (1-1-16)

看来问题与存储在 %temp% 中的文件直接相关。清除后,我不再遇到任何问题。

总结一下

1) 清除 Excel 可能使用的所有缓存(包括剪贴板)的正确方法是什么?

2) 什么可以解释工作簿无法打开并导致 Excel 崩溃,但在切换到不同的 Office 构建版本后成功打开?

3) 是否有一行代码会删除 Excel 存储在 %temp% 中的所有临时文件?

相关系统信息:Windows 10 Pro 64 位、AMD FX 8350、16 GB DDR3、Office365 1609 (Build 7369.2055)+

注意:我在我的笔记本电脑上也看到了这个问题,它是 Intel/DDR4,所以怀疑这个问题与处理器/RAM 有什么关系。

【问题讨论】:

  • 表单控件还是 ActiveX 控件?
  • 抱歉,表单控件

标签: excel vbscript macros large-files vba


【解决方案1】:
Public Declare Function CloseClipboard Lib "user32" () As Long
Public Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function EmptyClipboard Lib "user32" () As Long

Property Hwnd As Long
    read-only
    Member of Excel.Application

正常的架构是 UI 在一个事物中,数据在另一个事物中。我认为您应该主要在数据库中,而不是使用电子表格作为数据库。

Excel 在退出或粘贴到非 Excel 程序之前不会将任何内容复制到剪贴板。

所以调用 OpenClipboard、EmptyClipboard,然后调用 CloseClipboard。这将消除关于记忆的任何歧义。最终结果肯定不会被使用。根据帮助,不要使用 Excel 的 HWnd,而是使用 0。

这是 VB6/VBA6 alias 是可选的。

Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function EmptyClipboard Lib "user32" () As Long

Private Sub Form_Load()   
    x = OpenClipboard(0)
    y = EmptyClipboard()
    z = CloseClipboard()
    MsgBox x & " " & y & " " & z
End Sub

【讨论】:

  • 我无法让这些工作。我必须将“PtrSafe”添加到函数中以让它们清除调试器,但这删除了别名。我找不到清除地界线的方法。
  • 属性线来自对象浏览器,显示 Excel 的 hWnd 在哪里。
  • 我从没去过那个地区.. 找到了,谢谢!它显示的设置与您在那里的设置相同,因此我将在下次更新期间尝试通过此方法清除剪贴板。我编辑了我的问题以反映我到目前为止发现的内容。问题似乎与 %temp% 中存储的文件直接相关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 2017-05-26
相关资源
最近更新 更多