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