При разработке правил обмена в конфигурации «1С:Конвертация данных 2.1» (КД2) программисты часто сталкиваются с необходимостью модификации номеров документов. Одним из частых требований является добавление определенного символа или префикса к номеру документа (например, добавление символа "О" для разделения потоков данных из разных баз). Для этого в стандартных правилах часто используется функция ДобавитьКПрефиксу. Однако при попытке вызвать её в обработчиках событий (например, в ПКС «Перед выгрузкой» свойства «Номер») система может выдать ошибку компиляции:
Ошибка компиляции при вычислении выражения или выполнении фрагмента кода: {(1,12)}: Процедура или функция с указанным именем не определена (ДобавитьКПрефиксу)
В этой статье мы подробно разберем причины возникновения данной ошибки, проанализируем контекст выполнения кода в КД2 и рассмотрим несколько надежных способов решения этой проблемы.
Выясним причину такого поведения платформы. Функция ДобавитьКПрефиксу не входит в число глобальных функций платформы «1С:Предприятие». Она является экспортным методом модуля внешней обработки «Универсальный обмен данными XML» (V8Exim.epf).
Когда правила обмена выполняются в обычном режиме непосредственно через эту обработку, весь код обработчиков выполняется динамически с помощью платформенного метода Выполнить(). В этом случае контекст модуля обработки доступен, и вызов функции отрабатывает корректно. Ошибка компиляции «Процедура или функция не определена» происходит в следующих случаях:
УниверсальныйОбменДаннымиXML.Ниже мы подробно рассмотрим четыре практических способа решения этой проблемы.
Чтобы код правил обмена не зависел от контекста выполнения, режима отладки и версии обработки обмена, самым правильным решением будет вынесение функции в **Алгоритмы** внутри самой базы «Конвертации данных».
Рассмотрим по шагам, как это сделать:
ДобавитьКПрефиксу.
// ПараметрыАлгоритма: Стр, Добавок, Длина, Режим
Стр = СокрЛП(Формат(ПараметрыАлгоритма.Стр, "ЧГ=0"));
Длина = ПараметрыАлгоритма.Длина;
Добавок = ПараметрыАлгоритма.Добавок;
Режим = ПараметрыАлгоритма.Режим;
Если ПустаяСтрока(Длина) Тогда
Длина = СтрДлина(Стр);
КонецЕсли;
ЧисловаяЧасть = "";
Префикс = "";
// Разделяем номер на префиксную и числовую части
Для Инд = 1 По СтрДлина(Стр) Цикл
Символ = Сред(Стр, Инд, 1);
Если Найти("0123456789", Символ) > 0 Тогда
ЧисловаяЧасть = Сред(Стр, Инд);
Префикс = Лев(Стр, Инд - 1);
Прервать;
КонецЕсли;
КонецЦикла;
Если Режим = "Слева" Тогда
НовыйПрефикс = СокрЛП(Добавок) + Префикс;
Иначе
НовыйПрефикс = Префикс + СокрЛП(Добавок);
КонецЕсли;
Результат = НовыйПрефикс + ЧисловаяЧасть;
// Дополняем нулями до исходной или заданной длины, если это необходимо
Если СтрДлина(Результат) < Длина Тогда
НужноеКоличествоНулей = Длина - СтрДлина(НовыйПрефикс) - СтрДлина(ЧисловаяЧасть);
СтрокаНулей = "";
Для Шаг = 1 По НужноеКоличествоНулей Цикл
СтрокаНулей = СтрокаНулей + "0";
КонецЦикла;
Результат = НовыйПрефикс + СтрокаНулей + ЧисловаяЧасть;
КонецЕсли;
Возврат Лев(Результат, Длина);
Теперь в ПКС «Перед выгрузкой» свойства Номер мы можем безопасно вызывать наш алгоритм с передачей параметров через структуру:
ПараметрыАлгоритма = Новый Структура;
ПараметрыАлгоритма.Вставить("Стр", Источник.Номер);
ПараметрыАлгоритма.Вставить("Добавок", "О");
ПараметрыАлгоритма.Вставить("Длина", 11);
ПараметрыАлгоритма.Вставить("Режим", "Справа");
Значение = ВыполнитьАлгоритм("ДобавитьКПрефиксу", ПараметрыАлгоритма);
Этот способ полностью решает проблему компиляции в любых режимах отладки.
Если вам требуется выполнить простое добавление символа без использования сложных алгоритмов выравнивания длины номера, мы можем написать преобразование строки напрямую стандартными функциями платформы «1С:Предприятие».
Проанализируем пример, когда нам нужно добавить символ "О" после первых двух символов префикса организации для сохранения структуры кода:
ИсходныйНомер = СокрЛП(Источник.Номер);
// Извлекаем префикс (например, первые 2 или 3 символа)
ПрефиксОрганизации = Лев(ИсходныйНомер, 2);
ОставшаясяЧасть = Сред(ИсходныйНомер, 3);
// Формируем новый номер с добавлением символа "О" справа от префикса
НовыйНомер = ПрефиксОрганизации + "О" + ОставшаясяЧасть;
// При необходимости контролируем длину номера (например, для БП 3.0 стандартная длина 11 символов)
Если СтрДлина(НовыйНомер) > 11 Тогда
// Если длина превышена, можно попробовать убрать лишний лидирующий ноль в номере
НовыйНомер = СтрЗаменить(НовыйНомер, "О0", "О");
КонецЕсли;
Значение = НовыйНомер;
Преимущество этого метода в абсолютной автономности. Код выполнится быстро и без ошибок на любой конфигурации-источнике (будь то старая УПП 1.3 / КА 1.1 или современная ERP).
Если вы хотите использовать именно функцию обработки УниверсальныйОбменДаннымиXML, убедитесь, что вы передаете верное количество параметров. В оригинальном коде обработки функция определена следующим образом:
Функция ДобавитьКПрефиксу(Знач Стр, Добавок = "", Длина = "", Режим = "Слева") Экспорт
Обратите внимание, что функция принимает 4 параметра. Посмотрим на ошибочный вызов автора темы:
Значение = ДобавитьКПрефиксу(Источник.Номер,"О","Справа");
Здесь пропущен параметр Длина, из-за чего строка "Справа" попадает в параметр длины, а режим сдвига остается по умолчанию "Слева". Корректный вызов должен выглядеть так:
// Передаем пустую строку в качестве длины, чтобы функция вычислила ее автоматически по длине источника
Значение = ДобавитьКПрефиксу(Источник.Номер, "О", "", "Справа");
Важно: этот способ сработает только в том случае, если выгрузка производится в интерактивном режиме через саму обработку УниверсальныйОбменДаннымиXML.epf с выключенным режимом отладки обработчиков.
Если модификация номера на стороне источника вызывает трудности, мы можем выполнить данное действие при загрузке данных в базу-приемник. В современных конфигурациях (например, «Бухгалтерия предприятия 3.0»), созданных на базе БСП (Библиотеки стандартных подсистем), есть готовые общие модули для работы со строками кода.
В ПКО нужного документа в обработчике событий «После загрузки» мы можем использовать функции БСП общего модуля РаботаСоСтроками:
// Изменение номера объекта непосредственно при загрузке в базу-приемник
ИмяОбщегоМодуля = "РаботаСоСтроками";
Если ОбщегоНазначения.ЕстьОбщийМодуль(ИмяОбщегоМодуля) Тогда
Объект.Номер = РаботаСоСтроками.ДобавитьКПрефиксу(Объект.Номер, "О", "Справа");
КонецЕсли;
Этот вариант удобен тем, что код выполняется на стороне приемника, где гарантированно присутствуют актуальные функции БСП для работы с префиксами документов.
Мы проанализировали ошибку компиляции метода ДобавитьКПрефиксу в Конвертации данных 2.1. Наиболее стабильным и архитектурно правильным решением является создание собственного Алгоритма КД (Способ 1) или использование прямого строкового преобразования (Способ 2). Это гарантирует бесперебойную работу обмена как в режиме отладки правил, так и при автоматическом выполнении задач по расписанию через планы обмена.