Как вывести номер последнего платежного поручения в динамическом списке счета на оплату в 1С

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При доработке форм списков документов в конфигурации 1С:Бухгалтерия 8.3 часто возникает необходимость отображать данные подчиненных документов. Например, в форме списка Документ.СчетНаОплатуПоставщика требуется вывести номер оформленного платежного поручения. Однако на основании одного счета может быть создано несколько документов Документ.ПлатежноеПоручение, и в список необходимо выводить номер именно последнего из них.

В этой статье мы разберем причины возникновения ошибок при прямом левом соединении, проанализируем варианты запросов для динамического списка и рассмотрим наиболее эффективные способы решения задачи.

Анализ проблемы: почему дублируются строки или выводится один номер

Рассмотрим, с какими трудностями сталкивается разработчик при написании произвольного запроса динамического списка:

  1. Прямое левое соединение с подчиненной таблицей. Если выполнить ЛЕВОЕ СОЕДИНЕНИЕ таблицы счетов с таблицей платежных поручений по полю ДокументОснование, то при наличии нескольких платежек на один счет результирующая выборка раздвоится. Флаг БЕЗ ДУБЛЕЙ (или РАЗЛИЧНЫЕ) в данном случае не поможет, так как строки отличаются номерами платежных поручений.
  2. Использование конструкции ВЫБРАТЬ ПЕРВЫЕ 1 во вложенном запросе. Если написать вложенный запрос с ВЫБРАТЬ ПЕРВЫЕ 1 без связи с конкретной записью родительского документа, СУБД вернет одну единственную запись для всей таблицы. В результате у всех счетов в списке отобразится номер одного и того же платежного поручения.

Решение с использованием вложенного запроса и группировки

Для корректного сворачивания подчиненных документов по каждому счету применим вложенный запрос с группировкой по полю ДокументОснование. Разберем пример вложенного запроса, примененного автором темы:


ВЫБРАТЬ
    МАКСИМУМ(ЕСТЬNULL(ПлатежноеПоручение.Номер, 0)) КАК НомерПП,
    ПлатежноеПоручение.ДокументОснование.Ссылка КАК ДокументОснованиеСсылка,
    МАКСИМУМ(ПлатежноеПоручение.Дата) КАК Дата
ИЗ
    Документ.ПлатежноеПоручение КАК ПлатежноеПоручение
СГРУППИРОВАТЬ ПО
    ПлатежноеПоручение.ДокументОснование.Ссылка

Посмотрим, как встроить данную выборку в основной запрос динамического списка формы СчетНаОплатуПоставщика:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    ДокументСчетНаОплатуПоставщика.Ссылка КАК Ссылка,
    ДокументСчетНаОплатуПоставщика.ПометкаУдаления КАК ПометкаУдаления,
    ДокументСчетНаОплатуПоставщика.Номер КАК Номер,
    ДокументСчетНаОплатуПоставщика.Дата КАК Дата,
    ДокументСчетНаОплатуПоставщика.Проведен КАК Проведен,
    ДокументСчетНаОплатуПоставщика.Организация КАК Организация,
    ДокументСчетНаОплатуПоставщика.Контрагент КАК Контрагент,
    ДокументСчетНаОплатуПоставщика.ДоговорКонтрагента КАК ДоговорКонтрагента,
    ДокументСчетНаОплатуПоставщика.Ответственный КАК Ответственный,
    ДокументСчетНаОплатуПоставщика.СуммаДокумента КАК СуммаДокумента,
    ВложенныйЗапрос.НомерПП КАК НомерПП
ИЗ
    Документ.СчетНаОплатуПоставщика КАК ДокументСчетНаОплатуПоставщика
    ЛЕВОЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            ПлатежноеПоручение.ДокументОснование КАК ДокументОснование,
            МАКСИМУМ(ПлатежноеПоручение.Номер) КАК НомерПП
        ИЗ
            Документ.ПлатежноеПоручение КАК ПлатежноеПоручение
        ГДЕ
            НЕ ПлатежноеПоручение.ПометкаУдаления
        СГРУППИРОВАТЬ ПО
            ПлатежноеПоручение.ДокументОснование
    ) КАК ВложенныйЗапрос
    ПО ДокументСчетНаОплатуПоставщика.Ссылка = ВложенныйЗапрос.ДокументОснование

Важные нюансы и корректная логика получения номера по максимальной дате

Проанализируем тонкости работы агрегатных функций. Использование конструкции МАКСИМУМ(Номер) выполняет алфавитно-цифровую сортировку номеров. Если по счету были выписаны документы №0003 от 01.01 и №0001 от 10.01, функция вернет №0003, хотя хронологически последним является №0001.

Чтобы гарантированно получить номер документа с наибольшей датой, соединение следует выполнять в два этапа:

  1. Во вложенном запросе находим максимальную дату платежного поручения для каждого документа-основания через МАКСИМУМ(Дата).
  2. Вторым левым соединением связываем полученный результат с таблицей Документ.ПлатежноеПоручение одновременно по полям ДокументОснование и Дата.

Альтернативные варианты и производительность динамических списков

Выполняя доработку запросов динамического списка, важно учитывать особенности платформы 1С:

Если динамический список начинает работать медленно, разберем альтернативные подходы к решению:

  1. Обработчик ПриПолученииДанныхНаСервере: Основной запрос динамического списка остается стандартным. В форме создается несвязанная колонка, а в серверном событии ПриПолученииДанныхНаСервере вычисляются номера платежных поручений точечным запросом только для тех ссылок, которые выведены на экран в текущей порции данных.
  2. Использование регистра сведений (кэширование): Создается регистр сведений, обновляемый при проведении платежных поручений. В нем хранится актуальная связь «Счет на оплату — Последний номер ПП». В динамическом списке выполняется простое левое соединение с этим регистром, что обеспечивает максимальное быстродействие за счет индексации.
← На главную