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

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

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

Способ 1. Использование функций Библиотеки стандартных подсистем (БСП)

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

Разберем пример использования метода СвернутьМассив():


// Передаем массив, который содержит дубли
ОбщегоНазначенияКлиентСервер.СвернутьМассив(МойМассив);
// Теперь МойМассив содержит только уникальные значения

Также существует альтернативная функция ДополнитьМассив(), которая позволяет не только объединять коллекции, но и сразу отсекать дубликаты. Посмотрим на пример кода:


// МассивПриемник — куда добавляем, МассивИсточник — откуда берем
// Третий параметр Истина указывает на то, что нужно добавлять только уникальные значения
ОбщегоНазначенияКлиентСервер.ДополнитьМассив(МассивПриемник, МассивИсточник, Истина);

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

Способ 2. Использование объекта «Соответствие»

Проанализируем работу объекта Соответствие. Это один из самых быстрых способов получения уникальных значений благодаря особенностям хранения данных в памяти. Ключи в объекте Соответствие (Map) всегда уникальны. Если мы попытаемся добавить в него значение с уже существующим ключом, старое значение просто заменится новым, но сам ключ останется в единственном экземпляре.

Выясним, как реализовать этот алгоритм на практике:


// Создаем временный объект соответствие
УникальныеДанные = Новый Соответствие;
Для Каждого Элемент Из ИсходныйМассив Цикл
    // Используем элемент массива в качестве ключа
    УникальныеДанные.Вставить(Элемент, Истина);
КонецЦикла;

// Выгружаем уникальные ключи обратно в массив
НовыйМассив = Новый Массив;
Для Каждого КлючИЗначение Из УникальныеДанные Цикл
    НовыйМассив.Добавить(КлючИЗначение.Ключ);
КонецЦикла;

Этот метод работает со скоростью O(n), что делает его крайне эффективным для больших массивов (сотни тысяч элементов), так как поиск в Соответствии происходит практически мгновенно.

Способ 3. Использование таблицы значений и метода «Свернуть»

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

  1. Создаем объект ТаблицаЗначений.
  2. Добавляем в нее колонку (важно типизировать ее, если это возможно).
  3. Загружаем данные из массива в колонку таблицы.
  4. Вызываем метод Свернуть() по имени колонки.
  5. Выгружаем результат обратно в массив.

Пример кода реализации:


ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Значение");
// Загружаем массив в колонку ТЗ
ТЗ.ЗагрузитьКолонку(ИсходныйМассив, "Значение");
// Сворачиваем таблицу по колонке, удаляя дубли
ТЗ.Свернуть("Значение");
// Получаем массив уникальных значений
УникальныйМассив = ТЗ.ВыгрузитьКолонку("Значение");

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

Способ 4. Механизм запросов (ВЫБРАТЬ РАЗЛИЧНЫЕ)

Посмотрим на ситуацию, когда массив содержит огромное количество ссылочных данных. В 1С можно использовать объект Запрос, даже если данные еще не записаны в базу данных — для написания и отладки таких алгоритмов пригодится универсальная консоль запросов и кода для разработчиков. Мы можем передать массив как параметр и использовать временные таблицы.

Проанализируем пример кода:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	ВременнаяТаблица.Значение КАК Значение
    |ПОМЕСТИТЬ ВТ_Уникальные
    |ИЗ
    |	&ИсходныйМассив КАК ВременнаяТаблица
    |;
    |
    |ВЫБРАТЬ
    |	ВТ_Уникальные.Значение
    |ИЗ
    |	ВТ_Уникальные";

Запрос.УстановитьПараметр("ИсходныйМассив", ИсходныйМассив);
РезультатЗапроса = Запрос.Выполнить();
УникальныйМассив = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Значение");

Этот способ позволяет переложить нагрузку по обработке данных на СУБД, что может быть оправдано при очень больших объемах данных и сложных типах.

Типичные ошибки при ручном удалении дублей

Иногда разработчики пытаются удалять дубли напрямую в цикле по массиву. Разберем, почему код Массив.Удалить(Массив.Найти(ТекущееЗначение)) может работать некорректно. При удалении элемента из середины массива индексы всех последующих элементов сдвигаются. Если вы используете цикл Для Счетчик = 0 По Массив.Количество() - 1, вы рискуете либо пропустить элементы, либо получить ошибку выхода за границы массива. Для поиска таких и других уязвимых мест в коде полезно проводить анализ конфигураций на наличие ошибок или использовать статический анализатор кода проектов.

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


Для Индекс = -(Массив.Количество() - 1) По 0 Цикл
    ТекущийИндекс = -Индекс;
    // Логика проверки и удаления
КонецЦикла;

Выводы и рекомендации

Подведем итог нашему анализу:

Выяснив причину появления дублей и выбрав подходящий инструмент, вы сможете сделать ваш код более производительным и надежным — для удаления дубликатов непосредственно из справочников и документов базы данных есть обработка поиска и устранения дублей в 1С.

← На главную