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

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

В процессе разработки часто возникает задача, когда необходимо обменять или сопоставить данные из двух структур ТаблицаЗначений. Например, в одной таблице хранятся данные по продажам за определенный период, а во второй — текущие остатки товаров на складах. Нам требуется обратиться к каждой номенклатурной позиции, найти соответствующий остаток во второй таблице и высчитать итоговое значение по формуле.

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

Базовый вариант: Поиск строки методом Найти()

Разберем самый прямой способ решения задачи. Допустим, у нас есть первая таблица значений с продажами ЗаказПродажиЗа14д и вторая таблица с остатками ОстаткиНаТТбез0. В обоих случаях ключевой колонкой выступает Товар.

При обходе первой таблицы мы находим соответствующую строку во второй таблице с помощью метода Найти() и считываем нужные показатели:


Для Каждого СтрокаПродаж Из ЗаказПродажиЗа14д Цикл
    Для Каждого КолонкаПродаж Из ЗаказПродажиЗа14д.Колонки Цикл
        Если КолонкаПродаж.Имя = "Товар" Тогда 
            // Ищем соответствующую строку во второй таблице по номенклатуре
            НайденнаяСтрока = ОстаткиНаТТбез0.Найти(СтрокаПродаж[КолонкаПродаж.Имя]);
        Иначе
            Если НайденнаяСтрока <> Неопределено Тогда
                Продажи = СтрокаПродаж[КолонкаПродаж.Имя]; 
                Остаток = НайденнаяСтрока[КолонкаПродаж.Имя];
                
                // Выполняем требуемый расчет по формуле
                // ИтоговыйРезультат = Продажи / 14 * 3 * 1.5 - Остаток;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

Важное замечание: При вызове метода Найти() всегда обязательно проверяйте результат на равенство Неопределено. Если позиция из первой таблицы отсутствует во второй, попытка обращения к НайденнаяСтрока[ИмяКолонки] приведет к критической ошибке выполнения программы.

Оптимизация производительности: Индексация таблиц

Проанализируем работу метода Найти() на больших объемах данных. Без дополнительной подготовки поиск выполняется простым линейным перебором всей таблицы, что при тысячах строк существенно замедляет работу системы.

Чтобы ускорить поиск во второй таблице, рекомендуется использовать индексацию по ключевой колонке до начала цикла:


// Добавляем индекс по колонке Товар
ОстаткиНаТТбез0.Индексы.Добавить("Товар");

Для Каждого СтрокаПродаж Из ЗаказПродажиЗа14д Цикл
    НайденнаяСтрока = ОстаткиНаТТбез0.Найти(СтрокаПродаж.Товар, "Товар");
    Если НайденнаяСтрока <> Неопределено Тогда
        // Выполнение расчетов
    КонецЕсли;
КонецЦикла;

Альтернативный подход: Объединение и сворачивание таблиц

Выясним, как упростить структуру кода без использования вложенных циклов. Если структуры колонок схожи или совпадают, мы можем объединить данные из двух таблиц в одну и применить метод Свернуть().

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

Использование запросов к временным таблицам

Посмотрим на наиболее эффективный способ обработки данных с точки зрения стандартов разработки 1С. Когда данные находятся в двух таблицах значений, эффективнее всего передать их в запрос в качестве параметров и выполнить соединение на стороне СУБД или платформы.

Разберем порядок действий при работе через запрос:

  1. Убедиться, что колонки таблиц значений имеют строго заданные типы данных (объект ОписаниеТипов).
  2. Передать таблицы значений в менеджер временных таблиц через параметры запроса.
  3. В тексте запроса выполнить ПОЛНОЕ СОЕДИНЕНИЕ или ЛЕВОЕ СОЕДИНЕНИЕ по полю Товар.
  4. Применить функцию ЕСТЬNULL() для обработки отсутствующих значений и выполнить расчет формулы прямо в тексте запроса.
  5. Выгрузить результат запроса в итоговую таблицу значений.

Этот подход избавляет от необходимости вручную обходить колонки и строки в циклах, исключает ошибки обращения к несуществующим объектам и обеспечивает максимальную скорость выполнения операции.

← На главную