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