HelpF.pro

Соединение таблиц значений по ключевым полям

Иногда при разработке большых отчётов и различных шахмоток приходится соединять таблицы из разных выборок по определенному полю, например выборка по продаже и выборка по производству объединяем по номенклатуре, в запросе бывает это делать неудобно т.к. в Таблицу можно присваивать различные структуры для расшифровок.

Сделал функцию которая объеденяет 2 таблицы в одну, на подобии полного соединения в запросе.
Код 1C v 8.х
  // ТЗ1 - первая Таблица значений
// ТЗ2 - вторая Таблица значений
// KEYт_str - колонки по которым происходит объединение, пример: "номенклатура" или "номенклатура,ЕдИзм"

Функция ПОЛНОЕ_СОЕДИНЕНИЕ(ТЗ1,ТЗ2,KEYт_str)
ТЗ = новый ТаблицаЗначений;
//---------------------------------------------
// разбор ключевых колонок в масив
//---------------------------------------------
str = "" + KEYт_str; // Копирование исходной строки
KEYт_mas = новый Массив;
str = СтрЗаменить(str,",",Символы.ПС);
Для N=1 по СтрЧислоСтрок(str) Цикл
name = СтрПолучитьСтроку(str,N);
KEYт_mas.Добавить(name);
КонецЦикла;
//---------------------------------------------

//---- проверка на наличие ключевых колонок ---
Для каждого KEYт из KEYт_mas Цикл
Если (ТЗ1.Колонки.Найти(KEYт)=неопределено)
ИЛИ (ТЗ2.Колонки.Найти(KEYт)=неопределено) Тогда
Сообщить("нет ключевой колонки");
возврат неопределено;
КонецЕсли;
КонецЦикла;
//---------------------------------------------

//--- Формируем новую ТЗ из 2х таблиц ---------
Для каждого К Из ТЗ1.Колонки Цикл
// из первой ТЗ берём все колонки
ТЗ.Колонки.Добавить(К.Имя);
КонецЦикла;
Для каждого К Из ТЗ2.Колонки Цикл
// из второй все кроме ключевой
Если KEYт_mas.Найти(К.Имя) <> неопределено тогда
Продолжить;
КонецЕсли;
ТЗ.Колонки.Добавить(К.Имя);
КонецЦикла;
//---------------------------------------------

//----------------------------------------------------
// Заполняем строчки ключей которых НЕТ в ТЗ2
//----------------------------------------------------
Для каждого стр1 Из ТЗ1 Цикл

// Формируем структуру поиска
Отбор = Новый Структура;
Для каждого KEYт из KEYт_mas Цикл
Отбор.Вставить(KEYт,стр1[KEYт]);
КонецЦикла;

Если ТЗ2.НайтиСтроки(Отбор).Количество() = 0 тогда
стр = ТЗ.Добавить();
// копируем все значения из строчки ТЗ1
Для каждого К Из ТЗ1.Колонки Цикл
стр[К.Имя] = стр1[К.Имя];
КонецЦикла;
КонецЕсли;

КонецЦикла;
//----------------------------------------------------

//----------------------------------------------------
// Заполняем строчки ключи которых ЕСТЬ в ТЗ2
//----------------------------------------------------
Для каждого стр1 Из ТЗ1 Цикл

// Формируем структуру поиска
Отбор = Новый Структура;
Для каждого KEYт из KEYт_mas Цикл
Отбор.Вставить(KEYт,стр1[KEYт]);
КонецЦикла;

НайденныеСтроки = ТЗ2.НайтиСтроки(Отбор);

Если НайденныеСтроки.Количество() > 0 тогда
Для каждого стр2 Из НайденныеСтроки Цикл
//заполняем все колонки
стр = ТЗ.Добавить();
// из ТЗ1
Для каждого К Из ТЗ1.Колонки Цикл
стр[К.Имя] = стр1[К.Имя];
КонецЦикла;
// из ТЗ2
Для каждого К Из ТЗ2.Колонки Цикл
стр[К.Имя] = стр2[К.Имя];
КонецЦикла;
КонецЦикла;

КонецЕсли;

КонецЦикла;
//----------------------------------------------------

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

Если ТЗ1.НайтиСтроки(Отбор).Количество() = 0 тогда
стр = ТЗ.Добавить();
// копируем все значения из строчки ТЗ1
Для каждого К Из ТЗ2.Колонки Цикл
стр[К.Имя] = стр2[К.Имя];
КонецЦикла;
КонецЕсли;

КонецЦикла;
//----------------------------------------------------

возврат ТЗ;
КонецФункци

Автор: sashapere
Опубликовано на сайте: https://HelpF.pro
Прямая ссылка: https://HelpF.pro/faq/view/1109.html