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