Как собрать данные из разных типов задач в один список с фильтрацией по исполнителю и статусу

Программист 1С v8.3 (Обычные формы) Управленческий учет
← На главную

В практике разработки на платформе 1С часто возникает задача собрать воедино информацию из нескольких различных бизнес-процессов или задач. Например, когда необходимо вывести в одну таблицу «Задачи на согласование бюджета», «Задачи по выбору поставщика» и «Задачи по договорам». Поскольку это разные объекты метаданных, простое обращение к одной таблице невозможно. В рамках данной статьи мы разберем, как правильно построить запрос для объединения данных, как корректно передать параметры из формы и как реализовать гибкую фильтрацию по статусу выполнения.

Выбор стратегии объединения: Соединения или Объединения?

Проанализируем типичную ошибку начинающих разработчиков. Часто при попытке собрать данные из разных таблиц используется ЛЕВОЕ СОЕДИНЕНИЕ. Однако этот подход в корне неверен для данной задачи. Соединение предназначено для «склеивания» строк по горизонтали (добавление новых колонок к существующей записи), а нам нужно добавить строки по вертикали (собрать записи из разных таблиц в один список).

Использование соединений в данном контексте приводит к тому, что запрос становится тяжелым, нечитаемым и, что самое важное, он начинает множить количество колонок (Автор1, Автор2, Автор3), что крайне неудобно для вывода в одну таблицу. Правильным решением здесь является использование конструкции ОБЪЕДИНИТЬ ВСЕ (UNION ALL).

Шаг 1. Построение базового запроса через ОБЪЕДИНИТЬ ВСЕ

Рассмотрим, как правильно структурировать запрос. Основное правило при использовании ОБЪЕДИНИТЬ ВСЕ заключается в том, что количество и порядок колонок, а также их типы в каждом блоке ВЫБРАТЬ должны совпадать. Это позволит системе корректно сформировать итоговую таблицу.

Разберем пример запроса, который собирает данные из трех разных типов задач:


ВЫБРАТЬ
    НА_ЗадачаСогласованияВыбораПоставщика.БизнесПроцесс.Автор КАК Автор,
    НА_ЗадачаСогласованияВыбораПоставщика.БизнесПроцесс.Предмет КАК Предмет,
    НА_ЗадачаСогласованияВыбораПоставщика.Дата КАК Дата,
    НА_ЗадачаСогласованияВыбораПоставщика.Наименование КАК Наименование,
    НА_ЗадачаСогласованияВыбораПоставщика.ДатаВыполнения КАК ДатаВыполнения,
    НА_ЗадачаСогласованияВыбораПоставщика.Выполнена КАК Выполнена,
    НА_ЗадачаСогласованияВыбораПоставщика.Исполнитель КАК Исполнитель
ИЗ
    Задача.НА_ЗадачаСогласованияВыбораПоставщика КАК НА_ЗадачаСогласованияВыбораПоставщика

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    НА_ЗадачаСогласования.БизнесПроцесс.Автор,
    НА_ЗадачаСогласования.БизнесПроцесс.Предмет,
    НА_ЗадачаСогласования.Дата,
    НА_ЗадачаСогласования.Наименование,
    НА_ЗадачаСогласования.ДатаВыполнения,
    НА_ЗадачаСогласования.Выполнена,
    НА_ЗадачаСогласования.Исполнитель
ИЗ
    Задача.НА_ЗадачаСогласования КАК НА_ЗадачаСогласования

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    НА_СогласованиеЗаказаПоставщику.БизнесПроцесс.Автор,
    НА_СогласованиеЗаказаПоставщику.БизнесПроцесс.Предмет,
    НА_СогласованиеЗаказаПоставщику.Дата,
    НА_СогласованиеЗаказаПоставщику.Наименование,
    НА_СогласованиеЗаказаПоставщику.ДатаВыполнения,
    НА_СогласованиеЗаказаПоставщику.Выполнена,
    НА_СогласованиеЗаказаПоставщику.Исполнитель
ИЗ
    Задача.НА_СогласованиеЗаказаПоставщику КАК НА_СогласованиеЗаказаПоставщику

Обратите внимание: мы задаем псевдонимы колонок (через КАК) только в первом блоке выбора. Остальные блоки автоматически подстроятся под эти имена. Также важно помнить, что обращение Задача.БизнесПроцесс.Автор является обращением «через точку». Платформа 1С в этом случае автоматически выполнит неявное левое соединение с таблицей бизнес-процесса. Если база данных содержит сотни тысяч записей, это может снизить производительность, но для небольших и средних объемов это допустимый и наиболее наглядный способ.

Шаг 2. Корректная передача параметров из формы

Выясним причину, по которой запрос может выдавать пустой результат или игнорировать фильтры. В обычном интерфейсе 1С (8.1/8.2/8.3 в режиме обычного приложения) при обращении к реквизиту формы, например ЭлементыФормы.Исполнитель, мы получаем объект управления (поле ввода), а не само значение, которое в него введено.

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


Запрос = Новый Запрос;
// Получаем ссылку на пользователя из элемента формы
ИсполнительСсылка = ЭлементыФормы.Исполнитель.Значение; 

// Устанавливаем параметры запроса
Запрос.УстановитьПараметр("Исполнитель", ИсполнительСсылка);

Если пропустить .Значение, система попытается сравнить поле Исполнитель в базе данных (которое является ссылкой) с объектом формы, и условие ГДЕ никогда не выполнится.

Шаг 3. Реализация гибкой фильтрации по статусу выполнения

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

Многие разработчики пытаются использовать конструкцию ЕСЛИ... ТОГДА в коде 1С для формирования текста запроса, но это делает код громоздким. Элегантнее решить эту задачу внутри самого SQL-запроса с помощью логического условия в секции ГДЕ.

Рассмотрим логическую конструкцию: (&ВсеЗадачи ИЛИ Задача.Выполнена). Если параметр &ВсеЗадачи равен ИСТИНА, то всё условие целиком становится истинным для любой строки (так как используется оператор ИЛИ), и фильтр по полю Выполнена фактически игнорируется. Если же &ВсеЗадачи равен ЛОЖЬ, то результат будет зависеть только от того, что находится в поле Задача.Выполнена.

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


// Предположим, на форме есть флажок "ТолькоВыполненные" (Булево)
ТолькоВыполненные = ЭлементыФормы.ФлажокТолькоВыполненные.Значение;

Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Исполнитель", ЭлементыФормы.Исполнитель.Значение);
Запрос.УстановитьПараметр("ПоказыватьВсе", НЕ ТолькоВыполненные);

Запрос.Текст = 
"ВЫБРАТЬ
|    Т.БизнесПроцесс.Автор КАК Автор,
|    Т.БизнесПроцесс.Предмет КАК Предмет,
|    Т.Дата КАК Дата,
|    Т.Наименование КАК Наименование,
|    Т.ДатаВыполнения КАК ДатаВыполнения
|ИЗ
|    Задача.НА_ЗадачаСогласования КАК Т
|ГДЕ
|    Т.Исполнитель = &Исполнитель
|    И (&ПоказыватьВсе ИЛИ Т.Выполнена = ИСТИНА)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|    Т.БизнесПроцесс.Автор,
|    Т.БизнесПроцесс.Предмет,
|    Т.Дата,
|    Т.Наименование,
|    Т.ДатаВыполнения
|ИЗ
|    Задача.НА_ЗадачаСогласованияВыбораПоставщика КАК Т
|ГДЕ
|    Т.Исполнитель = &Исполнитель
|    И (&ПоказыватьВсе ИЛИ Т.Выполнена = ИСТИНА)";

// Выгружаем результат в табличное поле на форме
РезультатЗапроса = Запрос.Выполнить();
ТаблицаРезультата = РезультатЗапроса.Выгрузить();

// Если используется табличное поле "Список"
ЭлементыФормы.Список.СоздатьКолонки();
Список = ТаблицаРезультата; // Привязка данных

Подведем итоги

Для успешного создания отчета по задачам во внешней обработке мы выполнили следующие действия:

  1. Использовали конструкцию ОБЪЕДИНИТЬ ВСЕ для объединения данных из разных таблиц в один плоский список.
  2. Обеспечили идентичность колонок в каждом блоке запроса.
  3. Правильно извлекли ссылку на пользователя из элементов управления через свойство .Значение.
  4. Применили универсальное логическое условие в ГДЕ для управления фильтрацией без динамической сборки текста запроса.

Рекомендация: При работе с задачами в крупных конфигурациях (например, 1С:Документооборот) старайтесь также проверять адресацию. Задачи могут быть назначены не лично пользователю, а его роли. В таком случае вместо прямого сравнения Исполнитель = &Исполнитель может потребоваться соединение с регистром сведений АдресацияИсполнителей или использование виртуальных таблиц задач (если они предусмотрены для данных объектов).

← На главную