Гарантирует ли массив в 1С сохранение порядка элементов? Разбираемся в поведении коллекций

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

При проектировании бизнес-логики в платформе «1С:Предприятие» разработчики регулярно сталкиваются с необходимостью упорядочивания данных. Сортировка списков, подготовка данных для вывода в отчетах или на формах — все это требует четкого понимания того, как ведут себя различные коллекции. Иногда среди программистов возникает сомнение: гарантирует ли обычный Массив сохранение того порядка элементов, в котором они были в него добавлены? Или же платформа может произвольно перемешать данные внутри него?

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

Анализ исходной проблемы и пример кода

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


// Сортировка виджетов по наименованию
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Виджеты.Ссылка
|ИЗ
|	Справочник.Виджеты КАК Виджеты
|ГДЕ
|	Виджеты.Ссылка В(&Виджеты)
|
|УПОРЯДОЧИТЬ ПО
|	Виджеты.Наименование";

Запрос.УстановитьПараметр("Виджеты", ДоступныеВиджеты);
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");

У автора кода возникло опасение: если конечным результатом работы функции является Массив (который возвращается методом ВыгрузитьКолонку()), не «растеряется» ли сортировка, заданная в запросе через предложение УПОРЯДОЧИТЬ ПО? Давайте разберем эту цепочку вызовов по шагам, чтобы выяснить истину.

Как формируется порядок при выгрузке из запроса

Выполняемый код работает строго детерминировано. Давайте проанализируем каждый этап преобразования данных:

  1. Результат запроса: Конструкция УПОРЯДОЧИТЬ ПО Виджеты.Наименование гарантирует, что СУБД вернет выборку, отсортированную по алфавиту. Порядок строк на этом этапе строго определен требованиями запроса.
  2. Выгрузка в таблицу значений: Метод Выгрузить() переносит записи из результата запроса в объект типа ТаблицаЗначений. Строки добавляются в таблицу последовательно, одна за другой, строго в том порядке, в котором их вернула база данных. Каждая строка получает свой индекс — от 0 до N-1. Таблица значений гарантирует неизменность индексов строк, если с ней не производятся явные манипуляции (например, повторная сортировка или удаление строк).
  3. Получение массива колонок: Метод ВыгрузитьКолонку("Ссылка") осуществляет последовательный обход строк таблицы значений (от нулевого индекса до последнего) и копирует значения из указанной колонки в новый объект типа Массив.

Поскольку Массив в платформе 1С представляет собой классический индексированный динамический список, он физически сохраняет элементы ровно в той последовательности, в которой они в него добавлялись. Никакого «скрытого» перестроения индексов или хэширования внутри массива не происходит. Таким образом, возвращаемый массив гарантированно сохранит сортировку по наименованию.

Почему возникли сомнения: путаница со Структурой и Соответствием

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

Особенности работы со Структурой в 1С:Предприятии 8

Объект типа Структура предназначен для хранения пар «Ключ - Значение», где доступ к элементам осуществляется по имени ключа (свойства). Тем не менее, платформой поддерживается обход структуры с помощью цикла Для каждого ... Из .... И здесь кроется важный нюанс:

Непредсказуемый порядок в Соответствии

Объект Соответствие (аналог HashMap в других языках программирования) ведет себя еще более непредсказуемо:

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

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

Кардинальные изменения в современном стеке (1С:Элемент и 1С:Исполнитель)

Технологии 1С развиваются, и в новом стеке (проект 1С:Элемент) разработчики полностью пересмотрели поведение базовых коллекций, сделав его более современным и предсказуемым:

Резюме и правила для разработчика

Подводя итог, мы можем составить краткий свод правил, которыми следует руководствоваться при написании кода:

  1. Массив — это самый надежный способ хранения упорядоченных данных в 1С. Порядок элементов в нем всегда соответствует порядку их добавления или сортировки исходного источника (запроса, таблицы значений).
  2. Если вам необходимо гарантировать порядок следования пар «Ключ - Значение» в классической платформе 1С:Предприятие 8, используйте Массив, состоящий из Структур, либо Таблицу Значений с колонками «Ключ» и «Значение». Не полагайтесь на прямой обход одной лишь Структуры или Соответствия.
  3. Код вида Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ИмяКолонки") является абсолютно корректным, безопасным и широко применяется в типовых решениях фирмы «1С» для получения отсортированных списков значений.
← На главную