2009-07-16 76 views
12

我试图将自定义属性添加到我以编程方式创建的工作簿。我有一个方法来获取和设置属性,但问题是工作簿正在为CustomDocumentProperties属性返回null。我无法弄清楚如何初始化此属性,以便我可以从工作簿中添加和检索属性。 Microsoft.Office.Core.DocumentProperties是一个接口,所以我不能去,然后执行以下以编程方式访问Excel自定义文档属性

if(workbook.CustomDocumentProperties == null) 
    workbook.CustomDocumentProperties = new DocumentProperties; 

这里是我得和设置属性代码:

 private object GetDocumentProperty(string propertyName, MsoDocProperties type) 
    { 
     object returnVal = null; 

     Microsoft.Office.Core.DocumentProperties properties; 
     properties = (Microsoft.Office.Core.DocumentProperties)workBk.CustomDocumentProperties; 

     foreach (Microsoft.Office.Core.DocumentProperty property in properties) 
     { 
      if (property.Name == propertyName && property.Type == type) 
      { 
       returnVal = property.Value; 
      } 
      DisposeComObject(property); 
     } 

     DisposeComObject(properties); 

     return returnVal; 
    } 

    protected void SetDocumentProperty(string propertyName, string propertyValue) 
    { 
     DocumentProperties properties; 
     properties = workBk.CustomDocumentProperties as DocumentProperties; 

     bool propertyExists = false; 
     foreach (DocumentProperty prop in properties) 
     { 
      if (prop.Name == propertyName) 
      { 
       prop.Value = propertyValue; 
       propertyExists = true; 
      } 
      DisposeComObject(prop); 

      if(propertyExists) break; 
     } 

     if (!propertyExists) 
     { 
      properties.Add(propertyName, false, MsoDocProperties.msoPropertyTypeString, propertyValue, Type.Missing); 
     } 

     DisposeComObject(propertyExists); 

    } 

线 性质= workBk.CustomDocumentProperties作为DocumentProperties; 总是将属性设置为null。

这是使用Microsoft.Office.Core v12.0.0.0和Microsoft.Office.Interop.Excell v12.0.0.0(Office 2007中)

回答

10

我看了看自己的代码,并可以看到我的访问使用后期绑定的属性。我不记得为什么,但我会发布一些代码以防万一。

object properties = workBk.GetType().InvokeMember("CustomDocumentProperties", BindingFlags.Default | BindingFlags.GetProperty, null, workBk, null); 

object property = properties.GetType().InvokeMember("Item", BindingFlags.Default | BindingFlags.GetProperty, null, properties, new object[] { propertyIndex }); 

object propertyValue = property.GetType().InvokeMember("Value", BindingFlags.Default | BindingFlags.GetProperty, null, propertyWrapper.Object, null); 

编辑:啊,我现在还记得why。 :-)

编辑2:Jimbojones'的答案 - 使用动态关键字 - 是一个更好的解决方案(如果你看重易用性的使用超过使用dynamic的性能开销)。

+0

准确地说,我找到了这个链接,并且当您发布此内容时我发布了我的代码。 +1并接受为您:-) – 2009-07-16 14:18:46

+0

更新以链接“为什么”:https://support.microsoft.com/zh-cn/kb/303296 – 2016-02-09 18:18:37

7

我找到了解决方案here

这里是我结束了代码:

public void SetDocumentProperty(string propertyName, string propertyValue) 
    { 
     object oDocCustomProps = workBk.CustomDocumentProperties; 
     Type typeDocCustomProps = oDocCustomProps.GetType(); 

     object[] oArgs = {propertyName,false, 
       MsoDocProperties.msoPropertyTypeString, 
       propertyValue}; 

     typeDocCustomProps.InvokeMember("Add", BindingFlags.Default | 
            BindingFlags.InvokeMethod, null, 
            oDocCustomProps, oArgs); 

    } 

    private object GetDocumentProperty(string propertyName, MsoDocProperties type) 
    { 
     object returnVal = null; 

     object oDocCustomProps = workBk.CustomDocumentProperties; 
     Type typeDocCustomProps = oDocCustomProps.GetType(); 


     object returned = typeDocCustomProps.InvokeMember("Item", 
            BindingFlags.Default | 
            BindingFlags.GetProperty, null, 
            oDocCustomProps, new object[] { propertyName }); 

     Type typeDocAuthorProp = returned.GetType(); 
     returnVal = typeDocAuthorProp.InvokeMember("Value", 
            BindingFlags.Default | 
            BindingFlags.GetProperty, 
            null, returned, 
            new object[] { }).ToString(); 

     return returnVal; 
    } 

有些异常处理是必要的手,如果物业犯规时存在检索

3

晚回答这个问题,但我制定了一个简单的方法来添加将来可能对某人有用的自定义DocumentProperties。

我的问题是用System.String.GetType()提供的系统类型调用Add()方法触发了COMException:类型不匹配。参照在以前的答案的链接很明显,这种方法需要一个Office特定类型,从而使最终为我工作的代码是:

var custProps = (Office.DocumentProperties)this.CustomDocumentProperties; 
custProps.Add("AProperty", false, MsoDocProperties.msoPropertyTypeString, "AStringProperty"); 

因为它是一个CustomDocumentProperty办公室将添加自定义属性没有困难,但如果您需要检查存在或验证CustomDocumentProperty可能不存在时的值,您将不得不捕获一个System.ArgumentException。

编辑

正如奥利弗·博克的评论指出,这是一个Office 2007和仅占解决方案,据我所知。

12

如果你的目标是.NET 4。0,您可以使用dynamic关键字进行后期绑定

Document doc = GetActiveDocument(); 
if (doc != null) 
{ 
    dynamic properties = doc.CustomDocumentProperties; 
    foreach (dynamic p in properties) 
    { 
     Console.WriteLine(p.Name + " " + p.Value); 
    } 
}