Как реализовать динамическое обновление и оптимизировать работу с большими списками в обычных формах 1С?

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

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

Проблема использования Табличной Части для больших выборок

Рассмотрим стандартную ситуацию: разработчик создает обработку, где в объекте ТабличнаяЧасть хранятся данные, полученные тяжелым запросом. Основной минус этого подхода в том, что 1С вынуждена передать весь объем данных с сервера на клиент. Даже если после фильтрации остается 500 строк, первичная выборка из миллионов записей с расчетом процентов «на лету» создает колоссальную нагрузку на память и процессор.

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

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

Переход к Динамическому списку на Обычных Формах

Динамический список (ДС) в Обычных Формах (ОФ) работает иначе, чем в Управляемых. Он жестко привязан к метаданным (например, ДокументСписок.События). Чтобы реализовать сложную логику отбора, которую описывает автор темы, нам нужно использовать механизм отборов и событие ПриПолученииДанных.

Выясним, как сделать список «умным». Вместо того чтобы загружать все данные в ТЧ, мы используем табличное поле с типом значения ДокументСписок. Рассмотрим пошагово, как реализовать расчетные поля (например, проценты исправности) и раскраску строк без потери производительности.

Использование события ПриПолученииДанных для отрисовки статусов

Это ключевой метод для Обычных Форм. Событие ПриПолученииДанных вызывается только для тех строк, которые в данный момент видны на экране оператора (обычно это 30–40 записей). Это позволяет нам не рассчитывать данные для миллиона документов сразу.

Разберем пример кода, который позволяет подтягивать статусы из Регистров Сведений (РС) и раскрашивать строки:


Процедура СписокПриПолученииДанных(Элемент, ОформленияСтрок)
    // Создаем массив ссылок текущих видимых строк
    МассивСсылок = Новый Массив;
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        МассивСсылок.Добавить(ОформлениеСтроки.ДанныеСтроки.Ссылка);
    КонецЦикла;

    // Одним запросом получаем данные из РС для этих ссылок
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   СтатусыСобытий.Ссылка,
        |   СтатусыСобытий.Статус,
        |   СтатусыСобытий.Цвет
        |ИЗ
        |   РегистрСведений.СтатусыСобытий КАК СтатусыСобытий
        |ГДЕ
        |   СтатусыСобытий.Ссылка В(&МассивСсылок)";
    
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    РезультатЗапроса = Запрос.Выполнить().Выгрузить();

    // Оформляем строки на основе полученных данных
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        СтрокаДанных = РезультатЗапроса.Найти(ОформлениеСтроки.ДанныеСтроки.Ссылка, "Ссылка");
        Если СтрокаДанных <> Неопределено Тогда
            Если СтрокаДанных.Статус = "Завершено" Тогда
                ОформлениеСтроки.ЦветФона = ЦветаСтиля.ЗеленыйТекст;
            ИначеЕсли СтрокаДанных.Статус = "ВРаботе" Тогда
                ОформлениеСтроки.ЦветФона = Новый Цвет(255, 165, 0); // Оранжевый
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Используя этот подход, мы получаем мгновенный скроллинг. Система делает микро-запросы к базе данных только для видимой области, что практически незаметно для пользователя.

Оптимизация архитектуры: хранение расчетных данных

Как отмечают участники обсуждения, расчет «процента исправных плательщиков» по миллиону документов в момент открытия формы — это архитектурная ошибка. Для того чтобы динамический список работал быстро, сложные показатели должны быть предварительно рассчитаны.

Рекомендуем следующий алгоритм:

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

Таким образом, когда оператор открывает обработку, система не пересчитывает миллионы документов Событие, а просто читает готовое число из одной строки регистра. Это сокращает время ожидания с 40 секунд до долей секунды.

Эмуляция динамического списка через ПостроительОтчета

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

Посмотрим на преимущества этого метода:

Фоновое выполнение тяжелых операций

Если расчет данных всё же невозможно выполнить заранее, проанализируем ситуацию с использованием фоновых заданий. Чтобы форма «не висла», запустим расчет на сервере:

1. Запуск задания: При открытии формы или нажатии кнопки «Обновить» вызывается процедура, запускающая фоновое задание через ФоновыеЗадания.Выполнить().

2. Обработчик ожидания: На форме включается ПодключитьОбработчикОжидания, который каждые 2–3 секунды проверяет состояние задания.

3. Получение результата: Как только задание завершено, данные загружаются в список, а пользователь в это время может продолжать работу с другими элементами формы.

Заключение

Подведем итог. Чтобы избавиться от «тормозов» при работе с большими списками на Обычных Формах, необходимо отказаться от парадигмы «загрузить всё в таблицу значений». Использование динамических списков в сочетании с событием ПриПолученииДанных и предварительным расчетом тяжелых показателей в Регистрах Сведений позволяет превратить громоздкую обработку в быстрый и современный инструмент. Помните, что комфорт пользователя напрямую зависит от того, насколько эффективно вы используете ресурсы сервера и механизмы ленивой загрузки данных.

← На главную