Как оптимизировать открытие управляемой формы в 1С и запускать тяжелый код только при переходе на определенную вкладку?

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

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

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

Причина проблемы: Почему ПриСозданииНаСервере — не всегда лучшее место?

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

Решение 1: Использование события ПриСменеСтраницы

Для того чтобы перенести вычисления на момент нажатия вкладки, нам понадобится событие элемента формы с видом Страницы. Рассмотрим алгоритм реализации по шагам:

  1. Найдите на форме элемент, объединяющий ваши страницы (обычно он имеет тип ГруппаФормы с видом Страницы).
  2. В панели свойств этого элемента найдите событие ПриСменеСтраницы и создайте обработчик на клиенте.
  3. Внутри обработчика добавьте проверку: на какую именно страницу перешел пользователь.

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


&НаКлиенте
Процедура ГруппаСтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)
    
    // Проверяем, что пользователь перешел именно на вкладку "Документация"
    Если ТекущаяСтраница = Элементы.СтраницаДокументация Тогда
        // Вызываем серверную процедуру для выполнения расчетов
        ВыполнитьРасчетДанныхНаСервере();
    КонецЕсли;
    
КонецПроцедуры

Решение 2: Оптимизация с использованием флага (однократный расчет)

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

Для решения нам понадобится дополнительный реквизит формы (не путать с реквизитом объекта!).

  1. Создайте реквизит формы с именем ДанныеЗагружены и типом Булево. По умолчанию он будет равен Ложь.
  2. Модифицируйте процедуру обработки смены страницы, добавив проверку этого флага.

Проанализируем обновленный код:


&НаКлиенте
Процедура ГруппаСтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)
    
    // Выполняем расчет только если выбрана нужная страница и расчет еще не производился
    Если ТекущаяСтраница = Элементы.СтраницаДокументация И Не ДанныеЗагружены Тогда
        
        ВыполнитьРасчетДанныхНаСервере();
        
        // Устанавливаем флаг, чтобы больше не нагружать сервер при этом сеансе работы с формой
        ДанныеЗагружены = Истина;
        
    КонецЕсли;
    
КонецПроцедуры

Этот подход значительно экономит ресурсы сервера и время пользователя, так как тяжелая операция выполняется «On-demand» (по требованию) и только один раз.

Решение 3: Использование обработчика ожидания для плавности интерфейса

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

Рассмотрим, как это работает: при смене страницы мы не вызываем сервер сразу, а даем команде интерфейса завершиться, и через 0.1 секунды запускаем расчет. Это позволяет вкладке визуально «активироваться» до начала торможения.


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

&НаКлиенте
Процедура ИсполнитьОтложенныйРасчет()
    ВыполнитьРасчетДанныхНаСервере();
    ДанныеЗагружены = Истина;
КонецПроцедуры

Решение 4: Асинхронность и фоновые задания

Если код в цикле работает очень долго (более 5-10 секунд), даже перенос на вкладку не спасет от недовольства пользователей. В таких случаях правильно использовать механизм Фоновых заданий. Это позволяет выполнять расчет на сервере параллельно, не блокируя работу основного окна 1С.

Алгоритм работы через БСП (Библиотека стандартных подсистем):

Это наиболее профессиональный путь для обработки действительно больших объемов данных в управляемом приложении.

Общие рекомендации по оптимизации «тяжелого» кода

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

  1. Запросы в цикле: Если внутри вашего цикла происходит обращение к базе данных (через запрос или получение объекта), это главная причина низкой производительности. Перепишите код так, чтобы сначала одним запросом собрать все данные, а затем обработать их в памяти.
  2. Обращение через точку: Конструкции вида Строка.Номенклатура.Артикул внутри цикла заставляют платформу неявно подгружать объект номенклатуры из базы для каждой строки. Используйте запросы с выборкой нужных полей.
  3. Избыточный контекст: Помните, что при вызове &НаСервере вся форма (все её реквизиты) передается с клиента на сервер и обратно. Чем больше данных на форме, тем медленнее каждый вызов. Используйте &НаСервереБезКонтекста, где это возможно.

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

← На главную