Разработчики часто сталкиваются с задачей, когда пользователю необходимо предоставить возможность гибкой настройки табличной части или дерева значений на форме, а затем вывести именно этот настроенный состав колонок в печатную форму или отчет. Пользователь открывает стандартное окно «Изменить форму», снимает или устанавливает флажки видимости колонок, меняет их местами, а при формировании печатной формы ожидает увидеть именно свой индивидуальный вариант.
Проанализируем основную сложность этой задачи. Если мы попытаемся решить проблему «в лоб» и программно обратиться к свойству видимости элемента формы через код Элементы.ИмяКолонки.Видимость, то мы столкнемся с тем, что платформа всегда возвращает первоначальное значение Истина (или то значение, которое задано разработчиком в Конфигураторе). Платформа 1С:Предприятие разделяет базовую видимость элемента и так называемую пользовательскую видимость. Настройки пользователя накладываются поверх стандартных свойств, и напрямую прочитать их через стандартное свойство Видимость на клиенте обычным способом не удастся.
Разберем подробно несколько проверенных и рабочих способов, которые помогут нам программно определить, какие именно колонки пользователь оставил видимыми на форме.
Этот способ является одним из самых простых, быстрых и оригинальных решений, которое выполняется полностью на клиенте «здесь и сейчас». Нам не требуется выполнять серверные вызовы или обращаться к базе данных. Он базируется на особенности поведения платформы 1С:Предприятие: система физически не позволяет сделать активным скрытый элемент формы.
Выясним алгоритм реализации этого метода:
Попытка ... Исключение пытаемся установить фокус, сделав его текущим элементом формы.Посмотрим на пример практической реализации данного метода:
&НаКлиенте
Процедура ОпределитьВидимыеКолонкиПоФокусу()
// Запоминаем текущий фокус, чтобы вернуть его в конце
СтарыйАктивныйЭлемент = ЭтаФорма.ТекущийЭлемент;
// Создаем массив для хранения имен видимых колонок
МассивВидимыхКолонок = Новый Массив;
// Получаем коллекцию колонок нашей таблицы (замените "ДеревоДанных" на имя вашей таблицы)
КолонкиТаблицы = Элементы.ДеревоДанных.ПодчиненныеЭлементы;
Для Каждого Колонка Из КолонкиТаблицы Цикл
// Интересуют только элементы типа "ПолеФормы"
Если ТипЗнч(Колонка) <> Тип("ПолеФормы") Тогда
Продолжить;
КонецЕсли;
Попытка
// Пытаемся передать фокус текущей колонке
ЭтаФорма.ТекущийЭлемент = Колонка;
// Если фокус успешно перешел, добавляем колонку в список видимых
Если ЭтаФорма.ТекущийЭлемент = Колонка Тогда
МассивВидимыхКолонок.Добавить(Колонка.Имя);
КонецЕсли;
Исключение
// Сюда код попадает, если колонка скрыта пользователем через "Изменить форму"
// Платформа вызывает исключение при попытке активировать невидимый элемент
КонецПопытки;
КонецЦикла;
// Обязательно возвращаем фокус пользователю назад
ЭтаФорма.ТекущийЭлемент = СтарыйАктивныйЭлемент;
// Передаем полученный массив для дальнейшей генерации печатной формы
ОбработатьВыбранныеКолонки(МассивВидимыхКолонок);
КонецПроцедуры
Преимущества метода: Работает мгновенно, не требует серверных вызовов, отражает настройки пользователя, примененные только что (даже если форма еще не закрывалась и настройки не сохранились в базу данных).
Недостатки метода: На долю секунды интерфейс может визуально «моргнуть», когда фокус пробегает по колонкам. На производительных компьютерах этот эффект практически незаметен.
Когда пользователь закрывает форму или нажимает кнопку «Применить» в окне изменения формы, платформа автоматически сохраняет эти параметры в базу данных. Местом хранения является специальный системный объект — ХранилищеСистемныхНастроек.
Рассмотрим подробнее, как прочитать эти настройки на стороне сервера. Для этого нам понадобится сформировать уникальный ключ объекта настроек. Шаблон ключа обычно выглядит следующим образом:
"Обработка.[ИмяОбработки].Форма.[ИмяФормы]/НастройкиФормы"
Или, в зависимости от используемого интерфейса и конфигурации, ключ может заканчиваться на "/Такси/НастройкиОкна".
Разберем по шагам серверный код получения структуры настроек:
&НаСервере
Функция ПолучитьНастройкиВидимостиИзХранилища()
// Формируем ключ объекта настроек для нашей формы
КлючОбъекта = "Обработка.МояПечатнаяФорма.Форма.ФормаНастройки/НастройкиФормы";
ИмяПользователя = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
// Загружаем настройки из системного хранилища
Настройки = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта, "", , ИмяПользователя);
МассивВидимыхКолонок = Новый Массив;
Если Настройки <> Неопределено Тогда
// Настройки возвращаются в виде объекта НастройкиФормы
// Мы можем обойти структуру дерева элементов, хранящуюся внутри
Для Каждого ЭлементНастройки Из Настройки.Элементы Цикл
// Проверяем пользовательскую видимость элемента
Если ЭлементНастройки.Видимость Тогда
МассивВидимыхКолонок.Добавить(ЭлементНастройки.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат МассивВидимыхКолонок;
КонецФункции
Преимущества метода: Надежное и документированное получение настроек формы напрямую из системной базы данных без манипуляций с фокусом ввода.
Недостатки метода: Настройки записываются платформой в Хранилище окончательно только в момент закрытия формы. Если пользователь открыл форму, изменил состав колонок, не закрывая форму сразу нажал кнопку «Печать», данные в Хранилище могут оказаться устаревшими.
Выясним альтернативный вариант решения проблемы, который вообще не требует написания сложного программного кода по разбору коллекций. Если конечная цель пользователя состоит в том, чтобы просто распечатать настроенную им таблицу или сохранить ее в формате Excel/PDF, то в платформе 1С:Предприятие для этого есть готовый и мощный инструмент.
У любой стандартной таблицы на управляемой форме в меню «Ещё» присутствует стандартная команда «Вывести список». При ее вызове платформа автоматически анализирует текущую видимость колонок, их ширину, положение и выводит данные в новый табличный документ. Мы можем запустить это действие программно:
&НаКлиенте
Процедура ВыполнитьСтандартныйВыводСписка()
// Программный вызов стандартного окна формирования списка
ВыполнитьКоманду("ВывестиСписок");
КонецПроцедуры
Вы можете проинструктировать пользователя о наличии этой кнопки либо вынести ее на видное место формы в виде отдельной большой кнопки «Печать таблицы». Платформа сама позаботится о том, чтобы в отчет попали только те колонки, у которых в данный момент включена видимость.
Мы проанализировали три основных подхода к решению этой интересной задачи. Для мгновенного получения информации на клиенте без записи настроек используйте Способ 1 (с фокусом элементов). Если вам требуется надежная работа на сервере при генерации сложных печатных форм и вы можете гарантировать запись настроек в базу — выбирайте Способ 2 (с Хранилищем системных настроек). Если же нужно просто распечатать экранную таблицу — смело используйте штатный механизм платформы из Способа 3.