1sentry dbf что содержит
Описание таблиц 1С V77
1. Описание общих таблиц 1С V77
1.1. Общее описание хранения данных 1С.
1.1.1. Хранение ID объекта
ID может иметь 3 представления (уровня) в зависимости от длины (количества значащих символов):
В некоторых случаях, при указании неопределенного типа объекта (длина ID кода 23 символа) создается дополнительное поле с символом «T» вначале (например, если в справочнике задан реквизит SP235 как неопределенный, то в таблице справочника будет создано еще одно поле TSP235). Рассмотрим поподробнее значения этого поля. Это поле по умолчанию заполняется пустой строкой (3 пробела).
Поскольку для неопределенных реквизитов (полей) длина поля всегда равна 23 символам, то соответственно в такое поле можно записать значение максимум с 22 символьным значением (1 отводится под определение типа, в случае базовых типов, таких как число, строка, дата).
1.1.2. Хранение даты
1.1.3. Хранение времени
1.2. Описание таблиц 1С
Краткое описание:
Краткое описание: таблица предназначена для хранения уникального идентификатора сессии первого присоединившегося к базе данных пользователя в режиме предприятия (поэтому в таблице всегда только одна запись). Судя по всему, именно по наличию записи в этой таблицы и происходит верификация процедур при первом запуске в SQL.
Краткое описание: таблица предназначена для хранения значений констант и периодических реквизитов справочников.
Краткое описание: таблица предназначена для хранения ссылок подчиненных документов и граф отборов реквизитов документов, которые не являются общими реквизитами. Для хранения ссылок документов в подчиненном документе должен быть реквизит (поле) в котором будет ссылка на документ-родитель. Без такой ссылки документ не считается подчиненным.
Краткое описание: таблица предназначена для хранения списка всех документов. Именно эта таблица является узким местом при работе большого числа пользователей (так как она блокируется полностью каждым пользователем в момент проведения документов).
Краткое описание: таблица предназначена для хранения информации о зарезервированных номерах документов, т.е. тех. номерах документов, которые вводятся в данный момент в систему, но еще не сохранены (не записаны в таблицу журналов _1SJOURN)
Краткое описание: таблица предназначена для хранения информации о последовательностях.
Название поля | Описание |
---|---|
ID | Идентификатор последовательности (числовое представление). Тип – Число(4). |
DATE_TIME_DOCID | Дата+Время+идентификатор документа, на котором установлена последовательность. Это поле аналогично полю DATE_TIME_IDDOC таблицы _1SJOURN. Тип – Строка(23). |
Краткое описание: таблица предназначена для хранения информации о датах точки актуальности и рассчитанного периода бухгалтерских итогов, также в таблице хранится информация о параметрах УРБД.
Краткое описание: таблица предназначена для хранения информации о последнем ID коде документов и справочников.
Название поля | Описание |
---|---|
TYPEID | Идентификатор вида справочника, или же 0 для всех документов (у всех документов сквозная нумерация ID). Тип – Число(4). |
MAXID | Максимальный используемый идентификатор (ID). |
Краткое описание: таблица предназначена для хранения информации о подключенных пользователях. В таблице всегда одна строка. Именно по наличию строки в этой таблице 1С судит об аварийном завершении программы и предлагает переиндексировать ИБ в случае dbf-версии.
Название поля | Описание |
---|---|
USRSCNT | Количество подключенных пользователей к 1С в режиме 1С предприятия. |
NETCHGCN | Счетчик действий пользователей, которые привели к изменению в базе данных (записи в таблицы). Счетчик учитывает количество записей в таблицы (т.е. в случае проведения документа с несколькими движениями учитывается каждое движение). |
Краткое описание: таблица содержит записи ИД объектов, которые должны быть выгружены при очередном обмене данных.
Название поля | Описание |
---|---|
DBSIGN | Код ИБ куда должна произойти загрузка, char(3) |
TYPEID | Тип объекта, int |
OBJID | ИД объекта, char(9) |
DELETED | флаг удаления объекта из базы, char(1), (символ D или пусто) |
DWNLDID | идентификатор обмена. при выгрузке 1С ставит уникальное значение, после обмена 1С должна получить это значение от распределённой базы (от DBSIGN), т.о. считается, что выгрузка прошла успешно и записи из таблицы удаляются, иначе записи хранятся и попадают в следующую выгрузку, где им заново присваивается новый идентификатор, char(9) |
2. Подсистема справочников и констант
2.1. Предисловие
Данная часть предназначена для тех, кто пытается разобраться в структуре хранения данных в системе 1С версии 7.7. А также покажет, как можно получать данные напрямую из таблиц 1С, минуя программу 1С. Для понимания того, о чем идет речь в статье, необходимо понимать принципы работы 1С версии 7.7 и иметь начальные навыки работы с SQL Server Enterprise Manager и SQL Server Query Analyzer.
2.2. Введение
2.3. Описание полей таблиц справочников
Особое внимание надо уделить полям «TSP». Это поле создается лишь тогда, когда реквизит (измерение, ресурс) имеет неопределенный тип (длина ID кода 23 символа). Опытным путем было установлено, что это поле по умолчанию заполняется пустой строкой (3 пробела).
2.4. Описание полей таблицы констант и периодических реквизитов справочников
Описание таблицы _1SCONST находится выше.
Необходимо только учесть, что значения периодических реквизитов элементов справочников хранятся в таблице _1SCONST с заполненным полем OBJID, которое равно полю ID таблицы справочника. Для констант же значение поля OBJID всегда равно ‘ 0 ‘. Также необходимо учесть, что выбрать все периодические значения всех реквизитов одного элемента (одной записи) невозможно. Дело в том, что в поле OBJID хранится краткий (строка 9 символов) ID, а такое значение ID не подразумевает определения вида справочника. Соответственно чтобы получить значение конкретного периодического реквизита надо знать десятичное значение реквизита (_StrToID). Т.е., выбрав только с условием по OBJID получим периодические реквизиты всех справочников, с таким ID, а не только одного. Но, поскольку нумерация всех ID объектов конфигурации (включая и все реквизиты) сквозная, то не может быть в двух разных справочниках реквизитов с одинаковым ID реквизита. Соответственно, необходимым условием для получения значений периодических реквизитов является как условие по полю OBJID (ID элемента справочника), так и по полю ID (десятичное значение ID реквизита справочника).
2.5. Примеры запросов
2.5.1. Пример 1
2.5.2. Пример 2
2.5.3. Пример 3
Получение записей только элементов (не групп) справочника (кроме периодических реквизитов).
2.5.4. Пример 4
2.5.5. Пример 5
Получение записей элементов с периодическим реквизитом, значение которого получается на максимальную дату (возможно и будущую). В данном примере условие TabConst.ID = 101 необходимо для отбора периодических значений только по реквизиту с десятичным ID кодом равным 101.
В этом примере могут возвращаться и значения NULL для тех реквизитов, для которых не были установлены периодические реквизиты:
2.5.6. Пример 6
Получение записей элементов с периодическим реквизитом, на конкретную дату.
Периодический реквизит получается на 11.03.2006. В данном примере условие TabConst.ID = 101 необходимо для отбора периодических значений только по реквизиту с десятичным ID кодом, равным 101.
2.5.7. Пример 7
Первая часть запроса будет выглядеть так:
Но приведенный выше код содержит ошибку. Дело в том, что поле DESCR определено как Char, и его длина строго задана и равна длине наименования для справочника «Контрагенты». Например, если длина наименования 50 символов, то предыдущий запрос надо было написать так:
Как видно, в условии происходит сравнение на полную строку, включая недостающие пробелы. Для того, чтобы не заполнять строку поиска недостающими пробелами, можно воспользоваться функцией усечения пробелов справа, или же определить переменную как Char(50) и поиск вести по значению этой переменной.
Для первого случая пример запроса будет такой:
Для второго случая пример запроса будет такой:
Вторая часть запроса, получение имени менеджера. Необходимо сделать выборку из 2 таблиц. Это можно сделать как минимум двумя способами. В первом примере выборка из 2 таблиц с условием:
Во втором примере выборка из 2 таблиц с объединением. Этот код аналогичен предыдущему, за исключением того, что происходит объединение с условием, а не выборка из таблиц с условием:
Но эти оба примера не совсем корректные. Дело в том, что запросы работают по полном объединении (или полном условии), т.е. в выборку попадут лишь те записи из таблицы Контрагентов, для которых есть записи в таблице Сотрудников (т.е. поле «Менеджер» справочника Контрагенты заполнено). Если же для элемента с наименованием ‘Иванов А. А.’ поле Менеджер пустое (в таблице находиться или NULL или значение ‘ 0 ‘, именно так 1С хранит значения невыбранных реквизитов), то в выборку не попадет строка таблицы, так как не выполняется условие на вхождение в таблицу Сотрудников (в таблице SC258 в столбце ID нет ни одной записи, для которой есть значение ‘ 0 ‘).
Первый пример будет выглядеть так:
Второй пример выборки со связыванием 2 таблиц:
2.5.8. Пример 8
Рассмотрим пример получения значений записей элементов справочников с их родителями (группами).
В этом коде условие TabSpr.ISFOLDER = 2 необходимо для отбора только элементов (не групп). Левое внешнее связывание применяется для того чтобы вывести все элементы, а не только те, у которых есть выбранные родители (в случае с INNER JOIN).
Рассмотрим теперь более сложный пример. Получим всех родителей для элементов (т.е. включая и родителей родителей). Для получения родителей надо знать максимальное количество родителей. Это число легко узнать с помощью команды «Метаданные.Справочник(х).КоличествоУровней». Приведем пример для значения количества уровней, равного 4.
В результате выполнения данного запроса получаются данные по всем возможным родителям, даже если нет родителей у элемента 1 или 2, то все равно будет 3 колонки с родителями, но в таком случае в качестве родителя будет значение NULL. Для того чтобы в первой колонке всегда был родитель (если есть у элемента родитель), то необходимо выполнить вот такой запрос:
В этом коде условие TabSpr.ISFOLDER = 2 необходимо для отбора только элементов (не групп).
Вместо проверки на NULL можно воспользоваться функцией COALESCE, которая ищет слева направо в переданных параметрах значения не равные NULL, но тогда усложняется процесс получения различных значений групп на каждом уровне, поэтому рекомендуется это делать уже на клиентском приложении (после выполнения запроса).
2.5.9. Пример 9
В этом коде условие TabSpr.ISFOLDER = 2 необходимо для отбора только элементов (не групп). Ведь в 1С подчиненные элементы справочника существуют только у элементов. В результат выборки попадут и помеченные на удаление подчиненные элементы. Если надо получить только непомеченные подчиненные элементы (расчетные счета), тогда текст запроса должен быть таким:
3. Подсистема документов и регистров
3.1. Предисловие
Данная часть предназначена для тех, кто пытается разобраться в структуре хранения данных в системе 1С версии 7.7. А также покажет, как можно получать данные напрямую из таблиц 1С, минуя программу 1С. Для понимания того, о чем идет речь в статье, необходимо понимать принципы работы 1С версии 7.7 и иметь начальные навыки работы с SQL Server Enterprise Manager и SQL Server Query Analyzer.
3.2. Введение
Следует учесть, что в статье рассматриваются только примеры для SQL формата базы данных. Для DBF формата есть некоторые особенности, и не все запросы буду идентичны как для DBF, так и для SQL формата баз. В любом случае для выполнения запросов к DBF необходимы или ODBC или OLEDB драйвера. Можно использовать любой драйвер, работающий с DBASE2 форматом DBF. Опыт показывает, что наиболее сопоставимы по тексту запросов драйвера Visual FoxPro (ведь MS SQL Server и MS Visual FoxPro принадлежат одной фирме, и есть вероятность, что тексты запросов будут унифицироваться в будущем). Я советую использовать драйвер OLE DB Visual FoxPro 9.0, так как в нем меньше ограничений и он поддерживает больше функций и методов по сравнению с ODBC Visual FoxPro 6.0. Скачать последний драйвер (OLE DB Visual FoxPro 9.0) можно по этой ссылке: http://www.microsoft.com/downloads/details.aspx?FamilyId=E1A87D8F-2D58-491F-A0FA-95A3289C5FD4&displaylang=en.
Для того, чтобы получить ID имен таблиц, достаточно просмотреть файл КаталогоИБ()+»1cv7.dds» («1cv7.dd» для DBF формата базы).
Для получения ID объектов 1С можно воспользоваться компонентой 1С++ (http://www.1cpp.ru/) позволяющей получать ID объектов 1С прямо из 1С (например, преобразование значения ТекущийДокумент() в его ID (строка(9), или в длинную строку ИД (строка(13)), включая вид документа, или в самый длинный ID длиной 23 символа (строка(23)), включая ID типа, вида и самого объекта).
Также получение ID объектов рассмотрено в этой статье: http://www.sinor.ru/
Как формируется ID код, можно почитать выше.
3.3. Общее описание хранения данных 1С в подсистеме документов
Для начала рассмотрим диаграмму связей таблиц подсистемы оперативного учета (диаграмма не полная, но отражает тот минимум, который необходим для получения выборок по регистрам или документам).
3.3.1. Краткое описание таблиц
DT – таблицы документов (реквизитов табличной части). Создаются при первом добавлении реквизита табличной части в документ.
_1SJOURN – таблица документов (общих и системных реквизитов). Именно это и есть таблица полного журнала документов. Все остальные журналы формируются по полному журналу с дополнительным отбором по типам документов.
_1SCRDOC – Таблица подчиненных документов. В этой таблице хранятся ссылки документов-родителей на подчиненные документы.
В системе 1С 7.7 документы всегда хранятся максимум в 2 таблицах (т.е. табличная часть может быть только одна, и все данные табличной части хранятся в этой таблице) (за исключением общих реквизитов, которые хранятся в одной общей таблице).
В таблице реквизитов шапки хранятся все реквизиты за исключением общих реквизитов и атрибутов документов (также и системных, таких как время, флаг проведения и удаления). Они все хранятся в одной общей таблице журналов _1SJOURN (1SJOURN для dbf). Описание полей таблицы _1SJOURN можно посмотреть выше.
Таблица журналов _1SJOURN, таблица реквизитов шапки DHххх и таблица реквизитов табличной части DTххх «связаны» по полю IDDOC. Связь эта «мнимая» (т.е. значения полей как бы равны для соответствующих строк), но это не стандартные связи SQL.
Поэтому необходимо учесть, что 1С не создает связей для ограничения целостности данных (связи между полями) средствами MS SQL. Также особое внимание надо уделить тому, что все поля создаются как NOT NULL, т.е. в них нельзя записывать значения типа NULL (видимо поэтому и нет связей). И если значение пустое (в понимании SQL должно быть NULL), то 1С заполняет это поле таким образом:
3.3.2. Примеры запросов
3.3.2.1. Пример 1
Получение всех документов одного вида со всеми реквизитами шапки (кроме общих):
3.3.2.2. Пример 2
Получение всех документов одного вида со всеми реквизитами шапки (включая все общие и системные реквизиты):
3.3.2.3. Пример 3
Получение всех документов одного вида со всеми реквизитами шапки (включая все общие и системные реквизиты), а также всех реквизитов табличной части:
3.3.2.4. Пример 4
Получение всех документов одного вида со всеми реквизитами шапки (включая все общие и системные реквизиты) а также всех реквизитов табличной части с фильтром по дате документа (документов за один день).
В этом примере необходимо учесть, что дата документа храниться в SQL и DBF формате базы по-разному. Но, в любом случае, дата документа храниться в таблице журналов _1SJOURN, рассмотрим пример для SQL базы:
3.3.2.5. Пример 5
Получение списка документов родителей по подчиненному документу (получение только общих реквизитов с отборами и системных реквизитов).
где ‘ 6C3RK ‘ – ID документа родителя
3.3.2.6. Пример 6
Получение списка подчиненных документов (получение только общих реквизитов с отборами и системных реквизитов).
где @ИдДокРодителя – ID документа родителя (включая тип и вид документа, т.е. 23 символа), получить такой ID можно с помощью метода ЗначениеВСамуюДлиннуюСтрокуБД(ТекДок) класса MetaDataWork компоненты 1С++.
3.3.2.7. Пример 7
3.3.2.8. Пример 8
Получение списка документов, принадлежащих разным компонентам (у которых включен флажок принадлежности к типам учета). Для отбора документов по типам учета применяется унарное умножение поля APPCODE с требуемым значением. Список значений для отбора по типам учета:
Соответственно, если надо выбрать документы, принадлежащие оперативному и бухгалтерскому учету, надо наложить бинарную маску (бинарное умножение) на 000001 и 000100, или же вместе 000101, или же в десятичной системе 5.
3.3.2.9. Пример 9
Получение списка документов по графе отбора.
где соответственно ИДГрафы = 14730, а IDКлиента = ‘B1 4U 2 ‘.
3.4. Регистры
3.4.1. Общее описание подсиcтемы регистров
Физически регистры остатков состоят из двух таблиц: таблица остатков RGххх и таблица движений RAххх. В таблице движений хранятся все движения документов по регистрам. Список документов, которые сделали движения по регистру, можно получить, выбрав записи из таблицы журналов _1SJOURN с условием равенства поля RFxxx 1 (или не равно 0), например (в случае, если идентификатор регистра 16, т.е. таблица движений = RG16, а таблица остатков = RA16), для получения всех документов, сделавших движения по регистру, можно сделать так:
где CLOSED&1=1 – ограничение на выбор записей только проведенных документов. Фактически при корректных записях в базе, это условие лишнее, но при каких-то «глюках» таким условием можно «отловить» непроведенные документы с существующими движениями (к сожалению, такое может встречаться).
А вот условие APPCODE&1=1 означает отобрать документы, принадлежащие оперативному учету. Подробнее о полях таблицы _1SJOURN см. выше.
Рассмотрим более подробно, как хранятся данные в таблицах RG и RA.
3.4.2. Рассмотрим примеры
Рассмотрим получение остатков и оборотов по регистру остатков.
PERIOD | SP20 | SP22 | SP21 |
---|---|---|---|
2005-02-01 00:00:00.000 | ‘ AA ‘ | ‘ 1A ‘ | 35.00 |
2005-03-01 00:00:00.000 | ‘ AA ‘ | ‘ 1A ‘ | 20.00 |
Исходная таблица движений (RA):
IDDOC | LINENO_ | ACTNO | DEBKRED | IDOCDEF | DATE_TIME_IDDOC | SP20 | SP22 | SP21 |
---|---|---|---|---|---|---|---|---|
1 | 0 | 1 | 0 | 12 | ‘200502157579C0 1 ‘ | ‘ AA ‘ | ‘ 1A ‘ | 10.00 |
2 | 0 | 1 | 0 | 12 | ‘20050215759EHS 2 ‘ | ‘ AA ‘ | ‘ 1A ‘ | 10.00 |
6 | 0 | 1 | 0 | 23 | ‘200502157QOSK0 6 ‘ | ‘ AA ‘ | ‘ 1A ‘ | 15.00 |
7 | 0 | 1 | 1 | 23 | ‘200503013KLMO0 7 ‘ | ‘ AA ‘ | ‘ 1A ‘ | 15.00 |
Данное описание строится на регистрах остатков, регистры оборотов будут рассмотрены позже.
При описании таблицы остатков (RG) необходимо отметить важную особенность.
3.4.2.1. Структура и описание полей таблиц регистров
3.4.2.1.1. Таблица RGxxx
Краткое описание: таблица предназначена для хранения итогов по периодам в разрезе по измерениям и по всем ресурсам регистра.
3.4.2.1.2. Таблица RAxxx
Краткое описание: таблица предназначена для хранения движений по регистрам (включая все измерения, ресурсы и реквизиты регистра).
Особое внимание надо уделить полям «TSP». Это поле создается лишь тогда, когда реквизит (измерение, ресурс) имеет неопределенный тип (длина ID кода 23 символа). Опытным путем было установлено, что это поле по умолчанию заполняется пустой строкой (3 пробела).
3.4.2.2. Пример 1
Получение итогов на ТА или на конец периода (месяца в нашем случае).
Поскольку итоги в таблице RG хранятся на ТА или на конец месяца (для нашего примера), то для получения итогов не обходимо лишь указать условие по периоду, на который нам надо получить итоги.
где @PERIODR – переменная типа DateTime, условие по которой служит для получения результата запроса на тот период, который нам необходим.
Например, если надо получить остаток на ТА, при этом ТА = «19.02.2006», то переменной @PERIODR необходимо присвоить значение начала месяца «01.02.2006».
Если необходимо рассчитать остаток на конец января, то переменной необходимо присвоить значение «01.01.2006»:
Нетрудно догадаться, что если необходимо получить остаток на конец января, то надо в качестве условия поставить начало февраля (ведь остаток на конец января есть остаток на начало февраля. Именно так и делает 1С при расчете остатка на конец периода).
Спросите, почему присвоение переменной @PERIODR происходит с помощью функции CONVERT, да и еще дата в таком странном формате? Это все дело привычки (дело в том, что в таблице журналов дата документа в поле DATE_TIME_IDDOC как раз храниться в виде строки ГГГГММДД).
3.4.2.3. Пример 2
Получение сумм прихода и расхода за один месяц (оборотов).
Поскольку обороты хранятся в таблице RA, запрос выполняется только по этой таблице с условием на дату документа, сделавшего движение.
где @PERIODN, @PERIODK – переменные типа Char(8), условия по которых служат для получения результата запроса на тот период, который нам необходим.
В нашем случае @PERIODN = «20060201», @PERIODK = «20060228».
Код для установки переменных:
3.4.2.4. Пример 3
Получение итогов и остатков на произвольную дату.
Поскольку итоги в нашем примере хранятся только на конец месяца или ТА, то необходимо выполнить 2 запроса, первый – для получения итога на начало периода (из примера 1), второй – для получения оборотов (из примера 2).
где @PERIODR – переменная типа DateTime, условие по которой служит для получения результата запроса на период, меньший на 1 от рассчитываемого. В нашем случае для получения остатка на 20.02.2006 этой переменной необходимо присвоить значения начала января, т.е. «01.01.2006» (так как в случае условия на 01.02.2006 получим остаток или на конец февраля, или на точку актуальности):
@PERIODN, @PERIODK – переменные типа Char(8), условия по которым служат для получения результата в запросе за определенный период. Для нашего примера @PERIODN = «20060201», @PERIODK = «20060220»:
Следует отметить, что условие:
или условие предыдущее, но значение переменной устанавливается на дату @PERIODK = «20060221»:
3.4.2.5. Пример 4
Получение итогов и остатков на документ.
Задача аналогична задаче из предыдущего примера, за исключением того, что условие периода не по дату, а по позицию документа.
где @PERIODR – переменная типа DateTime, условие по которой служит для получения результата запроса на период, меньший на 1 от рассчитываемого. В нашем случае для получения остатка на 20.02.2006 этой переменной необходимо присвоить значения начала Января, т.е. «01.01.2006» (так как в случае условия на 01.02.2006 получим остаток или на конец февраля, или на точку актуальности):
где @PERIODN – переменная типа Char(8), условие по которой служит для получения результата в запросе на определенный период. Для нашего примера @PERIODN = «20060201».
где @POZDOK – переменная типа char(23), позиция документа (получаемая методом ПолучитьПозицию()).
Следует отметить, что поле DATE_TIME_IDDOC может быть в таблице движений регистра (в случае установленного флага «Быстрая обработка движения» при конфигурировании настроек регистра), в этом случае связь с таблицей журналов (_1SJOURN) необязательна, и условие:
Может выглядеть вот так:
Т.е. Запрос будет выглядеть так:
3.4.2.6. Пример 5
Получение остатков и оборотов за произвольный период.
3.4.2.7. Пример 6
Пересчет итогов по одному из регистров остатков.
Данный код приведен как пример работы с регистрами.
Оригинал статьи расположен по адресу http://www.metaprog.co.ua/secrprog/.
Перейти на главную страничку сайта (список статей, файлы для скачивания)