Есть ли способ вернуть ошибку в ячейку с UDF?

Автор eeigor, 8 апреля 2021, 22:13

0 Пользователи и 1 гость просматривают эту тему.

eeigor

Вот так это делается в Excel, чтобы, к примеру, отобразить в ячейке #ЗНAЧ! (#VALUE!):

Function UDF
   On Error GoTo Failed
   <...>

Failed:
   UDF = CVErr(xlErrValue)
Exit Function


Это будет ошибка, а не текст, имитирующий ошибку.

А в LO Calc? Обсуждение было здесь...

UPD:
Обходной путь весьма странный, чтобы вернуть "Err:502" в ячейку:
=MAKENUMBER(B3;C3)&IF(LEFT(CURRENT();1)=":";SQRT(-1);0)
Примечание. Ошибку вызывает SQRT(-1), если UDF - MAKENUMBER вернёт ":fail:".

Есть другие варианты?
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Устанавливает в ячейке ошибочное значение #Н/Д:

ThisComponent.Sheets(0).getCellByPosition(0,0).setDataArray Array(Array(Empty))
Владимир.

eeigor

Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Можно формулой:

ThisComponent.Sheets(0).getCellByPosition(0,0).formula="=SQRT(-1)"

Затем можно избавиться от формулы, скопировав в буфер обмена и вставив как значение.
Честно говоря, не вижу в этом особого практического смысла.
Владимир.

mikekaganski

Единственный способ, который я знаю, сделать это в пользовательской функции Basic - вернуть Array().

Интересно было бы попробовать поиграться с возвратом NaN - но тут нужен питон.
С уважением,
Михаил Каганский

eeigor

#5
mikekaganski, всегда рад услышать!
Я работаю над этой темой.
Цитата: sokol92 от  9 апреля 2021, 13:00Затем можно избавиться от формулы, скопировав в буфер обмена и вставив как значение.
@sokol92, подскажите, как покороче скопировать/вставить ошибку, чтобы убрать "формулу". После этого в ячейке действительно оказывается ранее заданная ошибка. oCell.DataArray = oCell.DataArray => get/set замещает ошибку. Макрос ниже нет. Активна одна ячейка, работаем с ней.
Запись макроса
sub Main2
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$D$39"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())

rem ----------------------------------------------------------------------
dim args3(5) as new com.sun.star.beans.PropertyValue
args3(0).Name = "Flags"
args3(0).Value = "SVD"
args3(1).Name = "FormulaCommand"
args3(1).Value = 0
args3(2).Name = "SkipEmptyCells"
args3(2).Value = false
args3(3).Name = "Transpose"
args3(3).Value = false
args3(4).Name = "AsLink"
args3(4).Value = false
args3(5).Name = "MoveMode"
args3(5).Value = 4

dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, args3())
end sub


UPD:
Ошибку #VALUE! даёт, к примеру, формула: =SIGN(".")
С неё и началась эта тема...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Специальную вставку еще в UNO не перенесли, как и копирование диапазона ячеек.
Владимир.

eeigor

#7
Однако, странно: почему простое копирование (как у меня выше) замещает результат ошибки, а копирование/вставка диспетчером - нет?

UPD:
Вот так покороче будет.
' Copies and pastes data into the selection.
Sub CopyPasteData
Dim document As Object, dispatcher As Object

document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

Dim args(0) As New com.sun.star.beans.PropertyValue
args(0).Name = "Flags"
args(0).Value = "SVD"
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, args())
End Sub


И как подавить вывод стандартного сообщения перед вставкой данных?

UPD: Исправлена ошибка в коде.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

#8
Записал в ячейке D39 формулу
=1/0

Выполнил макрос из #5 - формула заменилась на ошибочное значение.
Проверил на Win10 и Ubuntu.

Upd. Уберите "птичку" в сообщении и больше Вы это сообщение не увидите. На самом деле, это регулируется параметром Calc Общие/Показывать предупреждение о перезаписи данных при вставке.
Владимир.

eeigor

Спасибо.
Наверное, пока так: другого не придумали. Но мне в UDF нужна только одна ошибка - это ошибка при возвращении результата.
Как уже говорил: ошибку #VALUE! даёт, к примеру, формула: =SIGN("."), которая ожидает число.
Можно остановиться...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

eeigor

#10
В чём разница? Работает и без параметров.

'   Dim args(0) As New com.sun.star.beans.PropertyValue
'   args(0).Name = "Flags"
'   args(0).Value = "SVD"
'   dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, args())

   dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())

UPD1:
Я ошибся: работает именно вариант #5 (#7) с .uno:InsertContents.
UPD2: Или вот так
   dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
   dispatcher.executeDispatch(document, ".uno:PasteOnlyValue", "", 0, Array())
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community