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