При автоматизации процессов ценообразования, особенно в конфигурациях типа Альфа-Авто, часто возникает необходимость внедрения динамических условий, таких как «Если цена закупки больше 100, то наценка составляет 5%». Давайте разберем, как спроектировать такое решение и правильно организовать запись данных в базу.
Для создания гибких правил, которые пользователь может задавать самостоятельно, часто используют строковые выражения. Чтобы безопасно обработать конструкцию вида [ЦенаЗакупки] > 100, мы можем воспользоваться подходом парсинга формулы. Вместо прямого использования функции Вычислить, которая может быть небезопасна, мы разберем строку на составляющие.
Создадим процедуру, которая находит идентификаторы внутри квадратных скобок и заменяет их на реальные значения из информационной базы. Рассмотрим пример реализации:
Функция ПолучитьМассивИдентификаторовИзФормулы(Формула)
Табл = Новый ТаблицаЗначений;
Табл.Колонки.Добавить("ТекстЗамены");
Табл.Колонки.Добавить("Идент");
Для Поз = 1 По СтрДлина(Формула) Цикл
Буква = Сред(Формула, Поз, 1);
Если Буква = "[" Тогда ПозО = Поз; КонецЕсли;
Если Буква = "]" Тогда
ПозЗ = Поз;
НовТ = Табл.Добавить();
НовТ.ТекстЗамены = Сред(Формула, ПозО, ПозЗ - ПозО + 1);
НовТ.Идент = Сред(Формула, ПозО + 1, ПозЗ - ПозО - 1);
КонецЕсли;
КонецЦикла;
Возврат Табл;
КонецФункции
В основной процедуре расчета мы проходим по таблице идентификаторов, находим соответствующие им текущие значения цен в системе и подставляем их в рабочую строку формулы. Это позволяет превратить абстрактное правило в готовую математическую строку для вычисления.
Когда мы работаем с регистрами сведений, которые подчинены регистратору, мы сталкиваемся с ограничением платформы: такие данные нельзя записать просто как независимый набор записей. Система требует наличия документа-регистратора.
РегистрСведенийНаборЗаписей, обязательно установите отбор по регистратору. Если этого не сделать, при попытке записи вы можете случайно очистить весь регистр или получить ошибку доступа.Разберем типичный алгоритм работы с набором записей для таких регистров:
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// Заполняем записи новыми данными
Запись = НаборЗаписей.Добавить();
Запись.Регистратор = СсылкаНаДокумент;
Запись.Период = ТекущаяДата();
// ... заполнение остальных полей
НаборЗаписей.Записать();
Для того чтобы ваши правила наценки сохранялись между сеансами работы пользователя, не стоит полагаться только на переменные обработки. Рассмотрите следующие варианты:
ХранилищеОбщихНастроек, если правила уникальны для каждого пользователя. Это позволит избавиться от лишних объектов метаданных в конфигурации.Придерживаясь этих подходов, вы обеспечите стабильность системы и удобство для конечных пользователей, минимизируя риск случайного удаления данных или возникновения критических ошибок при записи в регистры.