Как обновить надпись или картинку на управляемой форме 1С во время длительной операции?

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

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

Почему интерфейс не обновляется мгновенно: особенности рендеринга 1С

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

Перерисовка интерфейса происходит в так называемом главном цикле обработки событий (idle loop), когда поток выполнения освобождается и управление возвращается самой платформе. Если сразу после изменения текста вы запускаете длительный синхронный процесс (например, чтение тяжелого файла Excel), поток остается занят, и платформа просто физически не успевает перерисовать форму. Вызов метода ОбновитьОтображениеДанных() в данном случае не гарантирует мгновенного рендеринга, особенно в веб-клиенте или тонком клиенте под нагрузкой.

Решение №1: Использование Поля надписи вместо Декорации

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

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

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

Давайте посмотрим на правильную настройку элемента формы по шагам:

  1. Создаем реквизит формы ТекстИнфо с типом Строка.
  2. Перетаскиваем его в список элементов формы, платформой будет автоматически создано Поле формы.
  3. В свойствах созданного элемента устанавливаем вид Поле надписи.
  4. В коде управляем текстом просто через присвоение значения реквизиту: ТекстИнфо = "Новый статус";.

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

Если нам необходимо выполнить действие немедленно после изменения текста на форме, отличным решением является «разрыв» контекста выполнения с помощью метода ПодключитьОбработчикОжидания(). Это классический паттерн для обхода синхронной блокировки UI.

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

Рассмотрим пример кода, реализующий этот подход:


&НаКлиенте
Процедура ВыбратьИЗагрузитьФайл(Команда)
    
    // 1. Изменяем статус на форме (используем реквизит формы ТекстИнфо)
    ТекстИнфо = "Выполняется подготовка к загрузке...";
    Элементы.КартинкаЗагрузка.Картинка = БиблиотекаКартинок.Ожидание;
    
    // 2. Подключаем обработчик ожидания на 0.1 секунды с признаком однократности (Истина)
    ПодключитьОбработчикОжидания("Подключаемый_ВыполнитьВыборИЗагрузку", 0.1, Истина);
    
    // 3. Завершаем процедуру. Управление возвращается платформе, интерфейс мгновенно перерисовывается!
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ВыполнитьВыборИЗагрузку()
    
    ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогОткрытияФайла.ПолноеИмяФайла = "";
    ДиалогОткрытияФайла.Заголовок = "Выберите файл для загрузки";
    Фильтр = "Microsoft Excel(*.xls;*.xlsx)|*.xls;*.xlsx";
    ДиалогОткрытияФайла.Фильтр = Фильтр;
    
    Если ДиалогОткрытияФайла.Выбрать() Тогда
        ПутьКФайлу = ДиалогОткрытияФайла.ПолноеИмяФайла;
        
        // Меняем статус перед тяжелой загрузкой
        ТекстИнфо = "Файл выбран. Выполняется загрузка данных...";
        
        // Снова используем небольшой разрыв контекста, чтобы текст успел обновиться перед тяжелым чтением файла
        ПараметрыЗапуска = Новый Структура("ПутьКФайлу", ПутьКФайлу);
        ПодключитьОбработчикОжидания("Подключаемый_ТяжелаяЗагрузка", 0.1, Истина);
    Иначе
        ТекстИнфо = "Выбор файла отменен";
        Элементы.КартинкаЗагрузка.Картинка = Новый Картинка;
    КонецЕсли;
    
КонецПроцедуры

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

Решение №3: Переход на современные асинхронные методы работы с файлами

В современной платформе 1С (начиная с версии 8.3.15) синхронные методы работы с файлами, такие как Выбрать() у объекта ДиалогВыбораФайла или метод ПоместитьФайл(), являются устаревшими. В веб-клиенте они заблокированы полностью, а в тонком клиенте их использование считается плохим тоном и может приводить к ошибкам.

Асинхронные методы работают по принципу обратного вызова (Callback) или через обещания (Promises / Описания Оповещения). При вызове асинхронного метода выполнение кода приостанавливается, управление возвращается платформе (в этот момент интерфейс гарантированно перерисовывается), а управление возвращается в отдельную процедуру только тогда, когда пользователь сделал свой выбор.

Проанализируем пример асинхронного выбора файла и его последующей загрузки на сервер:


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

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

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

Этот подход не только решает проблему своевременного обновления статусов на форме, но и делает вашу конфигурацию полностью кроссплатформенной (код будет одинаково стабильно работать и в Тонком клиенте, и в браузере под Веб-клиентом).

Решение №4: Использование механизма «Длительные операции» БСП

Если обработка файла (например, парсинг Excel на 10 000 строк) занимает значительное время (более 5-10 секунд), то даже при использовании асинхронных методов интерфейс программы «зависнет» во время выполнения серверного вызова. Пользователь не сможет нажать другие кнопки, а операционная система может пометить окно 1С как «Не отвечает».

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

Рассмотрим общую схему реализации длительной операции по шагам:

  1. Передача файла на сервер: Сначала файл помещается во временное хранилище асинхронным методом (как в Решении №3).
  2. Запуск фонового задания: С клиента вызывается серверная функция, которая запускает фоновое задание с помощью метода БСП ДлительныеОперации.ЗапуститьВыполнениеВФоне().
  3. Ожидание завершения: На клиенте открывается стандартная форма ожидания БСП с помощью метода ДлительныеОперацииКлиент.ОткрытьФормуОжидания(). Данная форма сама опрашивает сервер о состоянии выполнения процесса.
  4. Передача прогресса: В коде фонового задания на сервере мы можем использовать метод ДлительныеОперации.СообщитьПрогресс() для отправки информации о проценте выполнения или текущей строке обратно на клиент. Окно ожидания будет динамически показывать этот прогресс пользователю!

Ниже приведен пример реализации запуска фонового задания на сервере через БСП:


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

На клиенте после получения структуры Результат мы открываем форму ожидания, передавая в нее идентификатор задания. Это гарантирует профессиональный, отзывчивый и стабильный интерфейс, соответствующий лучшим практикам разработки фирмы «1С».

Резюме и рекомендации

Подводя итог, выделим ключевые правила работы с динамическими элементами управляемой формы 1С:

  1. Никогда не используйте декорации для вывода часто меняющегося текста. Заменяйте их на Поля формы с видом Поле надписи, связанными с реквизитами формы.
  2. При необходимости быстро обновить UI перед запуском тяжелого кода используйте разрыв контекста через обработчики ожидания.
  3. Отказывайтесь от устаревших синхронных методов выбора и помещения файлов на сервер в пользу современных асинхронных аналогов.
  4. Для процессов, длящихся дольше нескольких секунд, всегда внедряйте механизм Длительных операций БСП, чтобы обеспечить максимальный комфорт и прозрачность работы для пользователей вашей системы.
← На главную