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