Как проверить заполненность поля типа ХранилищеЗначения в запросе 1С?

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

При разработке отчетов и обработок часто возникает задача вывести признак наличия прикрепленного файла или картинки в виде булева значения (Истина или Ложь). Однако попытка обратиться к реквизиту с типом ХранилищеЗначения внутри запроса 1С или преобразовать его через ВЫРАЗИТЬ() приводит к ошибке несовместимости типов.

Разберем причины такого поведения платформы и рассмотрим рабочие способы решения этой задачи.

Почему ХранилищеЗначения нельзя обработать в запросе

Поле типа ХранилищеЗначения предназначено для хранения двоичных данных произвольного объема (BLOB). На уровне СУБД и языка запросов «1С:Предприятие» для таких полей действуют жесткие ограничения:

  1. Поля типа ХранилищеЗначения запрещено использовать в операциях сравнения (=, <>), функциях ВЫРАЗИТЬ(), условиях ВЫБОР КОГДА ..., секциях ГДЕ, СГРУППИРОВАТЬ ПО и УПОРЯДОЧИТЬ ПО.
  2. Конструкция ЕСТЬ NULL не позволяет определить пустоту хранилища — она проверяет только физическое отсутствие всей записи при соединениях таблиц.
  3. Даже если в реквизит записано пустое значение, платформа сохраняет внутренний бинарный заголовок, из-за чего поле в базе данных не является пустым.

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

Способ 1. Добавление реквизита-флага через расширение конфигурации

Если типовая конфигурация находится на поддержке, оптимальным решением без снятия с поддержки является использование механизма расширений (доступно начиная с платформы 8.3.11).

Разберем по шагам, как настроить этот вариант:

  1. Создаем или открываем расширение конфигурации.
  2. Заимствуем в расширение нужный объект (например, справочник Номенклатура).
  3. Добавляем в справочник реквизит ЕстьКартинка с типом Булево.
  4. В расширении перехватываем обработчик события ПередЗаписью или ПриЗаписи объекта и заполняем флаг:
    
    &Вместо("ПередЗаписью")
    Процедура Расш_ПередЗаписью(Отказ)
        // Проверяем заполненность хранилища перед сохранением
        Если ЭтотОбъект.Картинка.Получить() <> Неопределено Тогда
            ЭтотОбъект.ЕстьКартинка = Истина;
        Иначе
            ЭтотОбъект.ЕстьКартинка = Ложь;
        КонецЕсли;
        
        ПродолжитьВызов(Отказ);
    КонецПроцедуры
    
  5. Используем новый реквизит ЕстьКартинка в тексте запроса.

Важная особенность: если разработка запроса ведется во внешней обработке или отчете, Конструктор запросов в конфигураторе может не отображать реквизиты, добавленные в расширении. В этом случае имя поля (например, Товар.ЕстьКартинка) достаточно прописать в тексте запроса вручную — в режиме «1С:Предприятие» запрос выполнится корректно.

Способ 2. Программная постобработка результатов выборки

Если изменение конфигурации или добавление расширений невозможно, задачу можно решить программным обходом результата запроса. Чтобы не замедлять работу базы и не перегружать память передачей больших бинарных данных, из базы запрашиваются только ссылки на объекты, а само хранилище считывается точечно.

Посмотрим на пример программной обработки:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ПартииОстатки.Товар КАК Товар,
    |   ПартииОстатки.КоличествоОстаток КАК Количество
    |ИЗ
    |   РегистрНакопления.ПартииНоменклатуры.Остатки(&Период, ) КАК ПартииОстатки";

РезультатЗапроса = Запрос.Выполнить();
ТаблицаРезультат = РезультатЗапроса.Выгрузить();
ТаблицаРезультат.Колонки.Добавить("ЕстьФото", Новый ОписаниеТипов("Булево"));

Для Каждого Стр Из ТаблицаРезультат Цикл
    // Метод Получить() извлекает данные из ХранилищаЗначения
    ДвоичныеДанные = Стр.Товар.Картинка.Получить();
    Стр.ЕстьФото = (ДвоичныеДанные <> Неопределено);
КонецЦикла;

Способ 3. Получение данных через подсистему присоединенных файлов (БСП)

В большинстве современных конфигураций файлы и изображения хранятся не в реквизитах справочника, а в отдельных связанных объектах (например, справочниках НоменклатураПрисоединенныеФайлы).

В такой структуре проверка наличия картинки легко реализуется стандартным запросом через левое соединение:


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