Программный доступ к свойствам пользовательского документа Excel

Я пытаюсь добавить пользовательские свойства в книгу, которую я создал программно. У меня есть метод для получения и настройки свойств, но проблема заключается в том, что рабочая книга возвращает null для свойства CustomDocumentProperties. Я не могу понять, как инициализировать это свойство, чтобы я мог добавлять и извлекать свойства из книги. Microsoft.Office.Core.DocumentProperties – это интерфейс, поэтому я не могу пойти и сделать следующее

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)

Я посмотрел на свой собственный код и вижу, что я обращаюсь к свойствам с помощью позднего связывания. Я не могу вспомнить, почему, но я отправлю код на случай, если это поможет.

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

EDIT : ах, теперь я помню, почему . 🙂

EDIT 2 : ответ Jimbojones – использование динамического ключевого слова – лучшее решение (если вы цените простоту использования по служебной нагрузке на использование dynamic ).

Если вы используете .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); } } 

Я нашел решение здесь .

Вот код, в котором я закончил:

  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; } 

Некоторая обработка исключений необходима, если это свойство не существует при извлечении

Поздний ответ на этот вопрос, но я разработал более простой метод добавления пользовательских DocumentProperties, которые могут быть полезны кому-то в будущем.

Моя проблема заключалась в том, что вызов метода Add () с типом System, предоставленным System.String.GetType (), вызвал несоответствие типа COMException: Type. Ссылаясь на ссылку в предыдущих ответах, понятно, что этот метод предполагает тип Office, поэтому код, который закончился для меня, был:

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

Поскольку это CustomDocumentProperty Office добавит настраиваемое свойство без каких-либо трудностей, но если вам нужно проверить наличие или подтвердить значение, если CustomDocumentProperty может не существовать, вам придется поймать исключение System.ArgumentException.

РЕДАКТИРОВАТЬ

Как отмечалось в комментарии Оливера Бока, это, по-моему, это Office 2007 и только решение.

  • Как получить динамический массив размера c ++
  • Почему / когда использовать `intptr_t` для литья типов в C?
  • c - преобразовать строку в смешанном случае ко всему нижнему регистру
  • как проверить символ «backspace» в C
  • Какую библиотеку CI / O следует использовать в коде на C ++?
  • Не удалось отправить SMS через код C #, используя System.IO.Ports, используя gsm-модем
  • Как сохранить PictureBox.Image в файл?
  • Почему fseek или fflush всегда требуется между чтением и записью в режимах обновления?
  • Сериализация Xml - Скрыть нулевые значения
  • Как получить библиотеку / заголовки GL?
  • Сериализация C ++ JSON
  • Давайте будем гением компьютера.