Как реализовать заполнение табличной части документа без его принудительной записи в 1С:Розница 2.3

Программист 1С v8.3 (Управляемые формы) 1С:Розница Торговля и дистрибуция
← На главную

При разработке внешних обработок заполнения табличных частей для конфигураций на базе Библиотеки стандартных подсистем (БСП), таких как «1С:Розница 2.3», разработчики часто сталкиваются с неприятным поведением системы: перед выполнением команды программа принудительно требует записать документ. Это не всегда удобно, особенно если пользователь еще не завершил ввод данных или просто хочет «примерить» заполнение данных без фиксации в базе.

В этой статье мы подробно разберем, почему стандартный параметр РежимЗаписи = "НеЗаписывать" может не работать, проанализируем внутренние механизмы БСП и найдем надежный способ обработки данных «на лету».

Разбор механизма работы команд во внешних обработках

Для начала проанализируем, как БСП обрабатывает вызов внешней команды. В процедуре СведенияОВнешнейОбработке мы описываем таблицу команд. У каждой команды есть поле Использование, которое определяет, как именно будет выполняться код. Рассмотрим два основных варианта, которые вызывают наибольшее количество вопросов:

  1. ЗаполнениеФормы (FillingForm): Команда выполняется на сервере. Система пытается сама найти объект, передать его в обработку и вернуть результат. Именно здесь чаще всего возникает проблема с принудительной записью, так как БСП проверяет свойство Модифицированность формы.
  2. ВызовКлиентскогоМетода (ClientMethodCall): Команда вызывает экспортную процедуру в модуле формы вашей внешней обработки. Это дает полный контроль над контекстом, но требует написания клиент-серверного кода внутри самой обработки.

Проанализируем ситуацию пользователя: при использовании ЗаполнениеФормы в метод ВыполнитьКоманду передается только идентификатор команды. Если контекст формы не проброшен (например, команда вызвана из списка), система не видит объекта в оперативной памяти и требует его запись в базу данных.

Почему параметр НеЗаписывать игнорируется?

Выясним причину, по которой установка ОписаниеКоманды.РежимЗаписи = "НеЗаписывать" не всегда помогает. В коде общих модулей БСП (например, ДополнительныеОтчетыИОбработкиКлиент) существует жесткая проверка. Если система определяет, что обработка должна изменить данные объекта, она перестраховывается. В некоторых версиях «Розницы 2.3» наблюдался баг, когда контекст ЭтоФормаОбъекта определялся некорректно, и флаг записи выставлялся в Истина принудительно.

Важный нюанс: если вы вызываете обработку из формы списка (динамического списка), то объекта в памяти еще не существует — есть только ссылка. В этом случае запись (или перечитывание из базы) неизбежна. Чтобы работать без записи, обработка должна вызываться только из формы открытого документа.

Решение проблемы через ВызовКлиентскогоМетода

Рассмотрим наиболее надежный способ, который позволяет обойти ограничения сервера и работать напрямую с данными формы. Мы будем использовать тип команды ВызовКлиентскогоМетода.

Шаг 1. Настроим регистрацию обработки. В модуле объекта в функции СведенияОВнешнейОбработке укажем правильные параметры:


НоваяСтрока = ТаблицаКоманд.Добавить();
НоваяСтрока.Представление = "Заполнить ТЧ (без записи)";
НоваяСтрока.Идентификатор = "ЗаполнениеБезЗаписи";
НоваяСтрока.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
НоваяСтрока.ПоказыватьОповещение = Истина;
НоваяСтрока.Модификатор = "ПечатьDefault"; // Необязательно
НоваяСтрока.РежимЗаписи = "НеЗаписывать";

Шаг 2. В модуле формы внешней обработки создадим экспортную процедуру. Именно она будет «точкой входа». Посмотрим на пример кода:


&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
    
    // Получаем форму документа, из которой вызвана обработка
    ФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
    
    // Проверим, что мы находимся в форме объекта
    Если ФормаДокумента = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Обрабатываем данные напрямую в объекте формы
    // Например, заполним табличную часть "Товары"
    ЗаполнитьТабличнуюЧастьНаСервере(ФормаДокумента.Объект);
    
    // Сообщаем форме, что данные изменились, чтобы появилась "звездочка" (Модифицированность)
    ФормаДокумента.Модифицированность = Истина;

КонецПроцедуры

Работа с контекстом и передача данных

Разберем подробнее, что происходит в коде выше. Используя ПараметрыВыполнения.ЭтаФорма, мы получаем прямой доступ к расширению формы документа. Мы можем изменять ФормаДокумента.Объект (который является типом ДанныеФормыСтруктура), и эти изменения мгновенно отобразятся у пользователя на экране без обращения к базе данных.

Однако помните, что изменять ДанныеФормыСтруктура лучше на сервере. Для этого передайте ФормаДокумента.Объект в серверную процедуру модуля формы обработки:


&НаСервере
Процедура ЗаполнитьТабличнуюЧастьНаСервере(ДанныеФормыОбъект)
    
    // Пример: Очистим и заполним заново
    ДанныеФормыОбъект.Товары.Очистить();
    
    НоваяСтрока = ДанныеФормыОбъект.Товары.Добавить();
    НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Тестовый товар");
    НоваяСтрока.Количество = 1;
    НоваяСтрока.Цена = 100;
    НоваяСтрока.Сумма = 100;
    
КонецПроцедуры

Альтернативный вариант: Использование Оповещения

Если ваша обработка имеет сложный интерфейс (например, подбор товаров с фильтрами в отдельном окне), используем механизм оповещений. Рассмотрим этот сценарий по шагам:

  1. Пользователь нажимает кнопку заполнения, открывается форма вашей внешней обработки.
  2. В параметрах открытия передается ссылка на документ (или структура с данными ТЧ).
  3. Пользователь выбирает данные в форме обработки.
  4. При нажатии кнопки «Перенести в документ» выполняется команда ОповеститьОВыборе(СтруктураРезультата) или Оповестить("ЗаполнениеТЧ", СтруктураРезультата).
  5. В основной форме документа в процедуре ОбработкаОповещения (если это типовая форма, может потребоваться расширение) или в самой логике БСП данные подхватываются и записываются в ТЧ.

Важный совет: В конфигурации «Розница 2.3» для типа команды ЗаполнениеФормы БСП ожидает, что в модуле объекта обработки будет процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения). Если вы видите ошибку «Контекста — 0», это значит, что ПараметрыВыполнения не содержат ключа ЭтаФорма. Проверьте, не вызываете ли вы команду из списка документов.

Подведение итогов

Проанализировав проблему, мы приходим к выводу, что для реализации заполнения табличной части без записи в «Розница 2.3» следует придерживаться следующих правил:

Соблюдение этой методики позволит вам создавать удобные инструменты для пользователей, сохраняя при этом целостность данных и логику работы типовой конфигурации.

← На главную