пятница, 26 февраля 2010 г.

Особенности табличный частей в 1С

В любой табличной части документа или любого другого объекта метаданных присутствует как минимум 2 реквизита:

  • Ссылка (*_IDRRef);
  • Номер строки (_LineNo*);
Однако в структуре хранения таблицы мы можем наблюдать еще одно поле _KeyField - ключ записи табличной части в рамках одного объекта базы данных (полное описание структуры хранения данных 1С 8 можно посмотреть здесь).
Поля *_IDRRef и _KeyField образуют уникальный кластерный (упорядоченны по индексу, для ускорения чтения и записи группы ) индекс.  Наиболее интересно поведение поля _KeyField .

В "большинстве" случаев   _KeyField = Hex( _LineNo*). Такое равенство справедливо для не изменяемого документа(объекта метаданных).  Как только мы изменим любую строку табличной части(и запишем объект), тогда _KeyField = Hex(Max(_KeyField+1)). Другими словами последней в кластерном индексе любой табличной части будет  последняя измененная строка табличной части
Соответственно при выполнении запроса(без явного упорядочивания)
 ВЫБРАТЬ
    ОприходованиеТоваровТовары.Ссылка,
    ОприходованиеТоваровТовары.НомерСтроки
ИЗ
    Документ.ОприходованиеТоваров.Товары КАК ОприходованиеТоваровТовары
 к табличной части возможны вот такие результаты:
Ссылка НомерСтроки
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 2
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 3
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 4
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 6
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 7
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 8
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 9
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 10
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 11
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 1
Оприходование товаров СИ-00000034 от 30.09.2009 23:59:59 5
То есть сначала была изменена 1 строка и затем 5. 

Теперь та же самая выборка но в "терминах" СУБД 
SELECT
_Document354_VT7215_Q_000_T_001._Document354_IDRRef AS _IDRRef,
_Document354_VT7215_Q_000_T_001._LineNo7216 AS _LineNo,
_Document354_VT7215_Q_000_T_001._KeyField AS _KeyField
FROM
_Document354_VT7215 _Document354_VT7215_Q_000_T_001 WITH(NOLOCK)
LEFT OUTER JOIN _Document354 _Document354_1 WITH(NOLOCK)
ON _Document354_VT7215_Q_000_T_001._Document354_IDRRef = _Document354_1._IDRRef

_IDRRef _LineNo _KeyField
0xB1A8003048925A7E11DEB0C5778F5875 2 0x00000002
0xB1A8003048925A7E11DEB0C5778F5875 3 0x00000003
0xB1A8003048925A7E11DEB0C5778F5875 4 0x00000004
0xB1A8003048925A7E11DEB0C5778F5875 6 0x00000006
0xB1A8003048925A7E11DEB0C5778F5875 7 0x00000007
0xB1A8003048925A7E11DEB0C5778F5875 8 0x00000008
0xB1A8003048925A7E11DEB0C5778F5875 9 0x00000009
0xB1A8003048925A7E11DEB0C5778F5875 10 0x0000000A
0xB1A8003048925A7E11DEB0C5778F5875 11 0x0000000B
0xB1A8003048925A7E11DEB0C5778F5875 1 0x0000000C
0xB1A8003048925A7E11DEB0C5778F5875 5 0x0000000D

Вот на "пустом месте", образовалась система регистрации изменений табличной части.