0

我需要不时将html文件转换为excel。大约有 9000 个包含表格的 html 文件。

我发现使用 excel 2007 vba 转换它们很有用,并制作了一个宏来完成这项工作,我已经考虑到 excel 的一个错误,它会在 Workbooks 上停止宏。按下 SHIFT 键时打开功能,除此之外我禁用了警报、事件和屏幕更新,并使应用程序不可见,因为我不想在我做其他事情时打扰我。

'Declare API
Declare Function GetKeyState Lib "User32" _
(ByVal vKey As Integer) As Integer
Const SHIFT_KEY = 16

Function ShiftPressed() As Boolean
'Returns True if shift key is pressed
    ShiftPressed = GetKeyState(SHIFT_KEY) < 0
End Function

Sub ConvertHtmlToExcel()
    Dim wb As Workbook
    Dim strFile As String
    Dim strPath As String

    With Application
        .EnableEvents = False
        .DisplayAlerts = False
        .ScreenUpdating = False
        .Visible = False
    End With

    strPath = "c:\FolderToConvert\"
    strFile = Dir(strPath & "*.html")

    Do While strFile <> ""
        Do While ShiftPressed()
            DoEvents
        Loop
        Set wb = Workbooks.Open(strPath & strFile)
        strFile = Mid(strFile, 1, Len(strFile) - 5) & ".xls"
        wb.SaveAs strPath & strFile, XlFileFormat.xlWorkbookNormal
        wb.Close
        Set wb = Nothing
        strFile = Dir
    Loop

    With Application
        .EnableEvents = True
        .DisplayAlerts = True
        .ScreenUpdating = True
        .Visible = True
    End With
End Sub

宏似乎很好,但是在运行时,我每分钟的转换率如下:

  1. 40
  2. 31
  3. 25
  4. 21
  5. 19
  6. 18

并且在 500 个文件转换后它现在一直在下降,其当前的速率是每分钟 8 个。

在 2359 个文件之后,速率降低到每分钟 2 个,在测试时我有 visible = true 并且看到打开工作簿需要更多时间。

所以问题似乎出在 Workbooks.Open 上,它在循环开始时尽可能快地工作,但在进一步的循环中它开始变慢。

有没有人偶然发现这个?有什么解决方法吗?我的代码缺少什么吗?有时宏仍然会停止执行,我假设该函数没有捕获 shift 键。

4

1 回答 1

2

在 Excel 中没有覆盖“shift bypass”功能的标准方法(与 Access 中的“AllowByPassKey”属性相反)。如果您应用的代码有问题(我没有尝试过),您是否考虑过创建一个插件?

http://msdn.microsoft.com/nl-nl/library/aa671739(v=vs.71).aspx 在微软网站上明确提到:

将 Excel 加载项与典型工作簿文件区分开来的几个特征:

  • 用户不能使用 SHIFT 键绕过加载项中内置的事件。此功能可确保您在加载项中编写的任何事件过程都将在适当的时间运行。

关于速度:您似乎正确地为循环中的“工作簿”对象分配(.open)和释放(设置为空)内存,因此它在 RAM 中占用的内存在处理过程中不应增加或减慢。

这个有趣的线程可以提供一个解释:

http://www.add-ins.com/support/out-of-memory-or-not-enough-resource-problem-with-microsoft-excel.htm

“我们从上述测试中得出的结论是,VBA 加载项不会使用大量内存。工作簿是内存的主要用户。而 Excel 在关闭工作簿时不会释放所有内存。它支持一种关闭方法并在完成大量工作后重新启动 Excel。您应至少每两个小时关闭并重新打开 Excel 一次。

也许值得尝试每次设置一个新的应用程序并使用 application.quit,它会从内存中清除整个 Excel 应用程序。

 Dim appExcel As Excel.Application

 Set appExcel = CreateObject("Excel.Application")
 appExcel.Workbooks.Add
 'Do smtg
 appExcel.Quit

希望这对你有用!有趣的问题!

于 2012-06-29T09:23:23.947 回答