Как настроить ПКО для перечислений в Конвертации данных 2.1, если значение есть в источнике, но отсутствует в приемнике?

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

При настройке обмена данными между конфигурациями на платформе 1С (особенно в связке 1С 8.3 — 1С 7.7) разработчики часто сталкиваются с ситуацией, когда в базе-источнике состав перечисления шире, чем в базе-приемнике. При попытке выгрузить объект, содержащий "лишнее" значение, система выдает ошибку: «Не найдено соответствие для значения Источника». Это происходит потому, что правила конвертации объектов (ПКО) для перечислений ожидают четкого сопоставления каждого элемента.

В этой статье мы подробно разберем, как правильно обрабатывать такие ситуации, почему стандартный код в обработчиках не всегда срабатывает и какие механизмы «Конвертации данных 2.1» (КД) лучше всего использовать для передачи пустого значения в приемник.

Разбор причины ошибки: почему ПКО выдает исключение?

Рассмотрим ситуацию: в 1С 8.3 у нас есть перечисление ТипыДоговоров со значением ДоговорПереводДолга. В старой базе 7.7 такого типа нет. Разработчик пытается программно "обнулить" значение в обработчике ПередВыгрузкой ПКО:


Если Источник.ВидДоговора = Перечисления.ТипыДоговоров.ДоговорПереводДолга тогда
    Приемник.ВидДоговора = "";
КонецЕсли;

Проанализируем этот код. Ошибка возникает из-за того, что механизм КД при конвертации перечислений работает по жесткой таблице соответствий (ПКЗ — Правила Конвертации Значений). Если система видит, что для конкретного значения источника не определено правило в таблице, она прерывает выполнение, даже если вы попытались переопределить Приемник. Кроме того, в контексте ПКО перечисления обращение к Приемнику как к объекту со свойствами часто некорректно, так как перечисление — это не ссылочный объект с полями, а просто значение.

Решение 1: Сопоставление значений в ПКО (ПКЗ)

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

Разберем по шагам:

  1. Откроем ПКО соответствующего перечисления.
  2. Перейдем на закладку «Настройки соответствия значений» (или «Конвертация значений»).
  3. Нажмем кнопку «Добавить».
  4. В колонке «Источник» выберем наше проблемное значение (например, ДоговорПереводДолга).
  5. В колонке «Приемник» оставим пустое значение или выберем «0» (если мы выгружаем в 7.7, где перечисления часто идентифицируются строками или индексами).

Важный момент: Если мы хотим, чтобы для всех ненайденных значений система не выдавала ошибку, а подставляла пустое значение, в настройках ПКО перечисления можно установить флаг «Выгружать пустое значение, если не найдено соответствие». Это глобально решит проблему для данного типа данных.

Решение 2: Обработка в ПКС родительского объекта

Иногда логика требует более гибкого подхода. В этом случае мы можем перенести решение задачи из ПКО перечисления в ПКС (Правила Конвертации Свойств) объекта, который это перечисление использует (например, ПКО ДоговорыКонтрагентов).

Посмотрим на пример кода в обработчике ПередВыгрузкой свойства ВидДоговора:


Если Источник.ВидДоговора = Перечисления.ТипыДоговоров.ДоговорПереводДолга Тогда
    Значение = ""; // Передаем пустое значение в приемник
Иначе
    // Для остальных значений сработает стандартное правило конвертации
КонецЕсли;

Выясним, в чем преимущество этого метода. Используя переменную Значение, мы перехватываем процесс до того, как система обратится к ПКО перечисления. Если мы установили Значение = "", система поймет, что в базу-приемник нужно записать пустое перечисление, и ошибка сопоставления вообще не возникнет.

Решение 3: Использование «Неопределено» и «Отказ»

Проанализируем альтернативные варианты, которые предлагались в сообществе.

Вариант с Неопределено:

В некоторых случаях (особенно при обмене 8.x -> 8.x) лучше использовать Значение = Неопределено;. Это гарантирует, что в приемник попадет именно пустая ссылка соответствующего типа.

Вариант с Отказ = 1:

Если в ПКС прописать Отказ = 1;, то данное свойство просто не будет выгружено. Однако здесь есть "подводный камень": если в базе-приемнике в этом поле уже было заполнено какое-то значение, оно не очистится. Поле просто будет проигнорировано при загрузке. Если ваша цель — именно очистить поле в приемнике, используйте Значение = "";.

Особенности выгрузки в 1С 7.7

При обмене с платформой 7.7 нужно учитывать специфику работы обработки V77Exp.ert. В 7.7 перечисления не имеют уникальных идентификаторов (GUID), они работают по строковым идентификаторам или порядковым номерам. Поэтому, когда мы пишем Значение = "", загрузчик в 7.7 интерпретирует это как отсутствие значения (пустое перечисление).

Если вы столкнулись с тем, что код в обработчиках написан верно, но ошибка «Не найдено соответствие» сохраняется, проверьте следующие моменты:

  1. Кэширование правил: При тестировании обмена в 7.7 обязательно убедитесь, что вы загрузили обновленный файл правил в обработку выгрузки.
  2. Синхронизация по полям поиска: Если для перечисления настроены поля поиска, убедитесь, что пустое значение не конфликтует с ними.
  3. Входящие данные: В сложных случаях можно использовать структуру ВходящиеДанные, чтобы передать признак пустого значения напрямую в ПКО приемника, минуя стандартный поиск соответствий.

Итоги и рекомендации

Мы рассмотрели три основных подхода к решению проблемы отсутствующих значений перечислений. Подведем итог:

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

← На главную