Приветствуем вас, коллеги! Разработка и поддержка конфигураций на платформе 1С:Предприятие 7.7 часто преподносит сюрпризы, связанные с особенностями ее архитектуры. Одна из классических проблем, с которой сталкиваются как начинающие разработчики, так и опытные специалисты при работе с legacy-системами, — это «необъяснимый» сброс видимости элементов диалога при открытии формы или переключении закладок.
Давайте подробно разберем ситуацию: у нас есть форма, на которой расположен реквизит (например, перечисление или флаг). В зависимости от его значения нам нужно скрыть или показать другие поля на форме. Мы пишем логику в процедуре управления видимостью, отладчик послушно проходит по строке Видимость(0), но при открытии формы элемент все равно остается видимым. Проанализируем, почему это происходит, как устроена работа со слоями «изнутри» и как решить эту проблему раз и навсегда.
В отличие от современных управляемых форм на платформе 1С 8.3, где элементы интерфейса располагаются в строгой иерархической структуре (страницы, группы, панели), в 1С 7.7 слои представляют собой виртуальную сущность. Слой в системе 7.7 — это просто группировочный признак для элементов диалога, задаваемый в их свойствах.
Когда в коде формы вызывается предопределенный метод Форма.ИспользоватьСлой(), платформа выполняет автоматическое групповое управление свойствами элементов:
Видимость(1).Видимость(0).Главный нюанс: метод ИспользоватьСлой() полностью перезаписывает и сбрасывает любые настройки индивидуальной видимости полей, которые вы сделали программно до его вызова. Если вы сначала скрыли поле через Форма.ИмяРеквизита.Видимость(0), а затем платформа (или ваш код) выполнила активацию слоя, на котором лежит это поле, система вернет ему видимость по умолчанию.
Рассмотрим по шагам, как должна быть структурирована предопределенная процедура ПриОткрытии(), чтобы избежать сброса видимости. Основное правило — сначала настраиваем слои и закладки, и только в самом конце управляем индивидуальной видимостью элементов.
Посмотрим на пример правильной структуры кода:
Процедура ПриОткрытии()
// Шаг 1: Настраиваем закладки формы (если они используются)
Форма.ИспользоватьЗакладки(1);
Форма.Закладки.ДобавитьЗначение("Основная", "Основная вкладка");
Форма.Закладки.ДобавитьЗначение("Дополнительно", "Дополнительные сведения");
// Шаг 2: Устанавливаем активный слой по умолчанию
Форма.ИспользоватьСлой("Основная", 2);
// Шаг 3: В самом конце вызываем процедуру управления индивидуальной видимостью полей
ИзмВидимостьПолей();
КонецПроцедуры
В данном случае, когда управление дойдет до функции ИзмВидимостьПолей(), платформа уже завершит массовое распределение видимости по слоям, и ваши индивидуальные настройки успешно применятся поверх установленного слоя.
Вышеописанное решение отлично сработает при первоначальном открытии формы. Однако, как только пользователь кликнет на другую закладку, сработает предопределенная процедура ПриВыбореЗакладки(). Внутри нее разработчики обычно пишут следующий код:
Процедура ПриВыбореЗакладки(Ном, Зн)
// Переключаем активный слой в соответствии с выбранной закладкой
Форма.ИспользоватьСлой(Зн, 2);
КонецПроцедуры
Как только выполнится строка Форма.ИспользоватьСлой(Зн, 2), платформа снова сбросит все настройки индивидуальной видимости! Если скрытый нами элемент принадлежит активируемой закладке, он снова станет видимым.
Чтобы решить эту проблему, нам необходимо дублировать вызов нашей процедуры управления видимостью сразу после переключения слоев:
Процедура ПриВыбореЗакладки(Ном, Зн)
// 1. Активируем нужный слой
Форма.ИспользоватьСлой(Зн, 2);
// 2. Восстанавливаем индивидуальные настройки видимости полей
ИзмВидимостьПолей();
КонецПроцедуры
Сама процедура ИзмВидимостьПолей() может выглядеть стандартным образом. Проанализируем пример ее реализации:
Процедура ИзмВидимостьПолей()
// Проверяем значение реквизита ТЕСТ (тип: Перечисление.Тест)
Если ТЕСТ = Перечисление.Тест.А Тогда
// Скрываем ненужное поле
Форма.ПолеДляСкрытия.Видимость(0);
Иначе
// Показываем поле во всех остальных случаях
Форма.ПолеДляСкрытия.Видимость(1);
КонецЕсли;
КонецПроцедуры
При совместной работе со слоями и методом Видимость() существует еще одна недокументированная особенность платформы 1С 7.7. Ее часто называют эффектом «протекания» элементов.
Если элемент принадлежит какому-то скрытому в данный момент слою, но вы программно вызываете для него команду Видимость(1), этот элемент может внезапно отобразиться («проступить») поверх текущего активного слоя. Платформа теряет контроль над принадлежностью элемента к слою, если его видимость была изменена напрямую в обход логики слоев.
Золотое правило разработки под 1С 7.7: никогда не делайте элемент видимым программно с помощью Видимость(1), если слой, на котором физически расположен этот элемент, в данный момент не является активным.
Если динамически скрываемых элементов на форме много, постоянный пропись кода видимости для каждого реквизита засоряет модуль и усложняет его поддержку. В этом случае мы рекомендуем использовать встроенную возможность платформы — подслои.
В конфигураторе 1С 7.7 в свойствах элемента диалога в поле «Слой» можно указывать несколько слоев через запятую. Метод Форма.ИспользоватьСлой() умеет принимать список слоев. Мы можем сгруппировать условные элементы на отдельный виртуальный подслой (например, "ДопСлойА") и управлять отображением целых групп элементов без прямого использования метода Видимость() в коде:
Процедура ИзмВидимостьСлоями()
Если ТЕСТ = Перечисление.Тест.А Тогда
// Активируем основную закладку БЕЗ дополнительного подслоя
Форма.ИспользоватьСлой("Основная", 2);
Иначе
// Активируем основную закладку ВМЕСТЕ с дополнительным подслоем
Форма.ИспользоватьСлой("Основная, ДопСлойА", 2);
КонецЕсли;
КонецПроцедуры
Такой подход считается более профессиональным и чистым, так как он полностью исключает конфликты при работе платформенного механизма слоев и ручного переключения видимости отдельных элементов.