При интеграции двух информационных баз 1С с использованием механизма Внешние источники данных разработчики часто сталкиваются с задачей наложения условий на поля, содержащие перечисления. Попытка применить привычную синтаксическую конструкцию ЗНАЧЕНИЕ(Перечисление.ИмяПеречисления.ИмяЗначения) в запросе к таблице внешнего источника приводит к ошибке. Проанализируем, почему возникает эта проблема, как устроено физическое хранение перечислений в СУБД 1С и какими способами можно организовать корректную фильтрацию.
Выясним причину, по которой стандартная конструкция языка запросов оказывается неработоспособной:
ЗНАЧЕНИЕ(): Данная конструкция может обращаться только к метаданным текущей конфигурации. Платформа 1С не связывает таблицы внешнего источника данных с объектами метаданных удаленной базы, поэтому прямое обращение к перечислению другой конфигурации невозможно.config, к которой нельзя выполнить простой SQL-запрос JOIN.Разберем базовый вариант решения задачи. Поскольку во внешнем источнике данных поле перечисления представлено числовым значением или идентификатором (ID), мы можем передавать требуемое значение фильтра через параметры запроса.
Для определения числового соответствия или идентификатора конкретного значения в удаленной базе можно воспользоваться функцией ПолучитьСтруктуруХраненияБазыДанных() либо получить строковое представление идентификатора с помощью метода XMLСтрока().
Посмотрим на пример построения запроса с параметром:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВнешнийЗаказ.Ссылка КАК Идентификатор,
| ВнешнийЗаказ.Номер КАК Номер,
| ВнешнийЗаказ.СтатусЗаказа КАК СтатусЗаказа
|ИЗ
| ВнешнийИсточникДанных.УдаленнаяБаза.Таблица.Документ_ЗаказПокупателя КАК ВнешнийЗаказ
|ГДЕ
| ВнешнийЗаказ.СтатусЗаказа = &СтатусЗаказа";
// Передаем внутренний код или числовой индекс значения перечисления
Запрос.УстановитьПараметр("СтатусЗаказа", 2);
РезультатЗапроса = Запрос.Выполнить();
Этот способ является наиболее простым и не требует изменения структуры удаленной базы, однако требует предварительного сопоставления кодов и их фиксации в коде или настройках.
Рассмотрим вариант, когда необходимо получать данные с уже готовыми текстовыми наименованиями перечислений. В этом случае в целевой СУБД можно создать представление (SQL VIEW), трансформирующее внутренние коды в читаемые строки.
Разберем по шагам логику создания такого представления на стороне SQL Server:
CREATE VIEW v_OrdersWithStatus AS
SELECT
_IDRRef AS ID,
_Number AS OrderNumber,
CASE _Fld1234
WHEN 0x00 THEN 'Черновик'
WHEN 0x01 THEN 'КОтгрузке'
WHEN 0x02 THEN 'Закрыт'
ELSE 'Неизвестно'
END AS StatusName
FROM _Document100;
После создания представления во внешнем источнике данных 1С подключается именно эта виртуальная таблица. В запросах 1С можно будет использовать строковый фильтр ГДЕ ВнешняяТаблица.StatusName = "КОтгрузке".
Если в текущей конфигурации создано аналогичное по составу перечисление, можно реализовать программную карту соответствия (через объект Соответствие или регистр сведений). Проанализируем пример функции сопоставления:
Функция ПолучитьКодПеречисленияВнешнейБазы(ЗначениеПеречисления)
КартаСоответствий = Новый Соответствие;
КартаСоответствий.Вставить(Перечисления.СтатусыЗаказов.Черновик, 0);
КартаСоответствий.Вставить(Перечисления.СтатусыЗаказов.КОтгрузке, 1);
КартаСоответствий.Вставить(Перечисления.СтатусыЗаказов.Закрыт, 2);
Возврат КартаСоответствий[ЗначениеПеречисления];
КонецФункции
Такой подход делает код более читаемым и защищенным от случайных ошибок при смене числовых констант в запросах.
Прямое чтение таблиц СУБД через внешние источники данных не учитывает бизнес-логику 1С и правила контроля прав доступа (RLS). Если чтение внутренних ID перечислений вызывает сложности, рекомендуется рассмотреть стандартные интерфейсы платформы:
V83.COMConnector с использованием стандартных перечислений метаданных источника.