В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача анализа текущего состояния интерфейса, который настроил для себя пользователь. Одной из таких задач является получение реального порядка колонок в таблице (будь то табличная часть документа или динамический список). Проблема заключается в том, что стандартная коллекция ПодчиненныеЭлементы, доступная через программный интерфейс формы, чаще всего возвращает порядок, заданный разработчиком в конфигураторе, игнорируя ручные правки пользователя через меню "Еще — Изменить форму".
В этой статье мы подробно разберем, почему стандартные методы не работают, и рассмотрим надежные способы извлечения актуального порядка колонок с использованием системных хранилищ и механизмов сериализации.
Давайте проанализируем ситуацию, с которой сталкивается большинство разработчиков. При попытке перебора колонок таблицы через Элементы.ИмяТаблицы.ПодчиненныеЭлементы мы ожидаем увидеть их в том порядке, в котором они отображаются на экране. Однако на практике порядок элементов в этой коллекции остается статичным. Рассмотрим пример кода, который часто пробуют использовать:
Для Каждого ЭлементТЧ Из Элементы.Товары.ПодчиненныеЭлементы Цикл
Сообщить(ЭлементТЧ.Имя + " — Порядок в коллекции: " + Элементы.Товары.ПодчиненныеЭлементы.Индекс(ЭлементТЧ));
КонецЦикла;
Как показывает практика и обсуждения на форумах, этот цикл будет выдавать данные в порядке их создания в конфигураторе. Даже если пользователь поменяет местами "Номенклатуру" и "Количество", индекс элементов в программной коллекции не изменится. Это происходит потому, что платформа разделяет структуру формы и пользовательские настройки отображения.
Самый эффективный способ узнать, что именно "наворотил" пользователь в интерфейсе — это обратиться к ХранилищеСистемныхНастроек. Именно там платформа сохраняет все изменения, внесенные через диалог "Изменить форму".
Рассмотрим алгоритм получения этих настроек. Нам необходимо знать имя формы и имя пользователя. Ключ объекта в хранилище формируется по определенному шаблону: ИмяФормы + "/НастройкиФормы".
Разберем программную реализацию получения этих данных на стороне сервера:
Функция ПолучитьАктуальныйПорядокКолонок(ИмяФормы, ИмяПользователя) Экспорт
// Формируем структуру отбора для поиска настроек
Отбор = Новый Структура;
Отбор.Вставить("Пользователь", ИмяПользователя);
Отбор.Вставить("КлючОбъекта", ИмяФормы + "/НастройкиФормы");
// Выбираем данные из системного хранилища
Выборка = ХранилищеСистемныхНастроек.Выбрать(Отбор);
Если Выборка.Следующий() Тогда
// Настройки представляют собой сложный объект или структуру
НастройкиФормы = Выборка.Настройки;
// В современных версиях 1С настройки можно проанализировать
// как дерево элементов, повторяющее структуру формы
Возврат НастройкиФормы;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Важно понимать, что объект Настройки, который мы извлекаем, содержит иерархическую структуру. Если колонки вашей таблицы объединены в группы, вам придется рекурсивно обходить дерево настроек, чтобы составить плоский список колонок в правильном порядке.
Иногда объект настроек бывает сложно прочитать напрямую из-за специфических типов данных 1С. В таких случаях мы можем прибегнуть к хитрости: преобразовать настройки в XML-строку. В XML-представлении узлы элементов всегда следуют в том порядке, в котором они фактически расположены в интерфейсе пользователя.
Проанализируем следующий подход с использованием СериализаторXDTO:
// Получаем настройки из хранилища (как в предыдущем примере)
Настройки = ХранилищеСистемныхНастроек.Загрузить(ИмяФормы + "/НастройкиФормы");
Если Настройки <> Неопределено Тогда
// Используем запись XML для получения текстового представления
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Настройки);
ТекстНастроекXML = ЗаписьXML.Закрыть();
// Теперь мы можем распарсить ТекстНастроекXML с помощью ЧтениеXML
// Порядок тегов <item> внутри таблицы будет соответствовать визуальному порядку
КонецЕсли;
Этот метод позволяет "вытащить" не только порядок, но и состояние видимости колонок (свойство Visible или Использование), что критически важно, если ваша задача — выгрузить таблицу "как на экране".
Если ваша таблица на форме является Динамическим списком, ситуация усложняется. Пользователь может менять порядок колонок двумя способами:
Нужно учитывать, что визуальные настройки формы (Способ 1) имеют приоритет над настройками компоновки. Если вы хотите получить порядок полей именно из настроек списка, используйте КомпоновщикНастроек:
ПоляСписка = ЭтаФорма.Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
ЭтаФорма.Список.КомпоновщикНастроек.Настройки.ВыбранныеПоля.ИдентификаторПользовательскойНастройки
);
// Далее перебираем ПоляСписка.Элементы
Однако помните: если пользователь просто перетащил колонку мышкой в режиме "Изменить форму", изменения зафиксируются в НастройкиФормы, а не в компоновщике.
При реализации механизмов получения порядка колонок следует учитывать несколько критических факторов:
ХранилищеСистемныхНастроек возможен только на сервере. Не пытайтесь вызвать этот метод непосредственно в клиентской процедуре.Элементы.Переместить(), то в рамках текущего сеанса порядок в коллекции ПодчиненныеЭлементы обновится. Но это касается только действий, сделанных кодом, а не интерактивно пользователем.Подводя итог, можно сказать: наиболее универсальным решением для получения пользовательского порядка колонок является чтение данных из ХранилищеСистемныхНастроек с последующим анализом структуры (через XML или прямой обход коллекции элементов настроек). Это гарантирует, что ваше программное решение будет полностью соответствовать тому, что видит пользователь на своем мониторе.