4

我需要能够 GZip 压缩 Excel VBA 函数中的文件。具体来说,我需要能够使用“放气”算法。

有没有办法做到这一点而不必执行命令行应用程序?由于不依赖外部工具,代码将更加健壮。

理想情况下,代码将使用预安装的 VBA 或 COM 库函数——我不想自己实现这个逻辑或安装 DLL 等。

如果可能的话,我希望该功能的安装与将 .xla 文件添加到可用的 Excel 加载项一样简单。不需要 DLL、EXE、注册表项等。

编辑我可以使用.NET GZipStream 来做到这一点吗?

4

5 回答 5

4

VBA(实际上是 VB6 的一种方言)对于这类应用程序来说速度很慢。我记得我曾经在 VB6 和 C 上实现过 Shannon-Fano 算法,C 版本的速度大约快 10 倍,即使在变成 DLLMain 并从那里调用而不是在命令行可执行文件上调用之后也是如此。

有许多提供压缩服务的 COM DLL,包括开源和共享软件,其中一些实现了 GZIP 的 deflate 算法。仅从您的 VBA 代码中调用此类 DLL 中的一个函数来代表您进行压缩非常简单。

我理解您不愿意使用应用程序外部的东西,但在这种情况下,为了性能起见,您可能必须应用例外。

为了彻底破坏您的乐趣,请检查 windows\system32 上的文件 ZIPFLDR.DLL。您可能还想看看这些链接:

通过谷歌搜索找到了两个,你应该能够找到更多/更好的例子。

于 2008-10-03T19:35:48.250 回答
3

好的,我想我有一个答案给你。

zlib 是由编写您不想实现的放气算法的人编写的库。有一个 win32 DLL 可用。以下是有关从 Windows 使用它的常见问题解答:

http://www.zlib.net/DLL_FAQ.txt

查看问题 7。作者似乎不太热衷于 Windows 用户,似乎根本不热衷于 VB 用户,但只要他们好心提供库,我们就可以完成剩下的工作。

如果这足以帮助您,那就太好了。如果您需要从 VBA 调用 C 库的帮助,请添加评论,我们会解决的。多年来我没有做过任何 VB-to-C 调用——这听起来很有趣。

于 2008-10-03T21:29:41.297 回答
0

如果要在 VBA 中实现该算法,则需要(在 VBA 中)保存电子表格,然后使用 VB 的 I/O 函数打开文件,将其放气,然后再次保存。出于所有意图和目的,它与编写处理文件的普通 VB 应用程序相同。您可能需要将 VBA 宏放在单独的工作簿中以避免“文件正在使用”类型的错误,但如果您以只读方式重新打开文件并使用不同的文件名保存它,您应该可以将所有内容保存在一个工作簿中。

但我几乎可以肯定,从 VBA 中提取 gzip 在功能上是相同的并且非常容易。

编辑:一些代码。我运行它时它没有失败,因此可以将所有内容保存在同一个工作簿中。

Sub main()
    ActiveWorkbook.Save
    Open "macrotest.xls" For Binary Access Read As #1
    Open "newfile.zip" For Binary Access Write As #2
        'do your stuff here
    Close #2
    Close #1
End Sub
于 2008-10-03T17:10:16.500 回答
0

似乎你想打开一瓶酒,但你肯定拒绝使用开瓶器。只要没有允许 GZipping 文件的 VBA 功能,如果没有一些外部资源(例如 dll 或 exe 文件),您将无法完成这项工作。

于 2008-10-03T20:51:00.080 回答
0

如果有人想在不依赖第 3 方软件的情况下压缩文件,他们通常会将其实现为 COM 对象/DLL,因此它不仅适用于 Excel。如果有人想将 zip 功能合并到 Excel 中,他们会使用 3rd-party 工具,这样他们就不必重新实现算法。所以你在逆流而上。然而...

http://www.cpearson.com/excel/SaveCopyAndZip.htm

有两个版本。COM 插件版本“...允许您压缩已保存到磁盘的任何工作簿(但它可能处于未保存状态)。” 它依赖于 Moonlight Software 组件,但所有组件和设置都包含在安装程序中。它不是完全公共领域,但许可比 GPL 限制更少。最终结果是一个 Excel 加载项(使用第 3 方组件)。

但是,如果您真的,真的不希望对外部工具有任何依赖,您要么必须自己实现压缩算法,要么等到 Microsoft 将该功能构建到 Windows 中并通过 Excel 公开它。

我希望这有帮助。

于 2008-10-04T14:52:10.787 回答