Как получить структуру хранения базы данных в 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В отличие от современной платформы 1С:Предприятие 8, где для получения структуры СУБД существует удобный стандартный метод ПолучитьСтруктуруХраненияБазыДанных(), в легендарной версии 1С 7.7 разработчикам приходится использовать обходные пути. Физические имена таблиц и полей в базах данных 1С 7.7 (будь то файловая версия DBF или SQL-версия на MS SQL Server) скрыты за системными идентификаторами вида SC143 или SP2544.

В этой статье мы подробно разберем, как расшифровать структуру хранения базы данных 1С 7.7, сопоставить объекты метаданных с физическими таблицами и полями СУБД, а также рассмотрим практические примеры кода и сторонние инструменты, которые помогут решить эту задачу.

Понимание физической структуры базы данных 1С 7.7

Для начала проанализируем, как устроена база данных 1С 7.7 на физическом уровне. Все таблицы в каталоге базы данных (для DBF) или в базе данных SQL имеют строго регламентированные префиксы в именах файлов/таблиц. Давайте систематизируем эти знания:

Также существуют глобальные системные таблицы, единые для всей конфигурации:

Теперь рассмотрим основные практические способы сопоставления этих таблиц с объектами конфигурации.

Способ 1. Анализ файлов словаря данных (DD и DDS)

Самый простой и очевидный способ узнать структуру конкретной базы данных — изучить файлы словаря данных, которые автоматически создаются системой при сохранении конфигурации:

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

Чтобы упростить эту задачу, мы рекомендуем использовать специализированные бесплатные утилиты:

Также существуют готовые внешние отчеты и обработки (парсеры DD-файлов), которые загружают структуру в саму 1С и выводят ее в виде удобного отчета прямо на экран пользователя.

Способ 2. Получение имени таблицы без внешних компонент (Лайфхак)

Если вам нужно быстро определить имя физической таблицы справочника программным путем во встроенном языке, и при этом у вас нет возможности подключать внешние компоненты, можно воспользоваться хитрым недокументированным приемом. Он основан на анализе внутреннего строкового представления ссылки справочника через функцию ЗначениеВСтрокуВнутр().

Давайте посмотрим на пример функции, которая возвращает имя таблицы справочника по его элементу или по пустому значению:


Функция ПолучитьИмяТаблицыСправочника(тЭлемент) Экспорт
    тТхт = ЗначениеВСтрокуВнутр(тЭлемент);
    тСЗ = СоздатьОбъект("СписокЗначений");
    
    // Преобразуем сериализованную строку в список значений
    тСЗ.ИзСтрокиСРазделителями(Сред(Лев(тТхт, СтрДлина(тТхт) - 1), 2));
    
    // Получаем последний элемент списка, содержащий внутренний ID
    тТхт = тСЗ.ПолучитьЗначение(тСЗ.РазмерСписка());
    тТхт = СокрЛП(Лев(тТхт, 10));
    
    Возврат "SC" + тТхт;
КонецФункции

Этот метод работает чрезвычайно быстро и позволяет получить точное имя DBF-файла или SQL-таблицы (например, SC402) для любого справочника без парсинга файлов словаря данных.

Способ 3. Использование внешней компоненты «1С++» (Рекомендуемый)

Если вы регулярно работаете с прямыми SQL-запросами к базе данных 1С 7.7, то использование внешней компоненты 1С++ (1cpp.dll) является стандартом де-факто. В ее состав входит мощнейший класс MetaDataWork, который предоставляет разработчику полные возможности по сопоставлению метаданных.

Рассмотрим основные методы этого класса:

При использовании ODBCRecordset из состава 1С++ вам даже не обязательно вручную получать эти идентификаторы. Парсер запросов поддерживает метаимена. Например, мы можем написать следующий лаконичный SQL-запрос:


ТекстЗапроса = "
|SELECT
|   Номенклатура.ID as [Ссылка $Справочник.Номенклатура],
|   Номенклатура.CODE as Код,
|   Номенклатура.DESCR as Наименование
|FROM
|   $Справочник.Номенклатура AS Номенклатура
|";

Компонента автоматичеки транслирует конструкцию $Справочник.Номенклатура в физическое имя таблицы в СУБД перед непосредственным выполнением запроса.

Способ 4. Получение идентификаторов периодических реквизитов

Иногда возникает необходимость связать данные из таблицы _1sconst (где хранятся периодические значения) с конкретным справочником и реквизитом. Для этого нам нужно сопоставить ID реквизитов.

Рассмотрим пример программного кода, который обходит метаданные справочников, находит периодические реквизиты и сопоставляет их физические идентификаторы с помощью класса MetaDataWork:


// Создаем таблицу соответствия
ТаблицаРеквизитов = СоздатьОбъект("ТаблицаЗначений");
ТаблицаРеквизитов.НоваяКолонка("Спр");
ТаблицаРеквизитов.НоваяКолонка("Рекв");
ТаблицаРеквизитов.НоваяКолонка("АйДи");

// Обходим метаданные справочников
Для х = 1 По Метаданные.Справочник() Цикл
    Для у = 1 По Метаданные.Справочник(х).Реквизит() Цикл
        Если Метаданные.Справочник(х).Реквизит(у).Периодический = 1 Тогда
            ТаблицаРеквизитов.НоваяСтрока();
            ТаблицаРеквизитов.Спр = Метаданные.Справочник(х).Идентификатор;
            ТаблицаРеквизитов.Рекв = Метаданные.Справочник(х).Реквизит(у).Идентификатор;
            
            // Получаем физический ID периодического реквизита
            ТаблицаРеквизитов.АйДи = МетаДатаВорк.ИДРеквизитаСправочника(х, у);
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

После заполнения такой таблицы соответствий мы можем легко расшифровать данные, полученные прямым запросом из таблицы констант _1sconst, сопоставив колонку ID из СУБД с полученным значением АйДи.

Важный нюанс при работе с таблицей _1sconst

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

Если в системе выполняется удаление элементов справочников через метод Удалить(1) (непосредственное удаление без пометки), платформа 1С 7.7 из-за архитектурных особенностей СУБД не всегда корректно очищает связанные исторические записи в таблице периодических реквизитов _1sconst.

В результате при выполнении прямых SQL-запросов к _1sconst вы можете обнаружить множество «осиротевших» строк. Попытка получить объект по такому идентификатору с помощью метода ЗначениеИзСтрокиБД() вернет результат <Объект не найден>. При построении сложных отчетов этот момент необходимо обязательно учитывать и программно фильтровать недействительные ссылки.

Мы рассмотрели ключевые методы получения структуры хранения данных в 1С 7.7. Выбирайте наиболее подходящий для ваших задач способ — от простых текстовых словарей до динамического анализа средствами встроенного языка или внешних компонент!

← На главную