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文件并在其中执行宏,而不会被这个选项阻止,即使你使用"禁用所有而不通知"。
以下是将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;
}
}