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