【发布时间】:2012-04-29 11:17:55
【问题描述】:
我们在公司的几台机器上使用了一组 Excel 文件。这些文件包含一个 VBA 应用程序,它利用了来自mscomct2.ocx 库(即MonthView 和DateTimePicker)的几个ActiveX 控件对象。 ActiveX 对象将显示在用户窗体中。不幸的是,这些文件的可移植性似乎以一种非常特殊的方式受到限制。
似乎有 2 组机器:
-
A 组:我可以在这样的机器上创建一个包含
MonthView的 Excel 文件,并在任何 A 组 PC 上使用它。但是当我尝试在 B 组的任何机器上打开此文件时,我收到 Could not load an object because it is not available on this machine 错误。但是,在 B 组机器上创建的具有相同 ActiveX 的文件在 A 机器上可以正常工作。 - B 组: 在这些机器上创建的带有相关 ActiveX 的文件在任何地方都可以工作(即在任何 A 和 B 机器上)。但是,正如我之前所说,当打开A机器上保存的带有ActiveX的文件时,B机器会出现上述错误。
一句话:在A机器上创建的文件只能在其他A机器上工作,在B机器上创建的文件无处不在!
这里最奇怪的是每台机器都注册了mscomct2.ocx(再说一次:我可以用MonthView在任何有问题的机器上创建表单!)。 .ocx 本身位于每台机器上,并且存在整套注册表项(用于控件类的 CLSID、IID、typelib ID...)。此外,这些注册表项中的数据在 A 组和 B 组机器(GUID、ProgID、版本等)上似乎相同。某些机器上的描述字符串(如“Microsoft MonthView Control 6.0 (SP6)”之类的值)略有不同,但这似乎不会影响情况(B组中的一些机器有这样的描述不同,但在它们上创建的文件仍然可以在任何地方工作)。
自然,由于墨菲定律,我用来编辑这些 Excel 文件的机器属于 A 组,所以这里保存的文件对于 B 机器“不可移植”...
操作系统和 Excel 版本似乎不会影响这种情况。例如,其中一台 B 机器在 Win 7 64 位 (Excel 2007) 下工作,而大多数其他 A 和 B 组机器是 Win XP Prof (32 位) SP3,安装了 Excel 2003。所以看起来 OS 和 Excel 版本不影响兼容性,问题与 ActiveX 有某种联系。
我发现A组和B组之间唯一与ActiveX相关的区别是mscomct2.ocx的文件版本:至少有几台A机器有6.1.x.x版本,而B组有6.0.x.x。我不明白这种差异如何导致问题(ActiveX 毕竟是 COM 对象,根据注册表键值,暴露的 typelib、com 对象和接口似乎在所有情况下都是相同的)。尽管如此,我还是尝试用 6.0.x.x 版本替换我的 6.1.x.x ocx ......但遇到了更多麻烦。我所做的是:
-
regsvr32 /u mscomct2.ocx- 成功完成 - 将
mscomct2.ocx替换为 6.0.x.x 版本的文件 -
regsvr32 mscomct2.ocx- 成功完成
在这些步骤之后,我尝试制作一个包含MonthView 的单一表单的 Excel 文件。但是当我试图在表单中放置一个控件时,我得到了一个带有错误 Class not registered 的消息框。这真的很奇怪,因为一切似乎都已注册:控件类、它的接口、typelib(是的,我已经检查了注册表以确定)。但错误仍然存在。
之后,我再次执行取消注册/替换/注册过程以返回到我原来的 6.1.x.x 文件。这让我回到了最初的 SNAFU 情况:我可以再次将 ActiveX 安装到用户表单并使用它,但是 B 组机器仍然在我机器保存的文件上报错。
我认为文件与 ActiveX 的可移植性问题和ocx 注册问题有某种联系,但我不知道如何联系。在 Excel VBA 中注册 ActiveX 可能还有一些我不知道的额外要求...
我唯一需要的是让我的 Excel 文件中包含的 ActiveX 对象与其他机器兼容。谁能帮我解决这个问题?
【问题讨论】: