6

Много раз за многие годы я хотел использовать оператор If в Excel/OpenOffice Calc в виде:

If(A (comparison operator) B, A, C)

или, что не менее полезно:

If(A (comparison operator) B, C, A)

где A - очень длинное и запутанное выражение, а B и C - короткие и простые, часто (но не всегда) просто буквальное значение. Я хотел сделать один из них, который не включал бы дублирующееся выражение A (которое по меньшей мере вдвое уродливее, требует дублирования правок и вносит совершенно ненужные ошибки, которые даже не проявляются последовательно), или давая A выделенная ячейка, или использующая VBA (которая является собственностью Microsoft, таким образом, непривлекательная, а не в Calc).

Есть некоторые обходные пути для особых случаев, таких как Iferr() в Excel (это не в Calc) и манипулирование числами с помощью функций «условного» типа, таких как Abs (), округления и Mod (). Но этого недостаточно для того, чтобы делать то, что я хочу, большую часть времени (и манипулирование числами также не элегантно и неясно). Есть ли шанс, что есть функция или простой набор функций, которые я пропустил, которые могут это сделать? Кажется, это большая вещь, которую стоит оставить.

3 ответа3

3

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

Но, во-первых, я использую OpenOffice Calc, а не LibreOffice Calc, но они оба используют язык BASIC, который очень похож на VBA (Visual Basic для приложений от Microsoft, как используется в Excel).

Вы можете определить порции операторов через Sub (как в подпрограмме) и Function. Согласно этой странице в документации, загрузка / запуск макроса с функцией в нем делает именно это, позволяет вам вызывать его как функцию в обычных формулах ячеек. Это факт, о котором я не знал раньше, несмотря на попытки найти способ сделать это в прошлом.

Немного посмотрев обзор OOCalc Basic , я сделал функцию, которая работает, хотя и не совсем так, как хотелось бы, поскольку оператор и второй операнд передаются как два отдельных аргумента, а первый - как строка. Но, я помню, когда-то была хотя бы одна встроенная функция Excel, которая использовала то же самое, аргумент для оператора, передаваемого в виде строки, так что, по крайней мере, есть прецедент.

Думаю, проблема была в том, что я не знал, что было так просто создать "макрос", что вместо выполнения некоторого кода и выхода определял функцию, которую можно вызывать в формулах ячеек. Слово "макрос" выбило меня из колеи, поскольку обычно оно означает только вещи процедурного типа, плюс в "Руководстве пользователя" была информация о вызове этих функций в макросах, которая была в другой части сайта, чем Основной обзор.

Инструменты> Макросы> Упорядочить макросы> OpenOffice Basic> кнопка «Органайзер ...»> вкладка "Библиотеки"> Мои макросы и диалоги> "Стандартная" библиотека> кнопка "Редактировать"

Я вставил это в конце, сохранил и закрыл редактор. Он выполняет вторую из двух функций в исходном вопросе, но в форме IfAlt(A, operator, B, C), где operator - строка оператора сравнения. Если A op B имеет значение true, возвращает C, в противном случае возвращает A.

Function IfAlt(arg1, op, arg2, ifTrue)
    If (op="=" AND arg1=arg2) OR (op="<>" AND arg1<>arg2) OR _
        (op=">" AND arg1>arg2) OR (op=">=" AND arg1>=arg2) OR _
        (op="<" AND arg1<arg2) OR (op="<=" AND arg1<=arg2) Then
        IfAlt = ifTrue
    Else
        IfAlt = arg1
    End If
End Function
2

Для решения LO Calc я вижу два пути:

  1. поместите функцию, которая выдает результат для A на отдельный защищенный лист. Таким образом, маловероятно, что пользователь случайно попытается отредактировать ячейку, содержащую вашу функцию. У него есть и другие преимущества:

    • нет необходимости в макросе,
    • возможность скопировать лист "функции" в другие файлы ods ,
    • просто редактировать
  2. определить функцию как пользовательскую функцию внутри базового макроса. Star Basic, используемый LO Calc, не то же самое, что VBA, но он довольно похож, так как оба являются диалектами Basic. Преимущества:

    • полная сила звездного языка,
    • экспортировать его как "системную библиотеку"
    • или встраивать в шаблоны ods .

Создать пользовательскую функцию в Calc очень просто. Предполагая, что вам нужно вычислить значение A путем умножения трех разных значений, вы просто создадите макрос:

Function A(b, c, d)
A = b*c*d
End Function

Теперь вы можете использовать эту функцию внутри выражения If :

If(A(4, 5, 6) > B, A(4, 5, 6), C)

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

Function A()
A = 4*5*6
End Function

и назовите это просто используя

If(A() > B, A(), C)

Я знаю, что эти примеры слишком просты, чтобы проиллюстрировать решение. Просто подумайте о добавлении определения констант или создании полной библиотеки функций внутри макроса, возможно , с "частными" вспомогательными функциями невидимых для пользователя , который только редактирует ods листа.

0

Я думаю, что вы можете сделать это, но я собираюсь попробовать, чтобы убедиться, что это то, что вы имеете в виду. Так что я собираюсь использовать Excel в качестве примера, так как он у меня есть и не так хорошо знаком с OpenOffice Calc.

В Excel я знаю, что вы бы поставили =if(condition, if true, if false) для функции if, и если я вас правильно понимаю, вы просто хотите объединить ее в меньшую функцию, чтобы ее было легче читать, верно?

Единственный способ сделать это - использовать ячейку для каждой, поскольку из-за того, как работает Excel, нет способа объявить переменную без использования ячейки. Вы можете использовать VBA, но, как вы упомянули, вы не можете использовать это в openoffice. Проблема в том, что вы должны иметь возможность хранить формулу / значение / и т.д. где-то, поэтому это должна быть клетка.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .