Почему возникает ошибка «Процедура или функция с указанным именем не определена» в модуле управляемой формы 1С?

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

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

Разберем подробно, почему возникают эти ошибки, в чем заключается разница между директивами компиляции и инструкциями препроцессора, а также как правильно организовать выполнение алгоритмов в управляемом приложении.

Причина 1. Несоответствие имен переменных и параметров

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


Процедура ПоказНалога(Сотрудник, Стаж, Оклад)
    Налог = СтажРаботы * Оклад / 100 * 13;
    ТекстСообщения = Сотрудник + " Оклад:" + Оклад + " руб. Стаж:" + Стаж + " мес. Налог=" + Налог + " руб.";
    Сообщить(ТекстСообщения);
КонецПроцедуры

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

Исправленный вариант строки расчета выглядит следующим образом:

Налог = Стаж * Оклад / 100 * 13;

Причина 2. Разница между директивами компиляции и инструкциями препроцессора

Часто разработчики пытаются ограничить контекст исполнения с помощью препроцессора #Если Клиент Тогда ... #КонецЕсли, считая, что это делает все вложенные процедуры клиентскими. Однако в управляемых формах этот механизм работает иначе:

  1. Инструкции препроцессора (например, #Если Клиент Тогда) управляют только включением или исключением исходного текста на этапе предварительной обработки. Они определяют, попадет ли фрагмент кода в сборку для клиента или сервера, но не задают контекст исполнения конкретной процедуры формы.
  2. Директивы компиляции (&НаКлиенте, &НаСервере, &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста) указывают платформе, где именно должен выполняться метод формы.
  3. Если перед процедурой в модуле управляемой формы директива компиляции не указана явно, платформа 1С по умолчанию считает ее серверной (&НаСервере).

Если серверная процедура без директивы пытается вызываться из клиентского контекста или наоборот, платформа выдает ошибку о том, что метод не определен. Чтобы процедура стала доступна на стороне клиента, перед ней обязательно нужно указать директиву &НаКлиенте:


&НаКлиенте
Процедура ПоказНалога(Сотрудник, Стаж, Оклад)
    Налог = Стаж * Оклад / 100 * 13;
    ТекстСообщения = Сотрудник + " Оклад:" + Оклад + " руб. Стаж:" + Стаж + " мес. Налог=" + Налог + " руб.";
    Сообщить(ТекстСообщения);
КонецПроцедуры

Причина 3. Исполнение кода в разделе основной программы модуля формы

В обычных формах прошлых версий платформы код в конце модуля (вне процедур и функций) выполнялся как раздел инициализации. В управляемых формах раздел основной программы компилируется на сервере в момент инициализации контекста формы. Попытка вызвать из этого раздела клиентскую процедуру с директивой &НаКлиенте приводит к синтаксической ошибке.

Кроме того, если вызывать функцию Сообщить() в процессе инициализации формы до завершения ее отрисовки, окно сообщений может закрыться или очиститься сразу после завершения загрузки интерфейса.

Правильные способы реализации алгоритма в управляемой форме

Рассмотрим два корректных подхода к реализации интерактивных алгоритмов в управляемом интерфейсе.

Способ 1. Запуск кода по нажатию кнопки (Команда формы)

Это наиболее наглядный и рекомендуемый способ для интерактивных обработок:

  1. В редакторе формы перейдем на вкладку Команды.
  2. Создадим новую команду, например, РассчитатьНалог.
  3. В свойствах команды нажмем на значок лупы напротив строки Действие и создадим клиентский обработчик.
  4. Перетащим команду на панель элементов формы, чтобы появилась кнопка.
  5. В модуле формы разместим код вызова:

&НаКлиенте
Процедура ПоказНалога(Сотрудник, Стаж, Оклад)
    Налог = Стаж * Оклад / 100 * 13;
    ТекстСообщения = Сотрудник + " Оклад:" + Оклад + " руб. Стаж:" + Стаж + " мес. Налог=" + Налог + " руб.";
    Сообщить(ТекстСообщения);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьНалог(Команда)
    Сотрудник1 = "Иванов";
    СтажРаботы1 = 10;
    Оклад1 = 10000;
    ПоказНалога(Сотрудник1, СтажРаботы1, Оклад1);
КонецПроцедуры

Способ 2. Запуск кода при открытии формы

Если расчет должен выполняться автоматически сразу при запуске обработки, используем предопределенный обработчик события ПриОткрытии:

  1. Откроем свойства самой формы (выделив корень дерева элементов).
  2. Найдем событие ПриОткрытии и создадим процедуру-обработчик.
  3. Поместим логику вызова процедур внутрь этого события:

&НаКлиенте
Процедура ПоказНалога(Сотрудник, Стаж, Оклад)
    Налог = Стаж * Оклад / 100 * 13;
    ТекстСообщения = Сотрудник + " Оклад:" + Оклад + " руб. Стаж:" + Стаж + " мес. Налог=" + Налог + " руб.";
    
    // Вывод сообщения пользователю
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = ТекстСообщения;
    Сообщение.Сообщить();
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Сотрудник1 = "Иванов";
    СтажРаботы1 = 10;
    Оклад1 = 10000;
    ПоказНалога(Сотрудник1, СтажРаботы1, Оклад1);
    
    Сотрудник2 = "Петров";
    СтажРаботы2 = 5;
    Оклад2 = 12000;
    ПоказНалога(Сотрудник2, СтажРаботы2, Оклад2);
КонецПроцедуры

Использование объекта СообщениеПользователю вместо базового метода Сообщить() гарантирует корректную доставку информационных сообщений в пользовательский интерфейс управляемого приложения.

← На главную