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

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Почему вызов Форма.Обновить() мешает работе пользователя?

Проанализируем механику работы стандартных методов обновления интерфейса в 1С 7.7:

  1. Полная перерисовка диалога: Метод Форма.Обновить() принудительно перечитывает значения всех реквизитов документа и элементов формы из памяти и базы данных. Если оператор в момент срабатывания таймера набирал текст или число в поле ввода, буфер редактирования очищается, а несохраненное значение сбрасывается.
  2. Ограничения таймеров: Процедура ОбработкаОжидания() запускает глобальный таймер на уровне всей сессии 1С. В платформе может одновременно работать только один такой таймер. Если он периодически инициирует общее обновление диалога, ввод данных оператором превращается в постоянную борьбу со сбросом значений.
  3. Мерцание при перерисовке окна: Использование низкоуровневых команд принудительной перерисовки контекста окна Windows заставляет перерисовываться все графические элементы, но не приводит к автоматическому пересчету выражений во встроенных формулах элементов управления без прямого обращения к ним.

Способ 1. Точечное изменение текста элемента через метод Заголовок()

Наиболее простое, надежное и быстрое решение проблемы — отказаться от вызова Форма.Обновить() и менять текст конкретного элемента интерфейса напрямую. Для этого элементу диалога необходимо назначить уникальный идентификатор в конфигураторе.

Разберем реализацию этого подхода по шагам:

  1. Открываем диалог формы документа в конфигураторе.
  2. Размещаем элемент Текст, рамку группы или кнопку (например, кнопку «Принять данные»).
  3. В свойствах элемента переходим на вкладку параметров и в поле Идентификатор указываем имя, например ПоказанияДатчика. Поле «Формула» при этом оставляем пустым.
  4. В модуле формы в процедуре, вызываемой по таймеру, обращаемся к элементу через объект Форма и вызываем метод Заголовок().

Посмотрим на пример реализации кода в модуле формы документа:


Перем мПериодОпроса;

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

Процедура ПриОткрытии()
    мПериодОпроса = 2; // каждые 2 секунды
    ОбработкаОжидания("ОпроситьДатчики", мПериодОпроса);
КонецПроцедуры

Процедура ПриЗакрытии()
    // Обязательно отключаем глобальный таймер при закрытии формы
    ОбработкаОжидания("ОпроситьДатчики", 0);
КонецПроцедуры

Метод Форма.<Идентификатор>.Заголовок() напрямую посылает оконное сообщение операционной системы контролу диалога. Текст на экране меняется мгновенно, фокус ввода не теряется, а пользователь может продолжать непрерывный ввод данных в соседних полях документа.

Способ 2. Вывод показаний в заголовок окна или строку состояния

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

Рассмотрим два распространенных варианта:

  1. Вывод в шапку текущего окна: Метод Форма.Заголовок() позволяет динамически менять заголовок окна документа. Вы можете дополнять стандартное название документа актуальными цифрами.
  2. Вывод в строку состояния платформы: Стандартная функция Состояние() выводит текст в нижнюю панель окна 1С и совершенно не затрагивает элементы диалога.

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


Процедура ОпроситьДатчики()
    Перем ТекВес, СтрокаИнфо;
    ТекВес = ПолучитьПоказанияВесов();
    
    СтрокаИнфо = "Текущий вес: " + СокрЛП(ТекВес) + " кг";
    
    // Вариант А: меняем заголовок самого окна документа
    Форма.Заголовок("Приходная накладная [" + СтрокаИнфо + "]");
    
    // Вариант Б: дублируем информацию в статусную строку платформы
    Состояние(СтрокаИнфо);
КонецПроцедуры

Способ 3. Переход на внешние события оборудования

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

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

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

Использование метода Заголовок() в сочетании с корректным отключением таймеров в событии ПриЗакрытии() полностью устраняет проблему сброса полей ввода и обеспечивает комфортную работу оператора в 1С 7.7.

← На главную