Как программно прокрутить окно сообщений и реализовать автопрокрутку лога в 1С?

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

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

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

Ограничение платформы: почему стандартное окно сообщений нельзя прокрутить?

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

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

Тем не менее, решить задачу автоматического информирования пользователя можно и нужно. Рассмотрим эффективные альтернативные варианты.

Вариант 1. Вывод сообщений в обратном порядке (самый простой обходной путь)

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

Этот метод идеально подходит при выводе лога в обычное текстовое поле на управляемой форме или при накоплении строк в массиве/списке значений. Рассмотрим пример реализации:


&НаКлиенте
Процедура ДобавитьСтрокуВЛогОбратно(НовоеСообщение)
    // Добавляем новую строку в начало нашего текстового реквизита
    ТекстЛога = НовоеСообщение + Символы.ПС + ТекстЛога;
КонецПроцедуры

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

Недостатки: нарушается естественный хронологический порядок чтения (сверху вниз), что может быть непривычно для некоторых пользователей.

Вариант 2. Использование строки состояния для оперативного информирования

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

Для вывода информации используется метод ПоказатьСтрокуСостояния() или глобальный метод Состояние():


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

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

Недостатки: строка состояния показывает только одно текущее значение. История выполнения процесса (лог предыдущих шагов) при этом не сохраняется.

Вариант 3. Многострочное поле ввода и метод «УстановитьГраницыВыделения»

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

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

Разберем этот метод по шагам:

  1. Создадим на управляемой форме реквизит с именем ТекстЛога (тип: Строка, неограниченной длины).
  2. Вынесем его на форму как элемент «Поле текстового документа» или «Поле ввода» с установленным флагом «Многострочный режим». Назовем элемент формы ДекорацияЛог.
  3. Напишем процедуру добавления строки с последующим позиционированием курсора:

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

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

Вариант 4. Поле HTML-документа и JavaScript (самый гибкий и современный метод)

Использование элемента формы «Поле HTML-документа» является стандартом де-факто в современных конфигурациях 1С (таких как УТ 11, ERP, УНФ) для создания интерактивных чатов, систем обсуждений и красивых логов. С помощью HTML-разметки мы можем стилизовать сообщения (например, красить ошибки в красный цвет, а успешные операции в зеленый), а с помощью простого JavaScript-кода — управлять прокруткой страницы.

Рассмотрим, как реализовать автоматическую прокрутку HTML-поля до самого низа:

  1. Создадим реквизит формы СодержимоеHTML (тип: Строка) и свяжем его с элементом формы типа «Поле HTML-документа».
  2. При добавлении нового сообщения будем дополнять HTML-код новыми тегами <div>.
  3. Используем программный доступ к объектной модели документа (DOM) для выполнения скроллинга:

&НаКлиенте
Процедура ДобавитьСтрокуВHTMLЛог(НовоеСообщение, ТипСообщения = "Инфо")
    // Формируем HTML-код строки в зависимости от типа сообщения
    ЦветТекста = "black";
    Если ТипСообщения = "Ошибка" Тогда
        ЦветТекста = "red";
    ИначеЕсли ТипСообщения = "Успешно" Тогда
        ЦветТекста = "green";
    КонецЕсли;
    
    НовыйЭлементHTML = "<div style='color: " + ЦветТекста + "; font-family: Arial; font-size: 12px;'>" 
                     + НовоеСообщение + "</div>";
                     
    // Дописываем код в тело нашего HTML-документа
    СодержимоеHTML = СодержимоеHTML + НовыйЭлементHTML;
    
    // Прокручиваем документ вниз на клиенте
    ПрокрутитьHTMLВКонец();
КонецПроцедуры

&НаКлиенте
Процедура ПрокрутитьHTMLВКонец()
    // Получаем доступ к DOM-документу поля HTML
    ДокументHTML = Элементы.ПолеHTMLДокумента.Документ;
    Если ДокументHTML <> Неопределено Тогда
        // Смещаем вертикальную прокрутку на полную высоту тела документа
        ДокументHTML.body.scrollTop = ДокументHTML.body.scrollHeight;
    КонецЕсли;
КонецПроцедуры

Для создания плавного и красивого визуального эффекта прокрутки можно внедрить непосредственно в HTML-код небольшой JavaScript. Например, присвоить последнему добавленному сообщению уникальный идентификатор и вызвать метод:


document.getElementById('last-message-id').scrollIntoView({block: 'end', behavior: 'smooth'});

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

Недостатки: требует базовых знаний верстки HTML/CSS и работы с DOM-моделью.

Вариант 5. Табличная часть или таблица значений с позиционированием строки

Если лог должен быть структурированным (например, состоять из колонок «Время», «Важность», «Событие», «Объект»), то лучше всего выводить его не простым текстом, а в виде таблицы. Элемент формы «Таблица», связанный с таблицей значений или табличной частью, отлично поддается программному управлению.

Чтобы автоматически показывать пользователю самую последнюю добавленную строку в таблице, нам достаточно программно изменить свойство элемента формы ТекущаяСтрока, присвоив ему идентификатор только что добавленной записи.

Проанализируем пример кода:


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

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

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

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

Недостатки: требует выполнения серверного вызова для добавления строки в коллекцию данных (хотя в современных версиях платформы работа с коллекциями формы существенно оптимизирована).

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

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

При выборе архитектурного решения руководствуйтесь следующими правилами:

← На главную