При выгрузке заказов или других документов из 1С в Excel часто возникает ситуация, когда одна и та же номенклатура встречается в списке несколько раз. Это происходит потому, что в табличных частях документов позиции могут дублироваться из-за разных характеристик, складов или просто логики заполнения. Для получения чистого списка в Excel нам необходимо предварительно обработать данные. В этой статье мы подробно разберем, как избавиться от дублей, используя различные инструменты платформы 1С.
Если ваши данные уже получены в виде массива или таблицы, самым эффективным программным методом будет использование объекта ТаблицаЗначений и его встроенного метода Свернуть(). Рассмотрим ситуацию, когда у нас есть массив табличных частей заказов, и нам нужно получить уникальный список товаров.
Алгоритм действий будет следующим: сначала мы переносим все данные из табличных частей в одну общую таблицу значений, а затем применяем метод схлопывания строк. Проанализируем пример кода:
// Создаем пустую таблицу значений
ТЗ_Результат = Новый ТаблицаЗначений;
ТЗ_Результат.Колонки.Добавить("Номенклатура");
ТЗ_Результат.Колонки.Добавить("Количество");
// Предположим, у нас есть массив ТабличныеЧасти (как в Сообщении 4)
Для Каждого ТЧ Из МассивТабличныхЧастей Цикл
Для Каждого СтрокаТЧ Из ТЧ Цикл
НоваяСтрока = ТЗ_Результат.Добавить();
НоваяСтрока.Номенклатура = СтрокаТЧ.Номенклатура;
НоваяСтрока.Количество = СтрокаТЧ.Количество;
КонецЦикла;
КонецЦикла;
// Ключевой момент: сворачиваем таблицу по колонке Номенклатура
// Если нужно просуммировать количество, указываем его во втором параметре
ТЗ_Результат.Свернуть("Номенклатура", "Количество");
// Теперь в ТЗ_Результат только уникальные позиции, которые можно выгружать в Excel
Метод Свернуть() работает очень быстро: он группирует строки по значениям в первых колонках (параметр "Колонки группировки") и суммирует числовые значения в последующих (параметр "Колонки суммирования"). Это идеальный вариант, если вам нужно не просто удалить дубли, а объединить их в одну строку с итоговым количеством.
Вместо того чтобы перебирать строки табличных частей циклом, гораздо правильнее и быстрее будет использовать механизм запросов 1С. Это позволит отсечь дубликаты еще на этапе получения данных из базы. Разберем два ключевых слова, которые нам помогут: ВЫБРАТЬ РАЗЛИЧНЫЕ и СГРУППИРОВАТЬ ПО.
Если нам нужен только список уникальных наименований без суммирования количества, мы используем ВЫБРАТЬ РАЗЛИЧНЫЕ. Рассмотрим пример:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ЗаказКлиентаТовары.Номенклатура КАК Номенклатура
|ИЗ
| Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
|ГДЕ
| ЗаказКлиентаТовары.Ссылка В(&МассивЗаказов)";
Запрос.УстановитьПараметр("МассивЗаказов", СписокЗаказовДляВыгрузки);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Полученная таблица уже не содержит дублей
Если же в Excel нужно вывести общие итоги по количеству, следует использовать СГРУППИРОВАТЬ ПО. Выясним причину популярности этого метода: он позволяет гибко управлять тем, что именно мы считаем "дублем". Например, мы можем группировать только по номенклатуре или по связке "Номенклатура + Характеристика".
Когда данные для выгрузки собираются сложным образом (из разных документов, массивов и внешних источников), рекомендуется использовать временные таблицы. Это позволит "схлопнуть" данные средствами СУБД, что значительно быстрее, чем работа с большими коллекциями в памяти приложения. Мы помещаем наш массив данных во временную таблицу, а затем делаем из нее выборку с группировкой.
Это исключает ошибки переполнения памяти при обработке сотен тысяч строк и подготавливает "чистый" результат для записи в файл Excel.
Рассмотрим ситуацию, когда мы обходим данные в сложном цикле и хотим сразу отсеивать дубли. В этом случае удобно использовать объект Соответствие. В 1С Соответствие хранит уникальные ключи. Если мы попытаемся записать значение по ключу, который уже существует, старое значение просто заменится новым.
УникальныеДанные = Новый Соответствие;
Для Каждого СтрокаДанных Из ИсходныеДанные Цикл
// Ключом будет ссылка на номенклатуру
// Если такая номенклатура уже была, запись обновится, дубль не создастся
УникальныеДанные.Вставить(СтрокаДанных.Номенклатура, СтрокаДанных.Цена);
КонецЦикла;
После завершения цикла достаточно обойти Соответствие и выгрузить его элементы в Excel. Этот метод хорош тем, что нам не нужно выполнять поиск по таблице на каждой итерации.
Если ваша задача — регулярная выгрузка отчетов, самым правильным подходом будет создание внешнего отчета на СКД. В настройках компоновки можно просто задать группировку по номенклатуре. При выводе отчета в табличный документ 1С сама корректно обработает повторяющиеся данные. Вы сможете сохранить результат в формате .xlsx стандартной командой "Сохранить как", не написав при этом ни строчки кода для обработки дублей вручную.
Иногда "дубликаты" на самом деле являются разными позициями. Проанализируем ситуацию: если у вас один и тот же товар, но с разными характеристиками (например, "Кроссовки" синего и красного цвета), при сворачивании только по колонке Номенклатура эти позиции объединятся в одну. Важно решить заранее:
Если характеристики важны, их обязательно нужно добавлять в список колонок для группировки в методе Свернуть() или в секцию СГРУППИРОВАТЬ ПО в запросе.
Если изменить алгоритм выгрузки в самой 1С по каким-то причинам невозможно (например, используется закрытая внешняя обработка), мы можем воспользоваться инструментами Excel. Инструмент Power Query позволяет подключиться к выгруженному листу и в один клик применить операцию "Удалить дубликаты". Это надежный способ "посмертной" очистки данных, если источник выдает "грязный" результат.
Подводя итог, наиболее профессиональным подходом в 1С является использование запросов с группировкой, а наиболее быстрым в реализации для начинающего разработчика — использование метода Свернуть() для временной таблицы значений перед началом цикла записи в файл.