Как получить CustomDocumentProperties с помощью Excel Interop (VB.net)? - PullRequest
0 голосов
/ 29 марта 2019

У меня есть документ Excel, созданный с использованием Excel Interop, написанный на VB.net. Адаптируя информацию из этого поста , я могу успешно создать рабочую книгу и написать ее 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 предлагают прочитать эту недостающую статью MSDN , чтобы узнать больше о том, как это сделать, и заметить, насколько глупо это делать в Interop.в общем.Тем не менее, я использую Interop для остальной части моей программы, поэтому я хотел бы найти решение для Interop (вместо VSTO).

Адаптация из этого поста , I верю мой текущий код находится на правильном пути:

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))"   

ВыполнениеПохоже, что дальнейшие исследования связаны с тем, что в последней строке кода есть элемент «Значение».Я не смог понять, куда идти дальше.

Кто-нибудь имеет какие-либо идеи относительно этого последнего кусочка головоломки?Я был бы рад уточнить что-нибудь, если нужно!

1 Ответ

0 голосов
/ 29 марта 2019

Вот решение для моей конкретной проблемы:

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 в качестве аргумента в последней строке, а не наПеременная «properties» установлена ​​ранее.

Однако, поскольку на VB.net или C # не хватает документации по этой теме, вот некоторые ресурсы, которые могут помочь будущим пользователям:

Ссылка 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);

Ссылка 2 : отмечает, что этоэто проще сделать в VB.net, но вскоре C # будет поддерживать позднюю привязку с помощью «Dynamic» (написано 10 лет назад).Я где-то нашел другой пост, в котором объясняется важность «Динамического» как ответа в C #, но не смог найти его снова для ссылки.

Ссылка 3 : эта информация относится кExcel, но я полагаю, что это может помочь кому-то специально его искать.

Ссылка 4 : в этом примере приведен пример ошибки VTSO и Interop, что может помочь пользователям различать эти два.

...