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