В конфигурациях 1С, предназначенных для торговли (например, "1С:Розница", "1С:Управление торговлей"), часто возникает задача автоматического ценообразования. Одна из самых распространенных потребностей — установка прогрессивной наценки (или регрессивной, в зависимости от логики). Это означает, что процент наценки меняется в зависимости от величины закупочной цены товара: чем дороже товар, тем меньше наценка, и наоборот.
В этой статье мы подробно разберем, как правильно составить формулу для таких условий, используя встроенный конструктор формул. Проанализируем синтаксис, типичные ошибки и логику построения вложенных условий.
Рассмотрим конкретный пример из практики. Нам необходимо настроить автоматический расчет розничной цены на основании цены закупочной (в формулах она часто обозначается как [ЗакупочнаяЦена] или аналогично). Условия следующие:
В конструкторе формул 1С основным инструментом для создания условий является функция ? (знак вопроса). Это сокращенная форма условного оператора Если ... Тогда ... Иначе.
Синтаксис функции выглядит следующим образом:
?(Условие, ЗначениеЕслиИстина, ЗначениеЕслиЛожь)
Где:
[Цена] > 100).Когда диапазонов много, нам приходится вкладывать одну функцию ? внутрь другой. Частая ошибка пользователей заключается в неправильной расстановке скобок или нарушении логики проверки диапазонов.
Посмотрим на ошибочный вариант формулы, который часто пытаются написать новички:
?([ЗакупочнаяЦена] < 1000, [ЗакупочнаяЦена]*1.3, ?([ЗакупочнаяЦена] > 1000 И [ЗакупочнаяЦена] < 2500, ... ))
Такая запись становится громоздкой из-за постоянного использования логического оператора И для указания границ (от и до). Кроме того, легко запутаться в количестве закрывающих скобок в конце выражения. Если вы забудете третий параметр (значение "Иначе") в последнем вложенном условии, 1С выдаст синтаксическую ошибку.
Самый эффективный способ написать такую формулу — проверять условия последовательно, от самого большого значения к самому маленькому (или наоборот), используя ветку "Иначе" для перехода к следующему диапазону. Это избавляет нас от необходимости писать двойные условия с оператором И.
Давайте разберем логику "от обратного" (сверху вниз). Если мы проверяем, что цена больше 20 000, и это не так, то в ветку "Иначе" попадут все цены меньше или равные 20 000. Следовательно, в следующем условии нам уже не нужно проверять верхнюю границу, мы проверяем только порог 10 000.
Разберем пошагово структуру правильной формулы:
Ниже приведена полная формула, которую можно скопировать и вставить в конструктор формул для видов цен (например, в 1С:Розница или УТ). Обратите внимание на количество закрывающих скобок в конце — оно должно соответствовать количеству открывающих скобок ?.
?([ЗакупочнаяЦена] > 20000,
[ЗакупочнаяЦена],
?([ЗакупочнаяЦена] > 10000,
[ЗакупочнаяЦена] * 1.13,
?([ЗакупочнаяЦена] > 5000,
[ЗакупочнаяЦена] * 1.16,
?([ЗакупочнаяЦена] > 2500,
[ЗакупочнаяЦена] * 1.2,
?([ЗакупочнаяЦена] > 1000,
[ЗакупочнаяЦена] * 1.25,
[ЗакупочнаяЦена] * 1.3
)
)
)
)
)
Давайте проанализируем, как система будет вычислять эту формулу, если, например, [ЗакупочнаяЦена] равна 3000.
3000 > 20000? Нет. Переходим в ветку "Иначе" (внутрь следующего вопроса).3000 > 10000? Нет. Переходим глубже.3000 > 5000? Нет. Переходим глубже.3000 > 2500? Да.
3000 * 1.2.В некоторых современных конфигурациях поле "Формула" поддерживает язык выражений СКД. Если конфигурация позволяет, вместо громоздких вложенных ? можно использовать конструкцию ВЫБОР (аналог CASE в SQL). Это делает код более читаемым.
Пример (если поддерживается СКД):
ВЫБОР
КОГДА [ЗакупочнаяЦена] > 20000 ТОГДА [ЗакупочнаяЦена]
КОГДА [ЗакупочнаяЦена] > 10000 ТОГДА [ЗакупочнаяЦена] * 1.13
КОГДА [ЗакупочнаяЦена] > 5000 ТОГДА [ЗакупочнаяЦена] * 1.16
КОГДА [ЗакупочнаяЦена] > 2500 ТОГДА [ЗакупочнаяЦена] * 1.2
КОГДА [ЗакупочнаяЦена] > 1000 ТОГДА [ЗакупочнаяЦена] * 1.25
ИНАЧЕ [ЗакупочнаяЦена] * 1.3
КОНЕЦ
Важно: Перед использованием оператора ВЫБОР проверьте справку к вашей конкретной конфигурации или попробуйте проверить формулу. В 1С:Розница 2.3 базовый конструктор часто опирается именно на оператор ?.
Иногда пользователи пытаются использовать конструкции вида:
#ЕСЛИ [Цена] > 100 #ТОГДА ...
В конструкторе формул для пользовательского режима (редактирование видов цен, скидок) такие инструкции не работают. Эти директивы (#ЕСЛИ, #Область) предназначены для конфигуратора и компиляции модулей программистом. В пользовательских формулах используйте только функции встроенного языка (?, Окр, Макс, Мин и т.д.).
В приведенной выше формуле мы получаем точное математическое значение. В реальной торговле цены типа "1234.56" неудобны. Рекомендуем использовать правила округления.
В 1С это можно сделать двумя способами:
Окр().
Окр( ?( ... ), 0) — округлит результат всей нашей большой формулы до целого числа.
Используйте приведенный шаблон с вложенными вопросами для любых подобных задач, просто меняя пороговые значения и коэффициенты. Главное правило — соблюдать порядок проверки (строго по возрастанию или строго по убыванию).