【问题标题】:Is there a way to set temporary flags on Excel workbook objects?有没有办法在 Excel 工作簿对象上设置临时标志?
【发布时间】:2011-03-07 16:11:58
【问题描述】:

我有一个 C# 帮助程序类 (ExcelMacroHelper),它有助于将 VBA 宏代码注入打开的 Excel 工作簿并运行生成的宏。我刚刚意识到以下步骤会破坏我的代码:

  1. C# 应用程序将宏代码注入活动工作簿,这导致 ExcelMacroHelper 将其状态标记为准备运行宏

  2. 用户在 Excel 中切换到不同的工作簿。

  3. C# 应用程序尝试运行宏。 ExcelMacroHelper 会认为它已准备好运行宏,但 VBA 代码被注入到不同的工作簿中,因此调用将失败。

为了解决这个问题,我认为我需要一些方法在 Workbook 对象上设置一个临时属性,表明我的宏代码已被注入其中,或者至少是一种维护 Workbooks 列表的方法已处理。有什么想法吗?

【问题讨论】:

    标签: c# excel vba interop


    【解决方案1】:

    您可以使用名称来保存值(以及范围引用等)

    在伪代码中

    if not (name already exists) then
        Set nm = workbook.Names.add("Injected")
        nm.Value = False
        nm.Visable = False
    end if
    
    if nm.value = False
        //Inject Code
        nm.value = true
    endif
    

    注意:测试名称是否存在的最简单方法是尝试访问它并在不存在时处理错误

    【讨论】:

      【解决方案2】:

      您可以使用WorkbookTag 属性。

      当你注入代码时,你可以这样做:

      public class ExcelMacroHelper
      {
         public static void Inject(Workbook workbook)
         {
             if ((workbook.Tag as String != "Injected"))
             {
                //Inject the code
      
                 workbook.Tag = "Injected";
             }
         }
      }
      

      【讨论】:

      • 这似乎正是我想要的,除了 Workbook 对象没有我的 Tag 属性(使用 Office 2007)。
      • @jnylen - 这很奇怪......我刚刚启动了一个 Office 2007 工作簿项目 (Visual Studio 2008),它有一个标签属性。
      • 我正在使用 Microsoft.Office.Interop.Excel 库和命名空间。您似乎正在使用 VSTO Excel 库。
      【解决方案3】:

      我最终使用了自定义文档属性。像这样的:

      private bool needToInjectMacroCode() {
          // Get custom document property with name tagPropertyName
      
          object properties, property, propertyValue;
      
          properties = excel.ActiveWorkbook.GetType().InvokeMember(
              "CustomDocumentProperties",
              BindingFlags.Default | BindingFlags.GetProperty,
              null, excel.ActiveWorkbook, null);
      
          try {
              property = properties.GetType().InvokeMember(
                  "Item",
                  BindingFlags.Default | BindingFlags.GetProperty,
                  null, properties, new object[] { tagPropertyName });
          } catch (TargetInvocationException) {
              return true;
          }
      
          propertyValue = property.GetType().InvokeMember(
              "Value",
              BindingFlags.Default | BindingFlags.GetProperty,
              null, property, null);
      
          return (tagString != (propertyValue as string));
      }
      
      // ...
      
      private void setMacroCodeInjected() {
          // Set custom property with name tagPropertyName to value tagString
      
          object properties = excel.ActiveWorkbook.GetType().InvokeMember(
              "CustomDocumentProperties",
              BindingFlags.Default | BindingFlags.GetProperty,
              null, excel.ActiveWorkbook, null);
      
          try {
              properties.GetType().InvokeMember(
                  "Add",
                  BindingFlags.Default | BindingFlags.InvokeMethod,
                  null, properties, new object[] {
                      tagPropertyName, false,
                      Office.MsoDocProperties.msoPropertyTypeString,
                      tagString
                  });
          } catch (TargetInvocationException) {
              object property = properties.GetType().InvokeMember(
                  "Item",
                  BindingFlags.Default | BindingFlags.GetProperty,
                  null, properties, new object[] { tagPropertyName });
      
              property.GetType().InvokeMember(
                  "Value",
                  BindingFlags.Default | BindingFlags.SetProperty,
                  null, property, new object[] { tagString });
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-27
        • 2016-07-09
        • 1970-01-01
        • 1970-01-01
        • 2019-10-30
        • 2011-07-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多