Имя: Пароль:
1C
1C 7.7
v7: SQL запрос по свойствам номенклатуры
0 Fiasko
 
01.12.13
19:56
Помогите, пожалуйста, с прямым зарпосом. Мне надо получить список товаров с фильтром по списку значений свойств (товар должен иметь все свойства одновременно).

Запрос ниже возвращает товары, в которых содержится хотя бы одно свойство.

    |SELECT
    | Номенклатура.ID [Товар $Справочник.Номенклатура]
    |FROM
    | $Справочник.Номенклатура AS Номенклатура With (NOLOCK)
    | INNER JOIN $Справочник.СвойстваНоменклатуры AS СвойстваНоменклатуры With (NOLOCK) ON Номенклатура.ID = СвойстваНоменклатуры.PARENTEXT
    |WHERE
    | ($СвойстваНоменклатуры.ЗначениеСвойства IN (SELECT val FROM #СписокФильтров))
    |"
    ;

На данный момент я решил вопрос накладывая фильтр повторно на полученную тз после запроса, но, уверен, есть более эффективный способ!?
1 mehfk
 
01.12.13
20:01
Сформируй текст запроса динамически.
2 mikecool
 
01.12.13
20:02
лефт джойн + условие в он
3 mikecool
 
01.12.13
20:02
+2 или условия на значения свойств во вложенном запросе по свойствам, а результат уже лефт джойнить
4 КонецЦикла
 
01.12.13
20:09
Левые соединения по возможным видам свойств
Потом собираем те позиции которые дали в сумме case (1 = есть значение свойства) кол-во видов свойств номенклатуры
Как-то так тупенько сходу...
5 Стрелок
 
01.12.13
20:15
(0) я бы сделал т.к. в (1) советуют
6 Стрелок
 
01.12.13
20:16
(2) а кинь пример кода. интересно глянуть
7 Fiasko
 
01.12.13
20:22
(2) ок, буду пытаться..
(6) ниже

Для сч=1 По ЗначенияФильтра.РазмерСписка() Цикл
    
    ЗначениеФильтра = ЗначенияФильтра.ПолучитьЗначение(сч);
    
    Запрос.УстановитьТекстовыйПараметр("ЗначениеФильтра", ЗначениеФильтра);
    ТекСписокТоваров = СоздатьОбъект("СписокЗначений");
    тзБуфер.Выгрузить(ТекСписокТоваров,,,"Товар");
    
    Если ТекСписокТоваров.РазмерСписка() > 0 Тогда
        Запрос.УложитьСписокОбъектов(ТекСписокТоваров, "#ТекСписокТоваров", "Номенклатура");
    КонецЕсли;
    
    ТекстЗапроса = "
    |SELECT
    | Номенклатура.ID [Товар $Справочник.Номенклатура]
    |FROM
    | $Справочник.Номенклатура AS Номенклатура With (NOLOCK)
    | INNER JOIN $Справочник.СвойстваНоменклатуры AS СвойстваНоменклатуры With (NOLOCK) ON Номенклатура.ID = СвойстваНоменклатуры.PARENTEXT
    |WHERE
    | (Номенклатура.ISMARK <> 1)
    | AND (СвойстваНоменклатуры.ISMARK <> 1)
    | AND (Номенклатура.ID IN (SELECT val FROM #ТекСписокТоваров))
    | AND ($СвойстваНоменклатуры.ЗначениеСвойства = :ЗначениеФильтра)
    |"
    ;
    
    тзТоваров = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
    
    //Обновляем таблицу рукавов в соответствии с выбранными фильтрами
    
    УдаляемыеСтроки = СоздатьОбъект("СписокЗначений");
    тзБуфер.ВыбратьСтроки();
    Пока тзБуфер.ПолучитьСтроку() = 1 Цикл
        ТекТовар = тзБуфер.ПолучитьЗначение(тзБуфер.НомерСтроки,"Товар");
        Если тзТоваров.НайтиЗначение(ТекТовар,,"Товар") = 0 Тогда
            УдаляемыеСтроки.ДобавитьЗначение(тзБуфер.НомерСтроки);
        КонецЕсли;
    КонецЦикла;
    
    Для ъ=1 По УдаляемыеСтроки.РазмерСписка() Цикл
        УдСтр=УдаляемыеСтроки.ПолучитьЗначение(ъ);
        тзБуфер.УдалитьСтроку(УдСтр-ъ+1);
    КонецЦикла;
    
КонецЦикла;

Если тзБуфер.КоличествоСтрок() = 0 Тогда
    // если выбирается сначала товар - а затем меняется фильтр, то нужно перезаполнят таблицу, иначе ничего не найдем!!!
    Предупреждение("Не найдено номенклатуры, удовлетворяющей заданным условиям!",60);  
    тзРезультатыОтбора.УдалитьСтроки();
Иначе
    тзБуфер.Выгрузить(тзРезультатыОтбора);
    тзРезультатыОтбора.ВыводитьПиктограммы(1); // снова так как перезагружали таблицу
    тзРезультатыОтбора.ТекущаяСтрока(1);
КонецЕсли;
8 Fiasko
 
01.12.13
20:23
спасибо всем за советы )
9 Fiasko
 
01.12.13
20:30
вопрос к модераторам, кстати: что нужно делать, чтобы код, выкладываемый на форуме сворачивался автоматом?
10 Стрелок
 
01.12.13
20:33
(7)  я вообщето спрашивал "mikecool"
11 Fiasko
 
01.12.13
20:34
(10) не понял, сори )
12 mikecool
 
01.12.13
20:35
(10) мне лень
13 mikecool
 
01.12.13
20:35
+12 потому как я скорее всего не допонял чего хочет автор, а сегодня я совсем не телепат
14 Стрелок
 
01.12.13
20:37
(12) ясно ;)
15 КонецЦикла
 
01.12.13
20:42
(9) Спойлеров тут нет, не писать много кода :)
16 Fiasko
 
01.12.13
21:22
(13) я думал подробно выругался.. ладно, попробую по-другому. Мне нужно из справочника товаров выбрать все товары, в которых свойства "цвет" - желтый и "форма" - квадратный присутствуют одновременно..
отсюда вопрос - пост в (2) еще актуален?
17 КонецЦикла
 
02.12.13
01:08
(16) В (4) все написано или прямо текст нужен?
18 КонецЦикла
 
02.12.13
01:15
селект тут собираем суммы по кейсам
фром
(
селект ...
фром номенклатура
кейс вен знач1 из нулл зен 1 елсе 0 енд
кейс вен знач2 из нулл зен 1 елсе 0 енд
лефт джоин значение свойства знач 1 где значение = первое
лефт джоин значение свойства знач 2 где значение = второе
...
значения свойств парентекст
где значение = наше значение и вид
)
груп бай ...
хэвинг сум(кол-во значений св-ств) >= наше кол-во значений св-ств

Можно попробовать собрать через юнион олл по владельцу свойств
Компьютеры — прекрасное средство для решения проблем, которых до их появления не было.