При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда необходимо вызвать программный код, уже написанный в типовой конфигурации. Однако разработчики типовых решений часто скрывают внутреннюю логику, не помечая процедуры и функции ключевым словом Экспорт. В этой статье мы разберем, как законно и безопасно «дотянуться» до таких методов из расширения или внешней обработки, проанализируем различные подходы и выберем наиболее стабильный.
В платформе 1С процедуры модуля объекта без ключевого слова Экспорт являются локальными. Это означает, что они доступны только внутри самого модуля. Когда мы создаем объект программно в обработке, например, через Документы.ЗаказКлиента.СоздатьДокумент(), полученный объект предоставляет доступ только к своему экспортному интерфейсу. Попытка вызвать локальный метод ИнициализироватьДокумент() напрямую приведет к ошибке «Метод объекта не обнаружен». Разберем, как преодолеть это ограничение с помощью расширений.
Это самый эффективный и рекомендуемый способ. Суть заключается в том, что расширение модуля объекта и основной модуль в оперативной памяти «сливаются». Это дает коду расширения доступ к локальным методам основного модуля. Проанализируем этот процесс по шагам.
1. Сначала добавим документ (например, ЗаказКлиента) в наше расширение. В дереве конфигурации расширения нажмем правую кнопку мыши на документе и выберем «Добавить в расширение».
2. Перейдем в модуль объекта этого документа внутри расширения и создадим там новую экспортную процедуру. Важно: всегда используйте уникальный префикс для своих методов (например, Расш1_), чтобы избежать конфликтов при обновлениях.
// В модуле объекта расширения
Процедура Расш1_ВыполнитьИнициализацию(ДанныеЗаполнения) Экспорт
// Мы находимся в контексте объекта, поэтому локальный метод нам доступен
ИнициализироватьДокумент(ДанныеЗаполнения);
КонецПроцедуры
3. Теперь в нашей обработке, где создается документ, мы будем вызывать не скрытую процедуру 1С, а нашу новую экспортную процедуру-обертку:
НовыйДокумент = Документы.ЗаказКлиента.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
// Вызываем наш "мостик"
НовыйДокумент.Расш1_ВыполнитьИнициализацию(ПараметрыЗаполнения);
НовыйДокумент.Записать();
Этот метод хорош тем, что он не меняет логику типовой конфигурации, а лишь расширяет интерфейс объекта для внешних вызовов.
Прежде чем писать свой код, проанализируем, как сама система 1С вызывает процедуру ИнициализироватьДокумент. В типовых конфигурациях (УТ 11, ERP, КА) эта процедура обычно вызывается внутри стандартного события ОбработкаЗаполнения. Рассмотрим возможность использования штатного механизма:
ДокументОбъект = Документы.ЗаказКлиента.СоздатьДокумент();
// Стандартный метод, который инициирует событие ОбработкаЗаполнения
ДокументОбъект.Заполнить(ДанныеЗаполнения);
Почему это может не сработать? В некоторых конфигурациях внутри ОбработкаЗаполнения стоит жесткая проверка на тип передаваемых данных. Если вы передаете в ДанныеЗаполнения структуру, а код ожидает ссылку на другой документ, заполнение может не выполниться. В этом случае придется вернуться к первому решению или использовать расширение самого события ОбработкаЗаполнения через аннотацию &Перед.
Иногда нам нужно не просто вызвать процедуру, а вклиниться в ее работу. Для этого используется механизм переопределения. Рассмотрим пример:
&Вместо("ИнициализироватьДокумент")
Процедура Расш1_ИнициализироватьДокумент(ДанныеЗаполнения)
// Здесь можно выполнить код ДО основной логики
ПродолжитьВызов(ДанныеЗаполнения);
// Здесь можно выполнить код ПОСЛЕ основной логики
КонецПроцедуры
Однако стоит помнить: само по себе использование аннотации &Вместо не делает процедуру экспортной. Она по-прежнему будет вызываться только тогда, когда ее вызывает сама конфигурация. Поэтому для вызова из внешней обработки метод из Решения №1 остается приоритетным.
При работе с расширениями и неэкспортными методами следует придерживаться следующих правил:
МояКомпания_....Проанализировав все варианты, мы видим, что наиболее стабильным и понятным является создание экспортного метода-обертки в расширении модуля объекта. Это сохраняет структуру кода и позволяет обращаться к любым закрытым процедурам типовой конфигурации с минимальными рисками. Для контроля целостности метаданных и автоматического выявления проблем в кодовой базе можно использовать инструмент для анализа конфигураций и расширений на наличие ошибок в вызовах процедур.