При работе с платформой 1С:Предприятие 8.3 на управляемых формах часто возникает необходимость программно заполнять табличные части документов. Это может быть полезно для автоматизации ввода данных, реализации массового оформления продаж по выгрузкам Excel/CSV (для этого есть универсальная загрузка данных из Excel в 1С), интеграции с внешними системами или реализации сложной бизнес-логики. В этой статье мы подробно рассмотрим, как правильно добавить новые строки в табличную часть документа, заполнить их необходимыми данными, включая ссылки на справочники, и обработать сценарий заполнения нескольких строк из внешних источников.
Программирование в 1С требует понимания объектной модели и методов работы с данными. Например, часто требуется реализовать автоматическое создание возврата поставщику на основании возврата клиента, где данные переносятся между документами программно — поможет модуль автозаполнения связанных документов в 1С. Мы вместе разберем основные шаги и предоставим примеры кода, которые помогут вам эффективно управлять данными в табличных частях.
Прежде чем мы сможем программно заполнить табличную часть, нам нужно получить объект документа, с которым мы работаем. Существует два основных сценария: работа с уже открытым документом на форме или создание нового документа.
Работа с открытым документом на форме: Если код выполняется на стороне клиента или сервера в контексте формы открытого документа, мы можем получить объект документа из реквизита формы. Для этого используем методы РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы().
Метод РеквизитФормыВЗначение("Объект") позволяет получить текущий объект документа из реквизита формы с именем "Объект" (который по умолчанию содержит данные документа). После того как мы внесем изменения в этот объект (например, заполним табличную часть), нам необходимо сохранить эти изменения обратно в реквизит формы, используя ЗначениеВРеквизитФормы(ДокументОбъект, "Объект"). Это гарантирует, что изменения будут отображены на форме и доступны для дальнейшей работы.
Создание нового документа: Если нам нужно создать абсолютно новый документ и затем заполнить его табличную часть, мы используем метод СоздатьДокумент() соответствующего менеджера документов. Например, для документа "Реализация товаров и услуг" это будет Документы.РеализацияТоваровУслуг.СоздатьДокумент().
После получения объекта документа, мы можем получить доступ к его табличным частям как к свойствам. Например, если у документа есть табличная часть с именем "Товары", мы обращаемся к ней как ДокументОбъект.Товары. Для добавления новой строки в табличную часть используется метод Добавить(). Этот метод возвращает только что созданную строку табличной части, которую мы затем можем заполнить.
Рассмотрим пример кода для добавления одной строки в табличную часть "Товары" документа "Реализация товаров и услуг":
&НаСервере
Процедура ЗаполнитьОднуСтрокуТоваровНаСервере()
// 1. Получаем объект документа из реквизита формы
// Предполагается, что данный код выполняется в контексте формы открытого документа.
ДокументОбъект = РеквизитФормыВЗначение("Объект");
// 2. Добавляем новую строку в табличную часть "Товары"
НоваяСтрока = ДокументОбъект.Товары.Добавить();
// 3. Заполняем поля новой строки
// Для полей-ссылок (например, Номенклатура), сначала необходимо получить ссылку на нужный элемент справочника.
// Мы можем найти элемент по коду, наименованию или другому реквизиту.
// Важно проверять, что элемент найден, чтобы избежать ошибок.
КодНоменклатурыДляПоиска = "00001"; // Пример кода номенклатуры
НоменклатураСсылка = Справочники.Номенклатура.НайтиПоКоду(КодНоменклатурыДляПоиска);
Если НоменклатураСсылка <> Неопределено Тогда
НоваяСтрока.Номенклатура = НоменклатураСсылка; // Устанавливаем ссылку
НоваяСтрока.Количество = 10; // Заполняем числовое поле
НоваяСтрока.Цена = 100; // Заполняем числовое поле
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена; // Расчетное поле
Иначе
// Если номенклатура не найдена, сообщаем пользователю или логируем ошибку.
Сообщить("Номенклатура с кодом " + КодНоменклатурыДляПоиска + " не найдена.", СтатусСообщения.Важное);
КонецЕсли;
// 4. Возвращаем измененный объект документа обратно в реквизит формы
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедуры
В этом примере мы видим, как сначала получаем объект документа. Также в процессе заполнения может потребоваться заполнение цен по виду цен и номенклатуры партнера, что часто встречается в заказах поставщикам — здесь пригодится автоматическая загрузка номенклатуры и цен из Excel в 1С. Далее мы находим ссылку на элемент справочника Номенклатура с помощью Справочники.Номенклатура.НайтиПоКоду() и присваиваем ее полю Номенклатура в новой строке. В конце обязательно вызываем ЗначениеВРеквизитФормы(), чтобы изменения отразились на управляемой форме.
Важный момент: если вы создаете абсолютно новый документ, вместо РеквизитФормыВЗначение("Объект") используйте ДокументОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();. В этом случае, после заполнения всех данных, вам потребуется записать документ в базу данных с помощью ДокументОбъект.Записать().
Очень часто данные для заполнения табличной части приходят не по одной, а целыми наборами. Это может быть актуально при оформлении документов инвентаризации из Excel или когда требуется выполнить заполнение комплектаций номенклатуры из файла или скопированных строк — для этого подойдёт универсальный импорт данных из Excel в 1С без программирования. В таком случае нам потребуется организовать цикл по этим данным и в каждой итерации добавлять новую строку в табличную часть.
Для примера мы представим, что данные для заполнения хранятся в некоторой структуре, например, в Массиве структур или в ТаблицеЗначений. Перед началом заполнения полезно очистить существующие строки табличной части, если мы хотим полностью перезаписать ее содержимое.
Рассмотрим расширенный пример, который демонстрирует заполнение нескольких строк табличной части "Товары" документа "Реализация товаров и услуг" из подготовленного массива данных:
&НаСервере
Процедура ЗаполнитьНесколькоСтрокТоваровНаСервере()
// 1. Получаем объект документа.
ДокументОбъект = РеквизитФормыВЗначение("Объект");
// 2. Очищаем существующие строки табличной части, если это необходимо.
ДокументОбъект.Товары.Очистить();
// 3. Подготавливаем данные для заполнения.
// В реальной ситуации эти данные могут быть получены из файла, веб-сервиса и т.д.
ДанныеДляЗаполнения = Новый Массив;
СтруктураСтроки1 = Новый Структура("КодНоменклатуры, Количество, Цена");
СтруктураСтроки1.КодНоменклатуры = "00001";
СтруктураСтроки1.Количество = 10;
СтруктураСтроки1.Цена = 100;
ДанныеДляЗаполнения.Добавить(СтруктураСтроки1);
СтруктураСтроки2 = Новый Структура("КодНоменклатуры, Количество, Цена");
СтруктураСтроки2.КодНоменклатуры = "00002";
СтруктураСтроки2.Количество = 5;
СтруктураСтроки2.Цена = 250;
ДанныеДляЗаполнения.Добавить(СтруктураСтроки2);
// 4. Проходим по подготовленным данным и заполняем табличную часть.
Для Каждого СтрокаДанных Из ДанныеДляЗаполнения Цикл
НоваяСтрока = ДокументОбъект.Товары.Добавить();
КодНоменклатуры = СтрокаДанных.КодНоменклатуры;
НоменклатураСсылка = Справочники.Номенклатура.НайтиПоКоду(КодНоменклатуры);
Если НоменклатураСсылка <> Неопределено Тогда
НоваяСтрока.Номенклатура = НоменклатураСсылка;
НоваяСтрока.Количество = СтрокаДанных.Количество;
НоваяСтрока.Цена = СтрокаДанных.Цена;
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
Иначе
Сообщить("Внимание! Номенклатура с кодом " + КодНоменклатуры + " не найдена.", СтатусСообщения.Важное);
КонецЕсли;
КонецЦикла;
// 5. Возвращаем измененный объект документа обратно в реквизит формы.
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
Сообщить("Табличная часть 'Товары' заполнена.", СтатусСообщения.Информация);
КонецПроцедуры
В этом примере мы сначала получаем объект документа. Затем, используя ДокументОбъект.Товары.Очистить(), мы подготавливаем табличную часть к новому заполнению. Далее мы имитируем получение данных из внешнего источника. Подобная логика используется в решениях, обеспечивающих автоподбор номенклатуры и партнёров при массовой загрузке продаж — поможет автозагрузка документов и табличных частей из Excel в 1С.
В цикле мы итерируем по подготовленным данным, добавляем новую строку и находим номенклатуру по коду. Очень важно использовать проверку Если НоменклатураСсылка <> Неопределено Тогда. После заполнения всех строк мы снова вызываем ЗначениеВРеквизитФормы(). Если вы работали с новым документом, необходимо вызвать метод Записать().
При заполнении полей табличной части очень важно использовать именно ссылки. 1С оперирует уникальными идентификаторами объектов. Помимо НайтиПоКоду(), существуют и другие методы:
Справочники.<ИмяСправочника>.НайтиПоНаименованию(<СтрокаНаименования>): Поиск по полному наименованию.
Справочники.<ИмяСправочника>.НайтиПоРеквизиту(<ИмяРеквизита>, <ЗначениеРеквизита>): Поиск по произвольному реквизиту.
Новый УникальныйИдентификатор(<СтроковоеПредставлениеGUID>): Создание ссылки по GUID.
Для повышения производительности при работе с большим количеством строк рекомендуется выполнять операции на сервере. Примером такой оптимизации является автоматическое заполнение схем обеспечения номенклатуры в фоне, что позволяет не блокировать работу пользователя при длительных операциях.
Проанализировав различные подходы, мы видим, что программное заполнение табличных частей в 1С 8.3 — это мощный инструмент для автоматизации. Правильное использование методов объекта, работа со ссылками и обработка данных в цикле позволяют создавать гибкие решения. Не забывайте о проверках на существование ссылочных данных и правильной записи документа после его модификации.