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

Программист 1С v8.3 (Управляемые формы) Управленческий учет
← На главную

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

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

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

  1. Проблема последнего значения: В цикле обхода выборки значение суммы платежа постоянно перезаписывается, и в итоге в переменную Платежка попадает сумма только последнего найденного документа.
  2. Статичность данных: Условное оформление, заданное программно при создании формы, не будет динамически обновляться для каждой строки списка на основе данных этой строки, если оно привязано к фиксированным значениям.
  3. Производительность: Если в базе тысячи документов, выполнение сложного запроса при открытии формы и попытка раскрасить каждую строку вручную приведет к значительным задержкам.

Проанализируем правильный подход: использование Динамического списка с произвольным запросом. Это стандартный и наиболее производительный метод работы с формами списков в 1С 8.3.

Способ 1. Реализация через запрос в Динамическом списке

Для того чтобы в списке счетов появилась информация об оплате, нам нужно изменить основной запрос динамического списка (свойство Список на форме). Мы должны «присоединить» суммы оплат к основной таблице счетов. Посмотрим на пример запроса:


ВЫБРАТЬ
    ДокументСчет.Ссылка КАК Ссылка,
    ДокументСчет.Дата КАК Дата,
    ДокументСчет.Номер КАК Номер,
    ДокументСчет.СуммаДокумента КАК СуммаСчета,
    ЕСТЬNULL(ВложенныйЗапрос.СуммаОплаты, 0) КАК СуммаОплаты,
    ВЫБОР
        КОГДА ЕСТЬNULL(ВложенныйЗапрос.СуммаОплаты, 0) >= ДокументСчет.СуммаДокумента ТОГДА 1
        КОГДА ЕСТЬNULL(ВложенныйЗапрос.СуммаОплаты, 0) > 0 ТОГДА 2
        ИНАЧЕ 0
    КОНЕЦ КАК СтатусОплаты
ИЗ
    Документ.СчетНаОплату КАК ДокументСчет
    ЛЕВОЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            Расшифровка.СчетНаОплату КАК СчетНаОплату,
            СУММА(Расшифровка.Сумма) КАК СуммаОплаты
        ИЗ
            Документ.ПлатежныйОрдерПоступлениеДенежныхСредств.РасшифровкаПлатежа КАК Расшифровка
        ГДЕ
            НЕ Расшифровка.Ссылка.ПометкаУдаления
            И Расшифровка.Ссылка.Проведен
        СГРУППИРОВАТЬ ПО
            Расшифровка.СчетНаОплату
    ) КАК ВложенныйЗапрос
    ПО ДокументСчет.Ссылка = ВложенныйЗапрос.СчетНаОплату

Разберем, что мы сделали в этом запросе. Мы использовали ЛЕВОЕ СОЕДИНЕНИЕ со вложенным запросом. Вложенный запрос суммирует все оплаты из табличной части РасшифровкаПлатежа платежных ордеров, сгруппировав их по полю СчетНаОплату. Обратите внимание на использование ЕСТЬNULL: если оплат по счету нет, система вернет 0 вместо пустого значения, что критично для корректного сравнения сумм.

Способ 2. Использование регистров накопления (Оптимальный)

Если ваша конфигурация подразумевает ведение взаиморасчетов в разрезе документов (например, как в УТ 11 или ERP), то данные лучше брать не из самих документов оплаты, а из регистров накопления, таких как РасчетыСКлиентами или специализированных регистров по счетам. Выясним причину, почему это лучше: регистры уже содержат готовые итоги, и запрос к ним отработает в разы быстрее, чем сканирование табличных частей всех платежных документов.

Пример обращения к регистру в запросе списка:


ВЫБРАТЬ
    Счет.Ссылка,
    Счет.СуммаДокумента,
    ЕСТЬNULL(Остатки.СуммаОплатыОстаток, 0) КАК Оплачено
ИЗ
    Документ.СчетНаОплату КАК Счет
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОплатаСчетов.Остатки( , СчетНаОплату = &Ссылка) КАК Остатки
    ПО Счет.Ссылка = Остатки.СчетНаОплату

Настройка Условного оформления формы

После того как мы получили поле СуммаОплаты или СтатусОплаты в динамическом списке, необходимо настроить визуализацию. Выполним это по шагам:

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

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

Нюансы производительности и валютного учета

Проанализируем ситуацию с валютами. Если Счет на оплату выписан в долларах, а Платежный ордер пришел в рублях, прямое сравнение реквизитов СуммаДокумента будет неверным. В таком случае в запросе необходимо использовать суммы в валюте взаиморасчетов или приводить их к одной валюте через курсы на дату документа.

Также стоит помнить об индексации. Чтобы запрос динамического списка не тормозил систему, поле СчетНаОплату в табличной части платежного документа должно быть индексировано. Это позволит SQL-серверу мгновенно находить связи между документами.

Таким образом, мы рассмотрели комплексный подход к решению задачи: от архитектуры запроса до визуального представления данных пользователю. Правильное использование динамических списков и условного оформления — залог стабильной и быстрой работы интерфейса 1С.

← На главную