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