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