Имя: Пароль:
1C
1С v8
СКД: нетипичное использование необязательного параметра
,
0 vdeemer
 
17.08.22
16:23
Добрый день.
Необходимо сваять отчет по регистру накопления с необязательным отбором: товары надо брать из ТЧ документов. Соответственно, если документы не указаны, то по всем товарам. Вроде все просто:

ВЫБРАТЬ
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    ПродажиОбороты.КоличествоОборот КАК КоличествоПродажа
ИЗ
    РегистрНакопления.Продажи.Обороты(
            &НачалоПериода,
            &КонецПериода,
            Авто,
            Фирма = &Фирма И Склад = &Склад {(Номенклатура В
                (ВЫБРАТЬ РАЗЛИЧНЫЕ
                    ТоварыЗаявок.Номенклатура КАК Номенклатура
                ИЗ
                    Документ.ЗаявкаПокупателя.Товары КАК ТоварыЗаявок
                ГДЕ
                    ТоварыЗаявок.Ссылка В (&Заявки)))}) КАК ПродажиОбороты


Все работает, как и ожидается: если документы указаны, то выбираются данные только по позициям из них, если нет - по всем.
Теперь надо вывести отдельной колонкой общее количество товаров из заявок. Соответственно, если заявки не указаны, то это количество должно быть 0.
Добавляю ВТ, чтобы присоединить ее к итоговому запросу слева:

ВЫБРАТЬ
    ТоварыЗаявки.Номенклатура КАК Номенклатура,
    СУММА(ВЫБОР
            КОГДА ТоварыЗаявки.Коэффициент = 0
                ТОГДА 1
            ИНАЧЕ ТоварыЗаявки.Коэффициент
        КОНЕЦ * ТоварыЗаявки.Количество) КАК КоличествоЗаявки
ПОМЕСТИТЬ ВТ_ТоварыЗаявок
ИЗ
    Документ.ЗаявкаПокупателя.Товары КАК ТоварыЗаявки
ГДЕ
    ВЫБОР
        КОГДА &Заявки ЕСТЬ NULL ТОГДА ЛОЖЬ
        ИНАЧЕ ТоварыЗаявки.Ссылка В (&Заявки)
    КОНЕЦ

СГРУППИРОВАТЬ ПО
    ТоварыЗаявки.Номенклатура

ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

Как мне казалось, условие ГДЕ в ней должно на пустом значении параметра &Заявки дать ЛОЖЬ и ВТ будет пустая. Я оказался не прав, выдается "Ошибка при исполнении запроса набора данных", Не задано значение параметра "Заявки"
ИНАЧЕ ТоварыЗаявки.Ссылка В (<<?>>&Заявки)

Как можно решить эту проблему? Чет я совсем затупил и приуныл...
1 Kassern
 
17.08.22
16:27
(0) В СКД можно использовать характеристики для этих целей (выделяется в фигурные скобки). Откуда такая любовь к вложенным запросам в виртуальных таблицах?
2 vdeemer
 
17.08.22
16:32
(1) А как использовать другим способом {} для выбора из ТЧ документа?
3 Kassern
 
17.08.22
16:37
4 vdeemer
 
17.08.22
16:39
(3) Это нетиповая конфигурация, характеристики не используются. За ссылку спасибо.
5 Kassern
 
17.08.22
16:41
Еще как вариант - ваш вложенный запрос поместить во временную таблицу, где будет еще и количество. Далее вашу виртуальную таблицу соединить левым соединением с временной таблицей по номенклатуре. А в условии прописать, Выбор когда &ИспользоватьОтборПоЗаявкам тогда ЕстьNull(Заявки.Номенклатура,"")<>"" Иначе Истина Конец
6 Kassern
 
17.08.22
16:43
(4) Вы как раз и используете характеристики.... "Фирма = &Фирма И Склад = &Склад {(Номенклатура В" - вот тут объясните зачем вы фигурную скобку открыли?)
7 Kassern
 
17.08.22
16:43
речь идет не про характеристики номенклатуры
8 vdeemer
 
17.08.22
16:44
(5) Так запрос с этой таблицей выдаст ту же ошибку, если не заполнен параметр &Заявки
(6) Затем, что этот параметр необязательный - если он не заполнен, то фильтра по номенклатуре нет
9 Kassern
 
17.08.22
16:44
(8) так это и есть использование характеристик в запросе)
10 Kassern
 
17.08.22
16:45
и выделяются они фигурными скобками
11 Kassern
 
17.08.22
16:46
(8) А что вам мешает этот параметр заполнить в зависимости от указанных заявок?
12 Kassern
 
17.08.22
16:46
хотя бы при компоновки данных
13 vdeemer
 
17.08.22
16:47
(9) По данной Вами ссылке 1С пишет не так:
Характеристики в системе компоновки данных описываются в тексте запроса набора данных специальной инструкцией системы компоновки данных, начинающейся с ключевого слова ХАРАКТЕРИСТИКИ.
У меня этого слова нет.
(11) Он может быть НЕ ЗАПОЛНЕН, вот и вся проблема. В этом случае все плохо)
14 Kassern
 
17.08.22
16:58
(13) "Он может быть НЕ ЗАПОЛНЕН" - ну так сделайте, чтобы всегда был заполнен. Ничего сложного в этом нет. Скрыли от юзверов этот параметр, при компоновке всего пару строчек, проверяете, что есть отбор по заявкам и на основании этого устанавливаете программно отбор на использование заказов.
15 bolobol
 
17.08.22
17:11
В чём смысл этой записи "КОГДА &Заявки ЕСТЬ NULL ТОГДА ЛОЖЬ" ?
16 Kassern
 
17.08.22
17:30
(15) У вас есть основная таблица и с ней сопоставлена таблица заявок. При отборе по последней обрежутся строки первой. Если Первый параметр ложь (нет строк в таблице заявок) то тогда будет просто основная таблица, в противном случае будет действовать условие о наличии строк в правой таблице.
17 bolobol
 
17.08.22
17:38
(16) Вижу, что Вы тоже не поняли
18 Kassern
 
17.08.22
17:40
(17) а блин, вы про ТСа спрашиваете и его решение))
19 Kassern
 
17.08.22
17:41
даже если каким-то макаром Заявки вернут нул, то в Тогда должна быть Истина, а не ложь
20 Kassern
 
17.08.22
17:49
21 Kassern
 
17.08.22
17:49
Можно параметрами СКД это дело обыграть
22 vdeemer
 
19.08.22
08:57
(14) Задача именно в том, что этот параметр должен иметь возможность быть незаполненным. Если он не заполнен, то первая часть запроса (0) работает без фильтра, а вторая (которая ВТ) должна выдать ПУСТОЙ набор данных. Это требуемое поведение запроса.
(15) Смысл в том, что при незаполненном значении &Заявки в условии ГДЕ будет ЛОЖЬ и ни одной записи в результате быть не должно. Это, повторюсь, планируемое поведение, но при выполнении выдается ошибка. Проблема именно в этом.
(20) Если и можно, то я до этого никак не допру((
23 Kassern
 
19.08.22
09:28
(22) Вы учитесь, или для работы делаете?
24 vdeemer
 
19.08.22
09:36
(23) А какое это имеет значение по сути вопроса?)
25 Kassern
 
19.08.22
09:43
(24) самое простое. Вам написали как можно выйти из ситуации и решить вопрос рабочий. Но если это обучение, то от вас будут требовать именно тот способ, который задумывался.
26 Kassern
 
19.08.22
09:44
проще говоря проверка на ваши знания, а не на возможность решить задачу.
27 vdeemer
 
19.08.22
10:10
(25) Ткните, пожалуйста, на описание выхода из ситуации. То, что предложено в ветке, поставленную задачу не решает, увы.
28 Kassern
 
19.08.22
10:48
(27) Я же уже описывал, что и как сделать. Взять основную таблицу, к ней присоединить временную, в условии прописать, если есть отбор тогда, проверка на нул правой таблицы, иначе Истина.
А при компоновке прописать, что-то на подобие:
ИспользоватьОтборПоЗаказам= КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ИспользоватьОтборПоЗаказам");
    ОтборЗаказы=КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти("86afc649-ebbe-4132-856e-8b54ca9df044");
    ИспользоватьОтборПоЗаказам.Значение=ЗначениеЗаполнено(ОтборЗаказы.Значение);
    ИспользоватьОтборПоЗаказам.Использование=Истина;
29 VS-1976
 
19.08.22
10:55
Передавай параметр всегда, если заявок нет, то пустой массив
30 vdeemer
 
19.08.22
10:57
(28) Так я в запросе (0) это и делаю, разве нет?

ГДЕ
    ВЫБОР
        КОГДА &Заявки ЕСТЬ NULL ТОГДА ЛОЖЬ
        ИНАЧЕ ТоварыЗаявки.Ссылка В (&Заявки)
    КОНЕЦ

Разве "КОГДА &Заявки ЕСТЬ NULL ТОГДА ЛОЖЬ" не есть искомая проверка?
(29) Нельзя пустой массив передавать, он в запросе по регистру сыграет и даст неверный результат.
31 Kassern
 
19.08.22
11:01
(30) Не так вы делаете. "КОГДА &Заявки ЕСТЬ NULL ТОГДА" - что за бред? Зачем вы параметр на нул проверяете? Этот параметр всегда должен быть передан. Но либо пустой список, либо со значениями.
32 VS-1976
 
19.08.22
11:02
(30) да нет, проверка не проходит перед исполнением запроса. Добавь ещё  параметр

  ВЫБОР
        КОГДА &ЗаявкиЕсть = Ложь ТОГДА ЛОЖЬ
        ИНАЧЕ ТоварыЗаявки.Ссылка В (&Заявки)
    КОНЕЦ

УстановитьПараметр( "ЗаявкиЕсть", значениезаполнено(Заявки) )
33 Kassern
 
19.08.22
11:04
Держи уже простой пример на коленке сделанный:
ВЫБРАТЬ
    ВыручкаИСебестоимостьПродажОбороты.КоличествоОборот КАК КоличествоОборот,
    ВыручкаИСебестоимостьПродажОбороты.СуммаВыручкиОборот КАК СуммаВыручкиОборот,
    ВыручкаИСебестоимостьПродажОбороты.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ОсновнаяТаблица
ИЗ
    РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты КАК ВыручкаИСебестоимостьПродажОбороты
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ЗаказКлиентаТовары.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
    Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
ГДЕ
    ЗаказКлиентаТовары.Ссылка В(&Заказы)

СГРУППИРОВАТЬ ПО
    ЗаказКлиентаТовары.Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ОсновнаяТаблица.Номенклатура КАК Номенклатура,
    ОсновнаяТаблица.СуммаВыручкиОборот КАК СуммаВыручкиОборот,
    ОсновнаяТаблица.КоличествоОборот КАК КоличествоОборот
ИЗ
    ОсновнаяТаблица КАК ОсновнаяТаблица
        ЛЕВОЕ СОЕДИНЕНИЕ ВременнаяТаблица КАК ВременнаяТаблица
        ПО ОсновнаяТаблица.Номенклатура = ВременнаяТаблица.Номенклатура
ГДЕ
    ВЫБОР
            КОГДА &ИспользоватьОтборПоЗаказам
                ТОГДА ЕСТЬNULL(ВременнаяТаблица.Номенклатура, "") <> ""
            ИНАЧЕ ИСТИНА
        КОНЕЦ
34 Kassern
 
19.08.22
11:05
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    ИспользоватьОтборПоЗаказам= КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ИспользоватьОтборПоЗаказам");
    ОтборЗаказы=КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти("86afc649-ebbe-4132-856e-8b54ca9df044");
    ОтборЗаказы.Использование=Истина;
    ИспользоватьОтборПоЗаказам.Значение=ЗначениеЗаполнено(ОтборЗаказы.Значение);
    ИспользоватьОтборПоЗаказам.Использование=Истина;
        
КонецПроцедуры
35 Kassern
 
19.08.22
11:05
дальше сам
36 vdeemer
 
19.08.22
11:14
(32), (33) Спасибо, пробую.
(33) Параметр в виртуальной таблице пропущен, запрос вернет не то, что нужно. Но это, я так понимаю, описка.
37 Kassern
 
19.08.22
11:15
(36) Про какой параметр речь?
38 Kassern
 
19.08.22
11:16
Если про Период речь, то СКД сама воткнет эти параметры
39 vdeemer
 
19.08.22
11:19
(37) Про фильтр номенклатуры из заявок, все обороты не нужны
40 Kassern
 
19.08.22
11:27
(39) Всмысле пропущен?
Вот же ЗаказКлиентаТовары.Ссылка В(&Заказы)
А ЕСТЬNULL(ВременнаяТаблица.Номенклатура, "") <> "" заставит вывести только по номенклатуре из заказов строки, если есть отбор по заказам
41 vdeemer
 
19.08.22
11:35
(40) Параметр виртуальной таблицы регистра пропущен. Но если его поставить как в (0), то тогда параметр уже не будет "мягким" и выборка будет пустой... Похоже, в этом случае выбирать надо всю таблицу, а потом фильтровать
42 vdeemer
 
19.08.22
11:40
(41) Так и есть, в данном случае параметризовать ВТ нельзя.
Спасибо!!!
43 Kassern
 
19.08.22
11:49
(42) (41) Можно не выделять основную таблицу во временную. Сначала Создать временную с отбором. А во втором пакете ее прикрутить уже к основной.
44 Kassern
 
19.08.22
11:50
Но в любом случае возьмутся все обороты и потом уже обрежутся, если условие есть.
45 vdeemer
 
19.08.22
11:52
(44) Это да