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

Программист 1С v8.3 (Обычные формы) Торговля и дистрибуция
← На главную

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

Разберем типичный текст ошибки компиляции:


{Справочник.Номенклатура.МодульОбъекта(185,11)}: Процедура или функция с указанным именем не определена (ПроверитьПравоПользователяНаРедактированиеНоменклатуры)
Если НЕ <<?>>ПроверитьПравоПользователяНаРедактированиеНоменклатуры( ТекстСообщения ) Тогда 
{Справочник.Номенклатура.МодульОбъекта(186,4)}: Процедура или функция с указанным именем не определена (Предупреждение)
<<?>>Предупреждение( ТекстСообщения );

Проанализируем структуру сообщения платформы: числа (185, 11) и (186, 4) указывают на точные координаты ошибки в исходном коде. Первое число — номер строки в соответствующем модуле, а второе — позиция символа в строке.

Причины возникновения ошибки

Рассмотрим основные факторы, приводящие к данной ошибке:

  1. Некорректное сравнение и объединение конфигураций при обновлении: в процессе обновления нетиповой или доработанной базы блок старого доработанного кода был автоматически объединен с новым типовым модулем. При этом функция, к которой обращается алгоритм, была удалена разработчиками, перенесена в другой общий модуль или переименована.
  2. Нарушение контекста выполнения (вызов клиентских процедур на сервере): процедура Предупреждение() является интерактивной клиентской процедурой. В модулях объектов, а также в процедурах фонового обмена данными и внешних соединений (COM/Web-сервисы), клиентский контекст отсутствует. Вызов модальных окон в серверном коде вызывает критическую ошибку выполнения платформы.

Пошаговое устранение проблемы

Разберем по шагам алгоритм локализации и исправления ошибки.

  1. Сравнение с архивной копией (бэкапом):

    Развернем резервную копию информационной базы, сделанную до обновления, и откроем ее конфигурацию параллельно с текущей рабочей базой. Перейдем в Справочник.Номенклатура → МодульОбъекта к обработчику события ПередЗаписью.

  2. Анализ содержимого обработчика ПередЗаписью:

    Посмотрим на некорректный блок кода, вызывающий сбой при записи объекта:

    
    Процедура ПередЗаписью(Отказ)
        Если НЕ ОбменДанными.Загрузка Тогда        
            
            // Ошибочный блок: функции нет, Предупреждение недопустимо на сервере
            ТекстСообщения = "";
            Если НЕ ПроверитьПравоПользователяНаРедактированиеНоменклатуры( ТекстСообщения ) Тогда                
                Предупреждение( ТекстСообщения );
                Отказ = Истина;
                Возврат;                      
            КонецЕсли;                 
                    
            // Типовой алгоритм проверки перемещения групп
            Если НЕ ЭтоНовый() И ЭтоГруппа И ПланыОбмена.ГлавныйУзел() <> Неопределено Тогда
                Если Ссылка.Родитель <> ЭтотОбъект.Родитель Тогда
                    Сообщить("Перемещение групп товаров доступно только в главном узле.", СтатусСообщения.Внимание);
                    Отказ = Истина;
                КонецЕсли;
            КонецЕсли;
            
            НеобходимостьПроверкиДиапазона(ЭтотОбъект, ЭтотОбъект.СтатусПроверкиДиапазона);
            ...
    КонецПроцедуры
    
  3. Корректировка кода модуля:

    Если кастомная проверка прав на редактирование номенклатуры устарела и больше не используется в новой версии конфигурации, удалим лишний фрагмент из процедуры ПередЗаписью, оставив корректную типовую реализацию:

    
    Процедура ПередЗаписью(Отказ)
        Если НЕ ОбменДанными.Загрузка Тогда
            
            // При попытке перемещения группы
            Если НЕ ЭтоНовый() И ЭтоГруппа И ПланыОбмена.ГлавныйУзел() <> Неопределено Тогда
                Если Ссылка.Родитель <> ЭтотОбъект.Родитель Тогда
                    Сообщить("Перемещение групп товаров доступно только в главном узле.", СтатусСообщения.Внимание);
                    Отказ = Истина;
                КонецЕсли;
            КонецЕсли;
            
            НеобходимостьПроверкиДиапазона(ЭтотОбъект, ЭтотОбъект.СтатусПроверкиДиапазона);
            ...
    КонецПроцедуры
    
  4. Если проверка прав необходима в системе:

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

    
    Если НЕ ПроверитьПравоПользователяНаРедактированиеНоменклатуры( ТекстСообщения ) Тогда                
        Сообщить(ТекстСообщения, СтатусСообщения.Важное);
        Отказ = Истина;
        Возврат;                      
    КонецЕсли;
    
  5. Синтаксическая проверка конфигурации:

    После внесения изменений выполним полную проверку конфигурации через меню: Конфигурация → Проверка конфигурации. Обязательно установим флаги для проверки в режимах: Сервер, Внешнее соединение и Модули объектов. Это позволит заблаговременно выявить подобные ошибки во всех остальных объектах метаданных до запуска обмена.

Правила разработки кода для механизмов обмена

Для предотвращения подобных сбоев при выгрузке и загрузке данных соблюдайте следующие правила платформы 1С:

  1. Использование свойства ОбменДанными.Загрузка: любые проверки бизнес-логики и прав пользователей в модулях объектов должны быть обязательно обрамлены условием Если НЕ ОбменДанными.Загрузка Тогда, чтобы регламентные фоновые процессы и пакетная запись данных не прерывались.
  2. Изоляция интерфейсных процедур: процедуры работы с диалогами (Предупреждение, Вопрос, ОткрытьФорму) должны располагаться исключительно в модулях форм и клиентских общих модулях. В серверном коде для информирования пользователя следует использовать объект СообщениеПользователю или системную процедуру Сообщить().
← На главную