В процессе работы с конфигурацией 1С:Управление торговлей (редакции 11.4 и 11.5) часто возникает необходимость вывести на ценник или этикетку данные, которых нет в стандартном наборе полей. Типичный пример — вывод цены со скидкой 10% рядом с основной ценой. Сложность заключается в том, что механизм печати этикеток в УТ 11 использует динамическое формирование запроса СКД (Схемы компоновки данных), где типы полей определяются в момент исполнения, что часто приводит к ошибкам при попытке простых арифметических операций в запросе. Рассмотрим подробнее, как решить эту задачу различными методами.
Когда мы пытаемся добавить в запрос СКД выражение вида ИсходныеДанныеПоследнийЗапрос.Цена * 0.9, система часто выдает ошибку. Это происходит потому, что в обработке ПечатьЭтикетокИЦенников используется механизм «подмены» текста запроса. Сначала СКД инициализируется с пустым набором данных для формирования структуры, а затем программа заменяет текст временной таблицы на реальные данные. В момент проверки синтаксиса система еще не знает, что поле Цена будет числовым, и считает его неопределенным типом, с которым нельзя выполнять математические действия.
Этот метод подходит для тех, кто готов вносить изменения в код обработки. Разберем по шагам, как добавить поле «Цена со скидкой» через программный код.
Во-первых, необходимо подготовить саму схему компоновки данных (макет ПоляШаблонаТовары или ПоляШаблонаПечатьТовары). В запрос СКД в конфигураторе мы добавляем «пустое» поле-заглушку, чтобы оно стало доступно в структуре полей:
// В первом пакете запроса, где формируется временная таблица ИсходныеДанные
"Цена" КАК Цена,
"ЦенаСоСкидкой" КАК ЦенаСоСкидкой, // Добавляем строку-заглушку
// В итоговом запросе выбираем это поле
ИсходныеДанныеПоследнийЗапрос.Цена КАК Цена,
ИсходныеДанныеПоследнийЗапрос.ЦенаСоСкидкой КАК ЦенаСоСкидкой,
Во-вторых, в модуле обработки ПечатьЭтикетокИЦенников (или в модуле формы, в зависимости от версии) находим процедуру, отвечающую за подготовку печати, где происходит замена текста. Нам нужно внедрить свою логику расчета прямо в строку запроса:
// Находим блок, где подменяется стандартная цена
Запрос.Текст = СтрЗаменить(Запрос.Текст, """Цена""", "ИсходныеДанные.Цена");
// Добавляем нашу подмену с математическим расчетом
Запрос.Текст = СтрЗаменить(Запрос.Текст, """ЦенаСоСкидкой""", "ИсходныеДанные.Цена - (ИсходныеДанные.Цена * 0.1)");
Важный нюанс: Чтобы избежать проблем с дробной частью, рекомендуется использовать функцию ВЫРАЗИТЬ или округление прямо в строке замены, например: "ВЫРАЗИТЬ(ИсходныеДанные.Цена * 0.9 КАК ЧИСЛО(15, 2))".
Проанализируем ситуацию: если нам нужна «Цена со скидкой», мы можем создать её средствами самой системы без программирования. Это наиболее корректный путь с точки зрения методологии 1С.
[Розничная] * 0.9.Теперь в шаблоне этикетки нам достаточно вывести стандартное поле ЦенаДополнительно. Этот способ безопасен при обновлениях и понятен пользователям.
В новых версиях УТ 11.5 механизмы стали сложнее. Если нам нужно добавить не цену, а специфический реквизит номенклатуры (например, текст для маркетплейса), лучше использовать расширение. Рассмотрим алгоритм:
Проанализируем работу формы ФормаТовары обработки ПечатьЭтикетокИЦенников2_5. Нам нужно перехватить формирование текста запроса в процедуре ЗагрузитьНастройкиОтбораПоУмолчанию. С помощью механизма &ИзменениеИКонтроль мы можем внедрить свои поля напрямую в текст запроса СКД:
// В расширении добавляем поля в финальную выборку запроса
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ИсходныеДанныеПоследнийЗапрос.Номенклатура КАК Номенклатура,",
"ИсходныеДанныеПоследнийЗапрос.Номенклатура КАК Номенклатура,
| ИсходныеДанныеПоследнийЗапрос.Номенклатура.НашНовыйРеквизит КАК НашНовыйРеквизит,");
Однако просто добавить поле в запрос недостаточно — оно должно появиться в списке доступных полей в редакторе шаблона. Для этого в справочнике ШаблоныЭтикетокИЦенников в форме редактирования нужно найти процедуру ЗаполнитьДоступныеПоля и добавить туда имя нашего поля:
&После("ЗаполнитьДоступныеПоля")
Процедура Наш_ЗаполнитьДоступныеПоля(ИменаПолей)
ИменаПолей.Добавить("Номенклатура.НашНовыйРеквизит");
КонецПроцедуры
Выясним причину, почему даже после добавления кода поле не появляется в конструкторе этикетки. Список доступных полей в левой части редактора формируется жестко заданным списком. Если вы не хотите править код справочника ШаблоныЭтикетокИЦенников, вы можете воспользоваться «хитростью»: просто впишите имя поля вручную в макете, используя формат [Номенклатура.НашеПоле] или [ЦенаСоСкидкой]. Если в итоговом запросе СКД это поле присутствует с таким же именем, 1С успешно подставит данные при печати.
Рассмотрим еще один вариант: использование вкладки «Вычисляемые поля» в самой схеме компоновки. Вместо того чтобы мучиться с типами данных в запросе, мы можем добавить поле в список вычисляемых. В колонке «Выражение» пишем обычный код 1С: Цена * 0.9. Преимущество этого метода в том, что СКД сама позаботится о проверке типов и корректном выводе данных в макет, не требуя сложной подмены строк текста запроса.
Резюмируем:
СтрЗаменить).Выбор метода зависит от ваших навыков программирования и того, насколько часто вы планируете обновлять конфигурацию. Для большинства задач торгового предприятия настройки нового Вида цены оказывается более чем достаточно.