В практике разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда внешняя обработка, успешно работавшая ранее, внезапно начинает выдавать ошибку: Ошибка при вызове метода контекста: Неизвестная функция. Особенно часто это происходит при вызове процедур или функций, помеченных директивой &НаСервере или &НаСервереБезКонтекста, из клиентского контекста управляемой формы.
Рассмотрим подробнее причины возникновения этой проблемы, проанализируем представленный код и разберем по шагам методы решения, которые помогут восстановить работоспособность вашей обработки.
В представленном примере автор пытается вызвать функцию ПроверкаЗаказовДляСборкиНаСервере из клиентского метода ПроверкаЗаказовДляСборки. Типичная структура вызова выглядит следующим образом:
&НаКлиенте
Функция ПроверкаЗаказовДляСборки()
ПОПЫТКА
Если ФормаПроверкиЗаказовДляСборкиОткрыта = Ложь Тогда
ЕстьЗаказы = ПроверкаЗаказовДляСборкиНаСервере(Объект.Магазин);
// ... логика открытия формы
КонецЕсли;
ИСКЛЮЧЕНИЕ
Сообщить(ОписаниеОшибки());
КОНЕЦПОПЫТКИ;
КонецФункции
&НаСервереБезКонтекста
Функция ПроверкаЗаказовДляСборкиНаСервере(МагазинРМК)
// ... логика запроса
КонецФункции
Несмотря на то, что синтаксически код выглядит верно, система сообщает, что функция «неизвестна». Выясним причину, почему платформа «теряет» метод, который явно определен в модуле формы.
Когда вы запускаете внешнюю обработку (особенно через справочник Дополнительные отчеты и обработки), платформа копирует файл .epf во временный каталог пользователя на локальном диске или на сервере. Проанализируем механизм кэширования: если вы обновили обработку в справочнике, но у пользователя в сеансе осталась «старая» скомпилированная версия модуля, возникает конфликт. Платформа пытается вызвать метод по адресу в памяти, который уже не соответствует актуальному состоянию объекта.
Решение:
%AppData%\Local\1C\1Cv8 и %AppData%\Roaming\1C\1Cv8).Внешние обработки по умолчанию запускаются в так называемом Безопасном режиме. В этом режиме накладываются серьезные ограничения на использование некоторых методов. Рассмотрим, как это влияет на наш случай:
Во-первых, метод УстановитьПривилегированныйРежим(Истина) внутри модуля формы внешней обработки в безопасном режиме просто игнорируется. Если ваш запрос внутри функции ПроверкаЗаказовДляСборкиНаСервере обращается к данным, на которые у пользователя нет прав (например, к регистрам сведений или документам без RLS), запрос может вернуть ошибку или вызвать сбой компиляции функции.
Во-вторых, в редких случаях настройки профилей безопасности в кластере 1С могут блокировать вызовы &НаСервереБезКонтекста, если они не проходят проверку безопасности.
Рекомендация: Попробуйте изменить директиву на &НаСервере (с контекстом). Это увеличит объем передаваемых данных между клиентом и сервером, но поможет проверить, не связана ли проблема именно с безконтекстным вызовом.
Проанализируем ситуацию, когда модуль формы содержит синтаксическую ошибку, которая не видна при сохранении, но проявляется при компиляции на сервере. Например, использование конструкций #Если Сервер или обращение к переменным, которые недоступны в серверном контексте. Если модуль формы «не собирается» целиком из-за одной ошибки в любой его части, платформа может выдать сообщение «Неизвестная функция» на любую попытку обращения к любому методу этого модуля.
Посмотрите на фрагмент кода из примера:
Результат = Запрос.Выполнить().Выгрузить();
Возврат ?(Результат.Количество() = 0, Ложь, Истина);
УстановитьПривилегированныйРежим(Ложь);
КонецФункции
Здесь инструкция УстановитьПривилегированныйРежим(Ложь) стоит после оператора Возврат. Хотя платформа обычно игнорирует недостижимый код, в некоторых релизах (особенно 8.3.18) это может приводить к некорректной работе компилятора модулей внешних объектов. Перенесите отключение режима до возврата значения.
В коде автора используется переменная ПолноеИмяОбъекта для открытия формы:
ОткрытьФорму(ПолноеИмяОбъекта + ".Форма.ФормаСбораЗаказов", ...);
Если эта переменная не определена должным образом на клиенте (например, вы пытаетесь получить её через Метаданные(), что на тонком клиенте работает ограниченно), это может привести к сбою инициализации модуля формы. Выясним причину: если инициализация модуля формы прерывается ошибкой, все последующие вызовы методов этой формы будут возвращать ошибку «Неизвестная функция».
Для гарантированного решения проблемы рекомендуем выполнить следующие шаги:
Ctrl+F7. Убедитесь, что проверка проходит успешно для всех режимов (Клиент, Сервер).РеквизитФормыВЗначение("Объект").ИмяФункции().Объект.Магазин передайте Объект.Магазин.Ссылка. Хотя ссылка — это тоже объект, иногда это помогает при сериализации данных между контекстами.ПОПЫТКА...ИСКЛЮЧЕНИЕ не только на клиенте, но и внутри серверной функции, и записывайте ОписаниеОшибки() в Журнал регистрации через метод ЗаписьЖурналаРегистрации.Рассмотрим, как можно оптимизировать код функции, чтобы минимизировать риски возникновения ошибок контекста:
&НаСервереБезКонтекста
Функция ПроверкаЗаказовДляСборкиНаСервере(Знач МагазинСсылка)
// Включаем безопасный поиск данных
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| _ЗаказКлиента.Ссылка КАК Ссылка
|ИЗ
| Документ._ЗаказКлиента КАК _ЗаказКлиента
|ГДЕ
| _ЗаказКлиента.Магазин = &Магазин
| И _ЗаказКлиента.Проведен
| И _ЗаказКлиента.Дата >= &Дата";
Запрос.УстановитьПараметр("Магазин", МагазинСсылка);
Запрос.УстановитьПараметр("Дата", '20220601');
РезультатЗапроса = Запрос.Выполнить();
// Сначала отключаем режим, потом возвращаем результат
УстановитьПривилегированныйРежим(Ложь);
Возврат НЕ РезультатЗапроса.Пустой();
КонецФункции
В данном примере мы использовали ключевое слово Знач для параметра, чтобы исключить попытки обратного копирования данных, и метод Пустой() вместо выгрузки в таблицу, что значительно быстрее и безопаснее с точки зрения использования памяти сервера.
Соблюдение этих правил и понимание механизмов работы 1С:Предприятия с внешними компонентами позволит вам быстро диагностировать и устранять подобные ошибки в будущем.