Contents
- 1 Как просмотреть структуру базы данных 1С Предприятие 1Cv8.1CD
- 2 Структура файла базы данных 1CD
- 3 Получаем структуру базы данных (название таблиц и полей, т.е. метаданные) из 1С Предприятие 8.3
- 4 Загружаем из xml файлов название полей и таблицы
- 5 Скачать epf-файл для просмотра структуры базы данных 1С Предприятие 8.3 и LOAD Script для QlikView
- 6 Пример модуля для получения структуры данных из 1С и SQL запроса к Базе данных 1С Предприятие 8
Как просмотреть структуру базы данных 1С Предприятие 1Cv8.1CD
В этой статье будет накапливаться экспертиза по работе с файловой базой данных системы 1С Предприятие 8.
Первое на что я наткнулся – это утилита “Tool 1CD.exe”. Ниже будет приведена ссылка на скачивание.
Команда для массового экспорта таблиц из файла 1Cv8.1CD в XML:
1 |
Tool_1CD.exe C:\Users\Иван\Documents\1c\DemoSmallBusinessEduc\1Cv8.1CD -ExportAllToXML F:\1С_Аналитика\db_xml\ |
Программа “Tool_1CD” для распаковки базы данных 1С Предприятие 8 из 1Cv8.1CD в XML (Заархивировано сначала в RAR, потом в zip): Tool_1CD.zip.
Проверял на вирусы на касперском, вроде не было. Но в любом случае Вы используете этот файл на свой страх и риск. Всегда лучше работайте в “песочнице” или на скопированном файле, который не жалко потерять. Скачивая этот файл Вы соглашаетесь с тем, что Вы снимаете ответственность с владельца этого сайта. Вся ответственность за использование этого файла лежит на Вас.
НА БОЕВОЙ СРЕДЕ НИКОГДА НЕ ТЕСТИРУЙТЕ РАБОТУ ПОСТОРОННИХ УТИЛИТ!!!!!!!!
Интерфейс программы “Tool 1CD”
Структура файла базы данных 1CD
Техническое описание внутреннего устройства опубликовано мной в статье Краткое описание формата файлов *.1CD (файловых баз 1Сv8). Однако она достаточно сумбурна, плоха для восприятия, поэтому здесь я попытаюсь описать формат немного более популярно. Чтобы не было путаницы с термином «файл», сразу замечу, что когда я буду иметь в виду файл базы *.1CD, я буду говорить «файл базы», когда же я буду говорить про внутренние файлы, содержащиеся внутри базы, я буду употреблять просто термин «файл».
Страницы
На самом нижнем уровне файл базы данных 1CD состоит из страниц размером 4 килобайт (0x1000).
По сути, весь файл базы состоит из массива четырехкилобайтных страниц. Каждая страница имеет свой номер (индекс). Здесь и далее каждый прямоугольник с красной рамкой обозначает одну страницу.
Файлы
На более высоком уровне находятся файлы. Файл состоит из одной или более страниц. У каждого файла есть ровно одна заголовочная страница, в которой размещается массив номеров страниц размещения. В каждой странице размещения, в свою очередь, находится массив номеров страниц данных. Заголовочная страница и страницы размещения – это служебные страницы, которые нужны только для хранения служебных данных (сигнатура, длина файла, версия) и для нахождения страниц данных. Собственно содержимое файла хранится в страницах данных.
Структура таблиц
Каждая таблица состоит из нескольких файлов:
- файла описания таблицы DESCR;
- файла записей DATA;
- файла индексов INDEX;
- файла данных неограниченной длины BLOB.
Файл описания таблицы DESCR содержит текстовое описание таблицы – имя таблицы, состав полей и индексов. А также файл DESCR содержит номера файлов DATA, INDEX и BLOB. Таблица адресуется с помощью файла описания таблицы. Структуру файлов таблиц мы в данной статье рассматривать не будем, подробности можно узнать из моей статьи, ссылку на которую я приводил выше. Файл индексов может отсутствовать, если в таблице нет ни одного индекса. Файл данных неограниченной длины тоже может отсутствовать, если в таблице нет ни одного поля с данными неограниченной длины.
Адресация
База состоит из таблиц. Таблицы, в свою очередь, состоят из файлов. И наконец, файлы состоят из страниц. Адресом страницы является ее порядковый номер (индекс) в файле базы. Адресом файла является номер его заголовочной страницы. Адресом таблицы является адрес ее файла описания, а значит, номер заголовочной страницы файла описания. Т.е. о каком бы объекте мы бы не говорили – странице, файле или таблице, адресом объекта всегда является просто номер страницы.
Получаем структуру базы данных (название таблиц и полей, т.е. метаданные) из 1С Предприятие 8.3
Одним из способов получения подробного описания таблиц, полей (соответствие нормального наименования таблиц и технического) – использование “Внешней обработки .EPF”.
Файл .epf программируется через конфигуратор 1С Предприятия. В интернете много статей, я покажу лишь как его использовать.
Я нашел несколько файлов EPF (в архиве их три штуки):
epf файлы для получения метаданных из 1С Предприятия 8.3.zip
Как запустить epf файл для выгрузки из 1С метаданных
Приведу 2 примера подключения epf файла. Заходим в 1С Предприятие 8.3. Выбираем Файл – Открыть:
Далее выбираем файл внешней обработки 1С Предприятие для версии 8.3 СтруктураИБ_УФ.epf:
Нажимаем “Вывести список”:
Формат:
Расскрываем список
Получаем описание таблиц с полями:
И еще один пример:
Выводим структуру таблиц 1С Предприятие в текстовом формате
Таблица и “человеческие” названия:
Загружаем из xml файлов название полей и таблицы
1 2 3 4 5 6 7 8 9 10 11 |
for each fileName in FileList('F:\1С_Аналитика\db_xml\*.xml') Field: LOAD Name, Type, Length, Precision, '$(fileName)' as [Название файла] FROM '$(fileName)' (XmlSimple, Table is [Table/Fields/Field]); NEXT fileName |
После небольшой корректировки получаем отчет, можете скачать (но там ничего не понятно, нужна расшифровка метаданных): Таблицы и поля из 1С Предприятия 8.3 после обработки Tool 1CD.exe и выгрузкой в XML.xlsx
Скачать epf-файл для просмотра структуры базы данных 1С Предприятие 8.3 и LOAD Script для QlikView
Скачать epf-файл для просмотра структуры базы данных 1С Предприятие 8.3 и LOAD Script для QlikView:
DB Structure LOAD Script For QLIKVIEW.epf
1С Script Builder реализован в виде внешней 1С-обработки и предназначен для автоматизированного проектирования скрипта загрузки данных из БД 1С версии 8.x в аналитическое приложение QlikView. Использование 1С Script Builder позволяет получить максимальную скорость загрузки данных и максимальную гибкость при формировании самых сложных запросов.
Генерация Загрузочного скрипта для QlikView из метаданных конфигураций 8.3 (управляемые формы), тестировалась на конфигурации “Управление небольшой фирмой, ред. 1.6”.
Обработка получает таблицу метаданных конфигурации с помощью функции ПолучитьСтруктуруХраненияБазыДанных() и генерирует код QlikView SCRIPT с запросом SQL для объекта метаданных текущей строки. Работает в тонком и толстом клиентах управляемого приложения. Поля, индексы и состав индексов элемента метаданных отображается в отдельных таблицах.
Ниже скриншоты как зайти в управляемое приложение через конфигуратор.
ВНИМАНИЕ! В коде последнюю запятую перед SQL надо удалить. Не знаю, как программными средствами убрать.
Заходим в конфигуратор 1С Предприятие 8.3 Управление небольшой фирмой (Демо версия):
На вкладке LOAD Script For QlikView приведен загрузочный скрипт. Не забывайте про запятую, которую нужно убрать.
Пример модуля для получения структуры данных из 1С и SQL запроса к Базе данных 1С Предприятие 8
Размещаю этот пример в качестве отправной точки пример. Взят из файла: TableStruct.epf.7z
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
Перем мТаблицыХранения; Процедура ОбновитьТаблицы() мТаблицыХранения = ПолучитьСтруктуруХраненияБазыДанных(, Истина); мТаблицыХранения.Сортировать("ИмяТаблицыХранения"); ОтобратьСтрокиПоСтрокеПоиска(); КонецПроцедуры Функция НайтиТекСтрокуТаблицыХранения() СтрокаТаблХранения = Неопределено; ТекСтрокаТаблиц = ЭлементыФормы.ТаблицыSQL.ТекущаяСтрока; Если ТекСтрокаТаблиц <> Неопределено Тогда СтрокаТаблХранения = мТаблицыХранения.Найти(ТекСтрокаТаблиц.ИмяТаблицыХранения, "ИмяТаблицыХранения"); КонецЕсли; Возврат СтрокаТаблХранения; КонецФункции // НайтиТекСтрокуТаблицыХранения() Процедура ОбновитьПоля() СтрокаТаблХранения = НайтиТекСтрокуТаблицыХранения(); ИмяРодительскойТаблицы=""; Позиция=Найти(Прав(СтрокаТаблХранения.ИмяТаблицыХранения,СтрДлина(СтрокаТаблХранения.ИмяТаблицыХранения)-1),"_"); Если Позиция>0 Тогда ИмяРодительскойТаблицы=Лев(СтрокаТаблХранения.ИмяТаблицыХранения,Позиция); КонецЕсли; Если СтрокаТаблХранения <> Неопределено Тогда ПоляSQL.Очистить(); ПоляХранения = СтрокаТаблХранения.Поля; Для каждого СтрокаПоляХранения Из ПоляХранения Цикл СтрокаПоляSQL = ПоляSQL.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаПоляSQL, СтрокаПоляХранения); Если СтрокаПоляSQL.ИмяПоляХранения=ИмяРодительскойТаблицы+"_IDRRef" Тогда СтрокаПоляSQL.Комментарий="Ссылка"; КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ОбновитьИндексы() СтрокаТаблХранения = НайтиТекСтрокуТаблицыХранения(); Если СтрокаТаблХранения <> Неопределено Тогда ИндексыSQL.Очистить(); ИндексыХранения = СтрокаТаблХранения.Индексы; Для каждого СтрокаИндексаХранения Из ИндексыХранения Цикл СтрокаИндексаSQL = ИндексыSQL.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаИндексаSQL, СтрокаИндексаХранения); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ОбновитьПоляИндекса() ТекСтрокаИндексов = Неопределено; СтрокаИндексаХранения = Неопределено; СтрокаТаблХранения = НайтиТекСтрокуТаблицыХранения(); Если СтрокаТаблХранения <> Неопределено Тогда СтрокаИндексаХранения = Неопределено; ТекСтрокаИндексов = ЭлементыФормы.ИндексыSQL.ТекущаяСтрока; КонецЕсли; Если ТекСтрокаИндексов <> Неопределено Тогда ИндексыХранения = СтрокаТаблХранения.Индексы; СтрокаИндексаХранения = ИндексыХранения.Найти(ТекСтрокаИндексов.ИмяИндексаХранения, "ИмяИндексаХранения"); КонецЕсли; Если СтрокаИндексаХранения <> Неопределено Тогда ПоляИндексаSQL.Очистить(); ПоляИндекса = СтрокаИндексаХранения.Поля; Для каждого СтрокаПоляИндексаХранения Из ПоляИндекса Цикл СтрокаПоляИндексаSQL = ПоляИндексаSQL.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаПоляИндексаSQL, СтрокаПоляИндексаХранения); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ОбновитьИнформациюОТаблице() ИмяТекущейСтраницы = ЭлементыФормы.ПанельСвойствТаблицы.ТекущаяСтраница.Имя; Если ИмяТекущейСтраницы = "Поля" Тогда ОбновитьПоля(); ИначеЕсли ИмяТекущейСтраницы = "Индексы" Тогда ОбновитьИндексы(); ОбновитьПоляИндекса(); ИначеЕсли ИмяТекущейСтраницы="СтраницaSQL" тогда ОбновитьПоля(); ОбновитьSQL(); КонецЕсли; КонецПроцедуры Процедура ДействияФормыОбновить(Кнопка) ОбновитьТаблицы(); КонецПроцедуры Процедура ТаблицыSQLПриАктивизацииСтроки(Элемент) ОбновитьИнформациюОТаблице(); КонецПроцедуры Процедура ПанельСвойствТаблицыПриСменеСтраницы(Элемент, ТекущаяСтраница) ОбновитьИнформациюОТаблице(); КонецПроцедуры Процедура ИндексыSQLПриАктивизацииСтроки(Элемент) ОбновитьПоляИндекса(); КонецПроцедуры Процедура ПриОткрытии() ЕслиЕсть=Истина; Суффикс=Истина; ОбновитьТаблицы(); КонецПроцедуры Функция СоздатьSQLЗаголовок(ТаблицаИмя,ТаблицаИмя1С,ЕслиЕсть) Поле = "create view "; Если ТаблицаИмя1С = "" тогда ИмяВью = СтрЗаменить (ТаблицаИмя, ".", "_"); иначе ИмяВью = СтрЗаменить (ТаблицаИмя1С, ".", "_"); КонецЕсли; Если ЕслиЕсть тогда СтрокаУдаления = "IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'dbo." + ИмяВью + "'))" + Символы.ПС + "DROP VIEW dbo." + ИмяВью + Символы.ПС + "GO" + Символы.ПС; Иначе СтрокаУдаления = ""; КонецЕсли; Поле = СтрокаУдаления + Поле + "dbo."+ИмяВью; Возврат Поле; КонецФункции Функция СоздатьSQLСписокПолей(ТаблицаПолейSQL,Суффикс) Тело=Символы.ПС+"as "+Символы.ПС+"select"+Символы.ПС; Разделитель=Символы.Таб; Поле=""; Для Каждого Строка из ТаблицаПолейSQL цикл ИмяПоля=?(Строка.ИмяПоля<>"",Строка.ИмяПоля,Строка.Комментарий); Если Строка.ИмяПоляХранения = "_IDRRef" Тогда Поле = "Ссылка" ИначеЕсли ИмяПоля="" тогда Поле = Строка.ИмяПоляХранения; ИначеЕсли Прав(Строка.ИмяПоляХранения, 4) = "RRef" и Суффикс и Строка.Комментарий="" Тогда Поле = ИмяПоля + "_Ссылка"; ИначеЕсли Прав(Строка.ИмяПоляХранения, 4) = "TRef" Тогда Поле = ИмяПоля + "_СсылкаТип"; ИначеЕсли Лев(Строка.ИмяПоляХранения,11)="_TurnoverDt" Тогда Поле = ИмяПоля+"_ОборотДебет"; ИначеЕсли Лев(Строка.ИмяПоляХранения,11)="_TurnoverCt" Тогда Поле = ИмяПоля+"_ОборотКредит"; ИначеЕсли Лев(Строка.ИмяПоляХранения,9)="_Turnover" Тогда Поле = ИмяПоля+"_Оборот"; ИначеЕсли Прав(Строка.ИмяПоляХранения,5)="_TYPE" Тогда Поле = ИмяПоля+"_TYPE"; ИначеЕсли Прав(Строка.ИмяПоляХранения,2)="_N" Тогда Поле = ИмяПоля+"_N"; ИначеЕсли Прав(Строка.ИмяПоляХранения,2)="_S" Тогда Поле = ИмяПоля+"_S"; ИначеЕсли Прав(Строка.ИмяПоляХранения,2)="_D" Тогда Поле = ИмяПоля+"_D"; Иначе Поле = ИмяПоля; КонецЕсли; Тело=Тело+Разделитель+Строка.ИмяПоляХранения+" as "+Поле+Символы.ПС; Разделитель=Символы.Таб+","; КонецЦикла; Возврат Тело; КонецФункции Функция СоздатьSQLView(ТаблицаИмя,ТаблицаИмя1С,ЕслиЕсть,ТаблицаПолейSQL,Суффикс,ИмяБД) Префикс="dbo."; Если ИмяБД<>"" тогда Префикс="["+ИмяБД+"].dbo."; КонецЕсли; Тело=СоздатьSQLЗаголовок(ТаблицаИмя,ТаблицаИмя1С,ЕслиЕсть)+ СоздатьSQLСписокПолей(ТаблицаПолейSQL,Суффикс)+"from "+Префикс+ТаблицаИмя; Возврат Тело; КонецФункции Процедура ОбновитьSQL() СтрокаТаблХранения = НайтиТекСтрокуТаблицыХранения(); Если СтрокаТаблХранения <> Неопределено Тогда ТекстПредставления=СоздатьSQLView(СтрокаТаблХранения.ИмяТаблицыХранения,СтрокаТаблХранения.ИмяТаблицы,ЕслиЕсть,ПоляSQL,Суффикс,ИмяБД); КонецЕсли; КонецПроцедуры Процедура ЕслиЕстьПриИзменении(Элемент) ОбновитьSQL(); КонецПроцедуры Процедура ОбновлениеОтображения() Если (ИмяБД="") Тогда ЭлементыФормы.ИмяБД.ЦветФонаПоля=Новый Цвет(255,153,204); Иначе ЭлементыФормы.ИмяБД.ЦветФонаПоля=ЭлементыФормы.ЕслиЕсть.ЦветФонаПоля; КонецЕсли; КонецПроцедуры Процедура СтрокаПоискаПриИзменении(Элемент) ОтобратьСтрокиПоСтрокеПоиска(); КонецПроцедуры Процедура ОтобратьСтрокиПоСтрокеПоиска() ТаблицыSQL.Очистить(); Для каждого СтрокаТаблХранения Из мТаблицыХранения Цикл Если Найти(СтрокаТаблХранения.ИмяТаблицыХранения,СтрокаПоиска)>0 ИЛИ Найти(СтрокаТаблХранения.ИмяТаблицы,СтрокаПоиска)>0 ИЛИ Найти(СтрокаТаблХранения.Метаданные,СтрокаПоиска)>0 Тогда СтрокаТаблицыSQL = ТаблицыSQL.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаТаблицыSQL, СтрокаТаблХранения); КонецЕсли; КонецЦикла; КонецПроцедуры |