Как правильно передавать значения булевых полей и выборки запроса в параметры макета печатной формы 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Рассмотрим распространенную задачу при формировании печатных форм в 1С: в справочнике или документе есть флаг типа Булево и два поля с данными. В зависимости от состояния флага (установлен или сброшен) в печатную форму необходимо вывести значение первого или второго поля.

При реализации этого механизма программисты часто сталкиваются с ситуацией, когда запрос выполняется успешно, но ячейка в макете остается пустой. Разберем по шагам причины этой проблемы и варианты правильного решения.

Причина 1. Использование стороннего объекта вместо результата выборки

Проанализируем частую ошибку в алгоритме обхода выборки. В условии проверяется реквизит из запроса, но значение присваивается из другого объекта или структуры (например, Шапка.Контрагент):


Пока Выборка.Следующий() Цикл
    Если Выборка.Основной = Ложь Тогда    
        ОбластьМакета.Параметры.ДанныеФизЛица = Шапка.Контрагент.ДокументУдостоверяющийЛичность1;
    Иначе
        ОбластьМакета.Параметры.ДанныеФизЛица = Шапка.Контрагент.ДокументУдостоверяющийЛичность;
    КонецЕсли;    
КонецЦикла;

Если структура Шапка не содержит нужных данных или реквизит передан некорректно, параметр ДанныеФизЛица останется пустым. Значения необходимо брать непосредственно из переменной Выборка:


Пока Выборка.Следующий() Цикл
    Если Выборка.Основной Тогда    
        ОбластьМакета.Параметры.ДанныеФизЛица = Выборка.ДокументУдостоверяющийЛичность;
    Иначе
        ОбластьМакета.Параметры.ДанныеФизЛица = Выборка.ДокументУдостоверяющийЛичность1;
    КонецЕсли;    
КонецЦикла;

Также обратите внимание: если запрос выполняется по конкретной ссылке (выбирается ровно одна запись), вместо цикла Пока логичнее и эффективнее использовать условную конструкцию Если Выборка.Следующий() Тогда. Для сокращения кода BSL можно применить тернарный оператор ?():


Если Выборка.Следующий() Тогда
    ОбластьМакета.Параметры.ДанныеФизЛица = ?(Выборка.Основной, Выборка.ДокументУдостоверяющийЛичность, Выборка.ДокументУдостоверяющийЛичность1);
КонецЕсли;

Причина 2. Несовпадение псевдонима поля в запросе и имени параметра в макете

Более оптимальный подход — перенести логику выбора значения из кода BSL прямо в текст запроса с помощью конструкции ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ. Это снижает нагрузку на сервер приложений и уменьшает объем передаваемых данных.

Однако при составлении запроса важно следить за псевдонимом выбираемого поля:


Запрос.Текст = "ВЫБРАТЬ
               |    Контрагенты.Ссылка,
               |    ВЫБОР 
               |        КОГДА Контрагенты.Основной ТОГДА Контрагенты.ДокументУдостоверяющийЛичность
               |        ИНАЧЕ Контрагенты.ДокументУдостоверяющийЛичность1 
               |    КОНЕЦ КАК ДокументУдостоверяющийЛичность
               |ИЗ
               |    Справочник.Контрагенты КАК Контрагенты
               |ГДЕ
               |    Контрагенты.Ссылка = &Ссылка";

Если в макете параметр ячейки называется ДанныеФизЛица, а в запросе использован псевдоним ДокументУдостоверяющийЛичность, автоматическое заполнение или обращение по имени не сработает.

Укажем в запросе псевдоним, полностью совпадающий с именем параметра в макете:


Запрос.Текст = "ВЫБРАТЬ
               |    Контрагенты.Ссылка,
               |    ВЫБОР 
               |        КОГДА Контрагенты.Основной ТОГДА Контрагенты.ДокументУдостоверяющийЛичность
               |        ИНАЧЕ Контрагенты.ДокументУдостоверяющийЛичность1 
               |    КОНЕЦ КАК ДанныеФизЛица
               |ИЗ
               |    Справочник.Контрагенты КАК Контрагенты
               |ГДЕ
               |    Контрагенты.Ссылка = &Ссылка";

Благодаря совпадению имен псевдонима и параметра, вывод в макет упрощается до использования метода Заполнить():


Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);
Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда
    ОбластьМакета.Параметры.Заполнить(Выборка);
КонецЕсли;

Безопасная обработка булевых полей и значений NULL

В ситуациях, когда булево поле получается из левого соединения или реквизитов составного типа, оно может принимать значение NULL. Прямое сравнение Контрагенты.Основной = ЛОЖЬ при значении NULL вернет Ложь, что приведет к выполнению ветки ИНАЧЕ.

Для предотвращения ошибок оборачивайте булевы поля в функцию ЕСТЬNULL:


ВЫБОР 
    КОГДА ЕСТЬNULL(Контрагенты.Основной, ЛОЖЬ) ТОГДА Контрагенты.ДокументУдостоверяющийЛичность
    ИНАЧЕ Контрагенты.ДокументУдостоверяющийЛичность1 
КОНЕЦ КАК ДанныеФизЛица

Соблюдение этих правил гарантирует корректное заполнение параметров макета и защитит код от ошибок при пустых значениях реквизитов.

← На главную