Имя: Пароль:
1C
1С v8
И снова проблемы с ECTЬNULL
0 icherski
 
04.09.12
14:29
Второй час бьюсь над собственным отчетом по валовой прибыли - и не могу понять, почему в таблицу не попадает номенклатура с неустановленной закупочной ценой. Использую левое соединение с ЕСТЬNULL, но нужные строки в результате запроса так и не появляются. Помогите понять почему!

ВЫБРАТЬ
   ВложенныйЗапрос.Организация КАК Организация,
   ВложенныйЗапрос.Покупатель КАК Покупатель,
   ВложенныйЗапрос.ДоговорПокупателя КАК ДоговорПокупателя,
   ВложенныйЗапрос.Номенклатура КАК Номенклатура,
   ВложенныйЗапрос.Регистратор КАК Регистратор,
   ВложенныйЗапрос.Период КАК Период,
   СУММА(ВложенныйЗапрос.Количество) КАК Количество,
   СУММА(ВложенныйЗапрос.Стоимость) КАК Стоимость,
   ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0) КАК ЗакупочнаяЦена
{ВЫБРАТЬ
   Организация,
   Покупатель,
   ДоговорПокупателя,
   Номенклатура,
   Регистратор,
   Период}
ИЗ
   (ВЫБРАТЬ
       ПродажиОбороты.Контрагент КАК Покупатель,
       ПродажиОбороты.ДоговорКонтрагента КАК ДоговорПокупателя,
       ПродажиОбороты.Номенклатура КАК Номенклатура,
       ПродажиОбороты.Организация КАК Организация,
       ПродажиОбороты.Регистратор КАК Регистратор,
       ПродажиОбороты.Период КАК Период,
       ПродажиОбороты.КоличествоОборот КАК Количество,
       ПродажиОбороты.СтоимостьОборот КАК Стоимость
   ИЗ
       РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Регистратор, {(Организация).* КАК Организация, (Проект).* КАК Проект, (Подразделение).* КАК Подразделение, (Контрагент).* КАК Покупатель, (ДоговорКонтрагента).* КАК ДоговорПокупателя, (Номенклатура).* КАК Номенклатура, (ХарактеристикаНоменклатуры).* КАК ХарактеристикаНоменклатуры, (ЗаказПокупателя).* КАК ЗаказПокупателя}) КАК ПродажиОбороты
           ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
               ПродажиСебестоимость.Номенклатура КАК Номенклатура,
               ПродажиСебестоимость.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
               ПродажиСебестоимость.ЗаказПокупателя КАК ЗаказПокупателя,
               ВЫБОР
                   КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
                       ТОГДА ПродажиСебестоимость.ДокументДвижения
                   ИНАЧЕ ПродажиСебестоимость.Регистратор
               КОНЕЦ КАК Регистратор,
               СУММА(ПродажиСебестоимость.Стоимость) КАК СтоимостьОборот
           ИЗ
               РегистрНакопления.ПродажиСебестоимость КАК ПродажиСебестоимость
           ГДЕ
               ПродажиСебестоимость.Период МЕЖДУ &ДатаНачала И &ДатаКонца
           {ГДЕ
               ПродажиСебестоимость.Проект.* КАК Проект,
               ПродажиСебестоимость.Подразделение.* КАК Подразделение,
               ПродажиСебестоимость.Номенклатура.* КАК Номенклатура,
               ПродажиСебестоимость.ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
               ПродажиСебестоимость.ЗаказПокупателя.* КАК ЗаказПокупателя}
           
           СГРУППИРОВАТЬ ПО
               ПродажиСебестоимость.Номенклатура,
               ПродажиСебестоимость.ХарактеристикаНоменклатуры,
               ПродажиСебестоимость.ЗаказПокупателя,
               ВЫБОР
                   КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
                       ТОГДА ПродажиСебестоимость.ДокументДвижения
                   ИНАЧЕ ПродажиСебестоимость.Регистратор
               КОНЕЦ) КАК ТаблицаРегистраПродажиСебестоимость
           ПО (ТаблицаРегистраПродажиСебестоимость.Номенклатура = ПродажиОбороты.Номенклатура)
               И (ТаблицаРегистраПродажиСебестоимость.ХарактеристикаНоменклатуры = ПродажиОбороты.ХарактеристикаНоменклатуры)
               И (ТаблицаРегистраПродажиСебестоимость.ЗаказПокупателя = ПродажиОбороты.ЗаказПокупателя)
               И (ТаблицаРегистраПродажиСебестоимость.Регистратор = ПродажиОбороты.Регистратор)) КАК ВложенныйЗапрос
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
       ПО ВложенныйЗапрос.Номенклатура = ЦеныНоменклатуры.Номенклатура
           И ВложенныйЗапрос.Период > ЦеныНоменклатуры.Период
       ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
           ПродажиОбороты.Номенклатура КАК Номенклатура,
           ПродажиОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
           МАКСИМУМ(ЦеныНоменклатуры.Период) КАК Период,
           ПродажиОбороты.Регистратор КАК Регистратор
       ИЗ
           РегистрНакопления.Продажи.Обороты(&ДатаНачала, &ДатаКонца, Регистратор, ) КАК ПродажиОбороты
               ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
               ПО ПродажиОбороты.Регистратор.Дата > ЦеныНоменклатуры.Период
                   И ПродажиОбороты.ХарактеристикаНоменклатуры = ЦеныНоменклатуры.ХарактеристикаНоменклатуры
                   И ПродажиОбороты.Номенклатура = ЦеныНоменклатуры.Номенклатура
       ГДЕ
           ЦеныНоменклатуры.ТипЦен = &Закупочные
       
       СГРУППИРОВАТЬ ПО
           ПродажиОбороты.Номенклатура,
           ПродажиОбороты.Регистратор,
           ПродажиОбороты.ХарактеристикаНоменклатуры) КАК МаксДатыЦен
       ПО ВложенныйЗапрос.Номенклатура = МаксДатыЦен.Номенклатура
           И ВложенныйЗапрос.Регистратор = МаксДатыЦен.Регистратор
ГДЕ
   ВложенныйЗапрос.Номенклатура = &НомБезЗакуп
   И ЦеныНоменклатуры.Период = МаксДатыЦен.Период
   И ЦеныНоменклатуры.ТипЦен = &Закупочные

СГРУППИРОВАТЬ ПО
   ВложенныйЗапрос.Организация,
   ВложенныйЗапрос.Покупатель,
   ВложенныйЗапрос.ДоговорПокупателя,
   ВложенныйЗапрос.Номенклатура,
   ВложенныйЗапрос.Регистратор,
   ВложенныйЗапрос.Период,
   ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0)
1 mikecool
 
04.09.12
14:35
все не читал
если есть проблемы с условиями - выключай их по одному и определяй которое косячит, определил - включаешь мосх и исправляешь на правильное
2 ssh2006
 
04.09.12
14:37
ГДЕ
 .....
   И ЦеныНоменклатуры.ТипЦен = &Закупочные
3 ChAlex
 
04.09.12
14:56
(0) - все соединения переваривать влом - самая распространенная ошибка по связыванию регистров, табличных частей и пр. :

Набор1.....
ЛЕВОЕ СОЕДИНЕНИЕ Набор2
ПО Набор1.Поле1=Набор2.Поле1


!!! Вот тут внимание
ГДЕ Набор1.ПолеN=&Чегото
И Набор2.ПолеN=&ЧеготоЕще

Поясню: Делается выборка двух наборов, эти наборы соединяются левым соединением и к ним применяется фильтрация по условию ГДЕ (причем фильтрация к полям обоих наборов). Результат сего: сначала получается объединенный набор (некоторым записях Из первого набора не найдены записи из второго!!, и поля из второго набора = NULL, а к этм записям применяется условие ГДЕ поле чему то равно). В итоге из запроса исключаются нужные записи.

Отсюда рекомендации: фильтруйте записи наборов в подзапросах а потом объдиняйте.
4 mikecool
 
04.09.12
14:56
(3) а можно фильтровать прямо в условиях соединения таблиц без подзапросов
5 ChAlex
 
04.09.12
15:52
(4) - можно, но нужно хорошо понимать что нужно достичь и как организовывать условия. Как мне кажется - подзапросы более читабельны и легче сопровождаются. Но тут дело вкуса :)
6 ChAlex
 
04.09.12
15:54
(0) кстати вот тут и зарыта ошибка (на первый взгляд)


ГДЕ
   ВложенныйЗапрос.Номенклатура = &НомБезЗакуп
   И ЦеныНоменклатуры.Период = МаксДатыЦен.Период
   И ЦеныНоменклатуры.ТипЦен = &Закупочные

Как раз то, о чем писал выше
7 icherski
 
04.09.12
20:03
(6) ошибка именно здесь! Если убрать условия по регистру, то строки с nullевыми ценами попадают в отчет. Если вынести фильтр по закупочным ценам во вложенный запрос, а среднее условие изменить на ЕСТЬNULL(ЦеныНоменклатуры.Период, 0) = ЕСТЬNULL(МаксДатыЦен.Период, 0), то скорость работы отчета падает в несколько тысяч раз.

Вопрос: как посчитать стоимость проданных товаров, для которых не указана закупочная цена? Может, отдельный набор данных для этого дела создать? Или вложенный запрос?
8 ChAlex
 
05.09.12
00:05
(7) - скорость падает, потому что выборка становится полная. И вот насчет несколько тысяч раз - :) -ну вы тогда его вообще не сформировали бы. Опять же какую вы хотите получить скорость в таких тяжеловесных запросах? Один только регистр сведений с выборокой всех позиций и дат и соединением ... многого стоит. Так что вопрос оптимизации - вещь отдельная. Не знаю для чего вам нужен запрос, если для отчета - то попробуйте СКД - там есть возможность передавать параметр (в частности дату) в запрос при связывании наборов, и можно использовать срез последних для цен и список параметров для ускорения. Возможно такой путь будет быстрее. Надо смотреть и искать оптимальный вариант
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс