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