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

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

При организации интеграции между различными конфигурациями «1С:Предприятие» разработчики часто прибегают к использованию технологии COM-соединения (V83.COMConnector). Это достаточно простой способ напрямую подключиться к другой базе данных и программно создать в ней необходимые объекты, например, документы или справочники.

Однако при обновлении целевой конфигурации (особенно крупных систем, таких как «1С:ERP Управление предприятием» или «1С:КА») привычный обмен может внезапно прерваться критической ошибкой компиляции. Типичный пример такой ошибки:


{Документ.м29.Форма.ФормаДокумента.Форма(264)}: Ошибка при вызове метода контекста (СоздатьДокумент)
НовДок = СоединениеБУХ.Документы.ВнутреннееПотреблениеТоваров.СоздатьДокумент;
по причине:
Произошла исключительная ситуация (1C:Enterprise 8.3.12.1714):
Ошибка инициализации модуля: ОбщийМодуль.УСОERP_МодификацияКонфигурации.Модуль
{ОбщийМодуль.УСОERP_МодификацияКонфигурации.Модуль(3875,21)}: Процедура или функция с указанным именем не определена (ПолучитьСтруктуруОплаты)

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

Выясняем причину: как контекст COM-соединения влияет на компиляцию

Для того чтобы понять природу ошибки, рассмотрим механизм работы платформы «1С:Предприятие» при COM-подключении. Когда внешнее приложение выполняет вызов V83COMConnector.Connect() и пытается обратиться к метаданным (например, создать документ ВнутреннееПотреблениеТоваров), платформа инициализирует сеанс типа Внешнее соединение.

В этот момент происходит компиляция всех программных модулей, которые могут быть задействованы в работе данного сеанса. К ним относятся:

  1. Модуль приложения (точнее, Модуль внешнего соединения).
  2. Модули объектов и менеджеров создаваемых документов.
  3. Общие модули, у которых в свойствах установлен флаг «Внешнее соединение».

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

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

---

Шаг 1: Диагностика проблемы в Конфигураторе

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

Выполним следующие действия по шагам:

  1. Откроем базу-приемник (в нашем случае ERP) в режиме Конфигуратор.
  2. В главном меню перейдем в раздел Конфигурация — Проверка конфигурации....
  3. В открывшемся окне настройки проверки снимем все лишние флаги и оставим только три ключевых параметра:
    • Синтаксический контроль;
    • Сервер;
    • Внешнее соединение.
  4. Нажмем кнопку ОК и дождемся завершения анализа кода платформой.

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

---

Шаг 2: Способы исправления ошибки

В зависимости от того, имеем ли мы возможность изменять конфигурацию ERP напрямую (находится ли она на поддержке с возможностью редактирования) или конфигурация закрыта для изменений, мы можем применить один из трех подходов.

Вариант А. Использование директив препроцессора (если конфигурация доступна для редактирования)

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

Для этого обернем вызов проблемной функции в директиву препроцессора:


#Если Не ВнешнееСоединение Тогда
    // Данный код будет компилироваться и выполняться на клиенте и сервере,
    // но полностью проигнорируется при подключении через COM-соединение
    ПолучитьСтруктуруОплаты(ПараметрыДокумента);
#КонецЕсли

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

Вариант Б. Перенос логики в серверный модуль

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

В этом случае логику функции необходимо перенести из клиентского модуля в серверный общий модуль, у которого в свойствах взведены флаги «Сервер» и «Внешнее соединение». После этого вызов функции в модуле УСОERP_МодификацияКонфигурации переадресуется на новый серверный модуль.

Вариант В. Исправление через Расширение конфигурации (если ERP на замке)

Если типовая конфигурация ERP находится на строгой поддержке и напрямую вносить изменения в нее нельзя, мы можем использовать механизм расширений. Это современный и безопасный способ модификации логики без снятия конфигурации с поддержки.

Выполним исправление по шагам:

  1. Создадим новое расширение конфигурации (или откроем существующее). Убедимся, что назначение расширения установлено в значение «Адаптация» или «Дополнение».
  2. Добавим в расширение общий модуль УСОERP_МодификацияКонфигурации.
  3. Найдем метод, внутри которого происходит вызов недоступной функции ПолучитьСтруктуруОплаты(). Предположим, этот метод называется ПередЗаписьюДокумента.
  4. В модуле расширения переопределим этот метод с помощью аннотации &Вместо:

&Вместо("ПередЗаписьюДокумента")
Процедура Расш_ПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения)
    
    // Если обмен идет через COM-соединение, мы обходим вызов проблемных клиентских методов
    #Если ВнешнееСоединение Тогда
        // Здесь мы пишем альтернативную логику для COM, которая заменяет вызов ПолучитьСтруктуруОплаты
        // или просто игнорируем этот вызов, если он не критичен
    #Иначе
        // В обычном режиме вызываем стандартный метод конфигурации
        ПродолжитьВызов(Источник, Отказ, РежимЗаписи, РежимПроведения);
    #КонецЕсли
    
КонецПроцедуры

Важное примечание: Обязательно проверьте свойства самого расширения в дереве объектов. У него также должны быть правильно настроены свойства поддержки контекстов (клиент/сервер/внешнее соединение).

---

Глобальное решение: почему в современных реалиях стоит отказаться от COM-соединений

Рассмотренная нами ошибка — это лишь следствие более глубокой архитектурной проблемы. Использование технологии V83.COMConnector для интеграции крупных ERP-систем в современных реалиях накладывает на проект высокие риски и технические ограничения.

Рассмотрим подробнее ключевые недостатки COM-соединений:

  1. Нестабильность при обновлениях конфигурации. Разработчики типовых решений фирмы «1С» регулярно оптимизируют и рефакторят код общих модулей. Они ориентируются прежде всего на работу тонких клиентов и веб-клиентов. Проверить работоспособность всех модулей в контексте внешнего соединения при каждом обновлении физически сложно, поэтому подобные ошибки будут возникать регулярно после каждого минорного обновления ERP.
  2. Зависимость от операционной системы и разрядности. COM-объекты жестко привязаны к операционной системе Windows. Если ваша организация примет решение перевести сервер «1С:Предприятие» на операционную систему Linux, механизмы интеграции на основе COM полностью перестанут работать. Кроме того, на 64-разрядных серверах администрирование и регистрация 32-битных библиотек comcntr.dll через службы компонентов COM+ часто превращаются в сложную техническую проблему.
  3. Высокое потребление ресурсов. При каждом COM-подключении на сервере базы-приемника инициализируется полноценный сеанс работы пользователя, что требует выделения значительного объема оперативной памяти и процессорного времени.

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

Использование современных интеграционных механизмов сделает ваши системы независимыми от обновлений кода друг друга и гарантирует бесперебойную работу бизнес-процессов.

← На главную