ExcelDNA выдает исключение при доступе к Range.Value2 - PullRequest
0 голосов
/ 05 июля 2019

Я портирую Excel Addin (использованный Shimloader) на Exceldna, и да, я видел другие вопросы SO (и не SO), но ничего не решает мой вопрос, и я надеюсь, что есть более новые решения.

Код прост.

[ExcelFunction(Name="DoSomething")]
string DoSomething()
{
     var xl = ExcelDna.Application;    
     var callerCell = xl.Caller;
     var row = getRow(excelReference.RowFirst+1, callerCell.WorkSheet) ;
}

В GetRow ():

var row = (Range)worksheet.Rows[row];
var cell = (Range)bracketRow.Columns[4];

Когда я проверяю отладчик, я вижу, что найденная ячейка на 100% правильная, потому что cell.FormulaLocal соответствует формуле строки и столбца Excel.

Значение в FormulaLocal равно "OtherSheet!A12".

Но по какой-то причине, когда я пытаюсь cell.Value2, он выдает COMException и ничего больше. Это не многопоточное приложение, и я не могу понять, почему это происходит.

Есть идеи?

EDIT:

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

РЕДАКТИРОВАТЬ 2: Я справился с этим, добавив атрибут IsMacroType=true в функцию Excel. Но теперь xl.Caller возвращает null, argh

1 Ответ

0 голосов
/ 08 июля 2019

Необходимо решить две проблемы: range.Value2 выбрасывает COMException, если ячейка имеет недопустимое значение, например # ЗНАЧЕНИЕ в Excel. range.Value2 выдает исключение COMException, если ячейка ссылается на другой лист в той же книге, например "OtherSheet! A2"

Чтобы решить эту проблему, я установил для атрибута IsMacroType значение true:

[ExcelFunction(Name="DoSomething",IsMacroType=true)]
string DoSomething()
{
     var xl = ExcelDna.Application;    
     var callerCell = xl.Caller;
     var row = getRow(excelReference.RowFirst+1, callerCell.WorkSheet) ;
}

Проблема теперь в том, что IsMacroType вызывает xl.Caller теперь будет возвращать ноль.

Я обошел это:

ExcelReference reference = (ExcelReference)XlCall.Excel(XlCall.xlfCaller);

            string sheetName = (string)XlCall.Excel(XlCall.xlSheetNm,reference);

            int index = sheetName.IndexOf(']', 0) + 1;
            int endIndex = sheetName.Length - index;
            sheetName = sheetName.Substring(index, endIndex);
            var worksheet = (Worksheet)xl.ActiveWorkbook.Sheets[sheetName];

Это мой первый мир родео в Excel, есть ли побочный эффект от включения IsMacroType? Потому что я видел, как @Govert выражает некоторые опасения по поводу неопределенного поведения ...

...