Как программно заполнить реквизит формы типа «Список значений», привязанный к справочнику, в 1С?

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

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

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

Основные аспекты проблемы, которые мы рассмотрим

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

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

  3. Получение ссылок на справочники: Изучим методы для нахождения элементов справочника, которые будут использоваться для заполнения списка.

  4. Правильное заполнение «Списка значений»: Освоим методы Добавить() и ЗагрузитьЗначения() для добавления ссылок в реквизит формы.

  5. Место для инициализации: Определим оптимальный обработчик события формы для выполнения этих действий.

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

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

Наши первоначальные попытки, как мы видели в обсуждении, могли выглядеть так:

ЭтаФорма[ЭтаФорма.ПолучитьРеквизиты()[Счч].Имя] = "Администратор";

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

Каждый элемент в СписокЗначений на самом деле является объектом типа ЭлементСпискаЗначений. Этот объект имеет два ключевых свойства:

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

2. Поиск программно созданных реквизитов формы

Предположим, у нас есть несколько программно созданных реквизитов формы, чьи имена начинаются с определенного префикса, например, "МойРеквизит" — такая задача решается через конструктор документов и произвольных реквизитов. Чтобы получить к ним доступ, мы можем использовать метод формы ПолучитьРеквизиты(). Этот метод возвращает коллекцию описаний реквизитов формы. Затем мы можем перебрать эту коллекцию и отфильтровать нужные нам реквизиты по имени.

Давайте посмотрим на пример такого поиска:


Для Каждого РеквизитФормы Из ЭтаФорма.ПолучитьРеквизиты() Цикл
    Если СтрНачинаетсяС(РеквизитФормы.Имя, "МойРеквизит") Тогда
        // Здесь мы нашли нужный реквизит формы
        // РеквизитФормы.Имя содержит полное имя реквизита (например, "МойРеквизит1")
        // ЭтаФорма[РеквизитФормы.Имя] - это сам объект реквизита формы
    КонецЕсли;
КонецЦикла;

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

3. Получение ссылок на справочники

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

Например, если мы хотим добавить пользователя с наименованием "Администратор" из справочника "Пользователи", мы сделаем это так:


СсылкаНаАдминистратора = Справочники.Пользователи.НайтиПоНаименованию("Администратор");

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


ИБТСотрудник = Справочники.Пользователи.НайтиПоНаименованию("ИБТ");
Если ИБТСотрудник <> Неопределено Тогда
    // Можно добавить в список
КонецЕсли;

4. Правильное заполнение «Списка значений»

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

  1. Метод Добавить(): Используется для добавления одного элемента за раз.

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

    
    МойМассивСсылок = Новый Массив;
    МойМассивСсылок.Добавить(СсылкаНаАдминистратора);
    МойМассивСсылок.Добавить(СсылкаНаДругогоПользователя);
    
    МойСписокЗначений.ЗагрузитьЗначения(МойМассивСсылок);
    

Именно метод ЗагрузитьЗначения() с предварительно сформированным массивом ссылок является наиболее удобным и эффективным для нашей задачи.

5. Место для инициализации: Обработчик ПриСозданииНаСервере

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

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

Пример комплексного решения

Теперь давайте объединим все шаги и представим готовое решение в обработчике ПриСозданииНаСервере. Предположим, у нас есть несколько реквизитов формы с именами "МойРеквизит1", "МойРеквизит2", и мы хотим заполнить их ссылками на некоторых пользователей.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Шаг 1: Подготовка массива ссылок на элементы справочника
    МойМассивСсылок = Новый Массив;

    // Находим пользователя "Администратор"
    СсылкаНаАдминистратора = Справочники.Пользователи.НайтиПоНаименованию("Администратор");
    Если СсылкаНаАдминистратора <> Неопределено Тогда
        МойМассивСсылок.Добавить(СсылкаНаАдминистратора);
    КонецЕсли;

    // Находим другого пользователя, например, "ИБТ"
    СсылкаНаИБТ = Справочники.Пользователи.НайтиПоНаименованию("ИБТ");
    Если СсылкаНаИБТ <> Неопределено Тогда
        МойМассивСсылок.Добавить(СсылкаНаИБТ);
    КонецЕсли;

    // Можно также добавить текущего пользователя сеанса, как предложено в дополнительной информации
    // МойМассивСсылок.Добавить(ПараметрыСеанса.ТекущийПользователь);


    // Шаг 2: Перебор реквизитов формы и их заполнение
    Для Каждого РеквизитФормы Из ЭтаФорма.ПолучитьРеквизиты() Цикл
        // Проверяем, начинается ли имя реквизита с "МойРеквизит"
        Если СтрНачинаетсяС(РеквизитФормы.Имя, "МойРеквизит") Тогда
            // Получаем сам объект реквизита формы
            ТекущийРеквизитСпискаЗначений = ЭтаФорма[РеквизитФормы.Имя];

            // Проверяем, что реквизит действительно является СпискомЗначений
            // и у него установлен корректный тип для хранения ссылок на справочник Пользователи
            Если ТипЗнч(ТекущийРеквизитСпискаЗначений) = Тип("СписокЗначений") Тогда
                // Очищаем существующие значения, если необходимо
                ТекущийРеквизитСпискаЗначений.Очистить();
                
                // Загружаем подготовленный массив ссылок в список значений реквизита
                ТекущийРеквизитСпискаЗначений.ЗагрузитьЗначения(МойМассивСсылок);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

КонецПроцедуры

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

Важные нюансы и советы

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

  2. Проверка типа реквизита: Убедитесь, что реквизит формы, который вы пытаетесь заполнить, действительно имеет тип СписокЗначений. Это поможет избежать ошибок выполнения.

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

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

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

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

← На главную