Общие реквизиты. Опыт использования и жестокий косяк
Потребовалось объединять данные двух независимых баз в одной. Решение лежащее на поверхности — использование общего реквизита в режиме "Разделять" и использование разделяемых данных "Независимо и совместно". Для создания базы использовалась "Библиотека стандартных подсистем", где уже присутствовал общий реквизит рекомендованного 1С типа "Число". К чему это привело будет ниже.
- Описание
- Подробнее
Описание
Платформа 8.2.18.96
Механизм общих реквизитов расписывать не буду, т.к. это сделано неоднократно. Просто напомню, что при включении в состав общего реквизита какого-либо объекта в его таблице на сервере добавляется поле.
Итак, общий реквизит «ОбластьДанных» автоматически распространялся на все объекты метаданных.
Добавил свой реквизит «ИсточникДанных» — тип СправочникСсылка (о рекомендациях 1С на тот момент не знал), в файловой базе доделал всё, что надо, проверил, работает «замечательно» (почему в кавычках напишу в самом низу). Перенес в рабочую серверную базу и оказалось, что при установке параметров сеанса все разделенные данные «пропадают».
Оказалось, при наличии двух общих реквизитов у объекта в его таблице на сервере добавляется вычисляемое поле «_DataSeparationHash» формула:
(CONVERT([int],substring(hashbytes('MD5',CONVERT([varchar],[_Fld164],0)),(1),(4)),0)^checksum([_Fld2260RRef]))где [_Fld164] — это общий реквизит «ОбластьДанных» типа число(7,0)
а [_Fld2260RRef] — это мой общий реквизит.
Устанавливаем параметры сеанса (только мой общий реквизит, «ОбластьДанных» не используем), выполняем запрос «Первые 333» к справочнику без условий, который должен вернуть 333 строки, но запрос оказывается пустым. На сервере видим:
SELECT TOP 333
T1._IDRRef,
T1._Version,
T1._Marked,
T1._IsMetadata,
T1._ParentIDRRef,
CASE WHEN (T1._Folder = 0x00) THEN 0x01 ELSE 0x00 END,
T1._Code,
T1._Description,
T1._Fld2088,
T1._Fld2089RRef,
T1._Fld2136RRef,
T1._Fld2154RRef,
T1._Fld2157RRef,
T1._Fld2260RRef
FROM _Reference2046 T1 WITH(NOLOCK)
WHERE (T1._Fld164 = 0.0
AND T1._Fld2260RRef = ?
AND T1._DataSeparationHash = CAST(SUBSTRING(HASHBYTES('MD5',CONVERT(VARCHAR,0.0)),1,4) AS INT) ^ CHECKSUM(?))
p_0: 0x82F80025902DD79811E2CA0032A150E6
p_1: 0x82F80025902DD79811E2CA0032A150E6Итак, платформой, несмотря на отключенное использование разделения по реквизиту «ОбластьДанных», накладывается условие по полю «_Fld164″, впрочем, это никак не влияет, проблема оказалась в условии по полю «_DataSeparationHash» CAST(SUBSTRING(HASHBYTES(‘MD5’,CONVERT(VARCHAR,0.0)),1,4) AS INT) ^ CHECKSUM(?))
, тогда как в формуле
CONVERT([int],substring(hashbytes(‘MD5’,CONVERT([varchar],[_Fld164],0)),(1),(4)),0)^checksum([_Fld2260RRef])
Решение — не использовать два общих реквизита у одного объекта.
З.Ы.
Возможно, если использовать общие реквизиты нерекомендованного 1С типа, т.е. не число, то такой «косяк» и не всплывет.
И коротко про документы и их движения (досконально не разбирался, но в объяснение «замечательно» в кавычках).
Включил в состав общего реквизита три документа и один регистр накопления, по которому эти документы делают движения.
В файловой базе можно было «задвоить» движения, сначала провести при выключенном разделении, потом при установленном разделителе.
в серверном варианте возникает ошибка вставки неуникального индекса.
Так что, если пришли к необходимости использования общего реквизита, то придется распроводить документы, устанавливать разделитель и проводить. Или напрямую обновлять таблицы регистров (хотя сам я не решился на такое).
Надеюсь, эта информация кому-нибудь да пригодится.

