При разработке печатных форм в системе 1С:Предприятие часто возникает задача ограничить вывод данных только определенными позициями. Например, в документе ЧекККМ могут присутствовать и товары, и услуги, а в конкретную печатную форму должны попадать только смартфоны. Рассмотрим подробно, как реализовать такую фильтрацию, разберем типичные ошибки новичков и изучим профессиональные подходы к оптимизации кода.
Рассмотрим ситуацию, когда данные для печати собираются с помощью запроса, использующего временную таблицу. Типичная ошибка на начальном этапе — неправильное обращение к вложенным реквизитам объектов. Проанализируем фрагмент запроса, который требует доработки:
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаТовары.НомерСтроки,
| ТаблицаТовары.Номенклатура,
| ТаблицаТовары.Сумма,
| ТаблицаТовары.ВидНоменклатуры // Ошибка: этого поля может не быть в ТЧ документа
|ПОМЕСТИТЬ ТаблицаТовары
|ИЗ
| &Товары КАК ТаблицаТовары;
|
|ВЫБРАТЬ
| ДокументТовары.Номенклатура.НаименованиПолное КАК НоменклатураПредставление,
| ДокументТовары.ВидНоменклатуры КАК ВидНоменклатуры, // Попытка прямого обращения
| ДокументТовары.НомерСтроки
|ИЗ
| ТаблицаТовары КАК ДокументТовары";
Проблема 1: В табличных частях документов (например, Товары в документе ЧекККМ) обычно нет реквизита ВидНоменклатуры. Этот реквизит принадлежит справочнику Номенклатура. Следовательно, в запросе к нему нужно обращаться "через точку".
Правильное обращение в запросе:
| ДокументТовары.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры,
| ДокументТовары.Номенклатура.ТипНоменклатуры КАК ТипНоменклатуры,
Выясним причину, по которой условие Если Выборка.ВидНоменклатуры = "Телефон" Тогда не срабатывает. В системе 1С реквизит ВидНоменклатуры имеет тип СправочникСсылка.ВидыНоменклатуры. Это объектная ссылка, а не текстовая строка. Сравнение ссылки со строкой "Телефон" всегда будет давать результат Ложь (False).
Рассмотрим три способа решения этой задачи, от простого к правильному.
Если нам нужно быстро проверить условие в коде обхода выборки, можно воспользоваться методом НайтиПоНаименованию. Это позволит получить ссылку на нужный вид номенклатуры для сравнения.
Пока Выборка.Следующий() Цикл
НужныйВид = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Смартфон");
Если Выборка.ВидНоменклатуры = НужныйВид Тогда
// Здесь размещается код формирования области макета
ТабДок.Вывести(ОбластьСтрока);
КонецЕсли;
КонецЦикла;
Важный момент: Поиск по наименованию чувствителен к лишним пробелам и опечаткам. Если пользователь переименует "Смартфон" в "Смартфоны", код перестанет работать.
Проанализируем ситуацию с точки зрения производительности. Зачем выбирать из базы данных все строки, чтобы потом отсеивать их в цикле 1С? Правильнее и быстрее наложить фильтр еще на этапе выполнения запроса к базе данных.
Рассмотрим, как изменить текст запроса и передать в него параметр:
// В тексте запроса добавляем секцию ГДЕ
Запрос.Текст =
"ВЫБРАТЬ ...
|ИЗ ТаблицаТовары КАК ДокументТовары
|ГДЕ
| ДокументТовары.Номенклатура.ВидНоменклатуры = &НужныйВид";
// Устанавливаем параметр перед выполнением
ВидДляПечати = Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Смартфон");
Запрос.УстановитьПараметр("НужныйВид", ВидДляПечати);
Выборка = Запрос.Выполнить().Выбрать();
В этом случае в Выборка попадут только те товары, которые соответствуют условию. Код вывода печатной формы станет чище, так как дополнительные проверки Если ... Тогда в цикле больше не понадобятся.
Если логика печати жестко завязана на определенный вид номенклатуры, рекомендуется сделать такой элемент предопределенным в конфигураторе. Это гарантирует, что ссылка на него будет доступна в коде всегда, независимо от действий пользователей в режиме предприятия.
Тогда проверка в коде будет выглядеть максимально надежно:
Если Выборка.ВидНоменклатуры = Справочники.ВидыНоменклатуры.Смартфоны Тогда
// Код вывода
КонецЕсли;
Разберем еще несколько важных аспектов, которые помогут сделать ваш механизм печати более гибким:
ПустаяСсылка(), чтобы избежать неопределенного поведения системы.ВидНоменклатуры (справочник с настройками) и ТипНоменклатуры (перечисление: Товар, Услуга, Работа). Часто бывает полезно комбинировать условия, например: ГДЕ ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Товар).ВидыНоменклатуры дополнительный реквизит типа Булево (флажок) — "ВыводитьВФормуX". Тогда в запросе вы сможете проверять этот флажок. Это позволит пользователям самостоятельно управлять списком товаров для печати без помощи программиста.Проанализировав вышеописанные методы, мы видим, что наиболее качественным решением является фильтрация данных непосредственно в Запрос с использованием параметров. Это экономит ресурсы сервера и упрощает дальнейшую поддержку кода.