К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как свернуть массив в 1С: убираем дубли и повторяющиеся элементы

Как свернуть массив в 1С: удаление дублей через соответствие, таблицу значений и Свернуть(). Примеры кода, сравнение способов, типичные ошибки и FAQ.

Во встроенном языке 1С нет отдельного метода «Свернуть» для массива — такой метод есть только у таблицы значений. Поэтому под фразой «свернуть массив» разработчики обычно понимают одну из двух задач: убрать из массива дублирующиеся значения (получить список уникальных элементов) или сгруппировать однотипные данные с суммированием числовых показателей. Оба сценария решаются штатными средствами платформы без внешних компонент.

Выбор способа зависит от структуры данных. Если массив содержит простые значения — строки, числа, ссылки — быстрее всего свернуть его через объект «Соответствие» или через таблицу значений с методом Свернуть(). Если же массив хранит структуры с несколькими полями и нужно сгруппировать их с суммированием, без таблицы значений не обойтись: именно она умеет группировать строки по измерениям и суммировать ресурсы.

Ниже разобраны рабочие варианты кода для обеих задач, критерии выбора между ними, ограничения каждого подхода и типичные ошибки, из-за которых свёртка работает не так, как ожидается.

Что значит «свернуть массив» в контексте 1С

Термин пришёл из методики работы с таблицей значений, где метод Свернуть(КолонкиГруппировок, КолонкиСуммирования) объединяет одинаковые строки. Когда говорят «свернуть массив», чаще всего имеют в виду более простую операцию — оставить в массиве только уникальные значения, отбросив повторы. Например, из массива ссылок на номенклатуру, собранного из табличной части документа, получить список без повторений для запроса или отбора.

Вторая трактовка — свёртка с агрегацией: есть массив структур вида «Товар + Количество», и нужно получить итог по каждому товару. Это уже не удаление дублей, а группировка, и решается она иначе. Важно сразу определить, какая из задач стоит перед вами, потому что инструменты и код различаются принципиально.

Способ 1. Свернуть массив через Соответствие

Самый быстрый и короткий приём для массива простых значений — использовать объект «Соответствие». Его ключи уникальны по определению: повторная установка значения по тому же ключу просто перезаписывает элемент. Достаточно пройти по массиву, положить каждый элемент как ключ, а затем собрать ключи обратно в новый массив.

Функция СвернутьМассив(ИсходныйМассив)

Уникальные = Новый Соответствие;

Для Каждого Элемент Из ИсходныйМассив Цикл

Уникальные.Вставить(Элемент, Истина);

КонецЦикла;

Результат = Новый Массив;

Для Каждого КлючИЗначение Из Уникальные Цикл

Результат.Добавить(КлючИЗначение.Ключ);

КонецЦикла;

Возврат Результат;

КонецФункции

Порядок элементов в результате не гарантирован: соответствие не обязано сохранять последовательность вставки. Если порядок критичен (например, массив используется для вывода пользователю), добавьте проверку — помещайте элемент в результирующий массив только при первой встрече, а соответствие используйте как регистр «уже виденных» значений.

Функция СвернутьМассивССохранениемПорядка(ИсходныйМассив)

Встреченные = Новый Соответствие;

Результат = Новый Массив;

Для Каждого Элемент Из ИсходныйМассив Цикл

Если Встреченные[Элемент] = Неопределено Тогда

Встреченные.Вставить(Элемент, Истина);

Результат.Добавить(Элемент);

КонецЕсли;

КонецЦикла;

Возврат Результат;

КонецФункции

Способ 2. Свёртка через таблицу значений и метод Свернуть()

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

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Значение");

Для Каждого Элемент Из ИсходныйМассив Цикл

ТЗ.Добавить().Значение = Элемент;

КонецЦикла;

ТЗ.Свернуть("Значение");

СвернутыйМассив = ТЗ.ВыгрузитьКолонку("Значение");

Этот же подход закрывает вторую задачу — группировку с итогами. Пусть есть массив структур «Товар, Количество, Сумма». Выгружаем его в таблицу значений и сворачиваем по товару с суммированием:

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Товар");

ТЗ.Колонки.Добавить("Количество");

ТЗ.Колонки.Добавить("Сумма");

Для Каждого Стр Из МассивСтруктур Цикл

НоваяСтрока = ТЗ.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);

КонецЦикла;

ТЗ.Свернуть("Товар", "Количество,Сумма");

После вызова Свернуть() таблица изменяется «на месте» — исходные детальные строки теряются. Если они ещё понадобятся, сначала сделайте копию методом Скопировать() и сворачивайте копию.

Сравнение способов: что выбрать

Оба подхода рабочие, но у них разные накладные расходы и ограничения. Соответствие создаётся быстрее и не требует описывать колонки, зато таблица значений даёт суммирование и дальнейшую сортировку из коробки.

КритерийСоответствиеТаблица значений + Свернуть()
Тип элементовПростые значения, ссылкиЛюбые, включая многоколоночные данные
Суммирование при группировкеНет, только удаление дублейДа, по указанным колонкам
Сохранение порядкаТолько с дополнительной проверкойПорядок групп определяется первым вхождением
Объём кодаМинимальныйТребуется описание колонок и выгрузка
Дальнейшая обработкаТолько массив на выходеСортировка, поиск, итоги, выгрузка

Сравнение вариантов

Соответствие

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

Таблица значений

Подходит для структур и когда нужна группировка с итогами. Требует больше кода и изменяет исходную таблицу.

Запрос с СГРУППИРОВАТЬ ПО

Оптимален, если данные уже в базе: свёртку выполнит СУБД. Не работает с массивом, полученным вне запроса, без выгрузки во временную таблицу.

Свёртка на уровне запроса

Если массив формируется из данных информационной базы, часто правильнее вообще не сворачивать его в коде, а поручить группировку запросу. Оператор СГРУППИРОВАТЬ ПО с функциями СУММА, КОЛИЧЕСТВО, МАКСИМУМ выполняется на стороне СУБД и обычно быстрее циклической обработки, особенно на больших выборках.

Массив можно передать в запрос как параметр и использовать в условии В(&Массив) — но сам массив при этом не сворачивается, а лишь фильтрует выборку. Если нужно обратное — свернуть уже полученный массив через запрос — его придётся поместить во временную таблицу, что оправдано только при больших объёмах и необходимости соединения с данными базы.

Маршрут решения

Как выбрать действие

Массив содержит ссылки или строки, нужны только уникальные значенияИспользуйте Соответствие — минимум кода и высокая скорость
Массив содержит структуры, нужны итоги по группамВыгрузите в таблицу значений и примените Свернуть() с колонками суммирования
Данные ещё не выбраны из базыВыполните группировку в запросе через СГРУППИРОВАТЬ ПО, не формируя лишний массив
Порядок элементов важен для пользователяПрименяйте вариант с соответствием и проверкой первого вхождения

Проверка результата и типичные ошибки

После свёртки убедитесь, что результат соответствует ожиданиям: количество элементов не превышает исходное, повторы отсутствуют, суммы при группировке сходятся с итогом по исходным данным. Простой контроль — сравнить сумму числовых колонок до и после свёртки: она должна совпасть.

Контрольные точки

Как проверить результат

Число элементов после свёртки
Норма

Меньше или равно исходному, дублей нет

Тревожный признак

Элементов стало больше или пропали нужные значения

Сумма числовых колонок
Норма

Итог до и после свёртки совпадает

Тревожный признак

Сумма изменилась — ошибка в колонках группировки

Ссылки в результате
Норма

Все ссылки того же типа, что в исходном массиве

Тревожный признак

Появились Неопределено или пустые ссылки

Типичные ошибки
01
Свёртка массива структур через соответствие: структуры сравниваются по экземпляру, дубли не удаляются — нужен переход к таблице значений или сравнение по ключевому полю.
02
Вызов Свернуть() для исходной таблицы вместо копии: детальные строки теряются, и последующие этапы алгоритма получают неполные данные.
03
Указание в колонках суммирования нечислового поля: значение обнуляется или результат непредсказуем, суммировать можно только числа.
04
Ожидание сохранения порядка при свёртке через соответствие: порядок ключей не гарантирован, для упорядоченного результата нужна проверка первого вхождения.
Удобно оформить свёртку как функцию общего модуля с признаком сохранения порядка. Тогда в прикладном коде остаётся одна строка вызова, а отладка и изменение логики ведутся в одном месте, а не размазываются по десяткам процедур.
ПЗ
Практическое замечание

Ограничения и границы применения

Массив в 1С не поддерживает вложенные массивы произвольной глубины как ключи соответствия и не умеет сравнивать сложные объекты по содержимому. Если элементами являются структуры, единственный надёжный путь — свести задачу к таблице значений или сравнивать по одному ключевому полю, например по коду или ссылке внутри структуры.

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

Порядок действий
  1. 1
    Определите задачу: удаление дублей или группировка с суммированием
  2. 2
    Для простых значений создайте соответствие и соберите уникальные ключи
  3. 3
    Для структур выгрузите данные в таблицу значений и вызовите Свернуть() у копии таблицы
  4. 4
    Проверьте результат: отсутствие дублей и совпадение итоговых сумм
  5. 5
    Вынесите код в общий модуль при повторном использовании
Итог

Что важно запомнить

Метода Свернуть() у массива нет: дубли убирают через соответствие, группировку с итогами делают таблицей значений, а данные из базы выгоднее группировать запросом. Всегда сворачивайте копию таблицы и контролируйте итоги до и после операции.

Частые вопросы

Есть ли в 1С встроенная функция свёртки массива?

Нет. Метод Свернуть() существует только у таблицы значений. Для массива применяют обход через соответствие или промежуточную выгрузку в таблицу значений.

Как свернуть массив и сохранить исходный порядок элементов?

Используйте соответствие как регистр встреченных значений: добавляйте элемент в результат только если его ещё нет в соответствии. Порядок первых вхождений при этом сохранится.

Почему после Свернуть() пропали строки таблицы значений?

Метод работает «на месте» и физически удаляет сгруппированные строки из таблицы. Чтобы сохранить детальные данные, вызывайте Свернуть() у копии, полученной методом Скопировать().

Можно ли свернуть массив структур по одному полю?

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

Что быстрее: соответствие или таблица значений?

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

Как свернуть данные, которые ещё не выбраны из базы?

Не формируйте массив вовсе — выполните группировку в запросе оператором СГРУППИРОВАТЬ ПО с агрегатными функциями. СУБД обработает данные эффективнее, чем цикл в коде.