Имя: Пароль:
1C
1С v8
Оптимизация запроса из трех таблиц
0 slowklg
 
21.06.16
17:28
Здравствуйте. Подскажите как лучше сделать.
Делаю отчет по товарам в конкретной ячейке склада. Из регистров МестаХранения, ТоварыНаСкладах (по определенному складу) и справочника Номенклатура (для артикула). Если делаю одним запросом (с упорядочиванием по количеству), то не получаю номенклатуру с остатком 0.

Если делать последовательно двумя запросами (получить всю номенклатуру для конкретной ячейки) и для каждой получать количество, то заметно дольше выполняется и нет упорядочивания по кол-ву.

Как лучше сделать?
1 Ёпрст
 
21.06.16
17:33
зачем вам весь справочник номенклатура ?
2 torgm
 
21.06.16
17:34
Я так понимаю УТ 10?

Места хранения - Это РС?

тогда
Места хранения левый джоин товары на складах.
3 Ёпрст
 
21.06.16
17:35
К примеру, у нас несколько тысяч позиций номенклатуры, из которых на складе есть всего пара сотен. Зачем в отчете нужны эти тясячи "нулей" ?
4 impulse9
 
21.06.16
17:35
(0) "то не получаю номенклатуру с остатком 0"
Надо нужные галочки проставить во вкладке "Связи"
5 faramund
 
21.06.16
17:35
(0) Запросы по регистрам разнеси по двум временным таблицам, проиндексируй по соединяемому полю, в твоем случае это номенклатура, как я  понял. В параметрах виртуальных таблиц остатков по максимому необходимые условия (напрмиер Организация, Склад и т.п.)
Итоговый запрос это запрос по всему справочнику номенклатура (Таблица номенклатура) и левое соединение к двум верхним временным таблицам по ссылке. Поля в запросе: Номерклатуру берешь из таблицы номенклатура, значения остатков из временных таблиц остатков, обязательно еспользуй конструкцию ЕстьNULL к выбираемым ресурсным полям
6 Guk
 
21.06.16
17:36
(3) чтобы было видно, что НЕТУ товара!...
7 faramund
 
21.06.16
17:37
(5) "по ссылке" читать как "по номенклатуре"
8 impulse9
 
21.06.16
17:37
(5) судя по первому сообщению, парню рано еще про "левые соединения" рассказывать
9 slowklg
 
21.06.16
17:57
(4) а какие галочки и куда? я так понимаю, что в регистре накопления "ТоварыНаСкладах" на тек.момент нет записи с отсутствующим товаром в данном складе.
(8) левые соединения то я использую в запросе, а вот со временными таблицами да, сложности.
Подскажите тег здешний для вставки кода, чтоб я свой запрос выложил, или он ненужен?
(5) про конструкцию ЕстьNULL, это для чего? а то есть у меня подозрение, что она то мне и нужна
10 Михаил Козлов
 
21.06.16
18:13
(6) А товары, которые ВООБЩЕ никогда не участвовали в товарообороте тоже можно считать, что "НЕТУ"?
Ваша ситуация полностью аналогична обычному отчету по остаткам: нет остатка - нет и в отчете.
11 slowklg
 
21.06.16
18:16
(10) товар приписанный к конкретной ячейке конкретного склада (месту хранения), остатков щас нет, а завтра к примеру появятся
12 Михаил Козлов
 
22.06.16
15:38
(11) Ну и чем тогда не годится левое соединение справочника номенклатуры с остатками регистра?
13 ptiz
 
22.06.16
15:42
(0) "Как лучше сделать?" - показать текст запроса.
14 slowklg
 
23.06.16
10:42
(12) Не годится тем, что не выдает номенклатуру, приписанную с ячейке с отстатком 0. запрос -

"ВЫБРАТЬ
  |    МестаХраненияНоменклатуры.Номенклатура,
  |    СпрНоменклатура.Артикул,
  |    СпрНоменклатура.БазоваяЕдиницаИзмерения,
  |    ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток
  |ИЗ
  |    РегистрСведений.МестаХраненияНоменклатуры КАК МестаХраненияНоменклатуры
  |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
  |            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
  |            ПО СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
  |        ПО МестаХраненияНоменклатуры.Номенклатура.Ссылка = СпрНоменклатура.Ссылка
  |ГДЕ
  |    МестаХраненияНоменклатуры.МестоХранения.Ссылка = &Ячейка
  |    И ТоварыНаСкладахОстатки.Склад.Ссылка = &Склад
  |
  |УПОРЯДОЧИТЬ ПО
  |    КоличествоОстаток УБЫВ";
15 catena
 
23.06.16
10:47
И ТоварыНаСкладахОстатки.Склад.Ссылка = &Склад

нужно перенести в соединение
16 catena
 
23.06.16
10:47
ТоварыНаСкладахОстатки.КоличествоОстаток

Заменить на

ЕстьNULL(ТоварыНаСкладахОстатки.КоличествоОстаток,0), если потом с количеством нужно производить манипуляции.
17 Ёпрст
 
23.06.16
10:48
Ну и писать, лучше так:

  И ТоварыНаСкладахОстатки.Склад.Ссылка.ССылка.ССылка.ССылка.ССылка = &Склад

чтоб наверняка!
18 slowklg
 
23.06.16
11:53
(16) Попробовал замену на ЕстьNULL, ничего не изменилось. номенклатуры с остатком 0 не выдаёт. (17) Точно! забыл я ещё пару-тройку ссылок поставить, а если серьёзно, спасибо, лишние выкинул
19 ptiz
 
23.06.16
11:57
(14) лютая жесть
(17) +1
1: убрать ересь типа ".Склад.Ссылка"
2: сначала сделать запрос к РегистрСведений.МестаХраненияНоменклатуры и поместить результат в ВТ - и её использовать вместо обращения к регистру на последнем этапе
3: в ТоварыНаСкладах.Остатки вставить отбор по складу и товарам из ВТ из пункта 2
20 catena
 
23.06.16
12:01
(18)А (15) намеренно было проигнорировано??
21 vde69
 
23.06.16
12:05
ВЫБРАТЬ
  |    МестаХраненияНоменклатуры.Номенклатура,
  |    естьNULL(ТоварыНаСкладахОстатки.КоличествоОстаток,0) КАК КоличествоОстаток
  |ИЗ
  |    РегистрСведений.МестаХраненияНоменклатуры КАК МестаХраненияНоменклатуры
  |            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
  |            ПО МестаХраненияНоменклатуры.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
  |ГДЕ
  |    МестаХраненияНоменклатуры.МестоХранения= &Ячейка
  |    И ТоварыНаСкладахОстатки.Склад= &Склад
  |
  |УПОРЯДОЧИТЬ ПО
  |    КоличествоОстаток УБЫВ";


чего покажет?
22 vde69
 
23.06.16
12:07
(21) правда тут есть логическая ошибка которая может приводить к задвоению и затроению остатка, предлогаю ее найти самому
23 Михаил Козлов
 
23.06.16
12:16
ГДЕ
...
   И ТоварыНаСкладахОстатки.Склад= &Склад

Это и отрубает (превращает левое соединение во внутреннее).
Поставьте условие на склад в условие виртуальной таблицы остатков.
24 vde69
 
23.06.16
12:17
(23) его вообще лучше убрать это условие, ведь ячейка однозначно находится на складе
25 vde69
 
23.06.16
12:18
ВЫБРАТЬ
  |    МестаХраненияНоменклатуры.Номенклатура,
  |    естьNULL(ТоварыНаСкладахОстатки.КоличествоОстаток,0) КАК КоличествоОстаток
  |ИЗ
  |    РегистрСведений.МестаХраненияНоменклатуры КАК МестаХраненияНоменклатуры
  |            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
  |            ПО МестаХраненияНоменклатуры.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
  |ГДЕ
  |    МестаХраненияНоменклатуры.МестоХранения= &Ячейка
  |
  |УПОРЯДОЧИТЬ ПО
  |    КоличествоОстаток УБЫВ";


вот так!!!
26 slowklg
 
23.06.16
12:47
(25)без этого условия выдаётся остаток этой номенклатуры по всем складам, а мне нужен только по одному.
27 Ёпрст
 
23.06.16
12:49
(26)
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
  |            ПО МестаХраненияНоменклатуры.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
И ТоварыНаСкладахОстатки.Склад= &Склад
28 Ёпрст
 
23.06.16
12:50
хотя, если у тебя ячейка принадлежит разным складам - хз, что там у вас за учёт такой нелепый.
29 vde69
 
23.06.16
12:59
(26) ты возьми МОЙ запрос из (25) а не в своем убирай условие
30 slowklg
 
23.06.16
13:00
(28) вот жеж косноязычие то моё... ячейка принадлежит одному складу, к той ячейке приписана определённая номенклатура, по которой я соединением получаю кол-во остатков, но в регистре накопления остатков записи по номенклатуре расписаны по разным складам, из которых мне нужен только один (а если его нет, т.е. кол-во 0, то и записи не вернёт по запросу)
31 Ёпрст
 
23.06.16
13:02
(28) если ячейка принадлежит одному складу, условие на склад - лишнее
32 catena
 
23.06.16
13:06
(31)Так у него Номенклатура может принадлежать разным ячейкам же.
33 slowklg
 
23.06.16
13:06
(29) взял, и что с того? количество остатков номенклатуры выдаёт по всем складам.
34 catena
 
23.06.16
13:07
(30)ПОТОМУ  ЧТО у тебя условие на склад отрезает нулевые количества... И тебе уже раз 30 здесь сказали, что это условие надо перенести в связь.
35 Ёпрст
 
23.06.16
13:08
(32) аа..., ну тогда (25) + (27)
:)
36 trad
 
23.06.16
13:13
(28) у него не "ячейка принадлежит разным складам", а номенклатура может быть на разных складах
37 slowklg
 
23.06.16
13:16
(34) да это я понимал и так. послезавтра, как время появится, возьму книжку и буду вспоминать язык запросов 1с, чтоб тонкости со связями и внутренними таблицами реализовывать. а то когда этим годами не пользуешься, то напрочь забывается. Меня вот озадачило условие на ограничение доступа к полям в справочниках "прочие поля - ГДЕ Ложь", я так понимаю, что это просто чтоб никакие поля не подходили, но для чего тогда право-то на чтение давать с таким условием?
38 trad
 
23.06.16
13:16
(35) а артикул?
39 slowklg
 
23.06.16
13:17
(38) да артикул с ед.изм они выкинули, не беда, добавить то не долго
40 trad
 
23.06.16
13:18
(14)+(15)
вопрос закрыт
41 vde69
 
23.06.16
13:20
(33) условие по складу запихни в отбор виртуальной таблицы остатков (внутри скобок) тогда будет валидно, но все равно не всегда ибо остатки по складам ведутся более чем по 2м измерениям, и если ты юзаешь хоть одно измерение остаков кроме номенклатуры и склада - будет задвоение о чем я писал раньше....
42 vde69
 
23.06.16
13:23
ВЫБРАТЬ
  |    МестаХраненияНоменклатуры.Номенклатура,
  |    естьNULL(ТоварыНаСкладахОстатки.КоличествоОстаток,0) КАК КоличествоОстаток
  |ИЗ
  |    РегистрСведений.МестаХраненияНоменклатуры КАК МестаХраненияНоменклатуры
  |            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК ТоварыНаСкладахОстатки
  |            ПО МестаХраненияНоменклатуры.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура
  |ГДЕ
  |    МестаХраненияНоменклатуры.МестоХранения= &Ячейка
  |
  |УПОРЯДОЧИТЬ ПО
  |    КоличествоОстаток УБЫВ";
43 slowklg
 
23.06.16
13:35
(42) спасибо, оно. ну и я вернул ещё свои артикул и ед.изм.
И подскажите, если знаете про условие на ограничение доступа к полям в некоторых справочниках "прочие поля - ГДЕ Ложь", зачем это?
44 catena
 
23.06.16
13:37
45 slowklg
 
23.06.16
13:39
(44)благодарю ещё раз, про перенос условия в соединение Вы тоже писали, спасибо