如何使用Excel Interop(VB.net)获取CustomDocumentProperties?

问题描述 投票:0回答:1

我有一个使用VB.net编写的Excel Interop创建的Excel文档。 Adapting information from this post,我能够成功创建工作簿并使用以下命令编写其CustomDocumentProperties:

Dim objNewApp As Excel.Application
Dim objNewBook As Excel._Workbook
Dim objNewBooks As Excel.Workbooks

objNewApp = New Excel.Application With {
    .DisplayAlerts = True,
    .Visible = True,
    .UserControl = True,
    .ScreenUpdating = True
    }

objNewBooks = objNewApp.Workbooks
objNewBook = objNewBooks.Add

Dim properties As Object = objNewBook.CustomDocumentProperties
Dim propertiesType As Type = properties.[GetType]()
Dim documentClient As Object() = {"Client", False, Core.MsoDocProperties.msoPropertyTypeString, "In-Progress"}
propertiesType.InvokeMember("Add", BindingFlags.InvokeMethod, Nothing, properties, documentClient)

但是,设置后我无法成功读取此属性。在进行彻底的搜索之后,关于SO的主题以及MSDN的大多数帖子建议阅读this missing MSDN article以了解更多关于如何执行此操作的信息,并指出在Interop中通常会有多么愚蠢。但是,我在我的程序的其余部分使用Interop,所以我想找到一个Interop特定的解决方案(而不是VSTO)。

Adapting from this post,我相信我目前的代码是在正确的轨道上:

Dim ReadClient As String = "Client"
Dim ObjReadClient = propertiesType.InvokeMember("Item", BindingFlags.GetProperty, Nothing, properties, New Object() {ReadClient})
Dim TypeReadClient As Type = ObjReadClient.GetType
Dim ClientString As String

ClientString = TypeReadClient.InvokeMember("Value", BindingFlags.GetProperty, Nothing, properties, New Object() {})

但是,当我运行它时,我收到一个System.Runtime.InteropServices.COMException:

"Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"   

进行更多研究,这似乎是由于最后一行代码中的“价值”部分。我无法弄清楚从哪里去。

有没有人对这最后一块拼图有任何想法?如果需要,我很乐意澄清任何事情!

excel vb.net interop excel-interop
1个回答
0
投票

这是我特定问题的解决方案:

Dim ReadClientIndex As String = "Client"
Dim ReadClientValue As String
Dim ObjReadClient As Object = propertiesType.InvokeMember("Item", BindingFlags.GetProperty, Nothing, properties, New Object() {ReadClientIndex})
Dim TypeReadClient As Type = ObjReadClient.GetType()
ReadClientValue = TypeReadClient.InvokeMember("Value", BindingFlags.GetProperty, Nothing, ObjReadClient, New Object() {})

除了清理代码之外,问题在于我应该将“ObjReadClient”作为最后一行中的参数 - 而不是先前设置的“属性”变量。

但是,由于在VB.net或C#中有关于此主题的文档显着缺乏,以下是一些可能有助于未来用户的资源:

Link 1:最初在缺少的MSKB文章中提供了代码(在C#中,在下面再次复制以进行保存。):

Word.Application oWord;
   Word._Document oDoc;
   object oMissing = Missing.Value;
   object oDocBuiltInProps;
   object oDocCustomProps;

   //Create an instance of Microsoft Word and make it visible.
   oWord = new Word.Application();
   oWord.Visible = true;

   //Create a new Document and get the BuiltInDocumentProperties collection.
   oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, 
                              ref oMissing);
   oDocBuiltInProps = oDoc.BuiltInDocumentProperties;
   Type typeDocBuiltInProps = oDocBuiltInProps.GetType();

   //Get the Author property and display it.
   string strIndex = "Author";
   string strValue;
   object oDocAuthorProp = typeDocBuiltInProps.InvokeMember("Item", 
                              BindingFlags.Default | 
                              BindingFlags.GetProperty, 
                              null,oDocBuiltInProps, 
                              new object[] {strIndex} );
   Type typeDocAuthorProp = oDocAuthorProp.GetType();
   strValue = typeDocAuthorProp.InvokeMember("Value", 
                              BindingFlags.Default |
                              BindingFlags.GetProperty,
                              null,oDocAuthorProp,
                              new object[] {} ).ToString();
   MessageBox.Show( "The Author is: " + strValue,"Author" );

   //Set the Subject property.
   strIndex = "Subject";
   strValue = "The Subject";
   typeDocAuthorProp.InvokeMember("Item", 
                              BindingFlags.Default | 
                              BindingFlags.SetProperty, 
                              null,oDocBuiltInProps, 
                              new object[] {strIndex,strValue} );

   //Add a property/value pair to the CustomDocumentProperties collection.
   oDocCustomProps = oDoc.CustomDocumentProperties;
   Type typeDocCustomProps = oDocCustomProps.GetType();

   strIndex = "Knowledge Base Article";
   strValue = "Q303296";
   object[] oArgs = {strIndex,false,
                     MsoDocProperties.msoPropertyTypeString,
                     strValue};

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

   MessageBox.Show("Select \"Properties\" from the File menu "
        + "to view the changes.\nSelect the Summary tab to view "
        + "the Subject property and the Custom tab to view the Knowledge"   
        + "Base Article property.", "Check File Properties",
        MessageBoxButtons.OK,MessageBoxIcon.Information);

Link 2:注意在VB.net中更容易实现,但C#很快将支持使用“Dynamic”(10年前编写)的后期绑定。我在某个地方发现了另一个帖子,它解释了“动态”在C#中作为答案的重要性,但无法再次找到它链接到。

Link 3:这些信息特定于Excel,但我相信它可能会帮助某人专门寻找它。

Link 4:这给出了一个错误VTSO和Interop的例子,它可以帮助用户区分这两者。

© www.soinside.com 2019 - 2024. All rights reserved.