Имя: Пароль:
1C
1С v8
Не работает запрос
,
0 Malenhagen
 
23.08.22
12:09
Прохожу обучение по курсу "Программирование в 1с за 21 день"
Один из запросов отказывается работать. ТЗ пустая. Проверил разные части запроса, без ссылки на документ, запрос работает. Ссылка при отладке заполнена.
Запрос находится в модуле документа реализация товаров и услуг, в процедуре обработка проведения. Запрос должен находить товары в ТЧ документа, которых не хватет на складе.

        Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ТоварыНаСкладахОстатки.Номенкулатура КАК Номенкулатура,
        |    ТоварыНаСкладахОстатки.Склад КАК Склад,
        |    ТоварыНаСкладахОстатки.КолличествоОстаток КАК Колличество
        |ИЗ
        |    РегистрНакопления.ТоварыНаСкладах.Остатки(
        |            ,
        |            Склад = &Склад
        |                И Номенкулатура В
        |                    (ВЫБРАТЬ
        |                        РеализацияТоваровИУслугТовары.Товар КАК Товар
        |                    ИЗ
        |                        Документ.РеализацияТоваровИУслуг.Товары КАК РеализацияТоваровИУслугТовары
        |                    ГДЕ
        |                        РеализацияТоваровИУслугТовары.Ссылка = &Ссылка)) КАК ТоварыНаСкладахОстатки
        |ГДЕ
        |    ТоварыНаСкладахОстатки.КолличествоОстаток < 0";
    
    Запрос.УстановитьПараметр("Склад", Склад);  
    Запрос.УстановитьПараметр("Ссылка", Ссылка);  
    
    РезультатЗапроса = Запрос.Выполнить();

                Если Не РезультатЗапроса.Пустой() Тогда
            
            ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
        
            Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
                Сообщить("Недостаточно Товара " + ВыборкаДетальныеЗаписи.Номенкулатура + " в колличестве " + ВыборкаДетальныеЗаписи.Колличество);
            КонецЦикла;
        
        КонецЕсли;
1 Said_We
 
23.08.22
12:13
Так может всего хватает?
2 Гипервизор
 
23.08.22
12:15
Реально в курсе "Номенкулатура" и "Колличество"?
3 Михаил Козлов
 
23.08.22
12:17
(0) В консоли запросов правильно отрабатывает?
И еще учтите на всякий случай: перед проведением товара может хватать, а после - нет.
4 Said_We
 
23.08.22
12:19
(3) Он сначала проводит документ, потом проверяет остатки. Если остатков не хватает, то отказ от проведения. По запросу же видно.
5 Said_We
 
23.08.22
12:20
Единственное, я не увидел дату на которую остатки проверяются. Всегда на 3999 год?
6 Malenhagen
 
23.08.22
12:21
Консоль запросов это которая на Shift+f9?
7 mikecool
 
23.08.22
12:24
(5) а это уже от платформы зависит...
8 Malenhagen
 
23.08.22
12:28
Там таблица пустая. Точка останова Сразу после результатЗапроса=Запрос.Выполнить().
9 ptiz
 
23.08.22
12:30
(0) "Запрос должен находить товары в ТЧ документа, которых не хватет на складе. " - а приведенный тобой запрос работает не так: он сначала ищет товар в таблице остатков и только по тем, по которым остаток <> 0, но его не хватает - будет выводить сообщения.
10 Said_We
 
23.08.22
12:36
(9) Если этот запрос проверка остатков после проведения, то найдет.
11 Said_We
 
23.08.22
12:37
12 Kassern
 
23.08.22
12:41
(0) Это что теперь, советуют вложенные запросы делать в параметрах виртуальных таблиц вместо использования временных таблиц, или обучение старое? Имхо лучше вынести это дело во временную таблицу и присоединить к товарам на складах.
13 Волшебник
 
23.08.22
12:43
Гипотеза: поле "Товар" в документе имеет другой тип, например, строка.
14 Said_We
 
23.08.22
12:43
(12) не лучше.
В (0) я не увидел МометВремени:
       |   РегистрНакопления.СвободныеОстатки.Остатки(
        |           &МоментВремени,
...
ГраницаКонтроля = Новый Граница(МоментВремени(), ВидГраницы.Включая);
    Запрос.УстановитьПараметр("МоментВремени", ГраницаКонтроля);
15 Malenhagen
 
23.08.22
12:44
(9) Я правильно понял, что этот запрос находит не товары, которых не хватит при проведении документа, а товары, которых меньше 0 на складе? И если до проведения документа на продажу, товаров на складе 0, запрос ничего не найдёт?
16 Said_We
 
23.08.22
12:44
(13)  "Проверил разные части запроса, без ссылки на документ, запрос работает." - значит типы в порядке.
17 Malenhagen
 
23.08.22
12:45
(10) Запрос до проведения. Я не дописал, если запрос что-то нашёл, тогда будет отказ проведения.
18 Волшебник
 
23.08.22
12:45
(16) ну ок. Значит запрос перед списанием, а должен быть после
19 Said_We
 
23.08.22
12:46
(15) Внимательно прочитай статью в (11). Это минут 10-15. Там всё разжевано.
20 Said_We
 
23.08.22
12:47
(18) Нет. У него в 2025 году приход на 1000 единиц товара, а продает он сейчас. А остаток проверяет на 3999 год.
21 Malenhagen
 
23.08.22
12:48
(19) Хорошо, спасибо. Сейчас займусь
22 Kassern
 
23.08.22
12:49
(14) "не лучше. " - можете это чем-то обосновать? Вот тут рекомендации от 1с https://its.1c.ru/db/v8std/content/655/hdoc
23 Said_We
 
23.08.22
12:52
(22) Обоснования есть в той же статье в (11). Когда лучше и когда не лучше. Чем лучше и чем не лучше.
24 Kassern
 
23.08.22
12:58
(23) Так в статье именно принцип расписан, а не влияние временных таблиц и вложенных запросов. Причем в обоих случаях используется вложенный запрос.
25 Said_We
 
23.08.22
13:01
(24) " и присоединить к товарам на складах" - во втором случае ничего никуда не присоединяется.
26 Kassern
 
23.08.22
13:02
А я вам скинул инструкцию по разработке, где прописано:
При написании запросов не следует использовать соединения с вложенными запросами. Следует соединять друг с другом только объекты метаданных или временные таблицы. Если запрос использует соединения с вложенными запросами, то его следует переписать с использованием временных таблиц (не важно с какой стороны соединения находится вложенный запрос), кроме случая, когда вложенный запрос сканирует мало записей.
Последняя оговорка допускает использование вложенного запроса, но в примере из (11) нет гарантии отсутствия 1ляма позиций номенклатуры. Да и у ТС непонятно сколько позиций номенклатуры в реализации)
При чем данная оговорка не исключает использование временных таблиц и при малом количестве записей.
П.С. так как ТС еще только учится, то лучше бы ему понимать, в каких случаях уместно использовать вложенный запрос, а когда временную таблицу.
27 Kassern
 
23.08.22
13:02
(26) -> (23)
28 Said_We
 
23.08.22
13:03
(24) Ещё про блокировки начни на этапе курса за 21 день и с самого начала рассказывать. :-)
На сколько я понимаю, автор находится в самом начале обучения. Не нужны сейчас эти дебри.
29 Kassern
 
23.08.22
13:05
(28) пускай с самого начала привыкает в временным таблицам. Все можно через них оформить и в большинстве случаев это будет оптимальней и читабельнее. Меня лично так и учили в свое время, мол вложенный запрос это пережиток прошлого, когда временных таблиц не было.
30 Волшебник
 
23.08.22
13:06
Номенкулатура
КолличествоОстаток

надо переименовать, конечно
31 Said_We
 
23.08.22
13:09
(30) Тогда уже и в табличной части: РеализацияТоваровИУслугТовары.Товар не Товар, а Номенклатура.
И при проверки остатков надо услуги исключить и ...

Во время обучения надо немного дров наломать - без этого не бывает. :-)
32 Said_We
 
23.08.22
13:10
(30) Не знаю что там за курс. Но как правило курсы выстроены как дополнение знаний. От простого к сложному. Поэтому на сейчас автору как-то надо решить задачу в (0).
33 Said_We
 
23.08.22
13:13
(29) Не всегда вложенный запрос будет медленнее чем временная таблица. Если во временную таблицу надо засовывать всю физическую таблицу, то лучше этого не делать. Засовывание во временную таблицу это тоже ресурсоёмкая операция.
34 Kassern
 
23.08.22
13:17
(33) Вы можете назвать пример, когда временная таблица на порядок проиграет в оптимизации вложенному запросу? А вот обратно вполне может быть. Поэтому, пока он новичок, лучше использовать временные таблицы имхо.
35 Said_We
 
23.08.22
13:27
(33) Пример в (33), это когда во временную таблицу надо засовывать всю физическую таблицу.
36 Kassern
 
23.08.22
13:57
(35) Протестил на простом запросе:
ВЫБРАТЬ
    ВложенныйЗапрос.Ссылка КАК Ссылка
ИЗ
    (ВЫБРАТЬ
        Номенклатура.Ссылка КАК Ссылка
    ИЗ
        Справочник.Номенклатура КАК Номенклатура
    ГДЕ
        Номенклатура.ПометкаУдаления = ЛОЖЬ
        И Номенклатура.ЭтоГруппа = ЛОЖЬ) КАК ВложенныйЗапрос

И через временную таблицу

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ Товары
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.ПометкаУдаления = ЛОЖЬ
    И Номенклатура.ЭтоГруппа = ЛОЖЬ
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Товары.Ссылка КАК Ссылка
ИЗ
    Товары КАК Товары

Строк около 20тыс. В консоли у вложенного запроса результат выполнения действительно шустрее, чем у временной таблицы.
37 Kassern
 
23.08.22
13:58
Только вот для юзвера я особой разницы не заметил, так как вывод самой таблицы на экран существенно дольше, чем выполнение запроса)
38 Said_We
 
23.08.22
14:13
(37) А теперь представь, что это не вывод на экран, а проведение десятка другого документов.
39 Kassern
 
23.08.22
14:17
(38) дело в том, что при работе с большими таблицами в основном используют виртуальные таблицы, а не складывают физические. А на малых таблицах особой разницы не заметишь. В общем инфу про физ. таблицы просто нужно иметь в виду.
40 maxx079
 
23.08.22
14:27
(17) Видимо, это и есть ответ, почему не работает.
Твой запрос проверяет, что товары не ушли в минус - его надо делать после проведения (в процедуре проведения после записи движений по регистрам).
Т.к. если записи еще не сделаны, то проверка "остаток < 0" некорректна.
41 Malenhagen
 
23.08.22
18:01
(19) (22) Ребята, я решил! Запрос был после записи в регистр накопления, но я не поставил Движения.Записать();
Теперь всё заработало, спасибо! 3 дня мучался ) . И спасибо за наставления. Орфографию подучу, сам от себя в шоке )