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

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

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

Решение 1: Загрузка данных из справочника с помощью запроса

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

Многие начинающие программисты пытаются использовать в фильтрах наименования (строки), однако правильным подходом является использование ссылок. Ссылки обеспечивают уникальность данных и корректную работу фильтров в запросах, даже если два отдела называются одинаково.

Разберем пример кода для заполнения списка значений на сервере:


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

Обратите внимание на использование метода ЗагрузитьЗначения(). Это очень быстрый способ заполнить СписокЗначений данными из массива без использования циклов. Мы также добавили условие НЕ Отделы.ПометкаУдаления, чтобы не предлагать пользователю выбирать неактуальные (удаленные) подразделения.

Решение 2: Интерактивный выбор элементов пользователем

После того как мы подготовили список всех доступных отделов, нам нужно предоставить пользователю возможность отметить нужные. Для этого в 1С существует стандартный метод ОтметитьЭлементы(). Проанализируем, как правильно вызвать это окно и обработать результат выбора.

Важно помнить, что в управляемом приложении работа с диалоговыми окнами имеет свои особенности. Рассмотрим клиентскую процедуру:


&НаКлиенте
Процедура КомандаВыбратьОтделы(Команда)
    
    // Вызываем стандартное окно со списком флажков
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораОтделов", ЭтотОбъект);
    СписокОтделовНаФорме.ПоказатьОтметкуЭлементов(ОписаниеОповещения, "Выберите отделы для отчета");
    
КонецПроцедуры

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

Важный нюанс: часто возникает ошибка Поле объекта не обнаружено (Пометка). Это случается, если разработчик пытается обратиться к свойству Пометка у самого объекта СписокЗначений вместо того, чтобы обращаться к конкретному ЭлементСпискаЗначений внутри цикла. Выясним причину: СписокЗначений — это коллекция, а Пометка — это свойство каждого отдельного элемента этой коллекции.

Решение 3: Передача выбранного списка в запрос отчета

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


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

Использование оператора В (&Параметр) в языке запросов 1С позволяет эффективно фильтровать данные по массиву или списку значений. Платформа автоматически преобразует это в SQL-инструкцию IN (...).

Разбор критической ошибки: Передача данных между клиентом и сервером

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

Причина ошибки: Объект СписокЗначений может быть передан с клиента на сервер, так как он сериализуется. Однако отдельный объект ЭлементСпискаЗначений (который вы получаете в цикле Для Каждого) не может быть передан через границу "клиент-сервер".

Если вы попытаетесь передать элемент списка в серверную процедуру как параметр, система выдаст ошибку. Чтобы этого избежать:

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

Альтернативный способ (через СКД)

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

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

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

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

← На главную