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