Приведенный ниже код используется для получения настраиваемых свойств документа для книги Excel.
var xlApp = Globals.ThisAddIn.Application; // This works in VSTO Excel Add-in
var xlApp = new global::Microsoft.Office.Interop.Excel.Application(); // This doesn't work anywhere
xlApp.Visible = true;
global::Microsoft.Office.Interop.Excel.Workbook workbook = xlApp.Workbooks.Open(file, false, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, false, Type.Missing, Type.Missing);
global::Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties; // Exception occurs here
global::Microsoft.Office.Core.DocumentProperty property = properties["propertyname"];
Первые две строки - это ссылки на Excel Application
. Один получает ссылку из внутреннего устройства надстройки VSTO, другой - обычный new Application()
.
При использовании Application
из внутренних компонентов VSTO код запускает штрафы без каких-либо проблем. Но при использовании new Application()
строка workbook.CustomDocumentProperties
выдает InvalidCastException
:
Невозможно преобразовать COM-объект типа «System .__ ComObject» к типу интерфейса «Microsoft.Office.Core.DocumentProperties». Эта операция завершилась неудачно, поскольку вызов QueryInterface для COM-компонента для интерфейса с IID '{2DF8D04D-5BFA-101B-BDE5-00AA0044DE52}' завершился неудачно из-за следующей ошибки: такой интерфейс не поддерживается (исключение из HRESULT: 0x80004002 (E_NOINTERFACE)) .
Я пытаюсь заставить его работать над проектом winforms С # без VSTO. Во многих примерах и учебных пособиях new Application()
используется для взаимодействия с Excel, но я заметил, что Microsoft.Office.Interop.Excel.Application
- это интерфейс, поэтому использование new
в интерфейсе для меня на самом деле странно. Как я могу создать подходящее приложение, которое может получить CustomDocumentProperties
?
Эталонные сборки, которые я использую:
- Microsoft.Office.Interop.Excel v2.0.50727 Версия 14.0.0.0
- Microsoft.CSharp v4.0.30319 Версия 4.0.0.0
3 ответа
Я заметил, что Microsoft.Office.Interop.Excel.Application - это интерфейс, поэтому использование нового интерфейса для меня на самом деле странно.
Это действительно странно, но по замыслу. Интерфейс Excel.Application
украшен атрибутом CoClass
, сообщающим фактическому классу о необходимости создания экземпляра при "создании экземпляра" интерфейса. Подробнее об этом здесь а>.
Но при использовании
new Application()
строкаworkbook.CustomDocumentProperties
выдаетInvalidCastException
:
И снова действительно странно. Я сам столкнулся с некоторыми проблемами при использовании свойств документа. Кажется, что фактически возвращаемый класс отличается от спецификации, поэтому я перешел на использование dynamic
, чтобы предотвратить проблемы с приведением типов.
Итак, вместо этого:
Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties;
Использование:
dynamic properties = workbook.CustomDocumentProperties;
У меня была такая же проблема. Сегодня это решено. Есть другой подход к получению результатов. Вопрос и ответ на него находятся на
Как я могу прочитать пользовательское свойство документа Excel с помощью взаимодействия C # Excel
Вот моя реализация.
public string CheckDocProp(string propName, object props)
{
Excel.Workbook workBk = Globals.ThisAddIn.Application.ActiveWorkbook;
object customProperties = workBk.CustomDocumentProperties;
Type docPropsType = customProperties.GetType();
object nrProps;
object itemProp = null;
object oPropName;
object oPropVal = null;
nrProps = docPropsType.InvokeMember("Count",
BindingFlags.GetProperty | BindingFlags.Default,
null, props, new object[] { });
int iProps = (int)nrProps;
for (int counter = 1; counter <= ((int)nrProps); counter++)
{
itemProp = docPropsType.InvokeMember("Item",
BindingFlags.GetProperty | BindingFlags.Default,
null, props, new object[] { counter });
oPropName = docPropsType.InvokeMember("Name",
BindingFlags.GetProperty | BindingFlags.Default,
null, itemProp, new object[] { });
if (propName == oPropName.ToString())
{
oPropVal = docPropsType.InvokeMember("Value",
BindingFlags.GetProperty | BindingFlags.Default,
null, itemProp, new object[] { });
return oPropVal.ToString();
break;
}
else
{
return "Not Found.";
}
}
return "Not Found.";
}
Применение:
object docProps = wb.CustomDocumentProperties;
string prop1 = ExistsDocProp("<CustomProperty>", docProps);
Как я могу создать подходящее приложение, которое может получить CustomDocumentProperties?
Если вы разрабатываете надстройку, нет необходимости создавать новый экземпляр приложения Excel. Вы должны использовать свойство Application, предоставляемое средой выполнения VSTO:
var xlApp = Globals.ThisAddIn.Application; // This works in VSTO Excel Add-in
Но если вы разрабатываете автономное приложение, автоматизирующее Excel, в этом случае вам необходимо создать новый экземпляр приложения с помощью оператора new:
var xlApp = new global::Microsoft.Office.Interop.Excel.Application();
Используйте технологию позднего связывания (Type.InvokeMember) для получения или установки свойства документа в качестве Как использовать Предлагается в статье "Автоматизация получения и установки свойств документа Office с помощью Visual C # .NET".
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.