Как программно вернуть предыдущее значение переключателя на форме в 1С 7.7?

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

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

Разберем причины такого поведения платформы и подробно рассмотрим проверенные способы решения этой задачи.

В чем причина проблемы?

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

Если внутри этой процедуры мы меняем значение связанной переменной обратно, например:


Процедура ПриАннулированииЗаявки()
    Если ДляОбщегоЖурнала = 3 Тогда 
        // Некоторое условие проверки
        ДляОбщегоЖурнала = 2; // Возвращаем значение обратно
        Форма.Обновить(0);
    КонецЕсли;
КонецПроцедуры

В отладчике значение переменной ДляОбщегоЖурнала действительно становится равным 2, но на экране переключатель остается в позиции 3. Это происходит из-за того, что завершающий цикл внутренней обработки события нажатия Windows и платформенный механизм синхронизации элементов формы отрабатывают уже после завершения пользовательской процедуры, повторно отрисовывая отметку на том элементе, по которому кликнул пользователь.

Способ 1. Обходной прием с отменой закрытия формы

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

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

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

Посмотрим на пример программного кода:


Перем НеЗакрыватьФорму;

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

Процедура ПоФлагу()
    НеЗакрыватьФорму = 0;
    Если ДляОбщегоЖурнала = 3 Тогда
        // Проверяем условие, требующее отката
        НеЗакрыватьФорму = 1;
        Форма.Закрыть(0);
    КонецЕсли;
КонецПроцедуры

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

Способ 2. Принудительная смена фокуса ввода

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

Для этого в процедуре обработки переключателя активизируем любой другой доступный реквизит формы и обновляем контекст:


Процедура ПриАннулированииЗаявки()
    Если ДляОбщегоЖурнала = 3 Тогда
        ДляОбщегоЖурнала = 2;
        // Переносим фокус на другой элемент диалога
        Активизировать("Комментарий");
        Форма.Обновить(0);
    КонецЕсли;
КонецПроцедуры

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

Способ 3. Проверка порядка обхода и группировки элементов

Выясним причину возможных сбоев стандартного обновления. В платформе 1С 7.7 корректная работа переключателей напрямую зависит от настроек диалога:

  1. Флаг «Первый в группе» должен быть установлен строго у первого переключателя. У остальных переключателей этой же группы данный флаг должен быть снят.
  2. Порядок обхода (Tab Order): все элементы группы должны следовать в списке порядка обхода строго друг за другом без разрывов. Если между переключателями в списке затесался другой реквизит, надпись или рамка, синхронизация с переменной нарушается.
  3. Формула: вызов процедуры обработчика должен быть указан только в свойствах первого переключателя группы.

Способ 4. Альтернативные варианты интерфейса

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

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