Разработка и Конфигурация · 11 мин
Как свернуть массив в 1С: убираем дубли и повторяющиеся элементы
Как свернуть массив в 1С: удаление дублей через соответствие, таблицу значений и Свернуть(). Примеры кода, сравнение способов, типичные ошибки и FAQ.
Во встроенном языке 1С нет отдельного метода «Свернуть» для массива — такой метод есть только у таблицы значений. Поэтому под фразой «свернуть массив» разработчики обычно понимают одну из двух задач: убрать из массива дублирующиеся значения (получить список уникальных элементов) или сгруппировать однотипные данные с суммированием числовых показателей. Оба сценария решаются штатными средствами платформы без внешних компонент.
Выбор способа зависит от структуры данных. Если массив содержит простые значения — строки, числа, ссылки — быстрее всего свернуть его через объект «Соответствие» или через таблицу значений с методом Свернуть(). Если же массив хранит структуры с несколькими полями и нужно сгруппировать их с суммированием, без таблицы значений не обойтись: именно она умеет группировать строки по измерениям и суммировать ресурсы.
Ниже разобраны рабочие варианты кода для обеих задач, критерии выбора между ними, ограничения каждого подхода и типичные ошибки, из-за которых свёртка работает не так, как ожидается.
Что значит «свернуть массив» в контексте 1С
Термин пришёл из методики работы с таблицей значений, где метод Свернуть(КолонкиГруппировок, КолонкиСуммирования) объединяет одинаковые строки. Когда говорят «свернуть массив», чаще всего имеют в виду более простую операцию — оставить в массиве только уникальные значения, отбросив повторы. Например, из массива ссылок на номенклатуру, собранного из табличной части документа, получить список без повторений для запроса или отбора.
Вторая трактовка — свёртка с агрегацией: есть массив структур вида «Товар + Количество», и нужно получить итог по каждому товару. Это уже не удаление дублей, а группировка, и решается она иначе. Важно сразу определить, какая из задач стоит перед вами, потому что инструменты и код различаются принципиально.
Способ 1. Свернуть массив через Соответствие
Самый быстрый и короткий приём для массива простых значений — использовать объект «Соответствие». Его ключи уникальны по определению: повторная установка значения по тому же ключу просто перезаписывает элемент. Достаточно пройти по массиву, положить каждый элемент как ключ, а затем собрать ключи обратно в новый массив.
Функция СвернутьМассив(ИсходныйМассив)
Уникальные = Новый Соответствие;
Для Каждого Элемент Из ИсходныйМассив Цикл
Уникальные.Вставить(Элемент, Истина);
КонецЦикла;
Результат = Новый Массив;
Для Каждого КлючИЗначение Из Уникальные Цикл
Результат.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
Возврат Результат;
КонецФункции
Порядок элементов в результате не гарантирован: соответствие не обязано сохранять последовательность вставки. Если порядок критичен (например, массив используется для вывода пользователю), добавьте проверку — помещайте элемент в результирующий массив только при первой встрече, а соответствие используйте как регистр «уже виденных» значений.
Функция СвернутьМассивССохранениемПорядка(ИсходныйМассив)
Встреченные = Новый Соответствие;
Результат = Новый Массив;
Для Каждого Элемент Из ИсходныйМассив Цикл
Если Встреченные[Элемент] = Неопределено Тогда
Встреченные.Вставить(Элемент, Истина);
Результат.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Способ 2. Свёртка через таблицу значений и метод Свернуть()
Если под рукой уже есть таблица значений или массив легко в неё выгружается, удобно применить штатный метод Свернуть(). Он группирует строки по указанным колонкам и при необходимости суммирует числовые. Для простого удаления дублей колонки суммирования не указываются.
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Значение");
Для Каждого Элемент Из ИсходныйМассив Цикл
ТЗ.Добавить().Значение = Элемент;
КонецЦикла;
ТЗ.Свернуть("Значение");
СвернутыйМассив = ТЗ.ВыгрузитьКолонку("Значение");
Этот же подход закрывает вторую задачу — группировку с итогами. Пусть есть массив структур «Товар, Количество, Сумма». Выгружаем его в таблицу значений и сворачиваем по товару с суммированием:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Товар");
ТЗ.Колонки.Добавить("Количество");
ТЗ.Колонки.Добавить("Сумма");
Для Каждого Стр Из МассивСтруктур Цикл
НоваяСтрока = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);
КонецЦикла;
ТЗ.Свернуть("Товар", "Количество,Сумма");
После вызова Свернуть() таблица изменяется «на месте» — исходные детальные строки теряются. Если они ещё понадобятся, сначала сделайте копию методом Скопировать() и сворачивайте копию.
Сравнение способов: что выбрать
Оба подхода рабочие, но у них разные накладные расходы и ограничения. Соответствие создаётся быстрее и не требует описывать колонки, зато таблица значений даёт суммирование и дальнейшую сортировку из коробки.
| Критерий | Соответствие | Таблица значений + Свернуть() |
|---|---|---|
| Тип элементов | Простые значения, ссылки | Любые, включая многоколоночные данные |
| Суммирование при группировке | Нет, только удаление дублей | Да, по указанным колонкам |
| Сохранение порядка | Только с дополнительной проверкой | Порядок групп определяется первым вхождением |
| Объём кода | Минимальный | Требуется описание колонок и выгрузка |
| Дальнейшая обработка | Только массив на выходе | Сортировка, поиск, итоги, выгрузка |
Сравнение вариантов
Лучший выбор для массива строк, чисел или ссылок, когда нужны только уникальные значения. Не умеет суммировать и не гарантирует порядок.
Подходит для структур и когда нужна группировка с итогами. Требует больше кода и изменяет исходную таблицу.
Оптимален, если данные уже в базе: свёртку выполнит СУБД. Не работает с массивом, полученным вне запроса, без выгрузки во временную таблицу.
Свёртка на уровне запроса
Если массив формируется из данных информационной базы, часто правильнее вообще не сворачивать его в коде, а поручить группировку запросу. Оператор СГРУППИРОВАТЬ ПО с функциями СУММА, КОЛИЧЕСТВО, МАКСИМУМ выполняется на стороне СУБД и обычно быстрее циклической обработки, особенно на больших выборках.
Массив можно передать в запрос как параметр и использовать в условии В(&Массив) — но сам массив при этом не сворачивается, а лишь фильтрует выборку. Если нужно обратное — свернуть уже полученный массив через запрос — его придётся поместить во временную таблицу, что оправдано только при больших объёмах и необходимости соединения с данными базы.
Как выбрать действие
Проверка результата и типичные ошибки
После свёртки убедитесь, что результат соответствует ожиданиям: количество элементов не превышает исходное, повторы отсутствуют, суммы при группировке сходятся с итогом по исходным данным. Простой контроль — сравнить сумму числовых колонок до и после свёртки: она должна совпасть.
Как проверить результат
Меньше или равно исходному, дублей нет
Элементов стало больше или пропали нужные значения
Итог до и после свёртки совпадает
Сумма изменилась — ошибка в колонках группировки
Все ссылки того же типа, что в исходном массиве
Появились Неопределено или пустые ссылки
Удобно оформить свёртку как функцию общего модуля с признаком сохранения порядка. Тогда в прикладном коде остаётся одна строка вызова, а отладка и изменение логики ведутся в одном месте, а не размазываются по десяткам процедур.
Ограничения и границы применения
Массив в 1С не поддерживает вложенные массивы произвольной глубины как ключи соответствия и не умеет сравнивать сложные объекты по содержимому. Если элементами являются структуры, единственный надёжный путь — свести задачу к таблице значений или сравнивать по одному ключевому полю, например по коду или ссылке внутри структуры.
При работе на клиенте в управляемом приложении помните о контексте: таблица значений недоступна в тонком клиенте вне серверного вызова. Свёртку больших данных выполняйте в серверной процедуре, а на клиент возвращайте уже готовый массив. Это снижает трафик и исключает ошибки сериализации.
- 1Определите задачу: удаление дублей или группировка с суммированием
- 2Для простых значений создайте соответствие и соберите уникальные ключи
- 3Для структур выгрузите данные в таблицу значений и вызовите Свернуть() у копии таблицы
- 4Проверьте результат: отсутствие дублей и совпадение итоговых сумм
- 5Вынесите код в общий модуль при повторном использовании
Что важно запомнить
Метода Свернуть() у массива нет: дубли убирают через соответствие, группировку с итогами делают таблицей значений, а данные из базы выгоднее группировать запросом. Всегда сворачивайте копию таблицы и контролируйте итоги до и после операции.
Частые вопросы
Есть ли в 1С встроенная функция свёртки массива?
Нет. Метод Свернуть() существует только у таблицы значений. Для массива применяют обход через соответствие или промежуточную выгрузку в таблицу значений.
Как свернуть массив и сохранить исходный порядок элементов?
Используйте соответствие как регистр встреченных значений: добавляйте элемент в результат только если его ещё нет в соответствии. Порядок первых вхождений при этом сохранится.
Почему после Свернуть() пропали строки таблицы значений?
Метод работает «на месте» и физически удаляет сгруппированные строки из таблицы. Чтобы сохранить детальные данные, вызывайте Свернуть() у копии, полученной методом Скопировать().
Можно ли свернуть массив структур по одному полю?
Напрямую через соответствие — нет, структуры сравниваются как разные объекты. Варианты: использовать значение ключевого поля как ключ соответствия, а саму структуру хранить в значении, либо выгрузить массив в таблицу значений и свернуть по нужной колонке.
Что быстрее: соответствие или таблица значений?
Для простого удаления дублей соответствие обычно быстрее и требует меньше кода. Таблица значений оправдана, когда нужны суммирование, сортировка или дальнейшая табличная обработка результата.
Как свернуть данные, которые ещё не выбраны из базы?
Не формируйте массив вовсе — выполните группировку в запросе оператором СГРУППИРОВАТЬ ПО с агрегатными функциями. СУБД обработает данные эффективнее, чем цикл в коде.