При разработке интерфейсов в платформе 1С:Предприятие 7.7 разработчики нередко сталкиваются с ситуацией, когда требуется обработать выбор переключателя (радиокнопки) и при невыполнении определенного условия отменить выбор пользователя, вернув переключатель в исходное положение. Однако прямое присвоение старого значения переменной и даже стандартный вызов метода Форма.Обновить(0) на форме документа часто не приводят к визуальному обновлению отметки.
Разберем причины такого поведения платформы и подробно рассмотрим проверенные способы решения этой задачи.
Посмотрим, что происходит на уровне платформы в момент клика по переключателю. При нажатии левой кнопки мыши операционная система Windows самостоятельно переносит графическую отметку (точку) на выбранный элемент управления. Затем платформа 1С 7.7 запускает процедуру, прописанную в формуле первого переключателя группы.
Если внутри этой процедуры мы меняем значение связанной переменной обратно, например:
Процедура ПриАннулированииЗаявки()
Если ДляОбщегоЖурнала = 3 Тогда
// Некоторое условие проверки
ДляОбщегоЖурнала = 2; // Возвращаем значение обратно
Форма.Обновить(0);
КонецЕсли;
КонецПроцедуры
В отладчике значение переменной ДляОбщегоЖурнала действительно становится равным 2, но на экране переключатель остается в позиции 3. Это происходит из-за того, что завершающий цикл внутренней обработки события нажатия Windows и платформенный механизм синхронизации элементов формы отрабатывают уже после завершения пользовательской процедуры, повторно отрисовывая отметку на том элементе, по которому кликнул пользователь.
Рассмотрим надежный и проверенный разработчиками трюк, который заставляет форму документа полностью перерисовать элементы управления за счет вызова процедуры закрытия с ее последующей отменой.
Разберем по шагам реализацию этого механизма:
НеЗакрыватьФорму.Форма.Закрыть(0).ПриЗакрытии() проверяем флаг: если он установлен, сбрасываем его, восстанавливаем значение реквизита и отменяем закрытие формы с помощью СтатусВозврата(0).Посмотрим на пример программного кода:
Перем НеЗакрыватьФорму;
Процедура ПриЗакрытии()
Если НеЗакрыватьФорму = 1 Тогда
// Возвращаем переключатель в исходное положение
ДляОбщегоЖурнала = 2;
НеЗакрыватьФорму = 0;
// Отменяем закрытие формы
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецПроцедуры
Процедура ПоФлагу()
НеЗакрыватьФорму = 0;
Если ДляОбщегоЖурнала = 3 Тогда
// Проверяем условие, требующее отката
НеЗакрыватьФорму = 1;
Форма.Закрыть(0);
КонецЕсли;
КонецПроцедуры
При таком подходе платформа инициирует закрытие формы, что прерывает текущую цепочку оконных сообщений, а последующий вызов СтатусВозврата(0) оставляет форму открытой и принудительно синхронизирует все визуальные элементы с переменными модуля.
Проанализируем еще один способ, не требующий вызова закрытия формы. Во многих случаях сбросить зафиксированное состояние элемента управления удается путем временного переноса фокуса на другой реквизит диалога.
Для этого в процедуре обработки переключателя активизируем любой другой доступный реквизит формы и обновляем контекст:
Процедура ПриАннулированииЗаявки()
Если ДляОбщегоЖурнала = 3 Тогда
ДляОбщегоЖурнала = 2;
// Переносим фокус на другой элемент диалога
Активизировать("Комментарий");
Форма.Обновить(0);
КонецЕсли;
КонецПроцедуры
Смена активного элемента заставляет платформу завершить обработку сообщений переключателя и применить обновленное значение связанной переменной к группе радиокнопок.
Выясним причину возможных сбоев стандартного обновления. В платформе 1С 7.7 корректная работа переключателей напрямую зависит от настроек диалога:
Если специфика конкретного документа или наличие сложных закладок на форме продолжают мешать стабильной работе переключателей, рассмотрим альтернативные подходы к построению интерфейса:
ПриВыбореРеквизита(), где отмена выбора или возврат предыдущего значения через присвоение переменной отрабатывает мгновенно и без визуальных артефактов.