Как создать несколько документов на основании одного источника с разделением данных по табличным частям

Программист Управленческий учет Промышленность, строительство и АПК
← На главную

В практике разработки на платформе 1С часто возникает задача, когда один документ-источник содержит данные для нескольких хозяйственных операций. Например, документ выпуска продукции может одновременно отражать и поступление готовых изделий на склад, и списание материалов. Стандартный механизм "Ввод на основании" в метаданных ориентирован на создание одного подчиненного документа. Разберем подробно, как обойти это ограничение и реализовать гибкое заполнение нескольких документов перемещения или списания на основе разных табличных частей одного источника.

Анализ стандартного механизма и постановка задачи

Рассмотрим ситуацию: у нас есть документ ВыпускПродукции с двумя табличными частями: Продукция и Материалы. Нам необходимо создать два документа ПеремещениеТоваров. Первый должен заполниться данными из таблицы Продукция, а второй — из таблицы Материалы. Проблема заключается в том, что при стандартном вызове команды создания на основании в модуль объекта принимающего документа (в процедуру ОбработкаЗаполнения) передается только ссылка на источник. Система "не знает", в каком контексте создается документ.

Способ 1: Передача параметров через ЗначенияЗаполнения

Этот метод является наиболее универсальным для управляемого приложения. Мы откажемся от стандартной кнопки, создаваемой платформой автоматически, и реализуем собственную команду. Основная идея заключается в том, чтобы передать в форму нового документа не только ссылку на основание, но и специальный признак — "режим заполнения".

Рассмотрим по шагам реализацию этого подхода. Сначала проанализируем код вызова формы нового документа из формы источника или из общей команды:


// В модуле команды или формы документа-источника
ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("ДокументОснование", Объект.Ссылка);
ПараметрыЗаполнения.Вставить("РежимЗаполнения", "ТолькоМатериалы");

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);

ОткрытьФорму("Документ.ПеремещениеТоваров.ФормаОбъекта", ПараметрыФормы);

Теперь проанализируем, как принять эти данные в документе-приемнике. В модуле объекта ПеремещениеТоваров необходимо модифицировать процедуру ОбработкаЗаполнения. Выясним, как программно разделить логику:


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

Важный момент: использование параметра СтандартнаяОбработка = Ложь позволяет полностью перехватить управление процессом. Если же в ДанныеЗаполнения пришла просто ссылка (стандартный вызов), код продолжит работать по обычному сценарию.

Способ 2: Использование Библиотеки стандартных подсистем (БСП)

Если ваша конфигурация построена на базе БСП, рекомендуется использовать подсистему "Создание на основании". Это позволит добавить несколько пунктов в подменю "Создать на основании" для одного и того же типа документа. Вы прописываете логику в модуле менеджера или в специальном модуле переопределения.

Разберем преимущества этого метода:

  1. Гибкость интерфейса: Пользователь видит конкретные команды: "Перемещение (по продукции)" и "Перемещение (по сырью)".
  2. Программное создание: БСП позволяет формировать документы в фоновом режиме без открытия форм, что удобно для массовой обработки.
  3. Централизация: Вся логика заполнения выносится в модуль менеджера, что соответствует современным стандартам разработки (отказ от кода в модулях объектов в пользу менеджеров).

Для реализации необходимо зарегистрировать команды в процедуре ПриОпределенииКомандПодключенныхКОбъекту в модуле менеджера документа-источника. Каждая команда будет иметь свой уникальный идентификатор, который затем анализируется в обработчике заполнения.

Способ 3: Разделение через временное хранилище

В ситуациях, когда табличные части документа-источника содержат тысячи строк, передача данных через структуру параметров может привести к снижению производительности, так как данные будут сериализоваться и передаваться между сервером и клиентом несколько раз. В этом случае рассмотрим использование ВременногоХранилища.

Алгоритм действий следующий:

  1. В форме источника мы подготавливаем нужную таблицу данных (фильтруем, сворачиваем).
  2. Помещаем таблицу во временное хранилище функцией ПоместитьВоВременноеХранилище.
  3. Передаем адрес этого хранилища в параметрах открытия формы нового документа.
  4. В процедуре ОбработкаЗаполнения извлекаем таблицу по адресу и загружаем в объект.

Посмотрим на пример кода в модуле объекта документа-приемника:


Если ДанныеЗаполнения.Свойство("АдресДанныхВХранилище") Тогда
    ТаблицаДанных = ПолучитьИзВременногоХранилища(ДанныеЗаполнения.АдресДанныхВХранилище);
    Товары.Загрузить(ТаблицаДанных);
КонецЕсли;

Способ 4: Интерактивное рабочее место (Генерация документов)

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

Проанализируем преимущества такого подхода:

Рекомендации по реализации

При выборе метода учитывайте следующие технические нюансы:

  1. Контроль модифицированности: При программном заполнении не забывайте устанавливать признак того, что форма документа изменена, чтобы пользователь получил запрос на сохранение.
  2. Связь документов: Всегда заполняйте реквизит ДокументОснование в новых объектах. Это позволит корректно строить дерево подчиненности и упростит последующий аудит данных.
  3. Обработка событий: Если вы открываете две формы подряд программно, используйте асинхронные вызовы (ОписаниеОповещения), чтобы избежать блокировки интерфейса и обеспечить корректную последовательность открытия окон в веб-клиенте.

Подводя итог, можно сказать, что хотя типовой "конструктор" ввода на основании ограничен, платформа 1С предоставляет богатый инструментарий для реализации любой сложной логики. Использование структуры параметров в ЗначенияЗаполнения является "золотым стандартом" для решения задачи разделения табличных частей при создании документов.

← На главную