При разработке на платформе 1С:Предприятие 8 часто возникает вопрос о том, как те или иные объекты метаданных представлены на уровне системы управления базами данных (СУБД). Особый интерес вызывают перечисления (Enums), так как их поведение в коде и запросах отличается от привычных справочников или документов. В этой статье мы подробно разберем, как именно 1С хранит данные перечислений в SQL, почему в таблицах нет привычных имен и как платформа сопоставляет программные идентификаторы с двоичными данными.
Начнем с того, что для каждого объекта метаданных типа Перечисление, созданного в конфигураторе, платформа генерирует отдельную таблицу в базе данных (будь то MS SQL Server, PostgreSQL или Oracle). Рассмотрим структуру этой таблицы. Её имя в СУБД обычно имеет формат _Enum<N>, где <N> — это внутренний уникальный номер объекта метаданных в вашей конкретной конфигурации.
В отличие от справочников, таблица перечисления максимально упрощена. Проанализируем состав её полей:
binary(16). Оно представляет собой уникальный идентификатор значения перечисления (GUID). Именно это значение используется во всех остальных таблицах базы данных (документах, регистрах, справочниках), когда на данное перечисление ссылается какой-либо реквизит.Важное наблюдение: в таблице SQL вы не найдете полей для наименований (синонимов) или имен значений, которые вы задали в конфигураторе. Там нет ни «Оплачено», ни «EnumValues.Paid». Это фундаментальное отличие 1С от некоторых других систем, где перечисления могут храниться в виде строк или простых целочисленных констант прямо в коде.
Выясним, каким образом платформа понимает, что двоичный код 0x80C200505697000111E2 соответствует значению СтатусыЗаказов.Согласован. Вся информация о структуре метаданных, включая имена перечислений, их значений и синонимы на разных языках, хранится в системной таблице Config (или Params в зависимости от версии и режима). Эти данные хранятся в сжатом виде.
При запуске рабочего процесса сервера 1С:Предприятия платформа считывает структуру метаданных, кэширует её и выстраивает карту соответствий. Когда в коде 1С мы обращаемся к Перечисления.СтатусыЗаказов.Согласован, система уже знает, какой _IDRRef соответствует этому программному имени. На уровне SQL-запроса это превращается в простую фильтрацию по двоичному идентификатору.
Рассмотрим подробнее, как работать с перечислениями в языке запросов 1С. Часто программисты, привыкшие к классическому SQL, пытаются найти «текстовое поле» перечисления, но в 1С это работает иначе. Посмотрим на типичный пример использования перечисления в условии запроса:
ВЫБРАТЬ
Продажи.Номенклатура,
Продажи.Количество
ИЗ
РегистрНакопления.Продажи КАК Продажи
ГДЕ
Продажи.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказов.Выполнен)
Проанализируем, что происходит в этот момент под капотом. Платформа 1С при генерации итогового SQL-запроса не будет выполнять JOIN с таблицей перечисления. Вместо этого конструкция ЗНАЧЕНИЕ(...) будет заменена на литерал — конкретную 16-байтную последовательность. Это делает запросы к перечислениям чрезвычайно быстрыми, так как СУБД сравнивает константы, не обращаясь к лишним таблицам.
Если же нам необходимо выбрать само перечисление и его порядок, мы можем обратиться к виртуальным полям, которые предоставляет платформа:
ВЫБРАТЬ
ВидыНалогов.Ссылка КАК Ссылка,
ВидыНалогов.Порядок КАК Порядок
ИЗ
Перечисление.ВидыНалогов КАК ВидыНалогов
УПОРЯДОЧИТЬ ПО
Порядок
Здесь Порядок напрямую соответствует полю _Order в SQL, а Ссылка — полю _IDRRef.
Разберем ситуацию с сортировкой. В 1С:Предприятии 8 по умолчанию объекты сортируются по их представлению (тексту). Однако для перечислений поведение иное. Если вы напишете УПОРЯДОЧИТЬ ПО Статус, где Статус — это перечисление, платформа выполнит сортировку именно по полю _Order. Это критически важно понимать: порядок в отчетах будет таким, каким вы его задали в конфигураторе, а не алфавитным.
Что касается представления (получения текста «Согласован» или «Отклонен»), то платформа делает это на лету. Когда в ячейке отчета или формы нужно вывести текст, сервер приложений или клиентское приложение обращается к метаданным в памяти и подставляет нужную строку (синоним) в зависимости от текущего языка пользователя.
Проанализируем ситуацию, когда реквизит имеет составной тип, например, СправочникСсылка.Контрагенты и ПеречислениеСсылка.ТипыКлиентов. В этом случае в таблице SQL (например, в таблице документа) под один реквизит будет выделено несколько колонок:
Для простых (не составных) типов 1С использует только одну колонку _IDRRef, что экономит место и ускоряет работу.
Чтобы окончательно закрепить понимание, сравним перечисление со справочником в контексте хранения в БД:
_Code (Код), _Description (Наименование), пометку удаления _Marked и предопределенные элементы. Пользователь может создавать новые записи в режиме «Предприятие».Таким образом, перечисление в 1С — это не просто класс или текстовый список, а эффективный механизм хранения фиксированных наборов состояний, оптимизированный для быстрого выполнения запросов и корректной сортировки на уровне СУБД.