Как реализовать выбор нескольких организаций и фильтрацию по ним в 1С

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

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

Метод 1: Использование реквизита типа СписокЗначений на форме

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

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

  1. Создадим новый реквизит формы (не путать с реквизитом объекта). Назовем его, например, СписокОрганизаций.
  2. В колонке "Тип" выберем СписокЗначений.
  3. В свойствах этого реквизита обязательно укажем "Тип значения" — СправочникСсылка.Организации. Это критически важный шаг: если его пропустить, система не будет знать, какую форму выбора открывать при нажатии кнопки добавления.
  4. Перетащим реквизит на форму. По умолчанию 1С предложит отобразить его как Поле ввода. В этом случае пользователь увидит строку, где выбранные элементы перечислены через запятую. Если же нам нужен более наглядный список, реквизит можно вывести как Таблицу.

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


&НаКлиенте
Процедура КомандаПодбор(Команда)
    ПараметрыПодбора = Новый Структура;
    ПараметрыПодбора.Вставить("МножественныйВыбор", Истина);
    ПараметрыПодбора.Вставить("ЗакрыватьПриВыборе", Ложь);
    
    ОткрытьФорму("Справочник.Организации.ФормаВыбора", ПараметрыПодбора, ЭтаФорма);
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    // Если ВыбранноеЗначение — это массив (результат множественного выбора)
    Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда
        Для Каждого Элемент Из ВыбранноеЗначение Цикл
            Если СписокОрганизаций.НайтиПоЗначению(Элемент) = Неопределено Тогда
                СписокОрганизаций.Добавить(Элемент);
            КонецЕсли;
        КонецЦикла;
    Иначе
        // Обработка одиночного выбора, если нужно
        Если СписокОрганизаций.НайтиПоЗначению(ВыбранноеЗначение) = Неопределено Тогда
            СписокОрганизаций.Добавить(ВыбранноеЗначение);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Метод 2: Использование Табличной части для хранения данных

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

Создание табличной части вместо СпискаЗначений дает следующие преимущества:

В табличную часть достаточно добавить один реквизит Организация с типом СправочникСсылка.Организации. Для пользователя работа с такой таблицей будет привычной и понятной.

Работа с запросом: фильтрация по списку

После того как пользователь выбрал нужные организации, нам необходимо изменить запрос, чтобы он учитывал этот выбор. Разберем, как правильно написать условие. В языке запросов 1С для работы с множествами используется оператор В (английский аналог IN).

Проанализируем пример запроса:


ВЫБРАТЬ
    Продажи.Организация,
    Продажи.СуммаОборот
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
ГДЕ
    Продажи.Организация В (&СписокОрганизаций)

Важный нюанс: Если в параметр &СписокОрганизаций передать пустой список, запрос вернет пустой результат. Однако пользователи часто ожидают, что "пустой фильтр = выбирать всё". Рассмотрим, как реализовать универсальное условие:


// В коде перед выполнением запроса:
Запрос.УстановитьПараметр("СписокОрганизаций", СписокОрганизаций);
Запрос.УстановитьПараметр("ВыбиратьВсе", СписокОрганизаций.Количество() = 0);

// В тексте запроса:
ГДЕ (&ВыбиратьВсе ИЛИ Организация В (&СписокОрганизаций))

Такой подход позволяет избежать лишнего ветвления кода и делает работу с отборами максимально гибкой.

Использование Системы компоновки данных (СКД)

Если ваша задача — создать отчет, то самым правильным решением будет использование СКД. Рассмотрим подробнее, почему это "коробочное" решение является наиболее предпочтительным:

  1. Вам не нужно писать код для заполнения списка и обработки выбора.
  2. В настройках СКД достаточно добавить поле Организация в закладку "Отбор".
  3. Пользователь сам выберет вид сравнения "В списке" и укажет нужные элементы.
  4. СКД автоматически модифицирует текст запроса на лету, обеспечивая высокую производительность.

Если нужно вывести этот отбор прямо на форму отчета, в настройках СКД на вкладке "Настройки" выберите нужный отбор и установите для него свойство "Включать в пользовательские настройки". Это позволит пользователю видеть список выбора сразу при открытии отчета.

Почему нельзя использовать реквизиты "Организация1", "Организация2"

Разберем ситуацию, предложенную в одном из сообщений форума: создание нескольких отдельных полей. Это классический антипаттерн, и вот почему его стоит избегать:

Итог: Для реализации выбора нескольких значений одного типа всегда используйте либо СписокЗначений (для временных фильтров), либо Табличную часть (для хранения данных в базе), либо встроенные механизмы СКД. Это обеспечит надежность вашего кода и удобство для пользователей.

← На главную