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