Как исправить запрос для корректного расчета остатков?

База знаний Одина — Одинэсника Форумы ODIN — Форум по 1С Предприятию Как исправить запрос для корректного расчета остатков?

Просмотр 1 ветки ответов
  • Автор
    Сообщения
    • #38460
      Фото аватараOdineski
      Участник

        ВЫБРАТЬ

        ТоварыНаСкладах2Обороты.Период,

        ТоварыНаСкладах2Обороты.ХарактеристикаНоменклатуры,

        ТоварыНаСкладах2Обороты.КоличествоОборот,

        ТоварыНаСкладах2Обороты.СуммаОборот

        ПОМЕСТИТЬ Движения

        ИЗ РегистрНакопления.ТоварыНаСкладах2.Обороты(&НачалоПериода, &КонецПериода, День,) КАК ТоварыНаСкладах2Обороты

        ОБЪЕДИНИТЬ ВСЕ

        ВЫБРАТЬ

        ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, -1),

        ТоварыНаСкладах2Остатки.ХарактеристикаНоменклатуры,

        ТоварыНаСкладах2Остатки.КоличествоОстаток,

        ТоварыНаСкладах2Остатки.СуммаОстаток

        ИЗ РегистрНакопления.ТоварыНаСкладах2.Остатки(&НачалоПериода,) КАК ТоварыНаСкладах2Остатки ;

        ////////////////////////////////////////////////////////////////////////////////

        ВЫБРАТЬ РАЗЛИЧНЫЕ

        ДвиженияДенежныхСредствОбороты.Период КАК Период

        ПОМЕСТИТЬ Дни

        // Тут не важно, откуда брать дни, но это необходимо, поскольку в регистре накопления есть только те дни, в которые были движения. А нам хочется знать остатки, даже если в течении дня они не менялись. Выбирайте способ построения этой таблицы, наиболее быстрый для вашей конфигурации.

        ИЗ РегистрНакопления.ДвиженияДенежныхСредств.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ДвиженияДенежныхСредствОбороты ;

        ////////////////////////////////////////////////////////////////////////////////

        ВЫБРАТЬ

        Дни.Период КАК Период,

        Движения.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,

        СУММА(Движения.КоличествоОборот) КАК КоличествоОборот,

        Движения.СуммаОборот ПОМЕСТИТЬ ОстаткинаНачалоДня

        ИЗ Дни КАК Дни

        ЛЕВОЕ СОЕДИНЕНИЕ Движения КАК Движения

        ПО (Движения.Период < Дни.Период)

        СГРУППИРОВАТЬ ПО

        Дни.Период,

        Движения.ХарактеристикаНоменклатуры,

        Движения.СуммаОборот

      • #38461
        bot_avaOdin — Одинэсник
        Участник

          В вашем запросе есть несколько ошибок и неточностей, которые мешают получить корректный результат:

          1. В последнем блоке запроса:

          |ВЫБРАТЬ
          | Дни.Период КАК Период,
          | Движения.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
          | СУММА(Движения.КоличествоОборот) КАК КоличествоОборот,
          | Движения.СуммаОборот ПОМЕСТИТЬ ОстаткинаНачалоДня
          |ИЗ Дни КАК Дни
          | ЛЕВОЕ СОЕДИНЕНИЕ Движения КАК Движения
          | ПО (Движения.Период < Дни.Период)
          |СГРУППИРОВАТЬ ПО
          | Дни.Период,
          | Движения.ХарактеристикаНоменклатуры,
          | Движения.СуммаОборот

          — Здесь ошибка в условии соединения: «Движения.Период < Дни.Период» — это не корректно для левого соединения, так как для каждого дня нужно получить сумму оборотов до этого дня включительно или на начало дня. Обычно для получения остатков на начало дня нужно брать обороты с периодом строго меньше текущего дня.

          — Но при этом в выборке вы группируете по Движения.СуммаОборот, что не имеет смысла — сумма оборотов должна агрегироваться, а не группироваться.

          — Также поле Движения.СуммаОборот не агрегируется, а просто выбирается, что вызовет ошибку.

          Правильный вариант последнего блока:

          |ВЫБРАТЬ
          | Дни.Период КАК Период,
          | Движения.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
          | СУММА(Движения.КоличествоОборот) КАК КоличествоОборот,
          | СУММА(Движения.СуммаОборот) КАК СуммаОборот
          |ПОМЕСТИТЬ ОстаткинаНачалоДня
          |ИЗ Дни КАК Дни
          | ЛЕВОЕ СОЕДИНЕНИЕ Движения КАК Движения
          | ПО (Движения.Период < Дни.Период)
          |СГРУППИРОВАТЬ ПО
          | Дни.Период,
          | Движения.ХарактеристикаНоменклатуры

          2. В первом блоке с объединением остатков и оборотов:

          — Вы берёте остатки на день, который на 1 день меньше начала периода:

          |ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, -1)

          Это правильно, чтобы получить начальный остаток на день перед началом периода.

          3. В блоке с выборкой дней:

          — Вы берёте дни из регистра ДвиженияДенежныхСредств.Обороты, чтобы получить все дни с движениями.

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

          4. В целом, для получения остатков на каждый день, даже если движения отсутствуют, рекомендую использовать метод с календарём дней и левым соединением с оборотами, как в статье https://infostart.ru/1c/articles/102435/

          Пример исправленного последнего блока с календарём дней:

          |ВЫБРАТЬ
          | Календарь.День КАК Период,
          | Движения.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
          | СУММА(Движения.КоличествоОборот) КАК КоличествоОборот,
          | СУММА(Движения.СуммаОборот) КАК СуммаОборот
          |ПОМЕСТИТЬ ОстаткинаНачалоДня
          |ИЗ
          | (ВЫБРАТЬ
          | ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, T.n) КАК День
          | ИЗ
          | (ВЫБРАТЬ 0 КАК n
          | ОБЪЕДИНИТЬ ВСЕ
          | ВЫБРАТЬ 1
          | ОБЪЕДИНИТЬ ВСЕ
          | ВЫБРАТЬ 2
          | …
          | ВЫБРАТЬ 30) КАК T) КАК Календарь
          | ЛЕВОЕ СОЕДИНЕНИЕ Движения КАК Движения
          | ПО Движения.Период < Календарь.День
          |СГРУППИРОВАТЬ ПО
          | Календарь.День,
          | Движения.ХарактеристикаНоменклатуры

          Если нужна помощь с конкретным запросом под вашу задачу — уточните, что именно хотите получить: остатки на каждый день, обороты, или средние остатки.

      Просмотр 1 ветки ответов
      • Для ответа в этой теме необходимо авторизоваться.
      База знаний 1С