Как сохранить и загрузить настройки условного оформления динамического списка в 1С для разных пользователей?

Программист 1С v8.3 (Управляемые формы)
← К списку

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

1. Общий подход: Работа с КомпоновщикомНастроек динамического списка

Мы знаем, что каждый динамический список в 1С имеет свой КомпоновщикНастроек. Этот объект является центральным элементом для управления отображением данных в списке, включая отборы, сортировки, группировки и, что самое главное для нас, условное оформление. Рассмотрим подробнее, как мы можем взаимодействовать с ним:

  1. Получение текущих настроек: Чтобы сохранить настройки, нам сначала нужно их получить. Объект КомпоновщикНастроек динамического списка предоставляет метод ПолучитьНастройки(). Этот метод возвращает объект типа НастройкиКомпоновкиДанных, который содержит все текущие установки списка.
    
    НастройкиСписка = Список.КомпоновщикНастроек.ПолучитьНастройки();
    
  2. Установка настроек: Соответственно, для применения ранее сохраненных настроек используется метод УстановитьНастройки().
    
    Список.КомпоновщикНастроек.УстановитьНастройки(НастройкиДляЗагрузки);
    
  3. Пользовательские настройки: Условное оформление, как и другие специфические настройки, хранится в свойстве ПользовательскиеНастройки объекта КомпоновщикНастроек. Это свойство, в свою очередь, является объектом типа ПользовательскиеНастройкиКомпоновкиДанных. Мы можем обращаться к его элементам для добавления, изменения или удаления правил условного оформления.
  4. События сохранения/загрузки: Платформа предоставляет специальные обработчики событий для работы с пользовательскими настройками на сервере: ПриСохраненииПользовательскихНастроекНаСервере и ПриЗагрузкеПользовательскихНастроекНаСервере. Мы можем использовать их для перехвата стандартного процесса и внедрения нашей логики централизованного хранения и применения.

2. Решение с использованием ХранилищаЗначения и константы (пример из форума)

Один из способов, предложенных на форуме, — это сохранение настроек в ХранилищеЗначения, которое затем помещается в константу. Этот подход позволяет централизовать настройки, например, для администратора, который их задает, а остальные пользователи просто загружают. Давайте проанализируем ситуацию и разберем этот пример по шагам.

2.1. Концепция ХранилищаЗначения

ХранилищеЗначения — это универсальный тип данных в 1С, который позволяет сохранять в базе практически любые сериализуемые объекты, включая двоичные данные. Его важная особенность — возможность хранения данных в сжатом виде, что может быть полезно для экономии места. Мы можем использовать ХранилищеЗначения как реквизит справочника, документа, ресурс регистра сведений или тип константы.

2.2. Пример кода: Администратор задает, остальные загружают

Представим сценарий, когда определенный пользователь (например, "Администратор") настраивает условное оформление, а все остальные пользователи должны видеть это оформление.

Рассмотрим функцию Проверка(), которая реализует такую логику:


Функция Проверка()
    ТекПоль = ПользователиКлиентСервер.ТекущийПользователь();
    Если ТекПоль.Наименование = "Администратор" Тогда // Кто главный задает настройки
        ПолучаюНастройки = Список.КомпоновщикНастроек.ПолучитьНастройки();
        Хранилище = Новый ХранилищеЗначения(ПолучаюНастройки, Новый СжатиеДанных());
        Константы.ОСК_ХранЗнач.Установить(Хранилище);
    Иначе
        Попытка
            ХранилищеПолуч = Константы.ОСК_ХранЗнач.Получить();
            ХранилищеПолуч2 = ХранилищеПолуч.Получить();

            // Очищаем существующие элементы условного оформления
            // Элементы[2] здесь - это, предположительно, коллекция условного оформления
            // (индекс может отличаться в зависимости от структуры настроек)
            Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[2].Элементы.Очистить();

            // Перебираем и добавляем элементы условного оформления из сохраненных настроек
            Для Каждого ЭлПолуч Из ХранилищеПолуч2.УсловноеОформление.Элементы Цикл
                Для СчетЭл = 0 По ЭлПолуч.Оформление.Элементы.Количество()-1 Цикл
                    Если ЭлПолуч.Оформление.Элементы[СчетЭл].Использование = Истина Тогда
                        // Добавляем новый элемент условного оформления
                        ДобЭл = Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[2].Элементы.Добавить();
                        // Копируем значение и флаг использования
                        ДобЭл.Оформление.Элементы[СчетЭл].Значение = ЭлПолуч.Оформление.Элементы[СчетЭл].Значение;
                        ДобЭл.Оформление.Элементы[СчетЭл].Использование = Истина;
                    КонецЕсли;
                КонецЦикла;
            КонецЦикла;
        Исключение
            Сообщить("Ошибка загрузки оформления " + ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
КонецФункции

Давайте разберем эту логику:

  1. Определение пользователя: Сначала мы получаем текущего пользователя системы. Если это пользователь с наименованием "Администратор", то он будет отвечать за сохранение настроек.
    
    ТекПоль = ПользователиКлиентСервер.ТекущийПользователь();
    Если ТекПоль.Наименование = "Администратор" Тогда
    
  2. Сохранение настроек (для Администратора):
    • Мы получаем текущие настройки компоновщика данных динамического списка с помощью Список.КомпоновщикНастроек.ПолучитьНастройки().
    • Создаем новое ХранилищеЗначения, передавая в него полученные настройки и указывая, что данные нужно сжать (Новый СжатиеДанных()).
    • Сохраняем это ХранилищеЗначения в константу ОСК_ХранЗнач. Для этого константа должна быть соответствующего типа (ХранилищеЗначения).
    • 
      ПолучаюНастройки = Список.КомпоновщикНастроек.ПолучитьНастройки();
      Хранилище = Новый ХранилищеЗначения(ПолучаюНастройки, Новый СжатиеДанных());
      Константы.ОСК_ХранЗнач.Установить(Хранилище);
      
  3. Загрузка настроек (для остальных пользователей):
    • В блоке Иначе происходит попытка загрузки настроек. Мы получаем ХранилищеЗначения из константы и затем извлекаем из него сами настройки (ХранилищеПолуч.Получить()).
    • Важный момент: прямая загрузка настроек через Список.КомпоновщикНастроек.УстановитьНастройки() или Список.КомпоновщикНастроек.ПользовательскиеНастройки.ЗагрузитьНастройки() может не сработать, если у списка есть "фиксированные" настройки, которые не позволяют полностью перезаписать коллекцию. В этом случае, как показано в примере, приходится работать с элементами условного оформления вручную.
    • Мы сначала очищаем существующие элементы условного оформления (предполагается, что Элементы[2] в ПользовательскиеНастройки.Элементы соответствует коллекции условного оформления). Обратите внимание: индекс [2] является "магическим числом" и может меняться в зависимости от конфигурации и версии платформы. Лучше искать элемент по его типу или имени.
    • 
      Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[2].Элементы.Очистить();
      
    • Затем мы в цикле перебираем элементы условного оформления из загруженных настроек (ХранилищеПолуч2.УсловноеОформление.Элементы). Для каждого элемента, если он используется, мы создаем новый элемент в текущем компоновщике настроек списка и копируем в него значения оформления.
    • 
      Для Каждого ЭлПолуч Из ХранилищеПолуч2.УсловноеОформление.Элементы Цикл
          Для СчетЭл = 0 По ЭлПолуч.Оформление.Элементы.Количество()-1 Цикл
              Если ЭлПолуч.Оформление.Элементы[СчетЭл].Использование = Истина Тогда
                  ДобЭл = Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы[2].Элементы.Добавить();
                  ДобЭл.Оформление.Элементы[СчетЭл].Значение = ЭлПолуч.Оформление.Элементы[СчетЭл].Значение;
                  ДобЭл.Оформление.Элементы[СчетЭл].Использование = Истина;
              КонецЕсли;
          КонецЦикла;
      КонецЦикла;
      
    • Блок Попытка...Исключение обеспечивает обработку возможных ошибок при загрузке.

Недостатки данного подхода:

3. Рекомендуемый подход: Использование специализированных ХранилищНастроек

Платформа 1С:Предприятие предлагает более мощные и гибкие механизмы для хранения пользовательских настроек — это специализированные объекты ХранилищеНастроек. Они позволяют сохранять настройки как для текущего пользователя, так и для всех пользователей.

3.1. Виды ХранилищНастроек

Существует несколько предопределенных хранилищ настроек, каждое из которых предназначено для своих целей:

3.2. Как использовать специализированные хранилища

Вместо константы мы можем использовать, например, ХранилищеОбщихНастроек или ХранилищеПользовательскихНастроекДинамическихСписков. Рассмотрим общую логику:

  1. Определяем уникальный ключ: Для сохранения настроек нам понадобится уникальный ключ, по которому мы будем их идентифицировать. Это может быть имя формы, имя динамического списка или любой другой строковый идентификатор.
  2. Сохранение настроек:

    Мы получаем настройки компоновщика данных, как и в предыдущем примере, а затем используем метод Сохранить() соответствующего хранилища.

    
    НастройкиСписка = Список.КомпоновщикНастроек.ПолучитьНастройки();
    
    // Если хотим сохранить общие настройки для всех
    ХранилищеОбщихНастроек.Сохранить(НастройкиСписка, "МоиНастройкиУсловногоОформления");
    
    // Если хотим сохранить настройки для динамического списка
    // (обычно используется платформой автоматически, но можно и программно)
    // ХранилищеПользовательскихНастроекДинамическихСписков.Сохранить(Список, НастройкиСписка);
    

    Для ХранилищеОбщихНастроек первый параметр — это сохраняемое значение, второй — ключ. Для ХранилищеПользовательскихНастроекДинамическихСписков, если мы хотим использовать его как "общее", нам придется обернуть его в свой механизм, либо использовать его по прямому назначению (для индивидуальных настроек пользователя).

  3. Загрузка настроек:

    Для загрузки используется метод Загрузить(). Он вернет ранее сохраненные настройки, которые мы затем можем применить к компоновщику данных.

    
    // Загружаем общие настройки
    НастройкиДляЗагрузки = ХранилищеОбщихНастроек.Загрузить("МоиНастройкиУсловногоОформления");
    
    Если НастройкиДляЗагрузки <> Неопределено Тогда
        Список.КомпоновщикНастроек.УстановитьНастройки(НастройкиДляЗагрузки);
    Иначе
        Сообщить("Общие настройки условного оформления не найдены.");
    КонецЕсли;
    
  4. Применение в типовых решениях:

    Мы можем посмотреть, как реализовано копирование настроек пользователя в типовых конфигурациях. Часто там используются именно эти специализированные хранилища, что позволяет избежать ручной работы с элементами и обеспечивает большую надежность.

3.3. Лучшие практики при работе с условным оформлением

Проанализируем дополнительные рекомендации, которые помогут нам в работе:

  1. Место программной настройки: Рекомендуется выполнять программную настройку условного оформления форм и динамических списков в коде формы, предпочтительно в обработчике события ПриСозданииНаСервере. Это гарантирует, что настройки будут применены при каждом открытии формы.
  2. Общие модули: Для вынесения однотипных настроек в общие модули мы можем создавать функции, которые будут принимать КомпоновщикНастроек в качестве параметра и применять к нему стандартный набор правил.
  3. Избегайте скрытия строк: Не рекомендуется использовать условное оформление для скрытия строк целиком в таблице. Это может замедлять работу, особенно в веб-клиенте, и приводить к некорректному отображению. Для фильтрации данных лучше использовать отборы.
  4. Приоритет: Если у нас есть выбор между условным оформлением динамического списка и условным оформлением формы, предпочтительнее использовать условное оформление самого динамического списка. Это может ускорить открытие формы, так как часть обработки выполняется на стороне источника данных.
  5. Установка параметров: Для установки параметров динамического списка мы используем метод УстановитьЗначениеПараметра объекта динамического списка, также обычно в обработчике события ПриСозданииНаСервере формы.

Заключение

Мы рассмотрели несколько подходов к сохранению и загрузке условного оформления динамических списков в 1С. Хотя использование ХранилищаЗначения через константу может показаться простым решением, оно имеет свои ограничения. Мы выяснили, что более предпочтительным и гибким является использование специализированных ХранилищНастроек, таких как ХранилищеОбщихНастроек или ХранилищеПользовательскихНастроекДинамическихСписков. Эти механизмы обеспечивают большую надежность, масштабируемость и соответствуют архитектуре платформы 1С:Предприятие. Всегда стремитесь к использованию стандартных и рекомендуемых средств платформы для достижения наилучших результатов.

← К списку