Как в 1С:УНФ настроить расчет динамических цен в зависимости от единицы измерения номенклатуры

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Торговля и дистрибуция
← На главную

В типовой конфигурации 1С:Управление нашей фирмой (УНФ) механизм динамических цен (расчет по формуле) обладает определенными ограничениями. Основная проблема заключается в том, что стандартный конструктор формул оперирует исключительно числовыми данными: другими видами цен, порогами, коэффициентами или предопределенными показателями вроде Себестоимость. Однако на практике часто возникает задача: применить разный алгоритм наценки в зависимости от того, в чем измеряется товар — в килограммах, штуках или погонных метрах.

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

Стандартные ограничения и архитектурные особенности

Для начала проанализируем ситуацию. В 1С:УНФ все расчеты цен в конечном итоге привязываются к базовой единице измерения номенклатуры. Все остальные единицы (упаковки, ящики) считаются через коэффициенты пересчета. Если мы открываем редактор формул в виде цены, система ожидает, что результатом вычисления будет число. Мы не можем напрямую написать условие ?(ЕдиницаИзмерения = "кг", Цена * 1.1, Цена * 1.2), так как объект «Единица измерения» не входит в список доступных операндов.

Прежде чем переходить к коду, рассмотрим альтернативный «безопасный» способ решения задачи без программирования — использование Ценовых групп. Мы можем разделить номенклатуру на группы (например, «Весовые» и «Штучные») и для каждого вида цены настроить уточнения по этим группам. Для каждой группы можно прописать свою формулу. Это стандартный путь, который сохраняет конфигурацию на поддержке.

Если же ценовых групп слишком много или логика должна быть более гибкой, нам придется прибегнуть к кастомизации системы.

Программная реализация: добавление операнда «Единица измерения»

Рассмотрим подробнее техническую сторону вопроса. Весь расчет динамических цен происходит на стороне сервера в общем модуле ЦенообразованиеФормулыСервер. Наша задача — зарегистрировать новый операнд, который система будет распознавать в тексте формулы, и передать в него значение базовой единицы измерения номенклатуры.

Для этого нам потребуется внести изменения в две ключевые точки модуля:

  1. Функция МассивЗарезирвированныхСлов — здесь мы объявляем имя нашего нового операнда.
  2. Процедура ПодготовитьДанныеСтрокиКоллекции — здесь мы сопоставляем имя операнда с реальными данными из карточки номенклатуры.

Шаг 1: Регистрация операнда в системе

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


Функция МассивЗарезирвированныхСлов()
    МассивЗарезирвированныхОперандов = Новый Массив;
    // ... существующие операнды (Себестоимость, КурсЕвро и т.д.)
    
    // Добавляем наш новый операнд
    МассивЗарезирвированныхОперандов.Добавить("ЕдиницаИзмерения_Базовая");
    
    Возврат МассивЗарезирвированныхОперандов;
КонецФункции

Теперь система будет знать, что слово ЕдиницаИзмерения_Базовая в квадратных скобках — это не ошибка, а специальный параметр.

Шаг 2: Наполнение операнда данными

Далее проанализируем процедуру ПодготовитьДанныеСтрокиКоллекции. В ней происходит цикл по всем операндам, найденным в формуле. Нам нужно вставить условие, которое при встрече нашего операнда подставит в него строковое представление единицы измерения.

Важный нюанс: поскольку формула в конечном итоге вычисляется как выражение на языке 1С, текстовые значения (названия единиц) должны быть обернуты в кавычки.


// Внутри цикла по ТаблицаОперандов в процедуре ПодготовитьДанныеСтрокиКоллекции
ИначеЕсли СтрокаОперанда.Операнд = "[ЕдиницаИзмерения_Базовая]" Тогда
    // Получаем наименование единицы измерения и берем его в кавычки для формулы
    Значение = """" + СокрЛП(СтрокаКоллекции.Номенклатура.ЕдиницаИзмерения) + """";
    КлючЕдиницыИзмерения = "ЕдиницаИзмерения_ТекущееЗначение";
    ЕдиницаИзмерения = СтрокаКоллекции.Номенклатура.ЕдиницаИзмерения;

Обратите внимание, что мы используем СтрокаКоллекции.Номенклатура.ЕдиницаИзмерения. В контексте УНФ это и есть ссылка на базовую единицу измерения, указанную в карточке товара.

Шаг 3: Корректировка обработки типов в формуле

Стандартный механизм УНФ настроен на работу с числами. Если мы просто передадим строку, система может попытаться выполнить с ней арифметические операции или применить форматирование как к числу. Выясним причину возможных ошибок: в коде часто встречается проверка Если ЗначениеЗаполнено(Значение), после которой идет вызов функции Число(). Нам нужно убедиться, что для строковых операндов такая конвертация не производится.

Проанализируем фрагмент кода, отвечающий за форматирование чисел:


// Заменяем стандартную проверку на проверку типа
Если ТипЗнч(Значение) = Тип("Число") И Значение <> 0 Тогда
    ФорматСтрокиЗначение = "ЧЦ=15; ЧДЦ=3; ЧРД=.; ЧГ=0";
    // ... логика форматирования числа и учета курсов валют
Иначе
    // Если это строка (наша единица измерения), оставляем как есть
КонецЕсли;

Как использовать результат в интерфейсе

После внесения изменений (лучше всего это сделать через Расширение конфигурации, используя аннотации &Вместо), у вас появится возможность писать в поле формулы гибкие условия. Рассмотрим пример:

[ТекущееЗначение] * ?([ЕдиницаИзмерения_Базовая] = "кг", 1.2, 1.1)

В данном примере, если товар измеряется в килограммах, система применит наценку 20%, а для всех остальных единиц измерения — 10%. Это значительно расширяет возможности ценообразования без необходимости создания сотен ценовых групп.

Рекомендации по внедрению

Подводя итог, отметим несколько важных моментов для программиста и аналитика:

  1. Используйте расширения. Прямая правка общего модуля в основной конфигурации усложнит процесс обновления 1С:УНФ. Метод &Вместо для процедуры ПодготовитьДанныеСтрокиКоллекции позволит сохранить логику при обновлении релиза.
  2. Производительность. Динамические цены рассчитываются «на лету». Если у вас в документе 500 строк, сложная логика в формулах может замедлить открытие формы. Если расчет слишком сложен, рассмотрите вариант использования внешних обработок заполнения цен для документа «Установка цен».
  3. Точность наименований. Помните, что сравнение идет по строке. Если в справочнике «Единицы измерения» заведено две единицы «шт» (например, одна с точкой, другая без), формула может отработать некорректно. Старайтесь использовать предопределенные значения или уникальные коды, если это возможно.

Таким образом, несмотря на кажущуюся «жесткость» механизмов УНФ, система остается достаточно гибкой для кастомизации под нужды бизнеса, позволяя связывать ценообразование с любыми характеристиками товара, включая его физические параметры измерения.

← На главную