我怎样才能使用.xla文件中的代码从Excel VBA压缩文件?

我需要能够在Excel VBA函数中GZip压缩文件。 具体而言,我需要能够使用'deflate'algorithm。

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

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

如果可能的话,我想要安装这个function就像在可用的Excel加载项中添加一个.xla一样简单。 没有DLL,EXE,registry项等要求。

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

VBA(这实际上是VB6的一种方言)对于这类应用程序来说是很慢的。 我记得我曾经在VB6和C上实现过香农 – 法诺(Shannon-Fano)algorithm,C版本的速度提高了10倍左右,甚至在变成一个DLLMain并从那里调用,而不是在命令行可执行文件中调用。

有很多提供压缩服务的COM DLL,既有开源的,也有共享的,有的实现了GZIP的deflatealgorithm。 从VBA代码中的这样一个DLL中调用一个函数来代表您执行压缩将非常简单。

我明白你不愿意在你的应用程序中使用外部的东西,尽pipe在这种情况下,你可能需要为了性能而应用一个例外。

为了完全破坏你的乐趣,请检查windows \ system32上的ZIPFLDR.DLL文件。 你也可以看看这些链接:

  • 这里有一个例子,说明如何从VB.NET中完成你想要的function(使用Windows内build的ZIPfunction进行压缩),它与VBA或VB6应该没有多大区别: 带DLL调用的透明ZIP
  • 这个在VB6上有一个示例应用程序,使用Windows内置的压缩​​function(当然是ZIP而不是GZIP格式): 使用Windows XP“压缩文件夹”shell扩展来处理.zip文件

通过谷歌search发现,你应该能够find更多/更好的例子。

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

zlib是一个由写这个你不想实现的deflatealgorithm的人编写的库。 有一个win32 DLL可用。 这里是关于从Windows使用它的常见问题解答:

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

查看问题7.作者对Windows用户似乎不太感兴趣,似乎并不热衷于VB用户,但只要他们足够提供库,我们就可以完成剩下的工作。

如果这足以帮助你,那么很好。 如果你需要从VBA中调用C库的帮助,请添加评论,我们将解决它。 我多年来没有做任何VB到C的调用 – 这听起来很有趣。

看来你想打开一瓶酒,但你肯定拒绝使用开瓶器。 只要没有VBAfunction允许GZip一个文件,你将无法做一些外部的资源,如DLL或EXE文件的工作。

如果有人想在不依赖第三方软件的情况下压缩文件,他们通常会将其作为COM对象/ DLL来实现,因此它不仅仅可以用于Excel。 如果有人想将zipfunction整合到Excel中,他们将使用第三方工具,这样他们就不必重新实现algorithm。 所以你在逆潮stream游泳。 然而…

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

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

但是,如果你确实不想要任何外部工具的依赖,那么你要么必须自己实现压缩algorithm,要么等到微软在Windows中构build这个function并通过Excel公开它。

我希望这有帮助。

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

但是我几乎可以肯定的是,从VBA中退出gzip的function是相同的,并且非常容易。

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

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