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

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача анализа текущего состояния интерфейса, который настроил для себя пользователь. Одной из таких задач является получение реального порядка колонок в таблице (будь то табличная часть документа или динамический список). Проблема заключается в том, что стандартная коллекция ПодчиненныеЭлементы, доступная через программный интерфейс формы, чаще всего возвращает порядок, заданный разработчиком в конфигураторе, игнорируя ручные правки пользователя через меню "Еще — Изменить форму".

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

Почему стандартный обход коллекции Элементы не дает результата

Давайте проанализируем ситуацию, с которой сталкивается большинство разработчиков. При попытке перебора колонок таблицы через Элементы.ИмяТаблицы.ПодчиненныеЭлементы мы ожидаем увидеть их в том порядке, в котором они отображаются на экране. Однако на практике порядок элементов в этой коллекции остается статичным. Рассмотрим пример кода, который часто пробуют использовать:


Для Каждого ЭлементТЧ Из Элементы.Товары.ПодчиненныеЭлементы Цикл
    Сообщить(ЭлементТЧ.Имя + " — Порядок в коллекции: " + Элементы.Товары.ПодчиненныеЭлементы.Индекс(ЭлементТЧ));
КонецЦикла;

Как показывает практика и обсуждения на форумах, этот цикл будет выдавать данные в порядке их создания в конфигураторе. Даже если пользователь поменяет местами "Номенклатуру" и "Количество", индекс элементов в программной коллекции не изменится. Это происходит потому, что платформа разделяет структуру формы и пользовательские настройки отображения.

Способ 1. Получение данных из Хранилища системных настроек

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

Рассмотрим алгоритм получения этих настроек. Нам необходимо знать имя формы и имя пользователя. Ключ объекта в хранилище формируется по определенному шаблону: ИмяФормы + "/НастройкиФормы".

Разберем программную реализацию получения этих данных на стороне сервера:


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

Важно понимать, что объект Настройки, который мы извлекаем, содержит иерархическую структуру. Если колонки вашей таблицы объединены в группы, вам придется рекурсивно обходить дерево настроек, чтобы составить плоский список колонок в правильном порядке.

Способ 2. Использование XML-сериализации для анализа структуры

Иногда объект настроек бывает сложно прочитать напрямую из-за специфических типов данных 1С. В таких случаях мы можем прибегнуть к хитрости: преобразовать настройки в XML-строку. В XML-представлении узлы элементов всегда следуют в том порядке, в котором они фактически расположены в интерфейсе пользователя.

Проанализируем следующий подход с использованием СериализаторXDTO:


// Получаем настройки из хранилища (как в предыдущем примере)
Настройки = ХранилищеСистемныхНастроек.Загрузить(ИмяФормы + "/НастройкиФормы");

Если Настройки <> Неопределено Тогда
    // Используем запись XML для получения текстового представления
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Настройки);
    
    ТекстНастроекXML = ЗаписьXML.Закрыть();
    
    // Теперь мы можем распарсить ТекстНастроекXML с помощью ЧтениеXML
    // Порядок тегов <item> внутри таблицы будет соответствовать визуальному порядку
КонецЕсли;

Этот метод позволяет "вытащить" не только порядок, но и состояние видимости колонок (свойство Visible или Использование), что критически важно, если ваша задача — выгрузить таблицу "как на экране".

Особенности работы с динамическими списками

Если ваша таблица на форме является Динамическим списком, ситуация усложняется. Пользователь может менять порядок колонок двумя способами:

  1. Через "Изменить форму" (визуальный порядок элементов формы).
  2. Через "Настроить список — Поля" (настройки компоновки данных).

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


ПоляСписка = ЭтаФорма.Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
    ЭтаФорма.Список.КомпоновщикНастроек.Настройки.ВыбранныеПоля.ИдентификаторПользовательскойНастройки
);
// Далее перебираем ПоляСписка.Элементы

Однако помните: если пользователь просто перетащил колонку мышкой в режиме "Изменить форму", изменения зафиксируются в НастройкиФормы, а не в компоновщике.

Важные нюансы и ограничения

При реализации механизмов получения порядка колонок следует учитывать несколько критических факторов:

Подводя итог, можно сказать: наиболее универсальным решением для получения пользовательского порядка колонок является чтение данных из ХранилищеСистемныхНастроек с последующим анализом структуры (через XML или прямой обход коллекции элементов настроек). Это гарантирует, что ваше программное решение будет полностью соответствовать тому, что видит пользователь на своем мониторе.

← На главную