Пользовательские блокировки функций Excel при вызове электронной таблицы

Я использую NetOffice для редактирования электронной таблицы Excel. Если я вызову код из пользовательской функции Excel, он не позволит мне редактировать вызывающую электронную таблицу.

Excel.Application excelApplication = Excel.Application.GetActiveInstance();
Excel.Worksheet workSheet = (Excel.Worksheet) excelApplication.ActiveSheet;
Excel.Range cell = workSheet.Cells[2, 2];

object value = cell.Value; //works
cell.Value = 3; //Throws Exception

есть ли обходной путь, который позволит мне это сделать?

Исключение составляет

"System.Runtime.InteropServices.COMException (0x80004005): подробности см. В разделе о внутреннем исключении. ---> System.Reflection.TargetInvocationException: исключение было сгенерировано целью вызова. ---> System.Runtime. InteropServices.COMException: Исключение из HRESULT: 0x800A03EC --- Конец трассировки стека внутреннего исключения --- в System.RuntimeType.InvokeDispMethod (String name, BindingFlags invokeAttr, Object target, Object [] args, Boolean [] byrefModifiers, культура Int32, String [] namedParameters) в System.RuntimeType.InvokeMember (имя строки, BindingFlags bindingFlags, связыватель привязки, цель объекта, Object [] providedArgs, ParameterModifier [] модификаторы, культура CultureInfo, String [] namedParams) в System.Type.InvokeMember (String name, BindingFlags invokeAttr, Binder binder, Object target, Object [] args, CultureInfo culture) в NetOffice.Invoker.PropertySet (COMObject comObject, String name, Object [] value) в NetOffice.Invoker.PropertySet (COMObject comObject, String name, Объект [] va lue) в NetOffice.ExcelApi.Range.set_Value (значение объекта) в ExcelExamplesCS45.Example01.RunExample () в \ psf \ home \ Documents \ Visual Studio 2013 \ Projects \ Excel-REPL \ Excel-REPL \ Example01.cs: строка 29 в ClojureExcel.MainClass.Test () в \ psf \ home \ Documents \ Visual Studio 2013 \ Projects \ Excel-REPL \ Excel-REPL \ MainClass.cs: строка 310 "


person Matthew Molloy    schedule 18.02.2015    source источник
comment
Как правило, UDF в ячейке листа может возвращать значение только в эту ячейку. Он не может изменить другие клетки.   -  person Gary's Student    schedule 18.02.2015
comment
Мне интересно, есть ли какая-то блокировка на экземпляре Excel, когда он оценивает UDF, или есть способ обойти указанную блокировку.   -  person Matthew Molloy    schedule 18.02.2015
comment
Да, есть, просто запустите приведенный выше код в отдельном потоке. Работает как шарм!   -  person Matthew Molloy    schedule 04.03.2015
comment
При попытке обойти это ограничение Excel с помощью другого потока возникает ряд проблем: ваш код может не получить нужный экземпляр Excel или нужный лист (поскольку вы не знаете, когда выполняется код в другом потоке), и может оставить процесс Excel запущенным из-за висящих ссылок COM. Есть некоторые обходные пути, но Excel предотвращает такие вызовы по уважительной причине ...   -  person Govert    schedule 15.03.2015
comment
Традиционно я создавал электронные таблицы с помощью Apache POI, но недавно мне захотелось более реплицитного способа сделать это, поэтому я создал github. com / whamtet / Excel-REPL. Немного злоупотребляет Excel, но в целом работает нормально!   -  person Matthew Molloy    schedule 16.03.2015


Ответы (2)


    Exception from HRESULT: 0x800A03EC

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

HRESULT - это код ошибки, который может помочь вам определить основную причину ошибки. Он разделен на 3 части: серьезность ошибки, код «объекта» и код ошибки. Файл SDK WinError.h, который у вас есть на вашем компьютере, может показать вам, какие именно биты в коде соответствуют какой части информации. «Объект» - это забавное слово, означающее «источник ошибки».

Код объекта - 0x0A = 10. Это означает «ошибку, определяемую приложением». Или, другими словами, код ошибки очень специфичен для приложения, в котором возникла ошибка. Код ошибки: 0x03EC = 1004. Таким образом, вы можете выразить это словами: «Ошибка Excel 1004».

Это то, что вы можете найти в Google, вы получите 356 тысяч обращений. Потратьте некоторое время на чтение лучших хитов, чтобы понять, о чем идет речь. Игнорируйте обращения к вампирским сайтам, которые обещают исправить любую ошибку на вашем компьютере, если вы запустите программу очистки реестра. Суть в том, что эта ошибка очень распространена, она также генерируется в макросах и коде VBA. Обычно с немного более подробным сообщением об ошибке внутри Excel вы можете получить краткое описание ошибки помимо кода ошибки 1004. Однако при использовании автоматизации вам придется обойтись без нее, что, конечно, усложняет задачу.

Есть еще одна точка данных, которую вы можете получить, посмотрев на трассировку стека, вы можете увидеть, что делает NetOffice. Он использует позднее связывание (InvokeDispMethod), поэтому вы не можете быть на 100% уверены, какой конкретный метод взаимодействия дает сбой. Рекламируемая функция NetOffice на самом деле затрудняет устранение неполадок. Но очень примечательной точкой взаимодействия является Range.set_Value. Это то, что вы можете реконструировать до очень специфического свойства автоматизации Excel, объектная модель Excel имеет интерфейс Range и свойство Value. Не удается присвоить это свойство. Полное совпадение с тем, что вы пытаетесь сделать, установив значение ячейки.

Таким образом, вы можете улучшить свой запрос Google до «Ошибка Excel 1004 Range.Value». Это делает обращения намного более конкретными, четыре лучших обращения - это все ТОЧНЫЕ вопросы, и все обращения к вампирским сайтам фильтруются. Обобщая основные объяснения ошибки:

  • вы не можете писать в электронную таблицу, потому что она защищена
  • записанное вами значение несовместимо с форматом ячейки, например недопустимая дата
  • диапазон, который вы пытаетесь обновить, недействителен, например номер строки или столбца ‹= 0
  • код запускается из-за функции, введенной в ячейку, и пытается обновить другую ячейку.

Вы можете довольно легко избавиться от первого маркера, просто убедитесь, что электронная таблица не защищена, и / или используйте Unprotect (). То же самое для 2-го пункта, просто напишите то, что вы прочитали. Не может быть 3-го маркера, вы можете легко прочитать ячейку. Четвертый маркер - это точное совпадение с заголовком вашего вопроса «Функция, определяемая пользователем». Другими словами, проблема в том,

   Excel.Range cell = workSheet.Cells[2, 2];

Проблема заключается в том, что это не та ячейка, которая содержит пользовательскую функцию. Так что присвоение незаконно. Я не могу предложить обходной путь, не зная, в чем особенность [2, 2]. Попробуйте изменить его на ячейку, которая действительно содержит UDF.

Предполагается, что UDF должна возвращать значение, которое затем становится отображаемым значением ячейки. В этой статье базы знаний описаны ограничения UDF. На этот вопрос SO есть ответы, в которых говорится о при реализации UDF в коде .NET упоминается Excel-DNA.

person Community    schedule 21.02.2015

Есть очень простой обходной путь: просто отредактируйте рабочий лист в отдельном потоке. Почему я не подумал об этом с самого начала !! ???

person Matthew Molloy    schedule 04.03.2015