В современных конфигурациях 1С, таких как Розница 2.2, Управление торговлей 11 или ERP, работающих на базе Библиотеки стандартных подсистем (БСП), часто возникает задача автоматизировать заполнение документов из внешних файлов или по сложной логике. При этом важно сохранить конфигурацию на поддержке, не внося в нее изменения. Для этого используются внешние подключаемые обработки. Разберем подробно, как реализовать механизм заполнения табличной части (ТЧ) «с нуля».
Первым делом проанализируем, как система узнает о нашей обработке. Для этого в модуле объекта внешней обработки необходимо создать экспортную функцию СведенияОВнешнейОбработке. Именно она сообщает подсистеме «Дополнительные отчеты и обработки», к каким документам привязана программа и в каком режиме она должна запускаться.
Рассмотрим пример кода регистрации для документа Поступление товаров:
Функция СведенияОВнешнейОбработке() Экспорт
Назначения = Новый Массив;
Назначения.Добавить("Документ.ПоступлениеТоваров"); // Указываем целевой документ
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ЗаполнениеОбъекта"); // Тип для заполнения ТЧ
ПараметрыРегистрации.Вставить("Назначение", Назначения);
ПараметрыРегистрации.Вставить("Наименование", "Загрузка данных из файла");
ПараметрыРегистрации.Вставить("Версия", "1.1");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь); // Важно: Ложь, если нужно читать файлы с диска
Команды = ПолучитьТаблицуКоманд();
// Обратите внимание на тип использования: ОткрытиеФормы
ДобавитьКоманду(Команды, "Заполнить из файла...", "ЗаполнитьДокумент", "ОткрытиеФормы", Ложь);
ПараметрыРегистрации.Вставить("Команды", Команды);
Возврат ПараметрыРегистрации;
КонецФункции
В данном примере мы используем тип команды ОткрытиеФормы. Это позволит нам сначала открыть окно нашей обработки, где пользователь сможет выбрать файл или настроить параметры загрузки, а уже затем передать данные в документ.
Для корректного формирования структуры команд нам понадобятся две стандартные процедуры. Разберем их реализацию:
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Когда мы выбрали тип команды ОткрытиеФормы, форма внешней обработки открывается с установленным свойством ВладелецФормы. Через него мы получаем прямой доступ к контексту документа, из которого была вызвана обработка.
Выясним причину, по которой данные могут не обновляться. Часто программисты пытаются изменить реквизит Количество, однако в современных конфигурациях (Розница, УТ) в табличных частях используется реквизит КоличествоУпаковок. Проанализируем пример кода в модуле формы внешней обработки:
&НаКлиенте
Процедура ВыполнитьЗаполнение(Команда)
// Проверяем, что форма открыта из документа
Если ВладелецФормы = Неопределено Тогда
Возврат;
КонецЕсли;
// Получаем объект документа через владельца формы
ОбъектДокумента = ВладелецФормы.Объект;
// Пример: обнуление или заполнение табличной части "Товары"
Для Каждого ТекущаяСтрока Из ОбъектДокумента.Товары Цикл
// Работаем с правильными именами реквизитов БСП
ТекущаяСтрока.КоличествоУпаковок = 10;
// После изменения количества часто нужно пересчитать суммы
// В типовых конфигурациях это делается через оповещение или вызов серверных процедур
КонецЦикла;
// Сообщаем форме-владельцу, что данные изменились
ВладелецФормы.Модифицированность = Истина;
Закрыть(); // Закрываем форму обработки после завершения
КонецПроцедуры
Просто изменить значение в колонке недостаточно. Проанализируем дополнительные действия, которые необходимо выполнить, чтобы документ остался корректным:
ПриИзменении. Поэтому суммы, НДС и общие итоги документа могут не пересчитаться автоматически. Рекомендуется после заполнения вызвать на форме владельца стандартные процедуры пересчета, если они доступны, или имитировать изменение поля пользователем.Количество является скрытым и вычисляемым (КоличествоУпаковок * Коэффициент). Всегда заполняйте именно КоличествоУпаковок.СведенияОВнешнейОбработке установлен БезопасныйРежим = Истина, 1С заблокирует попытки чтения файлов с диска или работу с COM-объектами (например, Excel). Для загрузки данных всегда устанавливайте этот параметр в Ложь.ВладелецФормы.ОбновитьОтображениеДанных().Если интерактивное взаимодействие с пользователем не требуется, мы можем использовать тип команды ВызовСерверногоМетода. В этом случае код выполняется в модуле объекта обработки в процедуре ВыполнитьКоманду.
Рассмотрим, как это реализовать:
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
// ОбъектыНазначения - это массив ссылок на документы
Для Каждого СсылкаНаДокумент Из ОбъектыНазначения Цикл
// Получаем форму документа, если она открыта
ФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
// Заполняем ТЧ напрямую в данных формы
НоваяСтрока = ФормаДокумента.Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("00001");
НоваяСтрока.КоличествоУпаковок = 1;
КонецЦикла;
КонецПроцедуры
Этот метод считается более «чистым», так как он интегрирован в стандартные механизмы БСП и позволяет работать с объектом формы напрямую на сервере, что значительно ускоряет обработку больших объемов данных.
Таким образом, мы разобрали основные способы программного заполнения документов. Использование ВладелецФормы удобно для простых операций на клиенте, а серверные методы БСП обеспечивают более глубокую интеграцию с логикой конфигурации.