Как обновить встроенную таблицу на форме обработки в 1С 7.7

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

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

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

Причины проблемы и особенности платформы 1С 7.7

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

  1. Разделение циклов отрисовки элементов диалога и таблицы. Встроенный табличный документ не является классическим элементом управления диалога (контролом). Метод Форма.Обновить() посылает команду перерисовки только стандартным реквизитам диалога, но не вызывает принудительную инвалидацию графической области встроенной таблицы.
  2. Блокировка оконных операций. Ошибка Открытие окна в данном режиме недоступно! возникает тогда, когда метод Таблица.Показать() вызывается во время фазы инициализации формы (в процедуре ПриОткрытии()) либо напрямую из формулы текстового поля-«педали», предназначенного для отслеживания текущего состояния элементов формы. В этот момент платформа аппаратно блокирует методы управления окнами.

Способ 1. Использование флага инициализации формы

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

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

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

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


Перем мФормаИнициализирована;

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

Процедура ПриОткрытии()
    мФормаИнициализирована = 0;
    
    // Первоначальное заполнение ТаблицыЗначений на форме
    ЗаполнитьТЗ();
    
    // Разрешаем обновление интерфейса
    мФормаИнициализирована = 1;
    ОбновитьТаблицуНаФорме();
КонецПроцедуры

Способ 2. Вынос обновления в отдельную процедуру через ОбработкаОжидания

Если обновление подчиненной таблицы привязано к смене текущей строки в ТаблицеЗначений через текстовое поле формы (стандартный прием отслеживания позиции курсора в 1С 7.7), вызов Таблица.Показать() из контекста формулы текста будет вызывать ошибку. Чтобы разорвать контекст выполнения, применим асинхронный вызов через ОбработкаОжидания.

Рассмотрим, как это работает:

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

Посмотрим на пример реализации:


Процедура ВыполнитьОтложенноеОбновление()
    // Отключаем таймер ожидания
    ОбработкаОжидания("ВыполнитьОтложенноеОбновление", 0);
    
    // Перерисовываем данные
    ОбновитьТаблицуНаФорме();
КонецПроцедуры

Функция глСлежениеЗаСтрокойТЗ()
    Если ТЗДанных.ТекущаяСтрока() <> мПредыдущаяСтрока Тогда
        мПредыдущаяСтрока = ТЗДанных.ТекущаяСтрока();
        // Взводим таймер для безопасного обновления
        ОбработкаОжидания("ВыполнитьОтложенноеОбновление", 1);
    КонецЕсли;
    Возврат "";
КонецФункции

Способ 3. Программная смена фокуса (активация элементов)

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

Альтернативные подходы к архитектуре интерфейса

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

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