Имя: Пароль:
1C
1С v8
Запрос - сравить табличные части
0 ЭЦ
 
30.12.13
17:34
Господа !
Имеются документы - накладная.
У документов имеются табличная часть - Товар
с реквизитами : - Номенклатура - Цена/
Требуется выбрать все документы у которых таб. часть в точности совпадает с заданным документом.
(т.е.совпадает перечень всех номенклатур и их цена).
Для сравнения двух документов все просто
ВЫБРАТЬ
    ВЫБОР

ИЗ
    Документы.Накладная.Товар КАК Товар1
ПОЛНОЕ СОЕДИНЕНИЕ
    Документы.Накладная.Товар КАК Товар2
ПО
    Товар1.Номенклатура = Товар2.Номенклатура
    И Товар1.Цена = Товар2.Цена
ГДЕ
    Товар1.Ссылка = &ДОК1
    И Товар2.Ссылка = &ДОК2

Прошу подсказать
1 1sik
 
30.12.13
17:35
А если попробовать засунуть содержимое табчасти в одно значение по которому попробовать сгруппировать.
2 1sik
 
30.12.13
17:37
Например получится
Ложка5Вилка6Стул8
Ложка11Вилка6Стул8
Ложка5Вилка6Стул8
Ложка5Вилка6Стул8Табуретка11

Потом найти количество различных будет

Ложка5Вилка6Стул8             2
Ложка11Вилка6Стул8            1
Ложка5Вилка6Стул8Табуретка11  1,
главное упорядочить правильно
3 Wobland
 
30.12.13
17:39
я легко себе представляю две ТЗ, одинаковые по составу, но различные по сравнению "="
4 МихаилМ
 
30.12.13
17:39
(0)
в точности до позиции(номера) строки в документе ?
5 fisher
 
30.12.13
17:45
Как-то так навскидку:

ВЫБРАТЬ
    Товар2.Ссылка КАК Док
ИЗ
    Документы.Накладная.Товар КАК Товар1
СОЕДИНЕНИЕ
    Документы.Накладная.Товар КАК Товар2
ПО
    Товар1.Номенклатура = Товар2.Номенклатура
    И Товар1.Цена = Товар2.Цена
ГДЕ
    Товар1.Ссылка = &ДОК1
СГРУППИРОВАТЬ ПО
    Товар2.Ссылка
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(Товар2.Номенклатура) В (ВЫБРАТЬ КОЛИЧЕСТВО(Номенклатура) ИЗ Документы.Накладная.Товар ГДЕ Ссылка = &ДОК1)
6 recovery_man
 
30.12.13
17:51
(0) Заданный документ, можно положить во временную таблицу, выбрать все что нужно, потом не соединяя а просто сравнивая во втором запросе найти ссылки на одинаковые данные или сравнивать сумму, дело вкуса..! так вы получите 1 документ как образец, остальные в запросе его копии
7 ЭЦ
 
30.12.13
17:58
(4) Номер в строке - не важен -важен состав и цены
8 ЭЦ
 
30.12.13
18:01
(2) Эдак мы только совпадающих с точность дю до номера строки отловим
9 МихаилМ
 
30.12.13
18:10
10 seademon86
 
30.12.13
18:13
(8) Вариация способа (2):
Отсортировать ТЧ по необходимым полям, связать строки в одно значение и сравнивать по значению
11 recovery_man
 
30.12.13
18:17
У меня так получилось найти 3 одинаковых тч с разными номерами строк:

ВЫБРАТЬ
    АктВыполненныхРаботВходящийРаботыИУслуги.Номенклатура,
    АктВыполненныхРаботВходящийРаботыИУслуги.Цена
ПОМЕСТИТЬ ВТ
ИЗ
    Документ.АктВыполненныхРаботВходящий.РаботыИУслуги КАК АктВыполненныхРаботВходящийРаботыИУслуги
ГДЕ
    АктВыполненныхРаботВходящийРаботыИУслуги.Ссылка = &Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
    АктВыполненныхРаботВходящийРаботыИУслуги.Ссылка
ИЗ
    Документ.АктВыполненныхРаботВходящий.РаботыИУслуги КАК АктВыполненныхРаботВходящийРаботыИУслуги,
    ВТ КАК ВТ
ГДЕ
    АктВыполненныхРаботВходящийРаботыИУслуги.Номенклатура = ВТ.Номенклатура
            И АктВыполненныхРаботВходящийРаботыИУслуги.Цена = ВТ.Цена
12 ЭЦ
 
30.12.13
18:24
(11) Эдак помоему ты найдешь доки у которых есть хотябы одна совпадающая строка
13 recovery_man
 
30.12.13
18:27
да,щас пакетом переделаю, попадалось где-то точно помню ...
14 Dmitry1c
 
30.12.13
18:27
Предлагаю посчитать MD5 от каждой табличной части и сравнить хэши...
15 ЭЦ
 
30.12.13
18:32
Я пока ничеголучше чем посчитаь несовпадающиестроки не придумал :
ВЫБРАТЬ
   ВложенныйЗапрос.Ссылка
ИЗ
(ВЫБРАТЬ
    Товар2.Ссылка,
    СУММА(ВЫБОР
        КОГДА Товар1.Номенклатура ЕСТЬ NULL
        ИЛИ Товар1.Цена ЕСТЬ NULL
        ИЛИ Товар2.Номенклатура ЕСТЬ NULL
        ИЛИ Товар2.Цена ЕСТЬ NULL
            ТОГДА 1
        ИНАЧЕ
            0
    КОНЕЦ) КАК Кол
ИЗ
    Документы.Накладная.Товары КАК Товары1
ПОЛНОЕ СОЕДИНЕНИЕ
    Документы.Накладная.Товары КАК Товары2
ПО
    Товары1.Номенклатура = Товары2.Номенклатуры
    И Товары1.Цена = Товары2.Цена
СГРУППИРОВАТЬ ПО
    Товар2.Ссылка
ГДЕ
    Товары1.Ссылка = &ДОК1
) КАК ВложенныйЗапрос
ГДЕ
   ВложенныйЗапрос.Кол = 0
16 azernot
 
30.12.13
18:34
Вот тебе рабочий пример

ВЫБРАТЬ
    СчетСостав.Номенклатура,
    СчетСостав.Цена,
    СчетСостав.Количество
ПОМЕСТИТЬ ИскомаяТЧ
ИЗ
    Документ.Счет.Состав КАК СчетСостав
ГДЕ
    СчетСостав.Ссылка = &Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
    Данные.Ссылка
ИЗ
    (ВЫБРАТЬ
        ДокументТЧ.Ссылка КАК Ссылка,
        СУММА(1) КАК КоличествоСтрок,
        СУММА(ВЫБОР
                КОГДА ИскомаяТЧ.Номенклатура ЕСТЬ NULL
                    ТОГДА 0
                ИНАЧЕ 1
            КОНЕЦ) КАК КоличествоСвязей
    ИЗ
        Документ.РасходнаяНакладная.Состав КАК ДокументТЧ
            ЛЕВОЕ СОЕДИНЕНИЕ ИскомаяТЧ КАК ИскомаяТЧ
            ПО ДокументТЧ.Номенклатура = ИскомаяТЧ.Номенклатура
                И ДокументТЧ.Цена = ИскомаяТЧ.Цена
                И ДокументТЧ.Количество = ИскомаяТЧ.Количество
    ГДЕ
        ДокументТЧ.Ссылка <> &Ссылка
    
    СГРУППИРОВАТЬ ПО
        ДокументТЧ.Ссылка
    
    ИМЕЮЩИЕ
        СУММА(1) = СУММА(ВЫБОР
                КОГДА ИскомаяТЧ.Номенклатура ЕСТЬ NULL
                    ТОГДА 0
                ИНАЧЕ 1
            КОНЕЦ)
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        ДокументТЧ.Ссылка,
        СУММА(1),
        СУММА(ВЫБОР
                КОГДА ИскомаяТЧ.Номенклатура ЕСТЬ NULL
                    ТОГДА 0
                ИНАЧЕ 1
            КОНЕЦ)
    ИЗ
        Документ.Счет.Состав КАК ДокументТЧ
            ЛЕВОЕ СОЕДИНЕНИЕ ИскомаяТЧ КАК ИскомаяТЧ
            ПО ДокументТЧ.Номенклатура = ИскомаяТЧ.Номенклатура
                И ДокументТЧ.Цена = ИскомаяТЧ.Цена
                И ДокументТЧ.Количество = ИскомаяТЧ.Количество
    ГДЕ
        ДокументТЧ.Ссылка <> &Ссылка
    
    СГРУППИРОВАТЬ ПО
        ДокументТЧ.Ссылка
    
    ИМЕЮЩИЕ
        СУММА(1) = СУММА(ВЫБОР
                КОГДА ИскомаяТЧ.Номенклатура ЕСТЬ NULL
                    ТОГДА 0
                ИНАЧЕ 1
            КОНЕЦ)
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        ДокументТЧ.Ссылка,
        СУММА(1),
        СУММА(ВЫБОР
                КОГДА ИскомаяТЧ.Номенклатура ЕСТЬ NULL
                    ТОГДА 0
                ИНАЧЕ 1
            КОНЕЦ)
    ИЗ
        Документ.ПриходнаяНакладная.Состав КАК ДокументТЧ
            ЛЕВОЕ СОЕДИНЕНИЕ ИскомаяТЧ КАК ИскомаяТЧ
            ПО ДокументТЧ.Номенклатура = ИскомаяТЧ.Номенклатура
                И ДокументТЧ.Цена = ИскомаяТЧ.Цена
                И ДокументТЧ.Количество = ИскомаяТЧ.Количество
    ГДЕ
        ДокументТЧ.Ссылка <> &Ссылка
    
    СГРУППИРОВАТЬ ПО
        ДокументТЧ.Ссылка
    
    ИМЕЮЩИЕ
        СУММА(1) = СУММА(ВЫБОР
                КОГДА ИскомаяТЧ.Номенклатура ЕСТЬ NULL
                    ТОГДА 0
                ИНАЧЕ 1
            КОНЕЦ)) КАК Данные
17 fisher
 
30.12.13
19:19
А чем вариант (5) не нравится?
Типа полностью совпадающими считаем те документы, в которых количество совпадающих строк равно количеству строк эталонного документа.
18 Бертыш
 
30.12.13
19:24
(16) Вот же ж не ленивый программист
19 Бертыш
 
30.12.13
19:47
запрос 1 считает всего строк в тч каждого документа и группируя поссылочно сохраняет во временную таблицу 0
запрос 2 помещает все тч во временную таблицу 1
запрос 3 соединяет временную таблицу с собой же по условию совпадения номенклатуры цены и несовпадения ссылки.
на этом этапе если не null связь ставим единичку и прячем во временную таблицу 2 левую ссылку, правую ссылку, счетчик совпавших строк группировкой естественно
запрос 4 сравнивает количество строк временной таблицы 0 и количество совпавших связей временная 2. формируем реестр найденных дублей временная 3
запрос 5 проверяет временную 3 связав с временной 0 а совпадает ли количество строк дубля с количеством строк оригинала, на этом этапе мы отсекаем дубли в которых строк явно больше чем в оригинале и формируем из таких дублей
реестр временная 4
запрос 6 выводим временную 2 исключив по вхождению во временную 4 ссылок как правой ссылки так и левой. это делается засчет двукратного соединения с временной 4

как то так оно все не затейливо вроде
20 Бертыш
 
30.12.13
19:49
+19 в запросе 3 полное соединение надо кажись, а вот если связь не дала null замечаем этот факт
21 Бертыш
 
30.12.13
19:56
В рамках оптимизации можно в начало вставить запрос благодаря которому мы все эти пляски с бубном бум выполнять на документах только тех у которых совпадает количество строк.
Ну короче можно оптимизировать
22 Бертыш
 
31.12.13
11:44
Ну вот с оптимизацией реестр документов с реестром дублей
ВЫБРАТЬ
    _ДемоСчетНаОплатуПокупателюТовары.Ссылка,
    СУММА(1) КАК Строк
ПОМЕСТИТЬ Реестр1
ИЗ
    Документ._ДемоСчетНаОплатуПокупателю.Товары КАК _ДемоСчетНаОплатуПокупателюТовары

СГРУППИРОВАТЬ ПО
    _ДемоСчетНаОплатуПокупателюТовары.Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    _ДемоСчетНаОплатуПокупателюТовары.Ссылка,
    _ДемоСчетНаОплатуПокупателюТовары1.Ссылка КАК Ссылка1,
    СУММА(ВЫБОР
            КОГДА ЕСТЬNULL(_ДемоСчетНаОплатуПокупателюТовары.Ссылка, ИСТИНА) = ИСТИНА
                ТОГДА 0
            КОГДА ЕСТЬNULL(_ДемоСчетНаОплатуПокупателюТовары1.Ссылка, ИСТИНА) = ИСТИНА
                ТОГДА 0
            ИНАЧЕ 1
        КОНЕЦ) КАК Совпадений
ПОМЕСТИТЬ Реестр2
ИЗ
    Документ._ДемоСчетНаОплатуПокупателю.Товары КАК _ДемоСчетНаОплатуПокупателюТовары
        ПОЛНОЕ СОЕДИНЕНИЕ Документ._ДемоСчетНаОплатуПокупателю.Товары КАК _ДемоСчетНаОплатуПокупателюТовары1
        ПО _ДемоСчетНаОплатуПокупателюТовары.Номенклатура = _ДемоСчетНаОплатуПокупателюТовары1.Номенклатура
            И _ДемоСчетНаОплатуПокупателюТовары.Цена = _ДемоСчетНаОплатуПокупателюТовары1.Цена
            И _ДемоСчетНаОплатуПокупателюТовары.Ссылка <> _ДемоСчетНаОплатуПокупателюТовары1.Ссылка
ГДЕ
    ВЫБОР
            КОГДА ЕСТЬNULL(_ДемоСчетНаОплатуПокупателюТовары.Ссылка, ИСТИНА) = ИСТИНА
                ТОГДА 0
            КОГДА ЕСТЬNULL(_ДемоСчетНаОплатуПокупателюТовары1.Ссылка, ИСТИНА) = ИСТИНА
                ТОГДА 0
            ИНАЧЕ 1
        КОНЕЦ <> 0

СГРУППИРОВАТЬ ПО
    _ДемоСчетНаОплатуПокупателюТовары.Ссылка,
    _ДемоСчетНаОплатуПокупателюТовары1.Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Реестр1.Ссылка,
    МАКСИМУМ(ВЫБОР
            КОГДА Реестр1.Строк = Реестр2.Совпадений
                ТОГДА 1
            ИНАЧЕ 0
        КОНЕЦ) КАК Дубли
ПОМЕСТИТЬ ИмеютДубли
ИЗ
    Реестр2 КАК Реестр2
        ЛЕВОЕ СОЕДИНЕНИЕ Реестр1 КАК Реестр1
        ПО Реестр2.Ссылка = Реестр1.Ссылка
ГДЕ
    ВЫБОР
            КОГДА Реестр1.Строк = Реестр2.Совпадений
                ТОГДА 1
            ИНАЧЕ 0
        КОНЕЦ = 1

СГРУППИРОВАТЬ ПО
    Реестр1.Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Реестр2.Ссылка КАК Ссылка,
    Реестр2.Ссылка1 КАК Дубль,
    1 КАК Дублей
ИЗ
    Реестр2 КАК Реестр2
ГДЕ
    Реестр2.Ссылка В
            (ВЫБРАТЬ
                ИмеютДубли.Ссылка
            ИЗ
                ИмеютДубли КАК ИмеютДубли)
    И Реестр2.Ссылка1 В
            (ВЫБРАТЬ
                ИмеютДубли.Ссылка
            ИЗ
                ИмеютДубли КАК ИмеютДубли)
ИТОГИ
    СУММА(Дублей)
ПО
    Ссылка


Надо учитывать что документ А являющийся дублем Документа Б выводится и сам с дублем в виде документа Б
23 Бертыш
 
31.12.13
11:45
Документы которые имеют схожий состав но больше строк  отсекаются
24 Бертыш
 
31.12.13
11:49
Если нужен фильтр по конкретному документу то в самое начало ставим выборку табличной части по условию равенства ссылки и помещаем во временную таблицу с которой потом сравниваем полным соединением ТЧ потенциальных дублей. Если что тоже могу написать
25 Бертыш
 
31.12.13
12:03
Хотя проще в последнем запросе условие на ссылка наложить :)
26 Бертыш
 
31.12.13
17:41
Можно сделать вариант по одному документу но сначала надо определится с ответом на вопрос - могут ли в искомом входящем документе повторятся строки. То есть если во входящем документе дублей которого мы ищем есть дубли строк то и в документе дубле должно быть ровно такое же количество дублей тех же самых строк