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