Как сравнить значения в Структуре и Соответствии и сопоставить их ключи в 1С

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

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

Постановка задачи и выбор инструментов

Представим, что у нас есть Структура с набором элементов и Соответствие также с 10-ю элементами. В обеих коллекциях значениями являются некие идентификаторы (например, строки или числа). Нам необходимо проанализировать эти значения и, если они идентичны, записать в ТаблицуЗначений (ТЗ) в первую колонку ключ из структуры, а во вторую — ключ из соответствия.

Прежде чем переходить к коду, вспомним важные особенности коллекций:

Вариант 1. Классический перебор вложенными циклами

Рассмотрим самый простой и очевидный способ, который часто первым приходит в голову начинающим разработчикам. Это использование вложенных циклов. Проанализируем этот подход:


// Создаем итоговую таблицу значений
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("КлючСтруктуры");
ТЗ.Колонки.Добавить("КлючСоответствия");

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

Важное замечание: Этот метод имеет алгоритмическую сложность O(n * m). Если в каждой коллекции по 10 элементов, мы выполним 100 итераций. Если же элементов будет по 1000, количество операций вырастет до 1 000 000. Для небольших коллекций это допустимо, но для оптимизации работы системы следует рассмотреть более эффективные методы.

Вариант 2. Оптимизированный поиск через инверсию коллекции

Разберем более профессиональный подход. Платформа 1С позволяет мгновенно получать значение из Соответствия, если нам известен его ключ. Мы можем воспользоваться этим, "развернув" одну из коллекций. Процесс заключается в том, чтобы создать временное соответствие, где ключом станет Значение исходной коллекции, а значением — её Ключ.

Рассмотрим пошаговую реализацию этого алгоритма:

  1. Создаем вспомогательное Соответствие.
  2. Обходим исходное Соответствие и заполняем вспомогательное, меняя местами ключ и значение.
  3. Одним циклом обходим Структуру и проверяем наличие её значения во вспомогательном соответствии.

// 1. Подготовка данных
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("КлючСтруктуры");
ТЗ.Колонки.Добавить("КлючСоответствия");

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

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

Этот метод работает со сложностью O(n + m), что значительно быстрее при больших объемах данных. Мы фактически заменяем полный перебор второй коллекции мгновенным обращением к хеш-таблице через метод Получить().

Технические нюансы работы с коллекциями

Проанализируем важные детали, которые могут повлиять на результат сопоставления:

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

Типизация в Таблице Значений. При создании колонок в ТЗ хорошей практикой считается указание типов данных. Это предотвращает ошибки при дальнейшей обработке таблицы. Рассмотрим пример с типизацией:


МассивТиповСтрока = Новый Массив;
МассивТиповСтрока.Добавить(Тип("Строка"));
ОписаниеТипаСтрока = Новый ОписаниеТипов(МассивТиповСтрока);

ТЗ.Колонки.Добавить("КлючСтруктуры", ОписаниеТипаСтрока);

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

Резюме

Выясним причину, по которой стоит выбирать тот или иной метод. Если ваша задача разовая и данных крайне мало (до 10-20 элементов), вложенные циклы допустимы ввиду их простоты. Однако для промышленного кода и сложных алгоритмов инверсия коллекции является стандартом де-факто в 1С. Это не только ускоряет выполнение программы, но и демонстрирует глубокое понимание механизмов работы платформы.

Рассмотренные подходы позволяют гибко манипулировать данными и эффективно решать задачи сопоставления объектов без лишней нагрузки на серверную часть системы.

← На главную