При разработке отчетов в системе компоновки данных (СКД) и написании сложных запросов к регистрам накопления часто возникает задача отфильтровать остатки по определенному типу регистратора или документа-основания составного типа. Неправильное указание условий в параметрах виртуальных таблиц приводит к ошибкам несовместимости типов или синтаксическим ошибкам платформы. Разберем по шагам, как корректно составить условие отбора по типу документа и правильно обработать булевы поля в запросе.
Рассмотрим распространенные ошибки, которые возникают при попытке ограничить выборку в виртуальной таблице:
ТИПЗНАЧЕНИЯ с внешним параметром. Попытка передать тип объекта через параметр запроса вида ТИПЗНАЧЕНИЯ(ДокументРезерва) = &ТипСчет вызывает ошибку: «Неверные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов». В языке запросов 1С функция ТИПЗНАЧЕНИЯ не может сравниваться со значением типа ОписаниеТипов или Тип, переданным из кода.Период и Условие. Если пропустить запятую при отсутствии периода, написав Остатки(ДокументРезерва ССЫЛКА ...), платформа интерпретирует условие как первый параметр (дату) и выдает ошибку «Неверные параметры».Поле = &Истина или попытки передать логические литералы как параметры усложняют чтение запроса и нередко приводят к синтаксическим сбоям.Выясним причину корректной работы проверки типа: для полей составного типа в языке запросов платформы 1С предусмотрена специальная конструкция ССЫЛКА. Она транслируется СУБД в эффективное сравнение кодов таблиц и не требует передачи параметров.
Посмотрим на пример правильного вызова виртуальной таблицы с фильтром по типу конкретного документа:
ВЫБРАТЬ
ТоварыВРезервеНаСкладахОстатки.Номенклатура КАК Номенклатура,
ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&Период, ДокументРезерва ССЫЛКА Документ.СчетНаОплатуПокупателю) КАК ТоварыВРезервеНаСкладахОстатки
Если требуется передать условие без явного указания параметра периода, обязательно сохраняем запятую-разделитель:
РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(, ДокументРезерва ССЫЛКА Документ.СчетНаОплатуПокупателю)
Также допустимо использование конструкции с функцией ТИП, однако вариант с ССЫЛКА является более предпочтительным стандартом разработки:
ТИПЗНАЧЕНИЯ(ДокументРезерва) = ТИП(Документ.СчетНаОплатуПокупателю)
Проанализируем ситуацию, когда необходимо отобрать остатки только по тем документам, у которых установлен определенный признак (например, Оплачен = ИСТИНА). Обращаться через точку к реквизитам составного поля непосредственно в параметрах виртуальной таблицы нельзя. Для этого выполняется соединение с таблицей документа.
При проверке значений логического типа (Булево) в секции ГДЕ не требуется сравнивать поле со значением ИСТИНА или использовать параметры запроса. Достаточно указать само поле (для проверки на истинность) или оператор НЕ (для проверки на ложь):
ГДЕ СчетНаОплатуПокупателю.ОплаченГДЕ НЕ СчетНаОплатуПокупателю.ОплаченРазберем важную особенность: при соединении остатков с документами по одной позиции номенклатуры может существовать несколько оплаченных счетов. Чтобы исключить задвоение строк номенклатуры в основном отчете, результат выборки обязательно нужно сгруппировать по номенклатуре с вычислением агрегатной суммы остатка.
ВЫБРАТЬ
ТоварыВРезервеНаСкладахОстатки.Номенклатура КАК Номенклатура,
СУММА(ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток) КАК КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&Период, ДокументРезерва ССЫЛКА Документ.СчетНаОплатуПокупателю) КАК ТоварыВРезервеНаСкладахОстатки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю
ПО ТоварыВРезервеНаСкладахОстатки.ДокументРезерва = СчетНаОплатуПокупателю.Ссылка
ГДЕ
СчетНаОплатуПокупателю.Оплачен
СГРУППИРОВАТЬ ПО
ТоварыВРезервеНаСкладахОстатки.Номенклатура
Использование оператора ССЫЛКА в параметрах виртуальной таблицы позволяет СУБД отсечь ненужные записи регистра еще до выполнения соединения с таблицей документов, что обеспечивает высокую производительность отчета.