gifts2017

Функция сравнения двух таблиц

Опубликовал Екатерина Соколова (catena) в раздел Программирование - Практика программирования

Сравнение/склейка двух таблиц значений по произвольным колонкам. Пример формирования запроса для сравнения.

Не претендуя на какое-то открытие, просто в качестве примера динамического формирования текста запроса, вашему вниманию:

Функция для сравнения/склеивания двух таблиц по произвольным колонкам запросом.

В прикрепленных файлах пример использования - обработка для склейки двух ексель-файлов по выбранным колонкам.

 

Параметры функции:

тзОдин, тзДва - таблицы значений для сравнения.

КолонкиДляСравнения - таблица значений с колонками: Колонки1, Колонки2, содержащая имена колонок соответственно первой и второй таблиц, по которым нужно склеивать таблицы.

ВыводитьРавные - булево, добавлять или нет в результирующую таблицу найденные по соответствию строки.


Функция СравнитьДанные(тзОдин,тзДва,КолонкиДляСравнения,ВыводитьРавные=Истина)

   
Запрос = Новый Запрос;

   
ТекстЗапроса = "
    |ВЫБРАТЬ "
;

    Для
инд=0 по тзОдин.Колонки.Количество()-1 Цикл

       
ТекстЗапроса = ТекстЗапроса+"
        |тзОдин."
+тзОдин.Колонки[инд].Имя+" КАК "+тзОдин.Колонки[инд].Имя+",";

    КонецЦикла;

   
ТекстЗапроса = ТекстЗапроса+"
    |""ПоследнийСтолбец"" как ДляЗавершения__
    |ПОМЕСТИТЬ тзОдин
    |ИЗ
    |   &тзОдин КАК тзОдин
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ"
;

    Для
инд=0 по тзДва.Колонки.Количество()-1 Цикл

       
ТекстЗапроса = ТекстЗапроса+"
        |тзДва."
+тзДва.Колонки[инд].Имя+" КАК "+тзДва.Колонки[инд].Имя+",";

    КонецЦикла;

   
ТекстЗапроса = ТекстЗапроса+"
    |""ПоследнийСтолбец"" как ДляЗавершения__
    |ПОМЕСТИТЬ тзДва
    |ИЗ
    |   &тзДва КАК тзДва
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ"
;

    Для
инд=0 по тзОдин.Колонки.Количество()-1 Цикл

       
ТекстЗапроса = ТекстЗапроса+"
        |тзОдин."
+тзОдин.Колонки[инд].Имя+" КАК "+тзОдин.Колонки[инд].Имя+"_1,";

    КонецЦикла;

    Для
инд=0 по тзДва.Колонки.Количество()-1 Цикл

       
ТекстЗапроса = ТекстЗапроса+"
        |тзДва."
+тзДва.Колонки[инд].Имя+" КАК "+тзДва.Колонки[инд].Имя+"_2,";

    КонецЦикла;

   
ТекстЗапроса = ТекстЗапроса+"
    |   ВЫБОР
    |       КОГДА (НЕ тзДва."
+тзДва.Колонки[0].Имя+" ЕСТЬ NULL и не тзОдин."+тзОдин.Колонки[0].Имя+" ЕСТЬ NULL)
    |           ТОГДА ИСТИНА
    |       ИНАЧЕ ЛОЖЬ
    |   КОНЕЦ КАК ЕстьКонтакт
    |ИЗ
    |   тзОдин КАК тзОдин
    |       Полное СОЕДИНЕНИЕ тзДва КАК тзДва
    |       ПО Истина"
;

    Для
инд = 0 По КолонкиДляСравнения.Количество()-1 Цикл

       
ТекстЗапроса = ТекстЗапроса+"
        |   И тзОдин."
+КолонкиДляСравнения[инд].Колонки1+" = тзДва."+КолонкиДляСравнения[инд].Колонки2;

    КонецЦикла;

   
ТекстЗапроса = ТекстЗапроса+"
    |"
;

   
Запрос.УстановитьПараметр("тзОдин", тзОдин);
   
Запрос.УстановитьПараметр("тзДва", тзДва);

   
Запрос.Текст = ТекстЗапроса;

   
РЗ = Запрос.Выполнить().Выгрузить();

    Если не
ВыводитьРавные тогда
       
Отбор = Новый Структура("ЕстьКонтакт",Истина);
       
СтрокиДляУдаления = РЗ.НайтиСтроки(Отбор);
        Для каждого
удСтрока из СтрокиДляУдаления Цикл
           
РЗ.Удалить(удСтрока);
        КонецЦикла;
    КонецЕсли;

    Возврат РЗ;

КонецФункции

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
СравнениеФайловExcel
.epf 15,13Kb
27.07.12
43
.epf 15,13Kb 43 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. aspirator 23 (aspirator23) 01.08.12 08:12
А алгоритм vde69 не смотрела?
Он наверное быстрее будет.
2. Екатерина Соколова (catena) 01.08.12 08:29
3. Владимир Чаклин (vec435) 01.08.12 14:49
если колонки не строго типизированы, то ВТ не получится
4. Алексей Штепа (unknownDaemon) 07.11.12 12:54
А чего бы не так, как во вложении у мну? Просто, сударь, на кой черт нужны запросы, если потом результат прочесывается в циклах? :)))
Ну и … если надобно — можно еще и добавить логику анализа удаленных строк, например…
Прикрепленные файлы:
СравнениеТаблиц.txt
5. Екатерина Соколова (catena) 07.11.12 12:57
(4)Вложения не вижу. Вы о том, что можно удалять равные прямо в запросе? Ну да, логично :)
6. Алексей Штепа (unknownDaemon) 07.11.12 13:00
(5) catena, ссорь… не сразу прикрепился файл… Не только удалять равные, но разницу выводить в вариантах, например группировать… Псмотри файлик… ;-)
7. Екатерина Соколова (catena) 07.11.12 14:26
(6)Посмотрела. Не очень удобно, не каждая таблица имеет колонку НомерСтроки. И как искать среди колонок какой строке исходных таблиц что принадлежит?
8. Василий Орлов (Bublik2011) 17.01.13 21:00
Прекрасная функция (2) catena! Очень полезная. Могу пример привести, как еще можно использовать публикацию. Вот например у нас на складе при инвентаризации женщина пишет в журнале с нумерованными строками, а я сканирую товар. Можно вместо "крыжить" занести бумажный журнал в Excel или сразу в ЭтотДокумент :) \см.фото\


Применил другую функцию для сравнения (код не "причесал", извини:)


	ДокументДок = ЭтотОбъект.Ссылка; 
	Таб1 = ДокументДок.Товары.Выгрузить();
	Таб2 = ДокументДок.Список.Выгрузить();
СтрокаН = Таб1.Количество() - 1; 
Для Сч1 = 0 по СтрокаН Цикл
 Состояние("СтрокаН равна: "+Строка(Сч1+1)+" из "+Строка(СтрокаН));

							Строка1=ЭтотОбъект.Товары[Сч1];
	Таб1ЦенаСтрокаН=Строка1.Цена;//Таб1ЦенаСтрокаН=Таб1[Сч1].Цена;  
 	
		СтрокаНН = Таб2.Количество() - 1;
 
		Для Сч2 = 0 по СтрокаНН Цикл
			 //Состояние("СтрокаН равна: "+Строка(Сч1+1)+" из всего "+Строка(СтрокаН)+" - строка НН:"+Строка(Сч2+1));
							 Если Строка1.Количество=0 Тогда
				               Сч2=СтрокаНН;
									 //Прервать;
							КонецЕсли;
							Строка2=ЭтотОбъект.Список[Сч2]; 
	Таб2ЦенаСтрокаНН=Строка2.Цена;//Таб2ЦенаСтрокаН=Таб2[Сч2].Цена;
	ЕстьЧегоУбавлять=1;

 	           Пока ЕстьЧегоУбавлять=1 Цикл

					   Если Строка2.Количество>0 Тогда
		 			ЕстьЧегоУбавлять=1;	   
 				

 								
							Если Строка1.Количество>0		Тогда
		 			ЕстьЧегоУбавлять=1;	   
 	

 
                                Если Строка2.Цена=Строка1.Цена Тогда
							   		Строка2.Количество=Строка2.Количество-1;//Таб2[Сч2].Количество=Таб2[Сч2].Количество-1;
							   		Строка1.Количество=Строка1.Количество-1;//Таб1[Сч1].Количество=Таб1[Сч1].Количество-1;
									Если СтавитьИсточникЗаписи Тогда
									Строка1.Примечание=СокрЛП(Строка2.СтрокаЗаписи);
									Строка2.Примечание=СокрЛП(Строка1.СтрокаЗаписи);
									КонецЕсли;
									
									 Иначе	
									ЕстьЧегоУбавлять=0;
							    КонецЕсли;
							 Иначе
					ЕстьЧегоУбавлять=0;
 					 Прервать;

						   КонецЕсли;
						   
					   Иначе
					ЕстьЧегоУбавлять=0;
 
					 Прервать;
					   КонецЕсли;
				КонецЦикла;		   
					   
		КонецЦикла;	


...Показать Скрыть
Прикрепленные файлы:
9. Николай (nikolka75) 06.04.13 14:30
Функция не работае.
Только потратил время.
10. Николай (nikolka75) 06.04.13 14:43
Была ошибка:
Тип не может быть выбран в запросе.
1) Решение нашол (необходимо типизировать колонки ТЗ) но лучше чтобы обработка решала это сама.
2) Очень неудобный способ задания колонок,
лучше в строке, если пустая то автоматом по колонкам с совпадающими именами.
11. Игорь Лазаренко (kbjy) 02.10.14 07:42
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа