Как автоматически раскрасить список контрагентов по дням просрочки в 1С 8.2/8.3 (УТ 10.3)

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

В конфигурациях на обычных формах, таких как 1С:Управление торговлей 10.3, отсутствует встроенный механизм условного оформления динамических списков, который привычен пользователям управляемых форм. Однако задача визуального выделения должников остается крайне актуальной. В данной статье мы разберем, как реализовать автоматическую раскраску строк контрагентов в зависимости от срока просрочки их задолженности, используя механизм дополнительных свойств объектов и регистр сведений ЗначенияСвойствОбъектов.

Постановка задачи и выбор архитектуры

Рассмотрим ситуацию: нам необходимо выделить контрагентов в списке разными цветами. Если просрочка составляет от 3 до 30 дней — красим в один цвет, более 30 дней — в другой. При этом важно предусмотреть «ручной режим»: если менеджер уже покрасил контрагента в особый цвет (например, розовый), автоматика не должна его трогать. Проанализируем, почему запись напрямую в регистр сведений является оптимальным решением для старых конфигураций: расчет просрочки «на лету» в форме списка на несколько тысяч записей приведет к критическим задержкам при открытии формы.

Шаг 1. Расчет просрочки запросом

Прежде всего, нам необходимо получить актуальные данные о задолженности. В УТ 10.3 данные о расчетах хранятся в регистре накопления ВзаиморасчетыСКонтрагентами. Разберем пример запроса, который вычисляет дни просрочки, учитывая допустимое число дней задолженности, указанное в договоре. Рассмотрим структуру вложенного запроса для получения остатков по расчетным документам:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ВложенныйЗапрос.ДоговорКонтрагента.Владелец КАК Контрагент,
    ВЫБОР
        КОГДА &ДатаОтчета > ВложенныйЗапрос.ДатаОплаты
            ТОГДА РАЗНОСТЬДАТ(ВложенныйЗапрос.ДатаОплаты, &ДатаОтчета, ДЕНЬ)
        ИНАЧЕ 0
    КОНЕЦ КАК ПросроченоНа
ИЗ
    (ВЫБРАТЬ
        Остатки.ДоговорКонтрагента КАК ДоговорКонтрагента,
        ДОБАВИТЬКДАТЕ(ОсновнаяТаблица.Период, ДЕНЬ, 
            ЕСТЬNULL(ОсновнаяТаблица.ДоговорКонтрагента.ДопустимоеЧислоДнейЗадолженности, 0)) КАК ДатаОплаты
    ИЗ
        РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&ДатаОтчета, ) КАК Остатки
    ) КАК ВложенныйЗапрос

Проанализируем важный момент: использование функции ЕСТЬNULL. В запросах 1С при левом соединении таблиц (например, справочника договоров) могут возникать пустые значения NULL. Если мы попытаемся выполнить математическую операцию с таким значением, система выдаст ошибку. Поэтому всегда проверяем числовые реквизиты: ЕСТЬNULL(ДопустимоеЧислоДнейЗадолженности, 0).

Шаг 2. Работа с регистром сведений ЗначенияСвойствОбъектов

Для хранения цвета мы будем использовать типовой регистр ЗначенияСвойствОбъектов. Выясним причину, по которой не стоит использовать ПолучитьОбъект() и Записать() для самого контрагента: это лишняя нагрузка на базу данных и блокировки таблиц. Нам достаточно работать только с менеджером записи регистра. Рассмотрим правильный алгоритм обновления записи:


ВидСвойства = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Цвет в подборе");
ЦветИсключение = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию("Розовый");

Запись = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
Запись.Объект = ВыбранныйКонтрагент;
Запись.Свойство = ВидСвойства;
Запись.Прочитать(); // Ищем существующую запись в базе

Если Запись.Выбран() И Запись.Значение = ЦветИсключение Тогда
    // Если пользователь установил цвет вручную, пропускаем контрагента
    Продолжить;
Иначе
    Запись.Объект = ВыбранныйКонтрагент;
    Запись.Свойство = ВидСвойства;
    Запись.Значение = ВычисленныйЦвет; 
    Запись.Записать(); // Перезаписываем или создаем новую запись
КонецЕсли;

Обратите внимание на использование метода Прочитать(). Он заполняет свойства менеджера записи данными из БД. Только после этого мы можем проверить условие Запись.Значение = ЦветИсключение.

Шаг 3. Массовое обновление через НаборЗаписей

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


Набор = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей();
Набор.Отбор.Свойство.Установить(ВидСвойства);
// Предварительно выгружаем результат запроса в таблицу значений ТЗРезультат
Набор.Загрузить(ТЗРезультат); 
Набор.Записать(Истина); // Замещаем старые значения новыми

Важный нюанс: при использовании Набор.Записать(Истина) с установленным отбором по свойству «Цвет», система сначала удалит все старые автоматические раскраски для этого свойства и запишет новые. Это отличный способ «очистить» цвета у тех, кто погасил долг и больше не попадает в выборку запроса.

Шаг 4. Решение проблемы с NULL и группировками

Рассмотрим подробнее ошибку «Преобразование значения к типу Число не может быть выполнено». Она часто возникает при обходе результатов запроса с итогами. Если в запросе используются ИТОГИ ПО ОБЩИЕ, то в первой строке выборки (общий итог) многие поля будут содержать NULL. Выясним, как правильно обходить такую выборку:

  1. Всегда используйте ОбходРезультатаЗапроса.ПоГруппировкам, если в запросе есть итоги.
  2. Проверяйте тип значения перед вычитанием: Если ТипЗнч(Строка.Значение) <> Тип("Число") Тогда Продолжить; КонецЕсли;.
  3. Используйте конструкцию ВЫБОР КОГДА Поле ЕСТЬ NULL ТОГДА 0 ИНАЧЕ Поле КОНЕЦ непосредственно в тексте запроса.

Шаг 5. Автоматизация процесса

Чтобы менеджеры видели актуальные цвета, обработку необходимо запускать регламентно. В УТ 10.3 для этого можно создать регламентное задание, которое будет выполняться каждую ночь. Проанализируем алгоритм:

Во-первых, задание собирает всех дебиторов. Во-вторых, определяет нужные цвета согласно бизнес-логике. В-третьих, обновляет регистр сведений. Чтобы изменения отобразились в форме списка без перезапуска программы, можно использовать метод ОповеститьОбИзменении(Тип("СправочникСсылка.Контрагенты")), который заставит открытые формы перечитать данные из регистра.

Резюме

Мы проанализировали комплексный подход к визуализации данных в 1С:УТ 10.3. Использование регистра сведений ЗначенияСвойствОбъектов позволяет хранить результаты тяжелых расчетов, не нагружая клиентское приложение при каждой отрисовке списка. Помните о важности сохранения ручных правок пользователей и всегда оптимизируйте запросы, избегая избыточного получения объектов через ПолучитьОбъект().

← На главную