Как в запросе 1С сделать отбор по флажку (галочке) из формы, если возникает ошибка «Поле не обнаружено»?

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

Рассмотрим частую и довольно коварную ситуацию, с которой сталкиваются многие разработчики в 1С. Допустим, мы открываем форму элемента справочника, видим в табличной части колонку с флажками (галочками). Нам нужно написать запрос и отобрать те элементы, у которых этот флажок установлен (или, наоборот, снят) для определенного значения. Мы открываем консоль запросов, пытаемся обратиться к полю табличной части и получаем ошибку: «Поле не обнаружено».

Давайте разберем по шагам, почему так происходит, выясним причину такого поведения платформы «1С:Предприятие» и подробно проанализируем, как обойти это ограничение.

Выясним причину: почему флажка нет в базе данных?

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


ВЫБРАТЬ
    ОсновнойСправочникТЧ.Ссылка КАК Ссылка
ИЗ
    Справочник.ОсновнойСправочник.ТабличнаяЧасть КАК ОсновнойСправочникТЧ
ГДЕ
    ОсновнойСправочникТЧ.ИмяМоегоФлажка = ЛОЖЬ
    И ОсновнойСправочникТЧ.ЭлементВторогоСправочника = &НужныйЭлемент

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

Дело в том, что в базе данных этих флажков просто нет. Элемент, который мы видим на экране — это исключительно визуальный реквизит формы (или элемент управления). Он не является реквизитом объекта метаданных. Запрос же работает строго с таблицами базы данных, поэтому напрямую обратиться к элементу формы через язык запросов SQL-подобного синтаксиса 1С невозможно.

Посмотрим на архитектурные варианты: где на самом деле хранятся значения флажков?

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

  1. Сохранение в настройках пользователя (Хранилище настроек). У реквизитов формы есть свойство «Сохранять данные». Если у самой формы включено «Автоматическое сохранение данных в настройках», платформа автоматически записывает состояния таких флажков в ХранилищеСистемныхНастроек или ХранилищеНастроекПользователя. Эти данные привязаны к конкретному пользователю и форме, а не к таблице базы данных.
  2. Механизм дополнительных реквизитов и сведений (БСП). В современных конфигурациях на базе Библиотеки стандартных подсистем часто используются «Дополнительные реквизиты». Программно они выводятся на форму так, что визуально кажутся колонкой табличной части. Значения этих флажков нужно искать в специальной подчиненной табличной части объекта (например, ДополнительныеРеквизиты) или в отдельном регистре сведений ДополнительныеСведения.
  3. Использование типа «Хранилище значения». Разработчик мог добавить в сам справочник скрытый реквизит с типом ХранилищеЗначения. В обработчике события ПередЗаписью состояние всех флажков из ТЧ программно собирается в структуру и пакуется в хранилище. При открытии формы происходит обратный процесс. В конструкторе запросов поле ХранилищеЗначения выбрать можно, но наложить на него условие (через конструкцию ГДЕ) нельзя.
  4. Вычисляемые колонки формы. Иногда флажки динамически рассчитываются в событиях ПриЧтенииНаСервере или ПриСозданииНаСервере на основе анализа других данных: подчиненных справочников, остатков по регистрам накопления или статусов других документов.

Как решить задачу и передать данные отбора в запрос?

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

Шаг 1. Получение данных программным путем.

Вне запроса (в модуле формы или в модуле объекта) мы должны определить список элементов, для которых этот флажок установлен или снят. Например, мы можем прочитать сохраненные настройки пользователя или распаковать ХранилищеЗначения. В результате у нас должен получиться Массив или СписокЗначений, содержащий ссылки на элементы.

Шаг 2. Передача списка в параметры запроса.

Сформированный массив мы передаем в сам запрос в качестве параметра. Для фильтрации используем логический оператор В. Посмотрим на пример реализации в коде 1С:


// 1. Формируем массив снятых флажков (допустим, мы извлекли его из настроек)
МассивСнятыхФлажков = Новый Массив;
// ... (здесь программный код получения списка элементов) ...
МассивСнятыхФлажков.Добавить(НужныйЭлементСправочника);

// 2. Инициализируем запрос
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ОсновнойСправочникТЧ.Ссылка КАК Ссылка,
    |    ОсновнойСправочникТЧ.ЭлементВторогоСправочника КАК Элемент
    |ИЗ
    |    Справочник.ОсновнойСправочник.ТабличнаяЧасть КАК ОсновнойСправочникТЧ
    |ГДЕ
    |    ОсновнойСправочникТЧ.ЭлементВторогоСправочника В(&МассивСнятыхФлажков)";

// 3. Устанавливаем параметр и выполняем
Запрос.УстановитьПараметр("МассивСнятыхФлажков", МассивСнятыхФлажков);
РезультатЗапроса = Запрос.Выполнить();

Таким образом, мы выяснили, что если нужные вам данные являются лишь визуальным отображением (реквизитом формы), то получить их «одним махом» через запрос не выйдет. Разработчику необходимо проанализировать программный код модуля формы (события при открытии, чтении, закрытии и записи), найти механизм сохранения состояний этих флажков, извлечь их с помощью встроенного языка 1С и только затем использовать в качестве параметров для фильтрации данных в запросе.

← На главную