Как можно сравнить две таблицы значений и вывести различия?

1. 19.11.20 17:26 Сейчас в теме
Подскажите пожалуйста, есть две таблицы значений, одинаковые колонки "Номенклатура" и "Количество"

Нужно их сравнить и если есть расхождения то вывести в третью.

То есть в какой-то может не быть номенклатуры или разные количество

Можно ли их сравнить?

ТЗПриходныйОрдер = Новый ТаблицаЗначений;
	ТЗПриходныйОрдер.Колонки.Добавить("Номенклатура");
	ТЗПриходныйОрдер.Колонки.Добавить("Количество");
	
	//ТЗРасходныйОрдер = Новый ТаблицаЗначений;
	//ТЗРасходныйОрдер.Колонки.Добавить("Номенклатура");
	//ТЗРасходныйОрдер.Колонки.Добавить("Количество");
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	               |	ПриходныйОрдерНаТоварыТовары.Номенклатура КАК Номенклатура,
	               |	СУММА(ПриходныйОрдерНаТоварыТовары.Количество) КАК Количество
	               |ИЗ
	               |	Документ.ПриходныйОрдерНаТовары.Товары КАК ПриходныйОрдерНаТоварыТовары
	               |		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПриходныйОрдерНаТовары КАК ПриходныйОрдерНаТовары
	               |		ПО ПриходныйОрдерНаТоварыТовары.Ссылка = ПриходныйОрдерНаТовары.Ссылка
	               |ГДЕ
	               |	ПриходныйОрдерНаТовары.Распоряжение = &Перемещение
	               |	И ПриходныйОрдерНаТовары.Проведен
	               |
	               |СГРУППИРОВАТЬ ПО
	               |	ПриходныйОрдерНаТоварыТовары.Номенклатура";
	
	Запрос.УстановитьПараметр("Перемещение",Перемещение);
	ТЗПриходный = Запрос.Выполнить().Выгрузить();
	
	Для Каждого Стр ИЗ ТЗПриходный Цикл
		
		А = ТЗПриходныйОрдер.Добавить();
		А.Номенклатура = Стр.Номенклатура;
		А.Количество   = Стр.Количество;
		
	КонецЦикла;
	
	Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	СвязанныеДокументы.Ссылка КАК Ссылка
    |ИЗ
    |	КритерийОтбора.СвязанныеДокументы(&Значение) КАК СвязанныеДокументы
    |ГДЕ
    |	СвязанныеДокументы.Ссылка.Проведен
    |	И СвязанныеДокументы.Ссылка Ссылка Документ.РасходныйОрдерНаТовары";
    
    Запрос.УстановитьПараметр("Значение", Перемещение);
	
	ТЗРасходный = Запрос.Выполнить().Выбрать();
			
	Пока ТЗРасходный.Следующий() Цикл
		
		Для Каждого Стр ИЗ ТЗРасходный.Ссылка.ОтгружаемыеТовары Цикл
			
			А = ТЗПриходныйОрдер.Добавить();
			
			А.Номенклатура = Стр.Номенклатура;
			А.Количество   = Стр.Количество;	
			
		КонецЦикла;
		
	КонецЦикла;
	
	ТЗПриходныйОрдер.Свернуть("Номенклатура","Количество");
Показать
Вознаграждение за ответ
Показать полностью
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. Punisher_1C 6 19.11.20 17:46 Сейчас в теме
Сделайте один запрос, в первом пакете получите значения и поместите их в ВТ. Во втором пакете аналогично со второй таблицей. Потом в третьем пакете через объединить ВТ склеиваете. Используете ЕСТЬNULL для возможных отсутствующих значений. Затем сравниваете количество(из первой таблицы) с количеством во второй

|ВЫБРАТЬ
|    ПриходныйОрдерНаТоварыТовары.Номенклатура КАК Номенклатура,
|    СУММА(ПриходныйОрдерНаТоварыТовары.Количество) КАК Количество
|ИЗ
|    Документ.ПриходныйОрдерНаТовары.Товары КАК ПриходныйОрдерНаТоварыТовары
|        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПриходныйОрдерНаТовары КАК ПриходныйОрдерНаТовары
|        ПО ПриходныйОрдерНаТоварыТовары.Ссылка = ПриходныйОрдерНаТовары.Ссылка

| Поместить ВТ1 
|ГДЕ
|    ПриходныйОрдерНаТовары.Распоряжение = &Перемещение
|    И ПриходныйОрдерНаТовары.Проведен
|
|СГРУППИРОВАТЬ ПО
|    ПриходныйОрдерНаТоварыТовары.Номенклатура;
|
|////////////////////////////////////////////////////////////­///////////////////
|
|АНАЛОГИЧНО ПОЛУЧАЕТЕ ДЛЯ ТОГО С ЧЕМ СРАВНИВАЕТЕ
| Поместить ВТ2

|
|////////////////////////////////////////////////////////
|ВЫБРАТЬ 
|ВТ1.Номенклатура
|ВТ1.Количество КАК КОЛИЧЕТВО1
|0 КАК КОЛИЧЕСТВО2
| ИЗ ВТ1 КАК ВТ1
|ОБЪЕДИНИТЬ 
| 
|ВЫБРАТЬ 
|ВТ2.Номенклатура
|0,
|ВТ2.Количество
| ИЗ ВТ2 КАК ВТ2

Показать
4. user973528 19.11.20 17:51 Сейчас в теме
(2)Пытаюсь получить запросом данные своей ТЗ, но вываливается на ошибке

	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
				 |Заказы.Номенклатура,
				 |СУММА(Заказы.Количество) КАК Количество
				 |ПОМЕСТИТЬ Заказы
				 |ИЗ
				 |ТЗПриходныйОрдер КАК Заказы
				 |ГДЕ
				 |Заказы.Ссылка = &Таблица
				 |СГРУППИРОВАТЬ ПО
				 |Заказы.Номенклатура";
	
	Запрос.УстановитьПараметр("Таблица",ТЗПриходныйОрдер);
	
	ТЗ = Запрос.Выполнить().Выгрузить()
Показать
5. Torin 284 19.11.20 17:55 Сейчас в теме
6. user973528 19.11.20 17:56 Сейчас в теме
7. Torin 284 19.11.20 17:59 Сейчас в теме
(6)
ТЗПриходныйОрдер = Новый ТаблицаЗначений;
    ТЗПриходныйОрдер.Колонки.Добавить("Номенклатура");
    ТЗПриходныйОрдер.Колонки.Добавить("Количество");



                 |Заказы.Ссылка = &Таблица
                 |СГРУППИРОВАТЬ ПО
                 |Заказы.Номенклатура";
    
    Запрос.УстановитьПараметр("Таблица",ТЗПриходныйОрдер);
    

ну и где тут Ссылка?
8. user973528 19.11.20 18:02 Сейчас в теме
(7) Не понимаю как в запрос засунуть свою таблицу значений
9. Torin 284 19.11.20 18:06 Сейчас в теме
(8) ТЗ не содержит Ссылки!

Добавим

ТЗПриходныйОрдер = Новый ТаблицаЗначений;

  ТЗПриходныйОрдер.Колонки.Добавить("Ссылка");



 |Заказы.Ссылка В &Таблица
                 |СГРУППИРОВАТЬ ПО
                 |Заказы.Номенклатура";
    
    Запрос.УстановитьПараметр("Таблица",ТЗПриходныйОрдер);
10. lmnlmn 64 19.11.20 18:08 Сейчас в теме
(4) Вы недопоняли предложенную идею. Не надо из внешних таблиц данные тащить. Можно сделать объединение ваших двух запросов в одну временную таблицу, а по ней уже группировку с выводом только различающихся.
12. user973528 19.11.20 18:10 Сейчас в теме
(10) Приходные ордера я вытащу как предложили, а вот расходные не связаны по реквизитам с перемещением, получается их вытащить только через критерий отбора, вот в чём проблема
13. lmnlmn 64 19.11.20 18:15 Сейчас в теме
(12) У вас запросы рабочие, которые в самом начале приведены?
14. user973528 19.11.20 18:22 Сейчас в теме
(13) Да, я с них данные уже получил, поэтому и хотел свои таблицы подставить вместо предложенного выше запроса
15. lmnlmn 64 19.11.20 18:23 Сейчас в теме
(14) Хорошо. Предлагаю такой вариант без таблиц:
Запрос.Текст = "ВЫБРАТЬ
                   |	ПриходныйОрдерНаТоварыТовары.Номенклатура КАК Номенклатура,
                   |	СУММА(ПриходныйОрдерНаТоварыТовары.Количество) КАК Количество1,
                   |	0 КАК Количество2
                   |ПОМЕСТИТЬ ВТ_Сводная
                   |ИЗ
                   |	Документ.ПриходныйОрдерНаТовары.Товары КАК ПриходныйОрдерНаТоварыТовары
                   |		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПриходныйОрдерНаТовары КАК ПриходныйОрдерНаТовары
                   |		ПО ПриходныйОрдерНаТоварыТовары.Ссылка = ПриходныйОрдерНаТовары.Ссылка
                   |ГДЕ
                   |	ПриходныйОрдерНаТовары.Распоряжение = &Перемещение
                   |	И ПриходныйОрдерНаТовары.Проведен
                   |
                   |СГРУППИРОВАТЬ ПО
                   |	ПриходныйОрдерНаТоварыТовары.Номенклатура
                   |
                   |ОБЪЕДИНИТЬ ВСЕ
                   |
                   |ВЫБРАТЬ
                   |	РасходныйОрдерНаТоварыОтгружаемыеТовары.Номенклатура,
                   |	0,
                   |	СУММА(РасходныйОрдерНаТоварыОтгружаемыеТовары.Количество)
                   |ИЗ
                   |	КритерийОтбора.СвязанныеДокументы(&Значение) КАК СвязанныеДокументы
                   |		ЛЕВОЕ СОЕДИНЕНИЕ Документ.РасходныйОрдерНаТовары.ОтгружаемыеТовары КАК РасходныйОрдерНаТоварыОтгружаемыеТовары
                   |		ПО ВЫРАЗИТЬ(СвязанныеДокументы.Ссылка КАК Документ.РасходныйОрдерНаТовары).Ссылка = РасходныйОрдерНаТоварыОтгружаемыеТовары.Ссылка
                   |ГДЕ
                   |	СвязанныеДокументы.Ссылка.Проведен
                   |	И СвязанныеДокументы.Ссылка ССЫЛКА Документ.РасходныйОрдерНаТовары
                   |
                   |СГРУППИРОВАТЬ ПО
                   |	РасходныйОрдерНаТоварыОтгружаемыеТовары.Номенклатура";
Показать
16. FatPanzer 9 19.11.20 18:29 Сейчас в теме
(15) Зачем в первом запросе соединение?
17. lmnlmn 64 19.11.20 18:31 Сейчас в теме
(16) Это вопрос к автору темы. Я его вариант использовал
18. FatPanzer 9 19.11.20 18:32 Сейчас в теме
(17) Говнокод надо исправлять сразу, не спрашивая разрешения у автора )))
19. lmnlmn 64 19.11.20 18:36 Сейчас в теме
(18) А в чем, собственно, говнокодность этого кода с учетом того что распоряжение и проведенность проверяется?
20. FatPanzer 9 19.11.20 18:39 Сейчас в теме
(19) А почему бы не проверить эти показатели сразу из первой таблицы, не присоединяя вторую?
21. lmnlmn 64 19.11.20 18:42 Сейчас в теме
(20) Из-за опасений что платформа не оптимизирует запрос к субд и сделает соединение от табличной части к таблице документов что будет более затратным решением для этого запроса.
22. FatPanzer 9 19.11.20 18:44 Сейчас в теме
(21) Так вы ровно это же самое и делаете - соединения от табличной части к таблице документов.
23. lmnlmn 64 19.11.20 18:45 Сейчас в теме
(22) Оп, не заметил что все так с этими "ТоварыТовары"))
24. user973528 20.11.20 08:55 Сейчас в теме
(11) Подскажите пожалуйста, посмотрел вашу ссылку, не могу никак понять что передаётся в Измерения?

РазницаТаблицЗначений(Таблица0, Таблица1, Измерения)
25. SlavaKron 20.11.20 09:05 Сейчас в теме
(24) Там же всё расписано:
"Второе уточнение автоматически приводит к тому, что в таблице всегда будут одна или более колонок, значение (комбинация значений) в которых будут уникальными и могут служить идентификатором строки. Такую колонку (набор колонок) можно называть ключом: простым в случае одной колонки или составным в более сложном случае. А еще лучше, по аналогии с регистрами, упомянутые колонки называть измерениями таблицы, а оставшиеся – ресурсами."
Жаль, что даже после такого масштабного исследования, остаются приверженцы сравнения ТЗ в запросе.
27. user973528 20.11.20 11:26 Сейчас в теме
(25) Получил такую таблицу на выходе используя метод

Функция РазницаТаблицЗначений(Таблица0, Таблица1, Измерения) Экспорт
    
    Отбор = Новый Структура(Измерения);
    
    Ресурсы = Новый Массив;
    Для ИндексКолонки = 0 По Таблица0.Колонки.Количество() - 1 Цикл
        Если НЕ Отбор.Свойство(Таблица0.Колонки[ИндексКолонки].Имя) Тогда
            Ресурсы.Добавить(ИндексКолонки)
        КонецЕсли
    КонецЦикла;
    
    Таблица1.Колонки.Добавить("Знак", Новый ОписаниеТипов("Число"));
    Таблица1.ЗаполнитьЗначения(1, "Знак");
    НовыйИндекс = Таблица1.Индексы.Добавить(Измерения);
    
    Разница = Таблица1.СкопироватьКолонки();
    
    Для Каждого Строка0 Из Таблица0 Цикл
        ЗаполнитьЗначенияСвойств(Отбор, Строка0); 
        Строки1 = Таблица1.НайтиСтроки(Отбор);
        Если Строки1.Количество() = 0 Тогда     
            ЗаполнитьЗначенияСвойств(Разница.Добавить(), Строка0)     
        Иначе
            Строка1 = Строки1[0];
            Для Каждого Ресурс Из Ресурсы Цикл 
                Если Строка0[Ресурс] <> Строка1[Ресурс] Тогда    
                    ЗаполнитьЗначенияСвойств(Разница.Добавить(), Строка0);
                    ЗаполнитьЗначенияСвойств(Разница.Добавить(), Строка1);
                    Прервать 
                КонецЕсли 
            КонецЦикла;
            Строка1.Знак = 0 
        КонецЕсли 
    КонецЦикла;
    
    Для Каждого Строка1 Из Таблица1.НайтиСтроки(Новый Структура("Знак", 1)) Цикл 
        ЗаполнитьЗначенияСвойств(Разница.Добавить(), Строка1); 
    КонецЦикла;
    
    Таблица1.Колонки.Удалить("Знак");
    Таблица1.Индексы.Удалить(НовыйИндекс);
        
    Возврат Разница
    
КонецФункции
Показать
Прикрепленные файлы:
26. VZyryanov 20.11.20 09:18 Сейчас в теме
Функция КоллекцияРазличаются(ТЗ1,ТЗ2,ИсключаемыеКолонки="") Экспорт
	ИсклКол=СтрокаВМассив(ИсключаемыеКолонки);
	Если ТЗ1.Количество()<>ТЗ2.Количество() Тогда
		Если ТЗ1.Количество()=1 И ТЗ2.Количество()=0 Тогда
			Для К=0 По ТЗ1.Количество()-1 Цикл
				Стр1=ТЗ1[К];
				Для М=0 По ТЗ1.Колонки.Количество()-1 Цикл
					Имя=ТЗ1.Колонки[М].Имя;
					Если ИсклКол.Найти(Имя)<>Неопределено Тогда
						Продолжить;
					КонецЕсли;
					Если ЗначениеЗаполнено(Стр1[Имя]) Тогда
						Возврат Истина;
					КонецЕсли;
				КонецЦикла;
			КонецЦикла;
			Возврат Ложь;
		ИначеЕсли ТЗ1.Количество()=0 И ТЗ2.Количество()=1 Тогда
			Для К=0 По ТЗ2.Количество()-1 Цикл
				Стр2=ТЗ2[К];
				Для М=0 По ТЗ1.Колонки.Количество()-1 Цикл
					Имя=ТЗ1.Колонки[М].Имя;
					Если ИсклКол.Найти(Имя)<>Неопределено Тогда
						Продолжить;
					КонецЕсли;
					Если ЗначениеЗаполнено(Стр2[Имя]) Тогда
						Возврат Истина;
					КонецЕсли;
				КонецЦикла;
			КонецЦикла;
			Возврат Ложь;
		Иначе
			Возврат Истина;
		КонецЕсли;
	КонецЕсли;
	Для К=0 По ТЗ1.Количество()-1 Цикл
		Стр1=ТЗ1[К];
		Стр2=ТЗ2[К];
		Для М=0 По ТЗ1.Колонки.Количество()-1 Цикл
			Имя=ТЗ1.Колонки[М].Имя;
			Если ИсклКол.Найти(Имя)<>Неопределено Тогда
				Продолжить;
			КонецЕсли;
			Если Стр1[Имя]<>Стр2[Имя] Тогда
				Возврат Истина;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	Возврат Ложь;
КонецФункции
Показать
Оставьте свое сообщение
Вопросы с вознаграждением