В практике разработки на платформе 1С:Предприятие часто возникает задача сопоставления двух наборов данных. Ситуация, когда под «массивами» подразумеваются структуры с набором полей (колонок), требует особого подхода к сравнению. Разберем подробно, как реализовать алгоритм, который проверяет идентичность данных в двух коллекциях, учитывает обязательное пустое поле в одной из них и выполняет последующее объединение.
Прежде всего, проанализируем структуру данных. В среде 1С классический объект Массив не имеет колонок. Если речь идет о «столбцах», мы имеем дело либо с объектом ТаблицаЗначений, либо с массивом, элементами которого являются объекты Структура. Это крайне важно, так как методы работы с этими объектами различаются.
Условие задачи:
Рассмотрим наиболее гибкий способ — ручной обход коллекций. Этот метод подходит, если количество записей невелико (до нескольких тысяч) и требуется сложная логика проверки «пустоты» значения. Выясним, как реализовать такое сравнение на примере массива структур.
Для реализации нам потребуется вложенный цикл: внешний проходит по строкам, а внутренний — по ключам (колонкам) структур. Проанализируем пример кода:
// Предположим, Массив1 и Массив2 уже заполнены данными
МассивыРавны = Истина;
ИмяПустойКолонки = "НужноеПоле"; // Имя колонки, которая во 2-м массиве должна быть пустой
Если Массив1.Количество() <> Массив2.Количество() Тогда
МассивыРавны = Ложь;
Иначе
Для Индекс = 0 По Массив1.Количество() - 1 Цикл
Строка1 = Массив1[Индекс];
Строка2 = Массив2[Индекс];
Для Каждого ЭлементСтруктуры Из Строка1 Цикл
Ключ = ЭлементСтруктуры.Ключ;
Значение1 = ЭлементСтруктуры.Значение;
Значение2 = Строка2[Ключ];
Если Ключ = ИмяПустойКолонки Тогда
// Проверяем, что во втором массиве это поле пустое
Если ЗначениеЗаполнено(Значение2) Тогда
МассивыРавны = Ложь;
Прервать;
КонецЕсли;
Иначе
// Проверяем совпадение остальных данных
Если Значение1 <> Значение2 Тогда
МассивыРавны = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не МассивыРавны Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если МассивыРавны Тогда
// Логика объединения: например, создание новой таблицы или дополнение первой
ПоказатьПредупреждение(, "Условия пройдены, массивы объединены.");
КонецЕсли;
В данном коде мы используем функцию ЗначениеЗаполнено(), которая является универсальным инструментом 1С для проверки пустых ссылок, строк, нулевых чисел и дат.
Если данные представлены в виде таблиц значений, наиболее производительным методом будет использование временных таблиц в запросе. Рассмотрим подробнее, почему это эффективно: механизм СУБД выполняет операции соединения и фильтрации гораздо быстрее, чем интерпретатор встроенного языка.
Разберем этапы этого метода:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ по всем полям, которые должны совпадать.ГДЕ прописываем проверку на пустое значение целевой колонки.ОБЪЕДИНИТЬ ВСЕ для формирования итогового результата.Проанализируем пример текста запроса:
ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Первая ИЗ &ТЗ1 КАК ТЗ1;
ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Вторая ИЗ &ТЗ2 КАК ТЗ2;
ВЫБРАТЬ
Т1.Колонка1,
Т1.Колонка2,
Т1.ПустаяКолонка
ИЗ
ВТ_Первая КАК Т1
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Вторая КАК Т2
ПО Т1.Колонка1 = Т2.Колонка1
И Т1.Колонка2 = Т2.Колонка2
ГДЕ
(Т2.ПустаяКолонка ЕСТЬ NULL ИЛИ Т2.ПустаяКолонка = &ПустоеЗначение)
Этот подход гарантирует, что вы получите только те строки, которые соответствуют условию «совпадения всех полей, кроме одного пустого».
Если мы работаем с объектом ТаблицаЗначений, мы можем значительно ускорить поиск, создав индексы. Рассмотрим ситуацию: нам нужно проверить, есть ли во второй таблице строка, соответствующая первой. Посмотрим на алгоритм:
Таблица2 по всем проверяемым колонкам.НайтиСтроки().
// Индексация для ускорения
Таблица2.Индексы.Добавить("Колонка1, Колонка2");
Для Каждого Строка1 Из Таблица1 Цикл
Отбор = Новый Структура;
Отбор.Вставить("Колонка1", Строка1.Колонка1);
Отбор.Вставить("Колонка2", Строка1.Колонка2);
НайденныеСтроки = Таблица2.НайтиСтроки(Отбор);
Для Каждого СтрокаПоиска Из НайденныеСтроки Цикл
Если Не ЗначениеЗаполнено(СтрокаПоиска.ПустаяКолонка) Тогда
// Условие выполнено
КонецЕсли;
КонецЦикла;
КонецЦикла;
Существует нестандартный, но быстрый способ сравнить две структуры или строки таблиц на полную идентичность. Мы можем временно очистить «пустую колонку» в обеих коллекциях и преобразовать их в строку JSON. Если полученные строки идентичны — значит, данные в коллекциях полностью совпадают.
Выясним причину популярности этого метода: он избавляет от необходимости писать длинные блоки Если...ИначеЕсли для каждого поля. Достаточно использовать ЗаписьJSON и просто сравнить две строки. Однако стоит помнить, что порядок ключей в структуре при сериализации должен быть одинаковым.
После того как проверка пройдена, необходимо объединить коллекции. Рассмотрим два варианта объединения:
Добавить() в цикле или прямое копирование, если структуры колонок идентичны.ЗаполнитьЗначенияСвойств(Приемник, Источник).Подводя итог, выбор метода зависит от объема данных. Для небольших массивов в памяти идеально подойдет перебор в цикле с проверкой через ЗначениеЗаполнено(). Для обработки больших массивов данных из базы лучше всего использовать запросы с временными таблицами. Использование правильных инструментов 1С позволит избежать ошибок при сравнении типов и обеспечит высокую скорость работы вашей обработки.