Как правильно вывести результат запроса в таблицу на форме в 1С вместо использования массива?

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

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

Проанализируем исходную проблему

Часто можно встретить примерно следующий подход к обработке результата запроса:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|   Смены.Наименование КАК Наименование,
|   Смены.ПометкаУдаления КАК ПометкаУдаления,
|   Смены.Ссылка КАК Ссылка
|ИЗ
|   Справочник.Смены КАК Смены";

РезультатЗапроса = Запрос.Выполнить();
ВыгрузкаСКП = РезультатЗапроса.Выгрузить();
МассивСКП = Новый Массив;

Для Каждого Источник из ВыгрузкаСКП Цикл
    МассивСКП.Добавить(Источник);
КонецЦикла;

В этом коде кроется серьезная логическая ошибка. Разберем по шагам, что здесь происходит. Метод РезультатЗапроса.Выгрузить() автоматически формирует в оперативной памяти полноценный объект типа ТаблицаЗначений. Колонки этой таблицы в точности соответствуют полям, указанным в тексте запроса (в нашем случае это Наименование, ПометкаУдаления и Ссылка).

Когда мы используем цикл Для Каждого..., переменная Источник представляет собой не отдельные данные, а элемент коллекции — то есть целую строку таблицы значений (объект СтрокаТаблицыЗначений). Добавляя эту строку в одномерный массив МассивСКП, мы просто создаем список ссылок на строки таблицы. Массив в 1С не умеет визуализироваться как полноценная таблица с колонками, поэтому попытка вывести его на экран приведет к разочарованию.

Почему использование циклов для копирования — это антипаттерн

То, что мы попытались сделать с помощью цикла перебора — это явный антипаттерн в разработке на платформе 1С. Любое копирование наборов данных, будь то перенос из результата запроса в таблицу значений или из одной таблицы в другую, всегда следует делать штатными платформенными методами. Ручной построчный обход результата в цикле:

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

Посмотрим на правильные инструменты платформы.

Как правильно вывести данные на Управляемую форму (УФ)

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

  1. Создадим реквизит формы с типом ТаблицаЗначений. Назовем его, например, ТаблицаСмен.
  2. Вынесем этот реквизит в элементы формы (перетащим в дереве элементов), чтобы платформа сгенерировала визуальную таблицу на экране.
  3. Убедимся, что имена колонок реквизита формы строго совпадают с именами полей (псевдонимами) в нашем запросе.

Теперь мы можем использовать серверный код для прямой загрузки результата запроса в этот реквизит. Сделать это можно без единого цикла двумя отличными способами.

Способ 1: Использование метода Загрузить()

Если мы сначала выгружаем запрос в промежуточную таблицу значений, то можем использовать метод реквизита формы:


ТаблицаИзЗапроса = Запрос.Выполнить().Выгрузить();
ЭтотОбъект.ТаблицаСмен.Загрузить(ТаблицаИзЗапроса);

Способ 2: Использование ЗначениеВРеквизитФормы()

Это классический и наиболее быстрый метод для управляемых форм:


ТаблицаИзЗапроса = Запрос.Выполнить().Выгрузить();
ЗначениеВРеквизитФормы(ТаблицаИзЗапроса, "ТаблицаСмен");

Как вывести данные на Обычную форму

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


// Загружаем результат запроса напрямую в элемент формы
ЭлементыФормы.ТабличноеПолеСмены.Значение = Запрос.Выполнить().Выгрузить();
// Приказываем элементу создать колонки на основе загруженной таблицы
ЭлементыФормы.ТабличноеПолеСмены.СоздатьКолонки();

Динамическое создание колонок на форме

Рассмотрим ситуацию, когда заранее неизвестно, какие именно колонки вернет запрос. Такое бывает при использовании конструкции ВЫБРАТЬ * или при динамической сборке текста запроса. В 1С можно создать колонки на управляемой форме программно. Для этого на сервере получают массив колонок из выгруженной таблицы значений, формируют массив объектов Новый РеквизитФормы и применяют метод ИзменитьРеквизиты(). После этого новые элементы управления добавляются на форму функцией Элементы.Добавить(). Это более сложный, но очень гибкий механизм.

Использование многомерных массивов (если таблица не подходит)

Если специфика вашей задачи требует обязательного использования именно массива (например, для передачи данных во внешнюю систему или специфичный COM-объект), то загонять в одномерный массив целые строки таблицы — ошибка. Чтобы получить правильную структуру, нужно использовать двумерный массив. Разберем пример создания такого массива из результата запроса:


ВыгрузкаСКП = Запрос.Выполнить().Выгрузить();
// Создаем двумерный массив, где строки - количество записей, а 2 - количество нужных нам полей
МассивСКП = Новый Массив(ВыгрузкаСКП.Количество(), 2);

Для Уровень = 0 По ВыгрузкаСКП.Количество() - 1 Цикл
    МассивСКП[Уровень][0] = ВыгрузкаСКП[Уровень].Наименование;
    МассивСКП[Уровень][1] = ВыгрузкаСКП[Уровень].Ссылка;
КонецЦикла;

В данном случае к табличному полю мы обращаемся как к коллекции и забираем нужные поля из конкретной строки. Однако еще раз подчеркнем: для отображения данных пользователю внутри 1С сама ТаблицаЗначений — это "массив, только лучше". Она обладает богатым набором встроенных методов поиска, сортировки и отбора.

Рекомендация по отладке запросов

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

← На главную