Как программно определить колонки, которые настроил пользователь через "Изменить форму"

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Проанализируем основную сложность этой задачи. Если мы попытаемся решить проблему «в лоб» и программно обратиться к свойству видимости элемента формы через код Элементы.ИмяКолонки.Видимость, то мы столкнемся с тем, что платформа всегда возвращает первоначальное значение Истина (или то значение, которое задано разработчиком в Конфигураторе). Платформа 1С:Предприятие разделяет базовую видимость элемента и так называемую пользовательскую видимость. Настройки пользователя накладываются поверх стандартных свойств, и напрямую прочитать их через стандартное свойство Видимость на клиенте обычным способом не удастся.

Разберем подробно несколько проверенных и рабочих способов, которые помогут нам программно определить, какие именно колонки пользователь оставил видимыми на форме.

Способ 1. Обход через установку фокуса (Лайфхак на клиенте)

Этот способ является одним из самых простых, быстрых и оригинальных решений, которое выполняется полностью на клиенте «здесь и сейчас». Нам не требуется выполнять серверные вызовы или обращаться к базе данных. Он базируется на особенности поведения платформы 1С:Предприятие: система физически не позволяет сделать активным скрытый элемент формы.

Выясним алгоритм реализации этого метода:

  1. Запоминаем текущий активный элемент формы, чтобы в конце алгоритма вернуть фокус на место и не путать пользователя.
  2. В цикле обходим все колонки нашей таблицы или дерева значений.
  3. Для каждого элемента (колонки) в блоке Попытка ... Исключение пытаемся установить фокус, сделав его текущим элементом формы.
  4. Если платформа успешно перевела фокус на колонку, значит, колонка в данный момент видима. Если произошла ошибка или значение текущего элемента не изменилось — колонка скрыта пользователем.
  5. Возвращаем фокус на исходный сохраненный элемент.

Посмотрим на пример практической реализации данного метода:


&НаКлиенте
Процедура ОпределитьВидимыеКолонкиПоФокусу()
    
    // Запоминаем текущий фокус, чтобы вернуть его в конце
    СтарыйАктивныйЭлемент = ЭтаФорма.ТекущийЭлемент;
    
    // Создаем массив для хранения имен видимых колонок
    МассивВидимыхКолонок = Новый Массив;
    
    // Получаем коллекцию колонок нашей таблицы (замените "ДеревоДанных" на имя вашей таблицы)
    КолонкиТаблицы = Элементы.ДеревоДанных.ПодчиненныеЭлементы;
    
    Для Каждого Колонка Из КолонкиТаблицы Цикл
        
        // Интересуют только элементы типа "ПолеФормы"
        Если ТипЗнч(Колонка) <> Тип("ПолеФормы") Тогда
            Продолжить;
        КонецЕсли;
        
        Попытка
            // Пытаемся передать фокус текущей колонке
            ЭтаФорма.ТекущийЭлемент = Колонка;
            
            // Если фокус успешно перешел, добавляем колонку в список видимых
            Если ЭтаФорма.ТекущийЭлемент = Колонка Тогда
                МассивВидимыхКолонок.Добавить(Колонка.Имя);
            КонецЕсли;
        Исключение
            // Сюда код попадает, если колонка скрыта пользователем через "Изменить форму"
            // Платформа вызывает исключение при попытке активировать невидимый элемент
        КонецПопытки;
        
    КонецЦикла;
    
    // Обязательно возвращаем фокус пользователю назад
    ЭтаФорма.ТекущийЭлемент = СтарыйАктивныйЭлемент;
    
    // Передаем полученный массив для дальнейшей генерации печатной формы
    ОбработатьВыбранныеКолонки(МассивВидимыхКолонок);
    
КонецПроцедуры

Преимущества метода: Работает мгновенно, не требует серверных вызовов, отражает настройки пользователя, примененные только что (даже если форма еще не закрывалась и настройки не сохранились в базу данных).

Недостатки метода: На долю секунды интерфейс может визуально «моргнуть», когда фокус пробегает по колонкам. На производительных компьютерах этот эффект практически незаметен.

Способ 2. Чтение настроек из Хранилища системных настроек

Когда пользователь закрывает форму или нажимает кнопку «Применить» в окне изменения формы, платформа автоматически сохраняет эти параметры в базу данных. Местом хранения является специальный системный объект — ХранилищеСистемныхНастроек.

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

"Обработка.[ИмяОбработки].Форма.[ИмяФормы]/НастройкиФормы"

Или, в зависимости от используемого интерфейса и конфигурации, ключ может заканчиваться на "/Такси/НастройкиОкна".

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


&НаСервере
Функция ПолучитьНастройкиВидимостиИзХранилища()
    
    // Формируем ключ объекта настроек для нашей формы
    КлючОбъекта = "Обработка.МояПечатнаяФорма.Форма.ФормаНастройки/НастройкиФормы";
    ИмяПользователя = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
    
    // Загружаем настройки из системного хранилища
    Настройки = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта, "", , ИмяПользователя);
    
    МассивВидимыхКолонок = Новый Массив;
    
    Если Настройки <> Неопределено Тогда
        // Настройки возвращаются в виде объекта НастройкиФормы
        // Мы можем обойти структуру дерева элементов, хранящуюся внутри
        Для Каждого ЭлементНастройки Из Настройки.Элементы Цикл
            // Проверяем пользовательскую видимость элемента
            Если ЭлементНастройки.Видимость Тогда
                МассивВидимыхКолонок.Добавить(ЭлементНастройки.Имя);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
    Возврат МассивВидимыхКолонок;
    
КонецФункции

Преимущества метода: Надежное и документированное получение настроек формы напрямую из системной базы данных без манипуляций с фокусом ввода.

Недостатки метода: Настройки записываются платформой в Хранилище окончательно только в момент закрытия формы. Если пользователь открыл форму, изменил состав колонок, не закрывая форму сразу нажал кнопку «Печать», данные в Хранилище могут оказаться устаревшими.

Способ 3. Использование стандартной команды «Вывести список»

Выясним альтернативный вариант решения проблемы, который вообще не требует написания сложного программного кода по разбору коллекций. Если конечная цель пользователя состоит в том, чтобы просто распечатать настроенную им таблицу или сохранить ее в формате Excel/PDF, то в платформе 1С:Предприятие для этого есть готовый и мощный инструмент.

У любой стандартной таблицы на управляемой форме в меню «Ещё» присутствует стандартная команда «Вывести список». При ее вызове платформа автоматически анализирует текущую видимость колонок, их ширину, положение и выводит данные в новый табличный документ. Мы можем запустить это действие программно:


&НаКлиенте
Процедура ВыполнитьСтандартныйВыводСписка()
    // Программный вызов стандартного окна формирования списка
    ВыполнитьКоманду("ВывестиСписок");
КонецПроцедуры

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

Резюме

Мы проанализировали три основных подхода к решению этой интересной задачи. Для мгновенного получения информации на клиенте без записи настроек используйте Способ 1 (с фокусом элементов). Если вам требуется надежная работа на сервере при генерации сложных печатных форм и вы можете гарантировать запись настроек в базу — выбирайте Способ 2 (с Хранилищем системных настроек). Если же нужно просто распечатать экранную таблицу — смело используйте штатный механизм платформы из Способа 3.

← На главную