如何仅使用.xla文件中的代码通过GZip压缩Excel VBA中的文件?
我需要能够GZip压缩Excel VBA函数中的文件。具体来说,我需要能够使用"放气"算法。
有没有一种方法而不必执行命令行应用程序?不依赖外部工具,代码将更加健壮。
理想情况下,代码将使用预安装的VBA或者COM库函数,而我不想自己实现此逻辑或者安装DLL等。
如果可能,我希望该功能的安装就像将.xla添加到可用的Excel加载项一样简单。无需DLL,EXE,注册表项等。
编辑我可以利用.NET GZipStream做到这一点吗?
解决方案
如果要在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
对于这类应用程序,VBA(实际上是VB6的一种方言)运行缓慢。我记得我曾经在VB6和C上实现Shannon-Fano算法,即使被转换为DLLMain并从那里调用而不是在命令行可执行文件上,C版本的速度也要快10倍左右。
有许多COM DLL提供压缩服务,包括开源和共享软件,其中一些实现GZIP的deflate算法。仅从VBA代码中的此类DLL中调用一个函数来代表我们进行压缩是非常简单的。
我了解我们不愿意在应用程序外部使用某些内容,尽管在这种情况下,出于性能考虑,我们可能必须应用异常。
为了完全破坏乐趣,请检查Windows \ system32上的文件ZIPFLDR.DLL。我们可能还想看看这些链接:
- 这有一个如何从VB.NET进行所需操作(使用Windows内置ZIP功能进行压缩)的示例,它与VBA或者VB6并没有太大区别:使用DLL调用的透明ZIP
- 这是一个在VB6上的示例应用程序,使用Windows内置功能进行zip(当然是ZIP而不是GZIP格式):使用Windows XP"压缩文件夹" shell扩展来处理.zip文件
通过谷歌搜索找到两者,我们应该能够找到更多/更好的示例。
似乎我们想打开一瓶葡萄酒,但是我们一定要拒绝使用开瓶器。只要不存在允许对文件进行GZipping的VBA功能,如果没有某些外部资源(例如dll或者exe文件),我们将无法执行此工作。
好吧,我想我有一个答案。
zlib是由编写我们不想实现的deflate算法的人编写的库。没有可用的win32 DLL。这是有关在Windows上使用它的常见问题解答:
http://www.zlib.net/DLL_FAQ.txt
查看问题7. 作者似乎不太热衷于Windows用户,也不完全不喜欢VB用户,但是只要他们足够友好地提供库,我们就可以完成其余工作。
如果这足以,那就太好了。如果我们需要有关从VBA调用C库的帮助,请添加注释,我们将予以解决。多年来,我还没有进行过VB到C的呼叫-听起来很有趣。
如果有人想在不依赖第三方软件的情况下压缩文件,他们通常会将其实现为COM对象/ DLL,因此它不仅可以用于Excel,还可以使用。如果有人想将zip功能合并到Excel中,他们将使用3rd-party工具,这样他们就不必重新实现算法。因此,我们正顺应潮流。然而...
http://www.cpearson.com/excel/SaveCopyAndZip.htm
有两个版本。 COM加载项版本" ...允许我们压缩已保存到磁盘的任何工作簿(但可能处于未保存状态)。"它依赖于Moonlight Software组件,但所有组件和设置都包含在安装程序中。它不是公共领域,但是许可证的限制不如GPL。最终结果是一个Excel加载项(使用第3方组件)。
但是,如果我们确实确实不希望对外部工具有任何依赖关系,则我们或者必须自己实施压缩算法,或者等到Microsoft将功能嵌入Windows并通过Excel公开。
我希望这有帮助。