Как программно заполнить таблицу при открытии формы и реализовать индикатор загрузки

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

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

Вариант 1. Использование серверного события ПриСозданииНаСервере

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

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

Разберем пример кода для заполнения таблицы значений, которая является реквизитом формы:


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

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

Вариант 2. Оптимизация заполнения через ЗначениеВРеквизитФормы

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

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


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

Такой подход позволяет значительно ускорить работу с большими массивами данных за счет минимизации обращений к интерфейсным механизмам платформы в процессе заполнения.

Вариант 3. «Ленивая» загрузка через обработчик ожидания

Бывают ситуации, когда форма должна открыться мгновенно, чтобы пользователь увидел интерфейс, даже если данные еще подгружаются. Если мы напишем код в ПриСозданииНаСервере, пользователь будет видеть «песочные часы» до тех пор, пока сервер не закончит работу. Чтобы этого избежать, применим метод «ленивой» загрузки.

Разберем по шагам, как это реализовать:

  1. В событии ПриОткрытии на клиенте подключаем обработчик ожидания с минимальной задержкой.
  2. Форма отображается пользователю.
  3. Через 0.1 секунды срабатывает процедура, которая идет на сервер и заполняет таблицу.

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем однократный обработчик через 0.1 сек
    ПодключитьОбработчикОжидания("ВыполнитьОтложенноеЗаполнение", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьОтложенноеЗаполнение()
    ЗаполнитьДанныеНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДанныеНаСервере()
    // Здесь логика заполнения таблицы
КонецПроцедуры

Этот метод создает иллюзию мгновенной работы программы, так как форма уже доступна для осмотра, пока данные «доезжают» с сервера.

Вариант 4. Длительные операции и фоновые задания

Если заполнение таблицы занимает более 2–3 секунд, необходимо использовать фоновые задания. Это позволит не блокировать интерфейс 1С и вывести пользователю индикатор выполнения (прогресс-бар). В современных конфигурациях на базе БСП (Библиотека стандартных подсистем) для этого предусмотрена подсистема «Длительные операции».

Посмотрим на пример логики с использованием фонового задания:

  1. В процедуре ПриОткрытии запускается фоновое задание на сервере.
  2. Идентификатор задания сохраняется в реквизит формы.
  3. Подключается обработчик ожидания, который каждые 1–2 секунды опрашивает статус задания.
  4. По завершении данные из временного хранилища переносятся в таблицу формы.

Пример кода запуска фонового задания (упрощенно):


&НаСервере
Функция ЗапуститьЗаполнениеНаСервере()
    ПараметрыЗадания = Новый Структура("Параметр1", Значение1);
    Результат = ДлительныеОперации.ВыполнитьВФоне("ИмяВашегоМодуля.ЗаполнитьТаблицу", ПараметрыЗадания);
    Возврат Результат;
КонецФункции

Проанализируем преимущества: пользователь может даже свернуть окно или начать работать в другой вкладке, пока данные готовятся. Для визуализации прогресса можно использовать элемент формы вида Индикатор, связав его с числовым реквизитом, который обновляется в обработчике ожидания на основе данных из фонового процесса.

Вариант 5. Визуализация состояния загрузки

Когда мы выполняем длительную загрузку, важно информировать пользователя о том, что система не «зависла». Рассмотрим два способа визуализации:

  1. Метод ПоказатьСостояние(): Это небольшое всплывающее окно в нижней части экрана. Оно не блокирует действия, но дает понять, что идет процесс.
    
    ПоказатьСостояние("Загрузка данных...", , , БиблиотекаКартинок.ДлительнаяОперация48);
    
  2. Управление доступностью: Хорошим тоном считается на время загрузки устанавливать свойство ЭтаФорма.Доступность = Ложь или блокировать только конкретную таблицу и кнопки действий. Это предотвратит попытки пользователя изменить данные, которые еще не полностью загружены.

Вариант 6. Динамические списки как альтернатива таблицам

Если ваша цель — просто показать данные из базы (например, список документов или справочников) с возможностью поиска и отбора, проанализируем, не лучше ли использовать ДинамическийСписок вместо ТаблицыЗначений.

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

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

Подводя итог, выбор метода зависит от объема данных. Для простых задач идеально подходит ПриСозданииНаСервере. Для более тяжелых — сочетание ПодключитьОбработчикОжидания и фоновых заданий с использованием БСП. Главное — всегда помнить о комфорте пользователя и не оставлять его перед «замершим» экраном без объяснения причин.

← На главную