Как программно заполнить документ «Установка цен номенклатуры» и открыть его форму без сохранения?

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

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с задачей: нужно создать новый документ, заполнить его данными из другого объекта и показать пользователю, не записывая документ в базу данных. В обычных документах это решается простым копированием данных формы, но с документом Установка цен номенклатуры (используемым в УТ 11, ERP 2, КА 2 и Рознице) ситуация сложнее. Рассмотрим, почему стандартный подход не работает и как правильно реализовать эту задачу.

Проанализируем проблему: почему табличная часть не отображается?

Разберем ситуацию, представленную в исходном вопросе. Программист пытается получить форму документа через ПолучитьФорму, заполнить её объект на сервере и вернуть обратно на клиент. На первый взгляд, код логичен: данные помещаются в объект, вызывается ЗначениеВДанныеФормы, а затем КопироватьДанныеФормы. Однако при открытии формы пользователь видит заполненную дату и ответственного, но абсолютно пустые таблицы товаров и видов цен.

Выясним причину такого поведения. В современных типовых конфигурациях документ Установка цен номенклатуры имеет очень сложную визуальную логику. Данные в форме отображаются не напрямую из табличных частей Товары и ВидыЦен, а через специальный вспомогательный объект — Дерево цен. Это дерево строится динамически в момент создания формы на сервере (процедура ПриСозданииНаСервере). Когда мы принудительно «подсовываем» данные в объект формы через копирование, механизмы отрисовки дерева не срабатывают, и визуально документ остается пустым, хотя данные физически могут находиться в скрытых ТЧ.

Решение №1: Использование механизма «ЗначениеЗаполнения» (Рекомендуемый способ)

Для того чтобы документ заполнился корректно и все визуальные элементы (дерево цен, колонки) отрисовались правильно, мы должны использовать стандартный механизм платформы — параметр ЗначениеЗаполнения. Это позволит передать данные в процедуру ОбработкаЗаполнения модуля объекта, где 1С сама инициализирует все необходимые структуры.

Рассмотрим по шагам, как это реализовать. Сначала подготовим данные для заполнения на стороне вызывающей формы.


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

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

Теперь нам необходимо прописать логику в модуле объекта УстановкаЦенНоменклатуры. Перейдем в модуль объекта и найдем (или создадим) процедуру ОбработкаЗаполнения.


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

Почему этот метод лучше?

Проанализируем ситуацию: когда вы вызываете ОткрытьФорму с параметром ЗначениеЗаполнения, платформа 1С выполняет следующие действия:

  1. Создает новый объект документа в памяти.
  2. Вызывает процедуру ОбработкаЗаполнения в модуле объекта (где мы программно наполнили ТЧ).
  3. Создает форму документа.
  4. В процессе создания формы вызывается типовой код конфигурации, который «видит» заполненные табличные части и на их основе автоматически строит Дерево цен и устанавливает видимость колонок.

В итоге пользователь получает полностью готовую, корректно отрисованную форму, которую он может отредактировать и нажать кнопку «Провести и закрыть».

Решение №2: Использование параметра «Основание»

Если вы не хотите менять модуль объекта (например, конфигурация находится на поддержке без возможности изменения), можно попробовать использовать стандартный механизм «Заполнение по основанию». Посмотрите, какие типы объектов уже прописаны в качестве оснований для документа Установка цен номенклатуры.

Разберем этот вариант: если ваш исходный документ может выступать основанием, вы просто передаете ссылку на него в ОткрытьФорму. Однако, как заметил автор темы, при стандартном заполнении по основанию могут подтянуться лишние виды цен (все цены магазина). В этом случае в форме целевого документа после открытия всё равно придется программно «вычищать» лишнее, что менее удобно, чем первый способ.

Важные нюансы при работе с Установкой цен

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

Подведем итог: наиболее стабильным и правильным способом программного создания документов в управляемом приложении без их записи является использование ПараметрыФормы и ЗначениеЗаполнения. Это гарантирует, что вся внутренняя бизнес-логика конфигурации, заложенная разработчиками, отработает в штатном режиме.

← На главную