При настройке обмена данными между 1С:Предприятие (в частности, в конфигурации УПП) и внешними системами, такими как Битрикс, разработчики часто сталкиваются с необходимостью выгрузки пользовательских справочников. В процессе написания или адаптации кода может возникнуть критическая ошибка: «Таблица не найдена Справочник.МойСправочник.Изменения». Давайте разберем по шагам, почему это происходит и как правильно настроить метаданные, чтобы обмен заработал корректно.
Для начала проанализируем ситуацию. Ошибка возникает в момент выполнения запроса к базе данных. Рассмотрим типичный пример кода, который вызывает это исключение:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПользовательскийСправочник.Ссылка КАК Объект
|ИЗ
| Справочник." + ТекСпр.Справочник + " КАК ПользовательскийСправочник
|ГДЕ
| ВЫБОР
| КОГДА &ПолнаяВыгрузка
| ТОГДА ИСТИНА
| ИНАЧЕ ПользовательскийСправочник.Ссылка В
| (ВЫБРАТЬ
| ПользовательскийСправочникИзменений.Ссылка
| ИЗ
| Справочник." + ТекСпр.Справочник + ".Изменения КАК ПользовательскийСправочникИзменений
| ГДЕ
| ПользовательскийСправочникИзменений.Узел = &Узел)
| КОНЕЦ";
Запрос.УстановитьПараметр("Узел", ПараметрыОбмена.Ссылка);
Запрос.УстановитьПараметр("ПолнаяВыгрузка", (НЕ ПараметрыОбмена.ВыгружатьТолькоИзменения ИЛИ ПараметрыОбмена.ВыполнятьПолнуюВыгрузкуПринудительно));
Проанализируем этот запрос. Проблема кроется в обращении к таблице Справочник.ИмяСправочника.Изменения. В системе 1С такая таблица не является обычной табличной частью объекта. Это виртуальная таблица регистрации изменений.
Выясним причину: платформа 1С создает физические таблицы регистрации изменений в базе данных SQL (обычно они имеют префикс _ChngR) только в том случае, если объект метаданных (справочник, документ и т.д.) включен в Состав хотя бы одного Плана обмена. Если вы создали новый справочник МойСправочник, но не добавили его в план обмена, используемый для интеграции с Битрикс, система просто «не знает» о существовании таблицы изменений для этого объекта. Отсюда и возникает сообщение «Таблица не найдена».
Рассмотрим подробнее, как работает этот механизм. Когда мы включаем объект в план обмена, платформа начинает отслеживать все изменения его элементов (создание, модификация, пометка на удаление). Для этого используются следующие механизмы:
Записать().НаименованиеМетаданных.Изменения в языке запросов для получения списка «грязных» (измененных) данных.Важный момент: даже если в вашем запросе стоит условие ВЫБОР, которое при полной выгрузке теоретически не должно обращаться к ветке ИНАЧЕ, компилятор запросов 1С все равно проверяет наличие всех таблиц, указанных в тексте запроса, перед его выполнением. Поэтому ошибка возникает в любом режиме выгрузки.
Чтобы исправить ошибку, нам необходимо выполнить настройку метаданных. Разберем этот процесс по шагам:
Общие -> Планы обмена. Вам нужно найти тот план, который отвечает за интеграцию с Битрикс (часто он называется Битрикс, ИнтеграцияСБайтом или ОбменССайтом).МойСправочник и установите напротив него флажок.ПланыОбмена.ЗарегистрироватьИзменения(). Для стандартного обмена с Битрикс обычно устанавливают «Разрешить»..Изменения для вашего справочника.Рассмотрим ситуацию, когда мы пишем универсальный код выгрузки. Чтобы избежать подобных ошибок в будущем, рекомендуется проверять, входит ли объект в состав плана обмена, прежде чем формировать текст запроса. Посмотрим на пример такой проверки:
МетаданныеОбъекта = Метаданные.Справочники[ТекСпр.Справочник];
ПланОбменаМетаданные = Метаданные.ПланыОбмена.Битрикс; // Укажите имя вашего плана
Если ПланОбменаМетаданные.Состав.Содержит(МетаданныеОбъекта) Тогда
// Формируем запрос с использованием таблицы .Изменения
Иначе
// Либо выдаем ошибку, либо формируем запрос только для полной выгрузки без участия таблицы изменений
КонецЕсли;
Проанализируем также структуру самого запроса. В сообщении форума было замечено, что использование ВЫБОР КОГДА &ПолнаяВыгрузка внутри запроса для фильтрации по изменениям — не самый оптимальный путь. Разберем, как можно оптимизировать этот код, чтобы он был более надежным:
ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПользовательскийСправочник.Ссылка КАК Объект ИЗ Справочник." + ТекСпр.Справочник + " КАК ПользовательскийСправочник";
Если НЕ (НЕ ПараметрыОбмена.ВыгружатьТолькоИзменения ИЛИ ПараметрыОбмена.ВыполнятьПолнуюВыгрузкуПринудительно) Тогда
ТекстЗапроса = ТекстЗапроса + "
|ГДЕ ПользовательскийСправочник.Ссылка В
| (ВЫБРАТЬ Изменения.Ссылка ИЗ Справочник." + ТекСпр.Справочник + ".Изменения КАК Изменения ГДЕ Изменения.Узел = &Узел)";
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Такой подход позволяет избежать обращения к виртуальной таблице изменений, если выполняется полная выгрузка, что не только страхует от ошибок, но и повышает производительность системы.
Выясним еще несколько моментов, которые могут влиять на работу обмена:
Права доступа: Даже если справочник включен в состав плана обмена, пользователь, под которым запускается фоновое задание обмена, должен иметь права на «Чтение» и «Просмотр» этого плана обмена. В противном случае платформа также может сообщить о недоступности таблицы.
Имена метаданных: Убедитесь, что в переменной ТекСпр.Справочник действительно хранится Имя (Name) объекта из конфигуратора, а не его Синоним (Synonym). Запросы к виртуальным таблицам крайне чувствительны к точности метаданных.
Регистрация существующих данных: Помните, что включение справочника в состав плана обмена «сегодня» не регистрирует в нем те элементы, которые были созданы «вчера». После настройки состава плана обмена для первой выгрузки всех существующих данных вам может потребоваться выполнить полную выгрузку или программно зарегистрировать все элементы справочника на узле обмена с помощью функции ПланыОбмена.ЗарегистрироватьИзменения().
Таким образом, мы выяснили, что ошибка «Таблица не найдена ... .Изменения» является следствием отсутствия регистрации объекта в механизме обмена данными. Правильная настройка состава Плана обмена и корректная проверка метаданных в коде полностью решают эту проблему.