При переносе данных между конфигурациями «1С:Предприятие» с помощью конфигурации «1С:Конвертация данных 2.1» (КД 2) разработчики часто сталкиваются со специфическим поведением поиска объектов. Типичная ситуация: мы настраиваем синхронизацию справочника Контрагенты по уникальному идентификатору налогоплательщика (ИНН). Все элементы (клиенты и поставщики) переносятся отлично, но папки (группы) справочника начинают дублироваться при каждой последующей выгрузке-загрузке. Почему так происходит? Дело в том, что у папок в 1С нет реквизита ИНН (он пустой), и стандартный алгоритм поиска просто не может сопоставить их, создавая каждый раз новые группы.
В этой статье мы подробно разберем, как решить эту проблему, правильно настроить обработчик «Поля поиска» в ПКО (Правилах конвертации объектов), а также выясним нюансы работы с базой-источником на платформе «1С:Предприятие 7.7» (на примере конфигурации «Торговля и Склад 9.2»), где ИНН хранится не в самом справочнике контрагентов.
Прежде чем писать код, давайте проанализируем ситуацию. Когда мы указываем в правилах конвертации свойств (ПКС) для реквизита ИНН признак «Поиск», система при загрузке данных в базу-приемник пытается найти существующий объект по этому полю. Для элементов (юридических лиц) это работает отлично.
Однако для групп справочника (папок) реквизит ИНН не заполнен. База-приемник получает пустую строку в качестве ИНН и пытается найти группу с пустым ИНН. Если алгоритм настроен неверно, система либо сопоставит все папки с одной-единственной (где тоже пустой ИНН), либо вообще не найдет совпадений и создаст дубликат папки. Чтобы этого избежать, нам нужно разделить логику поиска: папки мы должны искать по их иерархии и названию (Наименование + Родитель), а элементы — по их уникальным реквизитам (ИНН + КПП).
Основным инструментом для решения нашей задачи является обработчик событий «Поля поиска», который находится внутри ПКО (Правила конвертации объектов) для справочника Контрагенты. Этот обработчик выполняется на стороне базы-приемника (1С 8) в момент загрузки данных.
Рассмотрим подробнее логику, которую нам необходимо реализовать. Мы должны проверить, является ли загружаемый объект группой. В платформе 1С 8 для этого используется булево свойство ЭтоГруппа. Если это группа, мы переопределяем состав полей поиска, исключая ИНН и добавляя наименование и родителя. Если это элемент — ищем по ИНН.
Давайте разберем по шагам код, который нужно вставить в обработчик «Поля поиска» ПКО Контрагенты:
// Проверяем, является ли текущий объект группой (папкой)
Если СвойстваПоиска.Получить("ЭтоГруппа") = Истина Тогда
// Для папок устанавливаем поиск по наименованию и родителю (с учетом иерархии)
СтрокаИменСвойствПоиска = "ЭтоГруппа, Родитель, Наименование";
Иначе
// Логика для элементов (контрагентов)
ИНН = СвойстваПоиска.Получить("ИНН");
Если ЗначениеЗаполнено(ИНН) Тогда
// Если ИНН заполнен, ищем по ИНН.
// Если переносится КПП, то для юрлиц лучше искать по связке ИНН + КПП
КПП = СвойстваПоиска.Получить("КПП");
Если ЗначениеЗаполнено(КПП) Тогда
СтрокаИменСвойствПоиска = "ЭтоГруппа, ИНН, КПП";
Иначе
СтрокаИменСвойствПоиска = "ЭтоГруппа, ИНН";
КонецЕсли;
Иначе
// Если ИНН не заполнен (например, физическое лицо или неопределенный контрагент),
// осуществляем поиск по наименованию и родителю во избежание дублирования
СтрокаИменСвойствПоиска = "ЭтоГруппа, Родитель, Наименование";
КонецЕсли;
КонецЕсли;
Важное примечание: Обратите внимание на синтаксис работы с коллекцией СвойстваПоиска. Рекомендуется использовать метод Получить("ИмяРеквизита") вместо прямого обращения через квадратные скобки (например, СвойстваПоиска["ЭтоГруппа"]). Метод Получить() вернет Неопределено, если реквизит отсутствует в выгруженных данных, и не вызовет критическую ошибку выполнения кода.
Теперь рассмотрим проблему, озвученную в сообщении 10. При переносе данных из конфигураций на платформе 1С 7.7 (в частности, ТиС 9.2) разработчики часто сталкиваются с тем, что в справочнике Контрагенты физически нет реквизита ИНН. В этой конфигурации данные о контрагенте разделены: общие сведения хранятся в Контрагенты, а официальные реквизиты — в подчиненных справочниках ЮрЛица или ФизЛица, ссылка на которые находится в реквизите ЮрФизЛицо.
Если мы попытаемся обратиться к ИНН напрямую в базе-источнике через Источник.ИНН, то получим ошибку. Нам нужно правильно извлечь ИНН на этапе выгрузки из 1С 7.7.
Выполним следующие действия по шагам:
Контрагенты.ИНН (Источник оставляем пустым, Приемник — ИНН).
// Код для 1С 7.7 в обработчике "Перед выгрузкой" ПКС ИНН
Если Источник.ЭтоГруппа() = 0 Тогда
// Проверяем, заполнено ли значение периодического или ссылочного реквизита ЮрФизЛицо
Если Источник.ЮрФизЛицо.Выбран() = 1 Тогда
// Получаем ИНН из подчиненного справочника (ЮрЛица или ФизЛица)
Значение = Источник.ЮрФизЛицо.ИНН;
КонецЕсли;
КонецЕсли;
Аналогичным образом мы можем настроить выгрузку КПП, если этот реквизит также необходим для точной идентификации контрагентов в базе-приемнике:
// Код для ПКС КПП в обработчике "Перед выгрузкой"
Если Источник.ЭтоГруппа() = 0 Тогда
Если Источник.ЮрФизЛицо.Выбран() = 1 Тогда
// Реквизит КПП есть только у ЮрЛиц, у ФизЛиц его нет
Если Источник.ЮрФизЛицо.Вид() = "ЮрЛица" Тогда
Значение = Источник.ЮрФизЛицо.КПП;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Рассмотрим еще одну частую проблему, упомянутую в обсуждении форума: при повторном переносе данных затираются ручные изменения в базе-приемнике. Например, пользователь пометил папку на удаление или изменил ее код вручную в 1С 8, но при следующей загрузке данных правила переноса восстанавливают старый код и снимают пометку удаления.
Это происходит потому, что по умолчанию механизм КД 2.1 при обнаружении сопоставленного объекта полностью обновляет (перезаписывает) все его реквизиты значениями из файла выгрузки. Чтобы изменить это поведение, мы можем воспользоваться встроенными флагами настройки ПКС.
Разберем, как защитить данные от перезаписи:
Код и ПКС для реквизита ПометкаУдаления. Установите флаг «Не замещать существующие значения в приемнике». Теперь, если объект уже существует в базе 1С 8, его код и статус пометки удаления не изменятся при повторном импорте, даже если в источнике они другие.Контрагенты и на вкладке «Основные» установите флаг «Не замещать существующие объекты в приемнике». В этом случае данные будут только дописываться, но не обновляться.Важный совет: Некоторые разработчики пытаются решить проблему сопоставления помеченных на удаление папок путем добавления свойства ПометкаУдаления в поля поиска (как предлагалось в Сообщении 8). Делать это крайне не рекомендуется. Если включить пометку удаления в список ключевых полей поиска, то при попытке перенести объект, который в источнике активен, а в приемнике помечен на удаление, система не сопоставит их. Поиск выдаст отрицательный результат, и в базе-приемнике создастся дубликат контрагента.
Мы успешно решили комплексную задачу синхронизации справочника контрагентов. Давайте зафиксируем основные правила хорошего тона при настройке переноса:
Поля поиска."ЭтоГруппа, Родитель, Наименование".Перед выгрузкой на стороне источника.Не замещать существующие значения в приемнике для сохранения ручных изменений, внесенных пользователями непосредственно в целевой базе данных.Применение этих простых правил позволит вам избежать появления дублей и обеспечит корректную иерархическую структуру справочника контрагентов при миграции данных любой сложности.