Excel Interop C#Can';t在工作簿上添加VBProject错误800A03EC.VBProjec

本文关键字:添加 VBProject 错误 VBProjec 800A03EC 工作簿 C#Can Interop Excel | 更新日期: 2023-09-27 18:02:32

I(全局解释

你好,

我正在使用Microsoft.Office.Interop.Excel在C#中开发一个应用程序。在我的情况下,我将存储在文件中的一些旧宏实现到由C#打开的Excel工作簿中,以便在不重新编码应用程序中的宏的情况下升级它们。

在全球范围内,我的应用程序中有我的流程:

  • 用户选择更新的宏
  • 我检查宏是否需要:
    • 在这里,我将注册表项CURRENT_USER''SOFTWARE''Microsoft''Office''[Office_ID].0''Excel''Security''AccessVBOM设置为1,以允许宏/VBProject修改
  • 我用新工作簿实例化Excel应用程序
  • 我设置了优化Excel执行参数(禁用刷新…诸如此类的东西(
  • 我将存储在文件中的宏添加到工作簿
  • 我通过Excel执行宏
  • 我从Excel中删除宏
  • 我取消设置优化Excel执行参数
  • 我重置寄存器键(…/AccessVBOM=0(

II(我的问题和我的研究结果

在"我将存储在文件中的宏添加到工作簿"部分,当我使用以下说明将VBProject添加到工作簿(添加宏所必需的(时,我收到错误800A03EC。

/// wb is a workbook object
VBComponent module = wb.VBProject.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule);

这个错误是通过一条消息发送的(严重的诽谤(:"对VB项目的访问不可信。">

正如我在互联网上看到的,当Excel中的某个选项设置不正确时,就会发生此错误。此选项可以使用CURRENT_USER''SOFTWARE''Microsoft''Office''[Office_ID].0.0''Excel''Security''AccessVBOM注册表项进行处理。我正在用注册密钥管理来构建我的应用程序,以避免这个问题。

正如您将在调试显示部分看到的,我们可以看到在执行时正确设置了选项。

我的问题:发生此错误时还有其他情况吗?

III(调试分析

当我捕捉到ComException时,我使用以下内容来显示寄存器键值。

/// RequirementManager is my own class, use to set and unset endpoints computers parameters, before and after each user action
RegistryKey reg;
for (int i = RequirementManager.EXCEL_ID_HANDLED_MIN; i < RequirementManager.EXCEL_ID_HANDLED_MAX; i++)
{
    reg = Registry.CurrentUser.CreateSubKey(@"SOFTWARE'Microsoft'Office'" + i + @".0'Excel'Security'", RegistryKeyPermissionCheck.ReadSubTree);
    Debug.WriteLine(String.Format(@"Value of CURRENT_USER'SOFTWARE'Microsoft'Office'{0}.0'Excel'Security'AccessVBOM = {1}", i, reg.GetValue("AccessVBOM")), "Debug");
    reg.Close();
}
reg = null;

这是这几行的控制台输出:

Debug: Value of CURRENT_USER'SOFTWARE'Microsoft'Office'11.0'Excel'Security'AccessVBOM = 1
Debug: Value of CURRENT_USER'SOFTWARE'Microsoft'Office'12.0'Excel'Security'AccessVBOM = 1
Debug: Value of CURRENT_USER'SOFTWARE'Microsoft'Office'13.0'Excel'Security'AccessVBOM = 1
Debug: Value of CURRENT_USER'SOFTWARE'Microsoft'Office'14.0'Excel'Security'AccessVBOM = 1
Debug: Value of CURRENT_USER'SOFTWARE'Microsoft'Office'15.0'Excel'Security'AccessVBOM = 1
Debug: Value of CURRENT_USER'SOFTWARE'Microsoft'Office'16.0'Excel'Security'AccessVBOM = 1

正如您所看到的,当发生错误时,该选项设置正确。并且在修改注册表项之前,Excel的所有实例都被关闭,以避免出现问题。我用类似的算法来修改这个范围的寄存器键,就像一个懒惰的男孩。


欢迎任何想法

问候,Dykoine


IV(回答反应

@prizm1这个参数如果宏被允许或不被允许(显示橙色警告消息(,并且在我的计算机上(测试时(我将其设置为允许所有宏。

经过测试,我可以看到这个选项并不能保护用户,因为我们可以用C#打开Excel文件并在其中执行宏,而不会被这个选项阻止,即使你使用"禁用所有而不通知"。

Excel Interop C#Can';t在工作簿上添加VBProject错误800A03EC.VBProjec

以下是将VBA放入Excel文件时没有出现任何问题的代码。也许你需要在输入代码之前先将其保存到磁盘上,因为项目是由文件名决定的。只是一个补充,没有真正的解决方案:

    public bool injectVBA(String scriptText, String target)
    {
        VBProject found = null;
        Access.Application currApplication = this.currentInstance.Application;
        if (target.Equals("") || scriptText.Equals(""))
            return false;
        foreach (VBProject vb in currApplication.VBE.VBProjects)
        {
            if (currApplication.CurrentDb().Name.Equals(vb.FileName))
            {
                found = vb;
                break;
            }
        }
        if (found != null)
        {
            foreach (VBComponent foundComponent in found.VBComponents) 
            {
                if (foundComponent.Name.Equals(target))
                {
                    return true;
                }
            }
            VBComponent module = found.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule);
            module.Name = target;
            module.CodeModule.AddFromString(scriptText);
            module.Activate();
            //currApplication.DoCmd.OpenModule(target, Type.Missing);
            currApplication.DoCmd.Save(Access.AcObjectType.acModule, target);
            return true;
        }
        else
        {
            return false;
        }
    }