Как получить данные из элементов формы документа при программном создании объектов в 1С?

Программист IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: почему нельзя обращаться к форме из модуля объекта

Первое, что мы должны осознать — это жесткое разделение системы на клиентскую и серверную части. Процедура ОбработкаПроведения, в которой автор темы пытается создать новый документ, выполняется на сервере. В этот момент «формы» как визуального объекта в памяти сервера просто не существует. Форма — это чисто клиентская сущность, предназначенная для взаимодействия с пользователем.

Проанализируем ситуацию, описанную в сообщении: автор пытается получить Элементы.Доходы.ТекущиеДанные.СуммаНУ. Здесь скрыты сразу две архитектурные ошибки:

  1. Зависимость от интерфейса: Если документ будет проводиться не пользователем вручную, а, например, регламентным заданием или через групповую обработку, никакой формы не будет в принципе. Код, обращающийся к ЭлементыФормы, вызовет исключение.
  2. Зависимость от фокуса: Свойство ТекущиеДанные указывает на строку, на которой в данный момент стоит курсор пользователя. При программной обработке «текущей» строки не существует, и логика должна опираться на перебор всех данных коллекции.

Решение 1: Перенос логики расчетов в общие модули

Если данные на форме «рассчитываются» динамически и не хранятся в базе, значит, в модуле формы прописан некий алгоритм. Рассмотрим правильный подход к проектированию такой логики. Вместо того чтобы дублировать код или пытаться «вытащить» результат из текстового поля формы, мы должны вынести расчет в Общий модуль с установленным флагом Сервер.

Разберем по шагам, как это реализовать:

  1. Создадим общий модуль, например, РасчетПоказателейСервер.
  2. Перенесем туда алгоритм расчета суммы, который ранее находился в форме.
  3. Функция должна принимать на вход объект или ссылку и возвращать структуру с результатами.

Теперь и форма документа сможет вызывать эту функцию для отображения данных пользователю, и модуль объекта сможет вызвать её же при проведении для заполнения нового документа Доходы. Проанализируем пример кода:


// В общем модуле
Функция РассчитатьСуммуНУ(ДанныеДокумента) Экспорт
    // Здесь ваша логика расчета на основе реквизитов Поступления
    Возврат РезультатРасчета;
КонецФункции

Решение 2: Использование коллекции ДополнительныеСвойства

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

Рассмотрим, как пробросить данные с клиента на сервер:

В модуле формы, перед тем как инициировать запись, мы заполняем специальную структуру в объекте:


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

Затем в модуле объекта (на сервере) в процедуре ОбработкаПроведения мы извлекаем эти данные:


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

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

Решение 3: Работа через реквизиты объекта (самый надежный способ)

Как справедливо отмечено в сообщениях форума, «программист должен опираться на данные». Если данные важны для проведения или создания связанных документов, они должны храниться в реквизитах объекта или его табличных частей.

Рассмотрим алгоритм правильного программного создания документа Доходы из модуля объекта Поступление:


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

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

Выводы и рекомендации

Подведем итог нашему разбору. Попытка получить ЭлементыФормы на сервере — это тупиковый путь, нарушающий базовые принципы платформы 1С. Чтобы ваша программа работала стабильно, придерживайтесь следующих правил:

Используя эти подходы, вы создадите надежный код, который будет корректно работать как при ручном вводе документов пользователем, так и при автоматизированных обменах или групповых обработках данных.

← На главную