Никакого ноухау здесь изложено не будет. Просто опубликую методику, которую я недавно для себя придумал.
Итак, есть регистр накопления
РН с измерением
Документ регистрации, составного типа, в который входят несколько документов: Документ1, Документ2, Документ3. Так же есть какие-то документы, в табличных частях которых есть одноименный реквизит такого же типа. При проведении документов требуется выбрать строки из табличной части, в которых заполнен
Документ регистрации и сделать движения по регистру РН
(на самом деле пример не реальный, но суть, надеюсь, ясна).
Если у реквизита документа имеется составной тип, то значение реквизита может принимать 2 и более значений, в нашем случае значений будет 4:
- Неопределено
- ДокументСсылка.Документ1
- ДокументСсылка.Документ2
- ДокументСсылка.Документ3
Как в запросе выбрать строки из табличной части с заполненными документами регистрации?
Запрос.Текст = "
|ВЫБРАТЬ
| *
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| НЕ (РеализацияТоваровУслугТовары.ДокументРегистрации = НЕОПРЕДЕЛЕНО ИЛИ
| РеализацияТоваровУслугТовары.ДокументРегистрации = ЗНАЧЕНИЕ(Документ.Документ1.ПустаяСсылка) ИЛИ
| РеализацияТоваровУслугТовары.ДокументРегистрации = ЗНАЧЕНИЕ(Документ.Документ2.ПустаяСсылка) ИЛИ
| РеализацияТоваровУслугТовары.ДокументРегистрации = ЗНАЧЕНИЕ(Документ.Документ3.ПустаяСсылка)
| )
|";
Сейчас все хорошо. Но проблемы начинаются тогда, когда в этот составной тип добавляется ещё что-то, потому что после этого нам надо ВО ВСЕХ запросах добавить строку, в которой указать условие на пустую ссылку ново добавленного типа, т.е. первоначальный запрос примет вид:
Запрос.Текст = "
|ВЫБРАТЬ
| *
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| НЕ (РеализацияТоваровУслугТовары.ДокументРегистрации = НЕОПРЕДЕЛЕНО ИЛИ
| РеализацияТоваровУслугТовары.ДокументРегистрации = ЗНАЧЕНИЕ(Документ.Документ1.ПустаяСсылка) ИЛИ
| РеализацияТоваровУслугТовары.ДокументРегистрации = ЗНАЧЕНИЕ(Документ.Документ2.ПустаяСсылка) ИЛИ
| РеализацияТоваровУслугТовары.ДокументРегистрации = ЗНАЧЕНИЕ(Документ.Документ3.ПустаяСсылка) ИЛИ
| РеализацияТоваровУслугТовары.ДокументРегистрации = ЗНАЧЕНИЕ(Документ.Документ4.ПустаяСсылка)
| )
|";
И так при каждой модификации нашего составного типа.
В моем случае все допустимые типы 100% будут присутствовать в измерении регистра, о котором я говорил в самом начале. Таким образом, в модуле менеджера регистра я определил функцию, которая мне возвращает массив пустых значений для данного типа:
Функция ПолучитьПустыеДокументыРегистрации() Экспорт
Массив = Новый Массив;
Массив.Добавить(Неопределено);
Тип = Метаданные.РегистрыНакопления.РН.Измерения.ДокументРегистрации.Тип;
Для Каждого ДокументМД ИЗ Метаданные.Документы Цикл
ПустаяСсылка = Документы[ДокументМД.Имя].ПустаяСсылка();
Если Тип.ПривестиЗначение(ПустаяСсылка) <> Неопределено Тогда
Массив.Добавить(Документы[ДокументМД.Имя].ПустаяСсылка());
КонецЕсли;
КонецЦикла;
Возврат Массив;
КонецФункции
После этого изначальный запрос можно привести к такому виду:
Запрос.УстановитьПараметр("МассивПустыхДокументов", РегистрыНакопления.РН.ПолучитьПустыеДокументыРегистрации());
Запрос.Текст = "
|ВЫБРАТЬ
| *
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| НЕ РеализацияТоваровУслугТовары.ДокументРегистрации В (&МассивПустыхДокументов)
|";
Теперь при изменении составного типа данных не надо нигде ничего менять. Только добавляем нужный тип в перечень типов в регистре - и всё.