Функция альтернативного If () в Excel / OOCalc

6

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

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

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

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

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

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

Aru
источник
1
Я искал способ сделать это без использования промежуточной ячейки, которая не имеет видимой цели. Многие из моих листов используют функции в интерактивном режиме и предназначены для непосредственного просмотра. Скрытый столбец может мешать выбору, копированию, а скрытый лист усложняет задачу, включая ссылки. (редактировать: я думаю, что был комментарий в ответ на комментарий, который был удален, тогда ответ был также удален.)
Aru
1
Добавлю, что эта функция будет особенно полезна при работе со случайными числами. Например, иногда я хочу сделать что-то вроде рисования чисел из нормального распределения, но не хочу никаких отрицательных значений. Я хотел бы отразить знак любых нарисованных отрицательных чисел, но из-за этой проблемы я не могу поместить условие на нарисованное число в одной ячейке. =IF(NORMINV(RAND(),1,0.3)<0,NORMINV(RAND(),1,0.3),NORMINV(RAND(),1,0.3)*-1) не работает, потому что тест и результат отличаются от распределения.
Excellll

Ответы:

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 простынь.

tohuwawohu
источник
3

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

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

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

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

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

Инструменты & gt; Макросы & gt; Организовать макросы & gt; OpenOffice Basic & gt; Кнопка "Органайзер ..." & gt; Вкладка "Библиотеки" & gt; Мои макросы & amp; Диалоги & gt; "Стандартная" библиотека & gt; Кнопка редактирования

Я вставил это в конце, сохранил и закрыл редактор. Он выполняет вторую из двух функций в исходном вопросе, но в форме 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
Aru
источник
0

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

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

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

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

dakre18
источник