Почему не срабатывает обработчик ПриСозданииНаСервере при открытии формы 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки программных решений на платформе 1С:Предприятие в режиме управляемого приложения разработчики часто сталкиваются с ситуацией, когда при открытии формы отработка кода из процедуры ПриСозданииНаСервере пропускается. Вызов сразу переходит к клиентскому событию ПриОткрытии, из-за чего параметры формы не инициализируются, а элементы и динамические списки не получают нужных настроек.

Рассмотрим подробнее основные причины возникновения этой проблемы и разберем по шагам варианты её исправления.

Причина 1. Отсутствие связи события с процедурой в свойствах формы

Самая частая и базовая причина — процедура с именем ПриСозданииНаСервере написана в модуле формы, однако она не назначена в качестве официального обработчика события в платформе Конфигуратор.

Наличие процедуры в тексте модуля не гарантирует её автоматический вызов платформой. Чтобы привязать процедуру к событию формы, выполним следующие действия:

  1. Откроем форму в Конфигураторе.
  2. Выделим корень дерева элементов формы (самую верхнюю строку в дереве элементов).
  3. Откроем Палитру свойств (сочетание клавиш Alt + Enter).
  4. Найдем раздел События и поле ПриСозданииНаСервере.
  5. Проверим значение поля: если оно пустое, то платформа не знает, какую именно процедуру вызывать при создании объекта формы. Укажем имя нужной процедуры вручную или выберем её из списка.

Проанализируем пример кода на клиенте, из которого вызывается форма с передачей структуры параметров:


&НаКлиенте
Процедура ИсходныеКомплектующиеНоменклатураПоставщикаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    ПараметрыФормы = Новый Структура("Номенклатура,Характеристика", 
        ЭтаФорма.Элементы.ИсходныеКомплектующие.ТекущиеДанные.Номенклатура,
        ЭтаФорма.Элементы.ИсходныеКомплектующие.ТекущиеДанные.Характеристика);
        
    Если СокрЛП(ЭтаФорма.Элементы.ИсходныеКомплектующие.ТекущиеДанные.Производитель) <> "" Тогда
        ПараметрыФормы.Вставить("Производитель", ЭтаФорма.Элементы.ИсходныеКомплектующие.ТекущиеДанные.Производитель);
    КонецЕсли;
    
    ОткрытьФорму("РегистрСведений.ЦеныНоменклатурыПоставщиков.Форма.ВыборЦен", ПараметрыФормы);
КонецПроцедуры

Если в форме ВыборЦен процедура привязана корректно, то в момент выполнения функции ОткрытьФорму платформа вызовет серверное событие, где мы сможем обработать полученные параметры:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("Производитель") И ЗначениеЗаполнено(Параметры.Производитель) Тогда
        Список.Параметры.УстановитьЗначениеПараметра("ОтборПоПроизводителю", Истина);
        Список.Параметры.УстановитьЗначениеПараметра("Производитель", Параметры.Производитель);
    Иначе
        Список.Параметры.УстановитьЗначениеПараметра("ОтборПоПроизводителю", Ложь);
        Список.Параметры.УстановитьЗначениеПараметра("Производитель", Справочники.Партнеры.ПустаяСсылка());
    КонецЕсли;
КонецПроцедуры

Причина 2. Повторное использование уже открытого экземпляра формы

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

Вместо него на клиенте срабатывает событие ПриПовторномОткрытии. Если необходимо, чтобы при каждом вызове метод ОткрытьФорму формировал новый экземпляр формы и заново отрабатывал серверный код, передадим параметр Уникальность со значением Истина:


ОткрытьФорму("РегистрСведений.ЦеныНоменклатурыПоставщиков.Форма.ВыборЦен", ПараметрыФормы, Элемент, Истина);

Причина 3. Перехват события в расширениях конфигурации

При использовании расширений конфигурации аннотации &Перед, &После или &Вместо для события ПриСозданииНаСервере не будут исполняться, если в основной конфигурации у исходной формы событие не было явно привязано в Палитре свойств.

Платформа проверяет наличие назначенного события в базовой форме до вызова процедур из расширения. Поэтому убедимся, что в основной конфигурации событие назначено, либо создадим форму заново в самом расширении.

Причина 4. Использование устаревшего метода ПолучитьФорму()

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

Для управляемого интерфейса рекомендуется отказаться от ПолучитьФорму() в пользу стандартного метода ОткрытьФорму().

Проанализируем сигнатуру и директивы компиляции

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

  1. Процедура обязательно должна сопровождаться директивой компиляции &НаСервере. Использование директивы &НаСервереБезКонтекста запрещено, так как при создании формируется контекст формы (дерево элементов и реквизиты).
  2. Сигнатура процедуры должна строго содержать два параметра: (Отказ, СтандартнаяОбработка). Изменение состава или порядка параметров приводит к ошибке или невозвожности вызова события платформой.

Альтернативный способ установки отборов в динамическом списке

Посмотрим на штатный механизм передачи отборов в форму динамического списка без написания ручного кода на сервере. Платформа 1С умеет автоматически накладывать отборы на динамический список, если передать параметр Отбор в структуре параметров вызова:


&НаКлиенте
Процедура ИсходныеКомплектующиеНоменклатураПоставщикаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("Номенклатура", ЭтаФорма.Элементы.ИсходныеКомплектующие.ТекущиеДанные.Номенклатура);
    
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("Отбор", СтруктураОтбора);
    
    ОткрытьФорму("РегистрСведений.ЦеныНоменклатурыПоставщиков.Форма.ВыборЦен", ПараметрыОткрытия, Элемент);
КонецПроцедуры

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

← На главную