Как не изобретать велосипед при разработке отчетов (22 минуты видео)



При построении отчетов есть ряд задач, которые при решении «в лоб» часто приводят к написанию тяжелых запросов или запросам в цикле или ручному выводу данных в таблицу.

Вот примеры таких задач:

  • Получение нарастающего объема продаж по месяцам, например, для вывода в виде диаграммы
  • Расчет разницы продаж текущего и предыдущего периода – для всех строк отчета
  • Сравнение объема продаж каждого менеджера с эталонным значением, которое вычисляется в ходе формирования этого отчета
  • Получение нарастающего итога по горизонтали и вертикали в кросс-таблицах

И все эти задачи решаются элементарно с помощью функций СКД – буквально за пару минут. Без запросов в цикле и кривого кода.

Сегодня рассмотрим использование некоторых функций СКД на конкретных примерах.

Видео 1. Как получить сумму в отчете нарастающим итогом?

Подобные задачи часто встречаются на практике. Наиболее типичный пример – в отчет должны выводиться продажи по периодам, необходимо знать не только сумму продаж текущего месяца, но и нарастающим итогом с начала формирования отчета.

На самом деле эту задачу можно решить и с помощью запроса (без функций СКД), но есть 2 проблемы:

  • Сам по себе подобный запрос будет сложным – уйдет время на его разработку и отладку.
  • Такой запрос будет серьезно нагружать систему – и чем больше данных, тем медленнее он будет работать.

С помощью функций СКД эта задача решается одной строчкой кода, и отчет будет работать максимально быстро, смотрим:

Видео 2. Как получить значение из предыдущей строки отчета?

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

Приведем несколько примеров, когда это может быть полезно:

  • Анализ дебиторской задолженности по дням – вычисляем тренд и абсолютное увеличение или уменьшение задолженности относительно прошлого периода
  • Анализ курсов валют и оценка прибыли или убытков от курсовой разницы – нужно получить дельту между текущим и предыдущим курсом и умножить на остаток денежных средств в валюте.

Такие задачи также трудоемко решить с помощью запроса, а в СКД это делается одной строкой:

Видео 3. Как сравнить итог по текущей строке с эталонным значением?

Пример, когда этот функционал может быть полезен:

  • В системе ведется учет продаж менеджерами
  • Руководитель отдела ведет личные продажи наряду с менеджерами
  • Требуется вывести отчет по продажам в разрезе менеджеров
  • В отчет также необходимо выводить дельту относительно объема продаж руководителя отдела.

То есть речь о том, что нужно сравнить каждую строку продаж менеджера с продажами руководителя отдела.

А эти данные могут, например, использоваться для начисления премии.

И опять же с помощью СКД эта задача решается в одну строку:

Видео 4. Получение нарастающего итога в кросс-таблице

В отчете вида кросс-таблица нарастающий итог может считаться как вертикально (по строкам), так и горизонтально (по столбцам).

Мы покажем, как с помощью одного параметра СКД управлять направлением расчета итогов:

Видео 5. Вывод табличной части в отдельной ячейке отчета

Допустим, необходимо разработать отчет, который выводит информацию о документах. При этом в отдельной ячейке должна содержаться табличная часть документа.

Чтобы решить подобную задачу с помощью обычного запроса, потребуется писать ручной вывод результата в табличный документ.

В СКД эта задача вновь решается одной функцией:

Чтобы не изобретать велосипед при разработке отчетов, рекомендуем изучить полный функционал Системы компоновки данных.

Эта тема детально раскрыта в курсе:

«Профессиональная разработка отчетов в 1С 8.3 на Системе Компоновки Данных (СКД)»

Поддержка – 2 месяца. Объем курса – 34 учебных часа.

Описание курса

Не откладывайте свое обучение!

Комментарии / обсуждение (90):

  1. sumener

    Добрый день, Василий!

    Подскажите пожалуйста, как в отчете на СКД получить суммы в колонке 3, складывая значения по одинаковой номенклатуре в колонке 1? https://prnt.sc/RozPOHjyQQft (иногда ссылка работает только через VPN из-за ограничений)

    Пытаюсь использовать:
    ВычислитьВыражение(Сумма(Потребность), “Номенклатура”, “ОбщийИтог”)
    ВычислитьВыражениеСГруппировкойМассив(“СУММА(Потребность)”, “Номенклатура”)

    с разными комбинациями параметров, но что-то запутался окончательно. Может этот способ в данном случае не подходит? Или я что-то делаю не так?

    • Василий Ханевич

      Добрый день!
      Не получается открыть скриншот. Поэтому затрудняюсь точно ответить на вопрос.
      В курсе по СКД (Занятие 14. Использование языка выражений СКД) рассматривали следующую задачу: Сравнить объем продаж каждого товара с объемом продаж заданного товара

      Сумма(Стоимость) * 100 / ВычислитьВыражение("Сумма(Выбор Когда Номенклатура = &ИсследуемыйТовар Тогда Стоимость Конец)", , "ОбщийИтог")

      Возможно, выражение из этого видео Вам поможет.

      • sumener

        Доброго времени, Василий!
        Спасибо за ответ – с этим справился только немного другим путем. Не знаю правильным ли, но нужный результат получил. Теперь возникла другая проблема. Т.к. со скриншотами какая-то проблема, то озвучу свой вопрос в коротком видео: https://somup.com/c0ltYXkDLP

          • Игорь

            Что-то у вас все не открывается… Ну, ок. Вот нашел точно такую же проблему здесь: https://forum.infostart.ru/forum9/topic208315/ (надеюсь это-то откроется!)

            В этой теме даже ответ есть на языке SQL. Но как это перевести на 1С (и есть ли такая возможность) непонятно. Мне не удалось подобрать параметры функции “ВычислитьВырвжение” таким образом, чтобы получить описанный в задаче результат :(

            Мучаюсь третий день.

            • Василий Ханевич

              Однозначного соответствия указанного SQL-запроса в 1С не существует.
              Поэтому предлагаю рассмотреть вариант получить такой нарастающий итог в самом запросе, а не в выражении СКД. Например, по аналогии с получением среза последних на каждую дату.

              • Игорь

                Василий, благодарю за ответ. А есть ли способ получить нарастающий итог по товару, находящемуся в разных группировках средствами СКД? Такой запрос я делал и он на нашей базе отрабатывает 25 минут, что весьма печально.

  2. Анатолий Скляднев

    Добрый день.
    Прошел ваш курс. Очень познавательно, спасибо.
    Но возник такой вопрос – при формировании отчета по курсам валют делаю отбор на значение предыдущего курса. Любой отбор, допустим равен нулю. При это отчет не формируется – пишет Выражение не может быть вычислено “НаборДанных1.Курс”.
    Дело в том, что мне нужно вывести только изменение курса

    • Василий Ханевич

      Добрый день!
      По описанию сложно понять, в чем дело.
      Задайте, пожалуйста, вопрос на страницах Мастер-группы курса, подробно опишите ситуацию, прикрепите к сообщению отчет, будем разбираться.

  3. Магомедгусен

    Добрый день!
    Пробовал использовать вычисление функции корреляции в СКД
    Например тестовый запрос типа Корреляция(1, 1) дает ошибку деления на ноль. Почему?
    Погуглить пример использование функции Корреляция в СКД не дает результата

    • Василий Ханевич

      Добрый день!
      Подробности про функцию Корреляция и другие статистические функции можно узнать в конфигураторе, меню Справка – Система компоновки данных – Язык выражений системы компоновки данных – Агрегатные функции. Указаны даже формулы, по которым выполняется расчет.
      Если будете использовать функцию в выражении для ресурса, то в отчете в общих итогах корреляция будет выводиться. Связываю это с наличием всех необходимых данных для выполнения расчета именно на таком уровне отчета.

      • Магомедгусен

        Спасибо за ссылка. Мой вопрос кажется сложным для уровня документирования в системной справки. Суть вопроса и ошибку которую дает функция корреляции на этом скрине https://photo-screen.ru/i/EhKeM0lKL

        • Василий Ханевич

          Для теста я создал простой набор данных по продажам, определил ресурсы следующим образом:
          Ресурс
          Получается вот такой отчет – с результатом на уровне общего итога:
          Отчет

          Еще как вариант – реализовать в общем модуле экспортную функцию, которая будет выполнять необходимые Вам расчеты, и в выражении ресурса воспользоваться своей собственной функцией, которая будет рассчитывать нужный показатель.

  4. Алексей

    Добрый день! Подскажие пожалуйста как ограничить подсчет нарастающего итога в пределах группировки “ЗаказДоговор” – ВычислитьВыражение(“Сумма(СуммаДокумента)”,”ЗаказДоговор” , , “Первая”, “Текущая”) – такая конструкция не работает и все равно считает все с первой записи. То есть за все группировки выше..

    • Василий Ханевич

      Добрый день!
      Предлагаю такой вариант выражений для ресурсов:
      Ресурсы
      Получим следующий отчет:
      Отчет

      • Алексей

        Спасибо большое! А как сделать, что бы в итоге по подразделению 2 например стояла цифра 11. То есть вывести итог с накоплением в группировке Подразделение 2=11, Подразделение 1 = 8 ?

        • Василий Ханевич

          Можно задать разные выражения для разных группировок при помощи свойства Рассчитывать по:
          Ресурсы
          Полученный отчет:
          Отчет

  5. also11

    Добрый день. А можно ли функцию ВычислитьЗначениеСГруппировкойВМассив эмулировать в языке запросов?

    • Василий Ханевич

      Добрый день!
      Функция ВычислитьВыражениеСГруппировкойМассив часто используется в выражениях для расчета ресурсов, значит, эти вычисления будут производиться не на сервере СУБД, а на сервере 1С:Предприятия. Поэтому нужно понимать, что это всё-таки разные расчеты, т.к. итоги – это дополнительно подсчитанные данные, которые не возвращает сервер СУБД. Но в некоторых случаях можно эмулировать такой расчет при помощи запроса.
      Например, есть выражение:

      СУММА(ВычислитьВыражениеСГруппировкойМассив("Максимум(Сумма)", "Контрагент"))

      Для такого расчета в запрос можно добавить дополнительные временные таблицы. В первой – при помощи агрегатной функции Максимум посчитаем максимальное значение, сгруппировав данные по контрагенту. А затем рассчитаем сумму полученных значений.

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

  6. Myasnoy

    Добрый вечер. Подскажите, как можно перемножить значения строк в колонке? В курсе по СКД этого не нашел.

    • Василий Ханевич

      Добрый день!
      Рассмотрите вариант использования экспортной функции общего модуля для вычислений.

      В таком случае выражение ресурса будет выглядеть следующим образом:

      ОбщийМодуль1.Перемножить(Массив(ИмяРесурса))
      • Myasnoy

        В таком случае выражение будет вычисляться для каждой записи? И получается общий модуль будет вызываться столько раз, сколько записей будет в отчете? При этом передаваться туда будет одна и та же таблица? Есть возможность как то передать таблицу или массив один раз, а не вычислять в каждой детальной записи?

        • Василий Ханевич

          Выражение для ресурса вычисляется столько раз, сколько раз этот ресурс нужно вывести в отчет. А это в свою очередь зависит от настроек компоновки отчета – какие группировки используются, какие выходные поля на каких уровнях группировки выводятся. В зависимости от этого при каждом вызове функции общего модуля (как и обычной агрегатной функции Сумма, Количество и т.д.) в нее могут передаваться в качестве аргумента разные значения, а не всегда один и тот же массив значений.

          • Myasnoy

            тогда получается, если структура отчета выглядит:
            |группировка1|ресурс1|
            и группировка1 выводится в отчете несколько раз (2-3 значения) , то нет возможности получить все значения ресурса1 за 1 раз? Массив(Русурс1) и ТаблицаЗначений(Русурс1) вызывают функцию общего модуля 4 раза. Передавая туда каждый раз все значения группировки. ВычислитьВыражениеСГруппировкойТаблицаЗначений (“Ресурс1”, “Группировка1”)) вызывает функцию общего модуля 3 раза.

            • Василий Ханевич

              Да, правильно. Нельзя получить все значения ресурса, выводимые в отчет, за один вызов функции общего модуля.

  7. ddok

    Здравствуйте.

    Есть одна проблема, которая не описана в курсе, при работе в режиме предприятия с изменением встроенных отчетов.
    Например, имеется отчет “Исполнение плана закупок по подразделениям”.

    Когда я добавляю в отчет пользовательское поле-выражение “Цена”, то прописываю формулу: Сумма/Количество. Но данная формула не работает – не считает результат, т.к. не понимает откуда брать значения, поскольку есть поля План.Сумма и План.Количество, а есть Факт.Сумма и Факт.Количество.

    При заполнении пользовательского поля-выражения выражением План.Сумма /План.Количество, с дальнейшей попыткой его сохранения, всплывает сообщение “Поле не найдено “План.Сумма”.

    Так как быть в этом случае, когда в пользовательских полях несколько одноименных полей, которые сгруппированы (пример: Факт.Сумма, Факт.Количество и План.Сумма, План.Количество), и необходимо сделать вычисления выражением в вновь создаваемом пользовательском поле, используя конкретные и существующие пользовательские поля?

    • Василий Ханевич

      Добрый день!
      В настройках отчета сохранил настройки компоновки в XML-файл, отредактировал его, добавил блок с описанием нового пользовательского поля:

      <item xsi:type="UserFieldExpression">
                          <dataPath>ПользовательскиеПоля.Поле5</dataPath>
                          <title>ЦенаПлан</title>
                          <detailExpression>План.Сумма/План.Количество</detailExpression>
                          <detailExpressionPresentation>План.Сумма/План.Количество</detailExpressionPresentation>
                          <totalExpression>Сумма(План.Сумма)/Сумма(План.Количество)</totalExpression>
                          <totalExpressionPresentation>Сумма(План.Сумма)/Сумма(План.Количество)</totalExpressionPresentation>
                      </item>

      Т.е. выражение простое – План.Сумма/План.Количество. И оно работает. А в режиме “1С:Предприятие” в конструкторе не дает его использовать.
      Такой файл с настройками компоновки успешно загружается, добавляем пользовательское поле в выбранные поля. Отчет корректно формируется:
      Отчет
      Приложил сохраненные настройки из демо-базы УТ:
      ИсполнениеПланаЗакупок_Тест.zip

  8. Вячеслав

    Видео 5. Вывод табличной части в отдельной ячейке отчета
    Вопрос: Как сделать, чтоб при расшифровке такой ячейки платформа не вываливалась в критическую ошибку?

    • Василий Ханевич

      Добрый день!
      Проверяю на платформе 8.3.17.1549. Падения платформы не происходит. Прикрепил отчет, на котором проверяю, – ТабличнаяЧасть.zip.

      В любом случае падение платформы – это некорректное поведение программы. Рекомендую протестировать на других релизах платформы, а также написать разработчикам платформы пример воспроизведения, чтобы они могли локализовать проблему, исправить ошибку или указать способ обхода.

  9. Saifa

    Добрый день! Проходила ваши курсы по СКД, очень многое стало понятно. Сейчас на реальной базе не могу решить простую не первый взгляд задачу: в отчете есть колонка, показывающая некоторую сумму. А в итогах по организации мне нужно показывать ДОЛЮ непустых сумм к общему числу строк. Простое деление Сумма(ВЫБОР КОГДА ПроцентКВКАСКО = 0 ТОГДА 0 ИНАЧЕ 1 КОНЕЦ) / Количество(ПроцентКВКАСКО) не помогает. Может, подскажете?

    • Василий Ханевич

      Добрый день!
      Предполагаю, что в колонке с суммами появляется значение типа NULL, которое и портит расчет.
      Приложил несколько примеров схем компоновки, где используется указанное Вами выражение для ресурса: Проценты.zip
      В этих примерах можно проверить, что если все значения – числа, то процент считается корректно. Если появляется значение типа NULL, то расчет нарушается.
      Поэтому можно воспользоваться функцией ЕСТЬNULL для получения правильного расчета.

  10. SinO

    Добрый день. Как можно рассчитать разницу между продажами за текущий год и такой же год предыдущий? Выше вы сказали, что нужно и Можно использовать объединение двух наборов данных – запросов. В каждом из них будут одинаковые тексты запросов, но разные параметры – периоды, задающие интервал времени для получения из базы данных о продажах.
    В курсе по СКД рассматривается пример такого отчета.

    Примера такого отчета в курсе я не нашел(.
    Подскажите пожалуйста в каком уроке этот пример?
    Так же я сделал как вы сказали выше, но ничего не получается, появляются пустые поля суммы, в строках отчета Номенклатура, а в колонках Период (год) и два ресурса Сумма2019 и Сумма2020 из разных наборов данных, а далее когда пытаешься эти ресурсы поделить при помощи вычисляемого поля, то ничего не выходит. Подскажите пожалуйста в чем моя ошибка?

    • Василий Ханевич

      Добрый день!
      В практическом задании 21.1 рассматривается отчет, который выводит продажи за два периода, вычисляется разница между этими значениями.
      Посмотрите решение этого задания.
      В нем не использовалось поле ПериодГод, только Номенклатура, продажи за текущий и предыдущий период. Если применяется объединение наборов, то поле ПериодГод не требуется, ведь у нас есть отдельный набор данных, который получает продажи за определенный год, значит, у нас есть отдельный ресурс для продаж каждого года.
      А можно объединение наборов данных не использовать, выбирать все данные одним запросом, тогда поле ПериодГод нужно, для расчета процента можно применять выражение:

      Сумма(Выбор
              Когда ПериодГод = ДатаВремя(2019, 1, 1)
                  Тогда Сумма
              Иначе 0
          Конец) / Сумма(Выбор
              Когда ПериодГод = ДатаВремя(2018, 1, 1)
                  Тогда Сумма
              Иначе 0
          Конец)
  11. big_ooo

    подскажите а как получить итог по по колонкам нарастающего итога?
    скд в итоге выводит последнее значение
    а надо сумму всех расчитанных

    • Василий Ханевич

      Добрый день!
      На закладке Ресурсы описываем два выражения для расчета ресурсов. Одно из них – для общего итога:
      Ресурсы
      Вот такое выражение получается – используем две функции (ВычислитьВыражениеСГруппировкойМассив и ВычислитьВыражение):

      Сумма(ВычислитьВыражениеСГруппировкойМассив("ВычислитьВыражение(""Сумма(КоличествоОборот)"", , , ""Первая"", ""Текущая"")"))
      • divoy

        Может есть рецепт или направление для получения корректных сумм в родительских группировках с нарастающим итогом в кросс-таблице?*
        Если, как в видео 4 рассчитывать ВычислитьВыражение(“Сумма(КоличествоОборот)”,”Период”,,”Первая,”Текущая”)
        а общий итог так Сумма(ВычислитьВыражениеСГруппировкойМассив(“ВычислитьВыражение(“”Сумма(КоличествоОборот)””, “”Период””, , “”Первая””, “”Текущая””)”))
        То ошибка отчета “Выражение не может быть вычислено…”

        • Василий Ханевич

          Добрый день!
          Приведите, пожалуйста, конкретный пример, желательно со скриншотами, какие данные выводятся в отчет, какова его структура, а также – что именно нужно получить в результате.
          Постараюсь предложить вариант решения.

          • divoy

            Отчет рассчитывает план продаж на несколько недель. По факту продаж определяется потребность на каждую неделю и попадает в план, но если она не превышает складского остатка. Если потребность больше остатка, то количество в плане уменьшается на величину превышения остатка. По номенклатуре отчет работает корректно, но по вышестоящей группировке модель итоговые данные не верны. На скрине показан пример.

            Сам ресурс рассчитывается так

            Выбор Когда
            ВычислитьВыражение(“Сумма(КоличествоПлан)”, “НомерНедели”, , “Первая”, “Текущая”) 0 Тогда
            ВычислитьВыражение(“Сумма(КоличествоПлан)”, “НомерНедели”, , “Текущая”, “Текущая”) + ВычислитьВыражение(“Сумма(КоличествоОстаток)”,”НомерНедели”) – ВычислитьВыражение(“Сумма(КоличествоПлан)”, “НомерНедели”, , “Первая”, “Текущая”)
            Иначе
            0
            Конец
            Конец

            Для агрегатной функции вышестоящей группировки пробовал варианты с Сумма(ВычислитьВыражениеСГруппировкойМассив… но группировка по номеру недели в нее не принимается.

            • Василий Ханевич

              Добрый день!
              Сложное выражение для ресурса получилось. Предлагаю следующие направления для размышлений:
              1. Упростить отчет за счет хранения данных в регистрах. Т.е. не рассчитываем данные в отчете, а используем документ, который выполняет расчеты и пишет в регистр готовые данные. В отчете остается только вывести их, выражения для ресурсов получатся простыми – вроде Сумма(ИмяРесурса), которые будут предстказуемо работать, в них проще разобраться, чем в многоэтажных выражениях.

              2. Попробовать для расчетов использовать экспортные функции общих модулей.
              В таком случае выражение ресурса будет выглядеть следующим образом:

              ОбщийМодуль1.ИмяФункции(Массив(ИмяРесурса))

              Кстати, выражение Массив(ИмяРесурса) может подсказать, какие значения используются при вычислении значения ресурса.

              3. Отказаться от использования СКД – выводить программно данные в табличный документ.
              Получим нужные значения в отчете. Но в таком случае лишимся удобных отборов, оформления и прочих инструментов, которые предоставляет СКД.

  12. SinO

    Добрый день Василий!

    Проходил ваши курсы по СКД и Запросам, курсы очень классные, всем рекомендую.

    Сейчас решаю одну задачку строю отчет на СКД, хочу получить отчет по дебиторской задолженности
    на конец каждого месяца (не дня, как у вас пример в курсе по товарным остаткам которые получаются на каждый день),
    а именно месяца, строю кросс таблицу в строках партнеры, а в колонках месяцы, и ничего не получается,
    например взял клиент товар в январе образовалась дебиторская задолженность 15000, задаю период в отчете
    1кв ,получается вот такая картина:
    |январь|февраль|март |
    |30000 |15000 |15000 |
    в январе сумма задваивается почему не пойму, если сделать документ корректировку реализации в июне
    к примеру в сторону увеличения на 5000, то логично получить вот такую таблицу:

    |январь|февраль|март |апрель|май |июнь |
    |15000 |15000 |15000 |15000 |15000|20000 |, а получается вот так:

    |январь|февраль|март |апрель|май |июнь |
    |35000 |20000 |20000 |20000 |20000|20000 |

    суммы вообще не те…
    Отчет делаю в УТ 11.4, ниже привожу запрос:

    ВЫБРАТЬ
    0 КАК Поле1
    ПОМЕСТИТЬ ВТ_Цифра

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

    ВЫБРАТЬ
    1

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

    ВЫБРАТЬ
    2

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

    ВЫБРАТЬ
    3

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

    ВЫБРАТЬ
    4

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

    ВЫБРАТЬ
    5

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

    ВЫБРАТЬ
    6

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

    ВЫБРАТЬ
    7

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

    ВЫБРАТЬ
    8

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

    ВЫБРАТЬ
    9
    ;

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&НачалоПериода, МЕСЯЦ, ВТ_Цифра.Поле1 + 10 * ВТ_Цифра1.Поле1), МЕСЯЦ) КАК Поле2
    ПОМЕСТИТЬ ВТ_Даты
    ИЗ
    ВТ_Цифра КАК ВТ_Цифра,
    ВТ_Цифра КАК ВТ_Цифра1
    ГДЕ
    НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&НачалоПериода, МЕСЯЦ, ВТ_Цифра.Поле1 + 10 * ВТ_Цифра1.Поле1), МЕСЯЦ) МЕЖДУ &НачалоПериода И &КонецПериода
    ;

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    РасчетыСКлиентамиОстаткиИОбороты.Период КАК Месяц,
    ЕСТЬNULL(РасчетыСКлиентамиОстаткиИОбороты.СуммаНачальныйОстаток, 0) КАК НачОстаток,
    ЕСТЬNULL(РасчетыСКлиентамиОстаткиИОбороты.СуммаКонечныйОстаток, 0) КАК КонОстаток,
    РасчетыСКлиентамиОстаткиИОбороты.АналитикаУчетаПоПартнерам.Партнер КАК Партнер
    ПОМЕСТИТЬ Вт_Остатки
    ИЗ
    РегистрНакопления.РасчетыСКлиентами.ОстаткиИОбороты(, , Месяц, , ) КАК РасчетыСКлиентамиОстаткиИОбороты
    ;

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    МИНИМУМ(Вт_Остатки.Месяц) КАК МесяцСвязи,
    Вт_Остатки.Партнер КАК Партнер,
    Вт_Остатки.КонОстаток КАК КонОстаток,
    ВТ_Даты.Поле2 КАК МесяцГруппировки,
    Вт_Остатки.НачОстаток КАК НачОстаток
    ИЗ
    ВТ_Даты КАК ВТ_Даты
    ЛЕВОЕ СОЕДИНЕНИЕ Вт_Остатки КАК Вт_Остатки
    ПО ВТ_Даты.Поле2 <= Вт_Остатки.Месяц

    СГРУППИРОВАТЬ ПО
    Вт_Остатки.Партнер,
    ВТ_Даты.Поле2,
    Вт_Остатки.НачОстаток,
    Вт_Остатки.КонОстаток

    Помогите пожалуйста если не сложно, уже неделю бьюсь, что я делаю не так?

    С Уважением,
    Олег.

    • Василий Ханевич

      Добрый день!
      Давайте попробуем решить эту задачу при помощи двух связанных наборов данных. В первом наборе данных выберем все даты, на которые нужно получить остатки. Во втором наборе данных получаем остатки по регистру накопления РасчетыСКлиентами на дату, указанную в параметре. Связываем эти наборы данных, дату из первого набора передаем в параметр второго набора. Подобный прием рассматривался в курсе по СКД.

      • SinO

        Добрый день Василий!
        Спасибо за ответ!
        Василий подскажите пожалуйста когда то проходил Ваш курс по запросам, курс супер, там есть урок и пример получение остатков на каждый день, сейчас решил освежить свою память и попытался воспроизвести этот пример только я вывожу еще и начальный остаток, приход, расход и конечный остаток (у вас в уроке только конечный остаток), но столкнулся с некоторыми трудностями когда выводишь данные с 01.07 по 31.07, то если в 31.07 были движения в данные выборки они не попадают к примеру остаток на начало 30.07 был 430 потом приход 100 далее расход 3 остаток на конец 30.07 527, тогда на начало 31.07 527 прихода не было расход 10 остаток на конец 31.07 517, а у меня получается две строки с датой 31.07:
        |31.07.2019 |Товар1 |430|100|3 |527| – это строка ошибочная дубль даты 30.07
        |31.07.2019 |Товар1|527|0 |10|517|
        подскажите пожалуйста, что я делаю не так? Ниже привожу текст запроса:
        ВЫБРАТЬ
        0 КАК Поле1
        ПОМЕСТИТЬ ВТ_Цифра

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

        ВЫБРАТЬ
        1

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

        ВЫБРАТЬ
        2

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

        ВЫБРАТЬ
        3

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

        ВЫБРАТЬ
        4

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

        ВЫБРАТЬ
        5

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

        ВЫБРАТЬ
        6

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

        ВЫБРАТЬ
        7

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

        ВЫБРАТЬ
        8

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

        ВЫБРАТЬ
        9
        ;

        ////////////////////////////////////////////////////////////////////////////////
        ВЫБРАТЬ
        ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, ВТ_Цифра.Поле1 + 10 * ВТ_Цифра1.Поле1 + 100 * ВТ_Цифра2.Поле1) КАК Цифра
        ПОМЕСТИТЬ ВТ_Даты
        ИЗ
        ВТ_Цифра КАК ВТ_Цифра2
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Цифра КАК ВТ_Цифра1
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Цифра КАК ВТ_Цифра
        ПО (ИСТИНА)
        ПО (ИСТИНА)
        ГДЕ
        ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, ВТ_Цифра.Поле1 + 10 * ВТ_Цифра1.Поле1 + 100 * ВТ_Цифра2.Поле1) МЕЖДУ &НачалоПериода И &КонецПериода
        ;

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

        ////////////////////////////////////////////////////////////////////////////////
        ВЫБРАТЬ
        ВТ_Остатки.Период КАК Период,
        ВТ_Остатки.Номенклатура КАК Номенклатура,
        ВТ_Остатки.НачальныйОстаток КАК НачальныйОстаток,
        ВТ_Остатки.Приход КАК Приход,
        ВТ_Остатки.Расход КАК Расход,
        ВТ_Остатки.КонечныйОстаток КАК КонечныйОстаток,
        МИНИМУМ(ВЫБОР
        КОГДА КОНЕЦПЕРИОДА(ВТ_Остатки1.Период, ДЕНЬ) = &КонецПериода
        ТОГДА &КонецПериода
        ИНАЧЕ ДОБАВИТЬКДАТЕ(ВТ_Остатки1.Период, СЕКУНДА, -1)
        КОНЕЦ) КАК Период1
        ПОМЕСТИТЬ ВТ_Результат
        ИЗ
        ВТ_Остатки КАК ВТ_Остатки1
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Остатки КАК ВТ_Остатки
        ПО (ВТ_Остатки.Номенклатура = ВТ_Остатки1.Номенклатура)
        И (ВТ_Остатки.Период < ВЫБОР
        КОГДА КОНЕЦПЕРИОДА(ВТ_Остатки1.Период, ДЕНЬ) = &КонецПериода
        ТОГДА ДОБАВИТЬКДАТЕ(&КонецПериода, СЕКУНДА, 1)
        ИНАЧЕ ДОБАВИТЬКДАТЕ(ВТ_Остатки1.Период, СЕКУНДА, -1)
        КОНЕЦ)

        СГРУППИРОВАТЬ ПО
        ВТ_Остатки.Период,
        ВТ_Остатки.Номенклатура,
        ВТ_Остатки.НачальныйОстаток,
        ВТ_Остатки.Приход,
        ВТ_Остатки.Расход,
        ВТ_Остатки.КонечныйОстаток
        ;

        ////////////////////////////////////////////////////////////////////////////////
        ВЫБРАТЬ
        ВТ_Даты.Цифра КАК День,
        ВТ_Результат.Номенклатура КАК Номенклатура,
        ВТ_Результат.НачальныйОстаток КАК НачальныйОстаток,
        ВТ_Результат.Приход КАК Приход,
        ВТ_Результат.Расход КАК Расход,
        ВТ_Результат.КонечныйОстаток КАК КонечныйОстаток
        ИЗ
        ВТ_Даты КАК ВТ_Даты
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Результат КАК ВТ_Результат
        ПО (ВТ_Даты.Цифра МЕЖДУ ВТ_Результат.Период И ВТ_Результат.Период1)

        СГРУППИРОВАТЬ ПО
        ВТ_Даты.Цифра,
        ВТ_Результат.Номенклатура,
        ВТ_Результат.НачальныйОстаток,
        ВТ_Результат.Приход,
        ВТ_Результат.Расход,
        ВТ_Результат.КонечныйОстаток

        УПОРЯДОЧИТЬ ПО
        День

        Заранее спасибо!
        С Уважением,
        Олег.

        • Василий Ханевич

          Добрый день!
          1. Посмотрите, пожалуйста, комментарий к курсу по запросам:
          https://xn—-1-bedvffifm4g.xn--p1ai/1c-v8/development-optimize-queries/startpage/module09/comment-page-3/#comment-755210
          В нем приводятся изменения для текста запроса, попробуйте у себя их же применить.

          2. Попробуйте решить эту задачу не при помощи одного большого запроса, а при помощи СКД – при помощи соединения двух наборов данных. В первом наборе данных будет перечень дат. Для каждой из этих дат во втором запросе получаем данные при помощи виртуальной таблицы ОстаткиИОбороты.

  13. Serge_ASB

    Добрый день.
    Скажите, а как изменить запрос СКД, если мне нужно выводить динамику (скажем, курсов валют по дням) не по одной валюте, а по всем?

    • Василий Ханевич

      Добрый день!
      Можно использовать простой текст запроса набора данных:

      ВЫБРАТЬ
          КурсыВалют.Период,
          КурсыВалют.Валюта,
          КурсыВалют.Курс
      ИЗ
          РегистрСведений.КурсыВалют КАК КурсыВалют

      Поле Курс определяем как ресурс.
      В настройках компоновки добавим диаграмму (тип диаграммы – график), у которой в точках будет Период, а в сериях – Валюта:
      Диаграмма
      В таком случае получим график изменения курса валют по дням.

  14. kulcha

    Добрый день. Как можно рассчитать разницу между продажами за текущий месяц и такой же месяц предыдущего года ?

    • Василий Ханевич

      Добрый день!
      Можно использовать объединение двух наборов данных – запросов. В каждом из них будут одинаковые тексты запросов, но разные параметры – периоды, задающие интервал времени для получения из базы данных о продажах.
      В курсе по СКД рассматривается пример такого отчета.

  15. Сураев Игорь

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

    • Насипов Фарит

      Проходите курсы – там раз в 20 больше, строго по порядку и систематизировано.

      А примеры.. – на то они и примеры, чтобы просто показывать примеры :)

  16. Владимир

    Спасибо за примеры,
    жаль что их так мало у 1С.

    Вернуться к вашей публикации меня натолкнула интересная комбинация с итогами в СКД, для которой пока не удалось найти решение, допускаю что Вы его знаете.
    Отчет содержит несколько вертикальных итогов, к которым нужно добавить еще один итог, который должен отображаться не самого нижнего уровня из 5-ти существующих, а с 3-го где данные нижних уровней не должны участвовать в этом итоге, данные для данного итога формируются отдельным запросом и присоединяются левым соединением к основному запросу. Для требуемого итога была использована следующее выражение в ресурсах: Сумма(ВычислитьВыражениеСГруппировкойМассив(“Остаток”, “Валюта”))
    где “Валюта” и есть та группировка с которой нужно начать считать итоги. Отчет правильно работал до тех пока была только одна валюта, как только валют стало больше, результат становился не верным и не объяснимым с точки зрения арифметики, соотношение между валютами примерно соблюдалось, но сами цифры отличались например в 2,28 раза. Учитывая, что нужно формировать итоги для данных из левого соединения была сделана попытка решить задачу через связанные наборы данных, но результат был точно таким же.
    Буду Вам очень благодарен если подскажите хотя бы идею решения. Спасибо!

    • Василий Ханевич

      Добрый день!
      Затрудняюсь однозначно подсказать вам. Я бы попробовал первым делом добавить соединение в запрос или соединение с дополнительным набором данных, собственно как вы и пишете. Далее проверял бы сами данные, которые возвращает запрос. Т.е. в настройках компоновки делаю одну группировку – детальные записи. Анализирую, какой получается результат. Все ли данные корректно выбираются из базы, нет ли задвоений и т.д. После этого добавлять группировки, смотреть, какой результат получается, как отрабатывают выражения для ресурсов. Вот в таком направлении я бы пробовал решать задачу.

  17. Анатолий

    Огромное спасибо за видео уроки.С удовольствием посмотрел, очень познавательно. У меня вопрос: “Почему при условном оформлении вычисляемых (и пользовательских) полей выдаётся ошибка “Поле не найдено.”?”. Непонятно,чем отличается вычисляемое (или пользователькое) поле?

    • Василий Ханевич

      Добрый день!
      Подобная ошибка может возникать, когда для вычисляемого поля не задается выражение, а только выражение на закладке Ресурсы. Получается, что на уровне детальных записей такое вычисляемое поле не определено, оно существует только на уровне группировки. Поэтому, когда мы пытаемся использовать это поле в детальных записях, то возникает такая ошибка.
      Пользовательское поле можно создать самостоятельно и при работе с отчетом в режиме “1С:Предприятие”, а вычисляемое поле может создать только разработчик при создании схемы компоновки данных.

  18. skv_79

    Объясните, пожалуйста: почему нужно накладывать именно на уровне ресурсов все выражения? Не могу понять ключевые различия между описанием функции в вычисляемом поле и на уровне ресурса.

    • Василий Ханевич

      Добрый день!
      Потому что мы хотим рассчитать итоговое значение выражения на уровне группировки, а не в детальных записях. Поэтому обращаемся к закладке Ресурсы в конструкторе схемы компоновки. Если планируем рассчитать значение на уровне детальных записей, то нужно задать выражение на закладке Вычисляемые поля.

  19. Esagila

    Здравствуйте!

    Спасибо за курс. За содержание и такое профессиональное объяснение.

    Спасибо за комментарии. Отдельное спасибо Snouphruh

  20. Dmitry K

    Этот материал есть в курсе который закончился 01.07? Есть смысл пересматривать?

    • Евгений Гилев (Мастер-тренер)

      Добрый день!

      Этот материал входит в курс, поэтому отдельно изучать покупателям не требуется

      Другие материалы по СКД, публиковавшиеся в июле, будут включены в курс сегодня-завтра.

      Ссылка на обновление будет выложена на стартовой странице курса.

  21. Крынецкий Александр

    Все хорошо, но есть поправка к первому видео.
    На вкладке “Вычисляемые поля” для добавляемых полей, все же лучше вписать в выражение: 0 (ноль, без кавычек). В противном случае, когда вы добавите детальные записи и попробуете в них вывести это поле – будет ошибка: “Поле не найдено …”(проверял на платформе 1С:Предприятие 8.3 (8.3.8.1502))

    • Василий Ханевич

      Добрый день!
      В отчете планировалось выводить в настройках компоновки только группировки, поэтому выражение указывалось на уровне ресурса. А так вы правы – если нужно выводить и детальные записи, то следует определить выражение для вычисляемого поля.

  22. Upit78

    Спасибо огромное! С помощью этих уроков стало в том числе понятно, как быстро и просто пронумеровать по порядку строки отчета.

    • Snouphruh

      в принципе, это делается в запросе:

      ВЫБРАТЬ
      Номенклатура,
      КоличествоОборот Количество,
      СтоимостьОборот Сумма

      ПОМЕСТИТЬ
      ВТ_Номенклатура

      ИЗ
      РегистрНакопления.Продажи.Обороты

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

      ;

      ВЫБРАТЬ
      КОЛИЧЕСТВО (Т2.Номенклатура) Порядок,
      Т1.Номенклатура,
      Т1.Количество,
      Т1.Сумма

      ИЗ
      ВТ_Номенклатура Т1

      ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Номенклатура Т2
      ПО Т2.Номенклатура < Т1.Номенклатура

      СГРУППИРОВАТЬ ПО
      Т1.Номенклатура,
      Т1.Количество,
      Т1.Сумма

      УПОРЯДОЧИТЬ ПО
      Порядок

      • Роман

        ну да тэта-соединением и пользовались еще в 8.1 пока не придумали новых скд-функций

        • Snouphruh

          обычное соединение таблицы с самой же существовало и до 1С.
          таким же способом делаются и эти нарастающие итоги, и получение предыдущих или последующих значений и прочие фишки, которые делаются в СКД через СКДшные функции-вычисления.

          • GolD

            Проблема, что работает это медленно и плохо. Вы, видимо, на практике не пытались использовать свое соединение на большой базе.

            • Snouphruh

              первый запрос из пакета выбирает необходимые данные и индексирует их по нужным полям, поэтому проблем со скоростью при соединении возникать не должно, хотя на практике я не мониторил тета-соединения. в моЁм опыте на практике на больших базах никогда не возникало ситуаций или какой-либо необходимости изголяться подобным образом. пронумеровать всегда можно программно при выводе данных из запроса, посчитать итоги (нарастающие суммой или процентом) тоже всегда можно программно, но некоторые компании при собеседовании (тестировании) любят давать задания, где в условии акцент делается на том, что данные должны быть представлены в определЁнном виде и только силами запроса, поэтому любая программная обработка не допускается.

    • Насипов Фарит

      Если только как-то захватывать поток. Видео опубликованы на Wistia, этот сервис не дает возможности просто скачать.

      • Snouphruh

        это лишние действия. ниже я описал порядок действий, чтобы сохранить нужный человеку контент.

    • Snouphruh

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

      я пользуюсь браузером Хромом.
      1. нажимаете левой кнопкой мыши на этой странице (практически в любом месте);
      2. выбираете последний пункт в меню Inspect (в русской верии должно быть Исследовать). после чего экран поделится на 2 части, в одной половине будет сама текущая страница, а в другой половине – код этой страницы;
      3. в вверху будет меню, там надо выбрать пункт Network (сеть) (4ый пункт слева). содержимое в половине окна, где код, изменится;
      4. чуть ниже будет ещЁ одно меню, в котором надо выбрать пункт Media (Медиа) (6ой справа);
      5. далее на самой странице сайта (то есть на левой половине) надо запустить воспроизведение интересующего Вас видео. в правой половине в таблице появится файл, типа file.mp4;
      6. 2 раза щЁлкните по нему. в новой закладке откроется новая страница с тем файлом;
      7. в любом месте новой страницы вне видео так же нажмите левую кнопку мыши и выберите пункт «Сохранить как»;
      8. в появившемся диалогом окне укажите (введите) название, под которым будет сохранено видео на Вашем компьютере. при необходимости там же (в диалоговом окне) можно выбрать путь (место), где на диске будет сохранено видео.

        • Snouphruh

          пожалуйста!

          кстати точно так же можно сохранять и музыку из контакта без всяких примочек в виде расширений для браузеров или дополнительных прог.

      • rmarkovych

        1-2 пункты заменяет клавиша F12. Далее по инструкции. Спасибо. Не знал такого способа

    • Евгений Гилев (Мастер-тренер)

      Добрый день!

      Есть. Оно не блещет оригинальностью и наглядными примерами, но формально функционал описан.

    • Василий Ханевич

      Добрый день!
      Да. В справке есть специальный раздел Система компоновки данных – Язык выражений системы компоновки данных:
      ЯзыкВыражений

    • vvi3ard

      Более того первые 2 видео полная копия описания на ИТС.
      С той только разницей что описание на ИТС я прочитал, и вероятно не очень понял, а по видео гораздо понятнее.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Вход на сайт

Зарегистрироваться

Подтверждение регистрации будет отправлено на указанный e-mail.

Я подтверждаю, что ознакомлен(а) с Пользовательским соглашением, принимаю его условия и даю свое согласие на обработку моих персональных данных.

Восстановить доступ

E-mail или логин

Ссылка на создание нового пароля будет отправлена на указанный e-mail.