Как получить имя общего модуля по ссылке в 1С

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

В процессе разработки и сопровождения сложных конфигураций на платформе 1С:Предприятие 8 программисты часто сталкиваются с механизмами динамического вызова процедур и функций. Особенно это актуально для конфигураций, использующих БСП (Библиотеку стандартных подсистем), где обработчики событий регистрируются в массивах или структурах. Одной из специфических проблем является идентификация конкретного общего модуля, когда в распоряжении разработчика есть только ссылка на него, а платформа выдает ошибку "Метод объекта не обнаружен".

Рассмотрим ситуацию: в цикле перебирается массив структур, где одно из полей содержит ссылку на общий модуль, полученную через Вычислить(ИмяОбщегоМодуля). Если один из модулей в этом списке не содержит вызываемого метода, система генерирует исключение, но в окне отладки мы видим лишь тип ОбщийМодуль, без указания его конкретного имени в дереве метаданных. Разберем по шагам, как решить эту задачу и найти "виновника" ошибки.

Способ 1: Программный поиск через коллекцию метаданных

Поскольку у объекта типа ОбщийМодуль нет встроенного метода Метаданные() или свойства Имя, нам необходимо выполнить обратный поиск. Мы будем перебирать все доступные в конфигурации общие модули и сравнивать их ссылки с той, что находится у нас в переменной. Проанализируем программный код, который позволяет это сделать:


Функция ПолучитьИмяОбщегоМодуля(СсылкаНаМодуль)
    Для Каждого ОбъектМетаданных Из Метаданные.ОбщиеМодули Цикл
        Попытка
            // Сравниваем объект общего модуля с результатом выполнения его имени
            Если Вычислить(ОбъектМетаданных.Имя) = СсылкаНаМодуль Тогда
                Возврат ОбъектМетаданных.Имя;
            КонецЕсли;
        Исключение 
            // Исключение может возникнуть, если модуль недоступен в текущем контексте (Клиент/Сервер)
            Продолжить;
        КонецПопытки;
    КонецЦикла;
    
    Возврат "Имя не найдено";
КонецФункции

Разберем подробнее, как работает этот механизм. Функция Вычислить() (или Eval) принимает строку с именем модуля и возвращает ссылку на сам объект модуля. Платформа 1С позволяет сравнивать такие ссылки между собой. Используя конструкцию Для Каждого по коллекции Метаданные.ОбщиеМодули, мы последовательно проверяем каждый модуль системы. Важным моментом является использование блока Попытка...Исключение, так как не все модули могут быть скомпилированы в текущем контексте выполнения (например, серверный модуль без флага "Вызов сервера" при вызове с клиента).

Способ 2: Использование отладчика и табло

Если проблема возникла здесь и сейчас в режиме отладки, и вы не хотите вносить изменения в код конфигурации, можно воспользоваться инструментами платформы. Посмотрим, какие манипуляции в Табло или Вычислении выражения (Shift+F9) могут помочь:

  1. Попробуйте вычислить выражение ТипЗнч(Модуль). Хотя чаще всего оно вернет просто ОбщийМодуль, в некоторых релизах платформы в строковом представлении типа при детальном просмотре свойств объекта может отображаться внутренняя информация.
  2. Если вы работаете с типовой конфигурацией на базе БСП, обратите внимание на структуру Обработчик. В стандартных механизмах регистрации событий (например, при заполнении параметров работы клиента) в структуру рядом с полем Модуль часто добавляется строковое поле ИмяМодуля. Проверьте все свойства структуры в окне "Локальные переменные".

Способ 3: Глобальный поиск по конфигурации

Когда мы знаем имя метода, который вызывает ошибку (например, ПриДобавленииПараметровРаботыКлиентскойЛогикиСтандартныхПодсистемПриЗапуске), самым быстрым способом найти все потенциальные модули будет глобальный поиск. Проанализируем ситуацию через поиск:

  1. Нажмите Ctrl+Shift+F в конфигураторе.
  2. Введите имя процедуры, на которой происходит сбой.
  3. Выберите область поиска "Во всей конфигурации".

Этот метод позволит увидеть список всех модулей, где данная процедура реализована. Однако наша проблема в том, что в каком-то модуле она отсутствует. Сверьте полученный список со списком модулей, которые регистрируются в процедуре ПриДобавленииОбработчиковСобытий (обычно она находится в определяемых модулях или модулях подсистем БСП). Тот модуль, который есть в списке регистрации, но отсутствует в результатах глобального поиска, и является причиной ошибки.

Способ 4: Оптимизация через соответствие (для промышленного кода)

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


// Пример создания кэша модулей
КэшМодулей = Новый Соответствие;
Для Каждого М Из Метаданные.ОбщиеМодули Цикл
    Попытка
        КэшМодулей.Вставить(Вычислить(М.Имя), М.Имя);
    Исключение
    КонецПопытки;
КонецЦикла;

// Теперь получение имени происходит мгновенно
Имя = КэшМодулей.Получить(СсылкаНаМодуль);

Такой подход позволяет избежать многократного прохода по метаданным, что положительно сказывается на производительности системы.

Важные нюансы и причины возникновения ошибок

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

Для предотвращения подобных ошибок в будущем рекомендуется использовать метод БСП ОбщегоНазначения.ЕстьПроцедураИлиФункцияКонфигурации(ПутьКМетоду). Это позволит перед вызовом убедиться, что метод существует и доступен, избегая аварийного завершения работы программы.

← На главную