В процессе разработки на платформе 1С:Предприятие 7.7 часто возникает задача анализа данных, выгруженных в таблицу значений (ТЗ). Типичный пример: после выполнения запроса необходимо найти строки, в которых совпадают значения определенных колонок (например, "Договор" и "Объект"), и пометить их для дальнейшей обработки. В этой статье мы подробно разберем несколько проверенных способов решения этой задачи, начиная от простых штатных методов и заканчивая более производительными алгоритмами.
Это самый простой и интуитивно понятный способ, не требующий использования дополнительных компонентов. Идея заключается в том, чтобы сгруппировать одинаковые записи рядом друг с другом, после чего сравнить каждую текущую строку с предыдущей.
Проанализируем алгоритм действий:
ФлагДубля), куда будем записывать результат.Рассмотрим пример кода, реализующий этот подход:
// Предположим, ТЗ уже заполнена данными
ТЗ.НоваяКолонка("ФлагДубля", "Число", 1);
// Сортируем по ключевым колонкам
ТЗ.Сортировать("Договор, Объект");
// Переменные для хранения значений предыдущей строки
ПредДоговор = "";
ПредОбъект = "";
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
Если (ТЗ.Договор = ПредДоговор) И (ТЗ.Объект = ПредОбъект) Тогда
// Нашли дубль
ТЗ.ФлагДубля = 1;
Иначе
// Это первое вхождение или уникальная строка
ТЗ.ФлагДубля = 0;
// Запоминаем текущие значения для следующего шага
ПредДоговор = ТЗ.Договор;
ПредОбъект = ТЗ.Объект;
КонецЕсли;
КонецЦикла;
Важный нюанс: при таком подходе первая строка из группы дублей останется помеченной нулем, а все последующие — единицей. Если вам нужно пометить все строки, входящие в группу дублей, алгоритм придется немного усложнить, добавив второй проход или запоминая индекс первой строки группы.
Метод Свернуть() — один из самых мощных инструментов в 1С 7.7 для работы с агрегированными данными. Мы можем использовать его, чтобы быстро определить, какие комбинации значений встречаются более одного раза.
Разберем этот способ по шагам:
Количество и заполняем её единицами.Количество.Посмотрим на пример реализации:
// 1. Подготовка основной ТЗ
ТЗ.НоваяКолонка("ФлагДубля", "Число");
// 2. Создание вспомогательной ТЗ
ТЗ_Копия = СоздатьОбъект("ТаблицаЗначений");
ТЗ.Выгрузить(ТЗ_Копия);
ТЗ_Копия.НоваяКолонка("Количество", "Число");
ТЗ_Копия.ВыбратьСтроки();
Пока ТЗ_Копия.ПолучитьСтроку() = 1 Цикл
ТЗ_Копия.Количество = 1;
КонецЦикла;
// 3. Сворачивание
ТЗ_Копия.Свернуть("Договор, Объект", "Количество");
// 4. Проставление отметок в основной ТЗ
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
НомСтроки = 0;
// Ищем комбинацию в свернутой таблице
Если ТЗ_Копия.НайтиЗначение(ТЗ.Договор, НомСтроки, "Договор") = 1 Тогда
ТЗ_Копия.ПолучитьСтрокуПоНомеру(НомСтроки);
// Проверяем еще и объект (так как НайтиЗначение ищет только по одной колонке)
Если (ТЗ_Копия.Объект = ТЗ.Объект) И (ТЗ_Копия.Количество > 1) Тогда
ТЗ.ФлагДубля = 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Обратите внимание, что штатный метод НайтиЗначение() в 7.7 ищет только по одной колонке. Для поиска по нескольким колонкам в свернутой таблице лучше использовать предварительную сортировку и метод НайтиПараметры или конкатенацию ключей в одну строковую колонку.
Если таблица значений содержит десятки тысяч строк, штатные методы перебора могут работать медленно. В таких случаях программисты часто прибегают к использованию объекта Scripting.Dictionary (словарь), который обеспечивает поиск со скоростью O(1).
Выясним, как применить словарь для нашей задачи:
Словарь = СоздатьОбъект("Scripting.Dictionary");.Этот метод считается одним из самых быстрых для "семерки", так как он заменяет вложенные циклы или тяжелые операции поиска внутри ТЗ на эффективное хеширование.
Для тех, кто использует в своей работе расширение 1С++, задача упрощается максимально. Объект ИндексированнаяТаблица позволяет создавать индексы по любым колонкам, что делает поиск дублей мгновенным.
Проанализируем возможности этого объекта:
Сгруппировать(), который работает быстрее стандартного Свернуть().ПолучитьСтрокиПоКлючу() позволяет сразу выгрузить все строки, соответствующие определенному договору и объекту.УстановитьФильтр), что позволяет видеть только повторяющиеся записи без физического удаления уникальных.Выбор метода зависит от объема данных и ваших условий работы:
Важный совет: Перед сравнением объектов (договоров, контрагентов) убедитесь, что они имеют одинаковый тип. В 1С 7.7 иногда в одну колонку могут попасть как ссылки на справочник, так и их строковые представления, что приведет к неверному результату при поиске дублей.