СКД: Корректный расчет остатков по нескольким регистрам

24.12.18

Разработка - СКД

Решение проблемы некорректного расчета остатков при получении данных с помощью СКД из нескольких таблиц

Я не претендую на то, что описанные этой статье механизмы работы СКД и мое понимание соответствует действительности, поэтому готов внести поправки в данную статью, если что-то не так.

Постановка задачи

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

Как решалась задача

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

В схеме компоновки данных, я добавил единственный Набор данных - запрос с текстом, который описывает Объединение двух запросов:

1. РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты

2. РегистрНакопления.ПартииТоваровНаСкладахБухгалтерскийУчет.ОстаткиИОбороты

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

Плюс добавил в каждый запрос поле "Раздел" (я всегда так делаю, чтобы при отладке понять из какого запроса выбираются те или иные данные) - значение этого поля текст: для первого - "1. Товары на складах", для запроса к партиям - "2. Партии товаров на складах" соответственно.

 
 Набор данных - Запрос:

При чем, конструктор СКД определил роли полей(что измерения, а что поля начальных, конечных остатков)

Настроил ресурсы для всех полей. Здесь ничего необычного

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

Смотрю, что получается - вроде, правильно:

Но если добавить группировку по регистратору или детальные записи, то итоги по номенклатуре становятся неправильными:

В чем проблема? Дело в том, что в СКД свой собственный механизм расчета начальных и конечных остатков(информация из видео-курса по СКД Гилева)

Алгоритм расчета итогов по полям остатка описан на ИТС https://its.1c.ru/db/v8310doc#bookmark:dev:TI000000628 (Спасибо Armando)

Упрощенно алгоритм для получения Конечных остатков таков: берем последнюю по хронологии запись в разрезе выбранных измерений и считаем, что значение поля Конечный остаток из нее и есть конечный остаток для группировки. И судя по скриншоту, получается, что последняя запись имеет конечный остаток по Товарам на складах = 0, Партии = 0 - СКД считает, что для Номенклатуры это и есть конечный остаток.

Чтобы это победить, для поля Раздел я добавил роль Измерение, и поскольку, данное поле не планируется выбирать в отчете, а СКД его будет оптимизировать и удалять из запроса - флаг Обязательное. Теперь итоги верные.

Верные итоги

Немного красоты

Для того чтобы исключить пустые строки, сообщающие о начальном и конечном остатке на Начало/Конец периода, поле Регистратор можно в запросе заменить на выражение и поставить для этого поля галку Игнорировать значения NULL.

ВЫБОР
    КОГДА Регистратор = НЕОПРЕДЕЛЕНО
        ТОГДА NULL
    ИНАЧЕ Регистратор
КОНЕЦ

В конце я еще дополнил текст запроса описанием характеристик

 
 Характеристики беру из заранее заготовленного шаблона

Выводы

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

  1. В наборе данных запрос используем таблицу ОстаткиИОбороты 
  2. В запросе для каждого раздела учета создаем поле "Раздел". Для каждого запроса объединения, пишем туда уникальное значение. Я так и пишу текстом, например "1. Товары на складах", "2. Партии товаров на складах"
  3. В запросе выбираем все нужные поля, в т.ч. поле "Раздел
  4. В СКД настраиваем роли для полей остатков(это СКД сделает сама) 
  5. Очень важный момент! В СКД для поля "Раздел" ставим роль "Измерение" и галку "Обязательное

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

СКД Правильный расчет итогов Итоги Остатки Неправильный остаток

См. также

SALE! %

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

12000 10000 руб.

02.09.2020    161363    893    399    

873

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

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

15.05.2024    9075    implecs_team    6    

47

Инструментарий разработчика СКД Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

3 стартмани

05.02.2024    7232    56    obmailok    21    

79

Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    3197    5    Yashazz    1    

34

СКД WEB-интеграция Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Долгое время поддерживаю web-портал, в котором появилась необходимость создавать отчеты. Просмотрев различные фреймворки на js, я решил сделать свое решение, которое позволяло бы быстро разрабатывать и добавлять новые отчеты на web-портал.

2 стартмани

11.12.2023    10966    24    John_d    25    

124

СКД Программист Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

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

05.12.2023    8249    PROSTO-1C    15    

68
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Сурикат 401 18.11.17 11:55 Сейчас в теме
Как альтернатива предлагаемого решения - наборы данных
3. echo77 1908 19.11.17 12:39 Сейчас в теме
(1) Я тоже в один момент подумал, что объединив два набора данных можно получить правильные итоги сразу, но, поскольку, роли полей настраиваются уже для Объединения, а не для отдельных наборов данных в него входящих - получим тоже самое
Прикрепленные файлы:
4. Сурикат 401 19.11.17 12:55 Сейчас в теме
(3)
я Объединения, а не для отдельных наборов данных в него входящих - получим тоже самое


Просто такую же проблему у меня получилось решить именно объединением наборов... Причем в наборах поля ресурсов не пересекались.
Но может ситуация была немного другая =)
2. Armando 1401 18.11.17 22:47 Сейчас в теме
На ИТС описан алгорит получения остатка. В виде кода, т.к. ИС съедает отступы

Полем остатка с точки зрения макета компоновки данных является то, у которого в роли проставлен признак Остаток.

10.8.1. Расчет итогов по полям остатка
Если в макете компоновки данных в некотором наборе данных присутствует поле начального остатка, то в наборе данных также должно присутствовать соответствующее ему поле конечного остатка, и наоборот.

Все поля-периоды, описанные в наборе данных, должны иметь непрерывную нумерацию, начинающуюся с единицы.

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

При расчете итогов по полям-остаткам используется следующий алгоритм:

    ● если требуется осуществить расчет итога поля остатка для группировки по полю-периоду:

        ● если по всем полям-периодам уже была осуществлена группировка:

            ● для каждой комбинации полей измерений, по которым осуществлялась группировка:

                ● получается запись, ближайшая к текущему периоду;

                ● если полученная запись была на текущий период, то из данной записи будут получаться начальные и конечные остатки;

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

                ● иначе начальный остаток полученной записи будет использоваться как начальный и конечный остаток;

    ● иначе (группировка еще не произведена по всем полям-периодам):

        ● для каждой комбинации полей измерений, по которым осуществлялась группировка:

            ● получаются первая и последние записи, у которых поля использованных периодов равны текущему периоду;

            ● если записи найдены, то первая запись будет использоваться как начальный остаток, последняя – как конечный;

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

    ● иначе (не группировка по полю-периоду):

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


https://its.1c.ru/db/v8310doc#bookmark:dev:TI000000628
Irwin; user811769; begemot; d4rkmesa; AlexKo; Сурикат; echo77; +7 Ответить
5. logarifm 1123 22.11.17 00:25 Сейчас в теме
Во-первых чтобы СКД корректно рассчитывала остаток надо обязательно в ресурсах указывать поля Нач.Кон остатки
6. logarifm 1123 22.11.17 00:26 Сейчас в теме
Прекрасно делается через Набор данных Объединение только там есть интересный момент следует учесть Значения разных ресурсов регистров под разныими именами!
7. logarifm 1123 22.11.17 00:53 Сейчас в теме
А вот это диво-дивное и чудо чудное решается как с помощью Набора данных Объединение так и с помощью просто Объеденить в запросе. Но с одной особенностью, что роли необходимо самому указать и проверить для Измерений чтобы были измерениями, а для остатков остатками. Но можно упороться на одну интересную ошибку особенно если использовали к примеру одно поле КонОст и остатка и партии во тут получим ошибку.

Короче что тут разговоры говорить решал я подобную задачу и в конце увидил, что можно ее решить по-разному и оставил вариант как в обработке. Не обесудьте!

Оговорюсь только , что это делалось для конфигурашки на обычных формах 10..х под CRM.
Прикрепленные файлы:
ПартииТоваровНаСкладахСУчетомРезерва.erf
Team leader; +1 Ответить
8. echo77 1908 23.11.17 18:55 Сейчас в теме
(7) Все хорошо, пока не добавить группировку по регистратору.
При добавлении группировки - остаток по партиям для Номенклатуры и для Склада - 0
Эти грабли я и описал в статье, и как их поборол

p.s. В отчете, что вы скинули, нет никакого смысла делать объединение наборов, т.к. вы ничего не объединяете. И не совсем понятно, почему так сложно рассчитываются ресурсы
Прикрепленные файлы:
24. Team leader 12 02.01.19 17:37 Сейчас в теме
(7) взял на вооружение +1
9. alexz69 06.12.17 09:01 Сейчас в теме
Спасибо большое, за вашу статью. Такая же проблема была, только я использовал три регистра в самописной конфигурации. Пришел к выводу, что при добавлении третьего регистра плывет остаток по конечному остатку по измерениям. Хотя по регистратору всё нормально. Проверял все роли, делал и в одном запросе и в объединении - ничего не помогало. Благодаря добавлению раздела всё стало на свои места. Нутром чувствовал, что СКД путает. Очень выручили )).
Andr0med; echo77; +2 Ответить
10. mitia.mackarevich 75 01.03.18 10:17 Сейчас в теме
Для остатков по регистратору вы использовали вспомогательное поле период секунда?
11. echo77 1908 01.03.18 10:42 Сейчас в теме
(10) Да, псевдоним у поля - Период
12. mitia.mackarevich 75 01.03.18 10:58 Сейчас в теме
(11)Тогда проблем с остатками по регистратору быть не должно, а если вы искусственно добавляете разрез (новое измерение) в набор, то это вроде как правило, именно правило а не фича какая то, что его нужно отметить измерением. Разработка сложных отчетов книга есть у Хрусталевой. Во второй редакции это должно быть описано.
13. rozer 311 01.03.18 12:23 Сейчас в теме
(12) да на итс уже как 100 лет есть это https://its.1c.ru/db/metod8dev/content/3093/hdoc - если регистратор то надо секунду добавлять и роли полей поставить правильно
14. echo77 1908 01.03.18 14:26 Сейчас в теме
(12)
если вы искусственно добавляете разрез (новое измерение) в набор, то это вроде как правило, именно правило а не фича какая то, что его нужно отметить измерением

- согласен. Но далеко не все разработчики это осознают, когда создают отчеты по нескольким разделам учета и хотят видеть корректные остатки.
Цель статьи - заострить внимание на том, что задачу решить можно, путем введения нового разреза и установкой роли - Измерение для этого разреза.

Ничего сверхестественного, просто тонкость, которую нужно понимать
Shrayky2; mitia.mackarevich; +2 Ответить
15. alanchik 21.05.18 14:47 Сейчас в теме
Спасибо автору!!! Столкнулся я с проблемой этих остатков, когда объединял два регистра накопления, день бился не добился результата, пока не наткнулся на эту статью. Интуитивно было понятно, что надо что-то делать с разделами учета, потому что по-отдельности запросы считали корректно, а при объединении нет, но как сочинить сие действо мозгов не хватило)))
16. Noveng 16.10.18 12:02 Сейчас в теме
У меня несколько иная задача(. есть начальный остаток по регистру товары на складах и приход по нему материала. Но расход высчитывается как нормативный. Берется перемещаема продукция. по ней ищется спецификация, выбирается материал и рассчитывается нормативный расход. Общего из двух запросов получается только склад и номенклатура. А вот конечный остаток вычисляется как начальный остаток +приход-нормативный расход. Не получается подружить конечный остаток ни с одним периодом из регистра. Группировка склад и номенклатура - всё нормально, но как только добавляешь регистратор, день...остатки разлетаются. Искусственное измерение типа - раздела учета не помогает....
17. echo77 1908 16.10.18 19:16 Сейчас в теме
(16) И не поможет. Вам в итоге нужно получить выборку вида:
Регистратор НачальныйОстаток, Приход, Расход, КонечныйОстаток

В одной строке выборки должен присутствовать начальный и конечный остаток.
18. rom-x 152 28.11.18 14:31 Сейчас в теме
Почему-то если добавляю поле Раздел, в поля группировки к Регистратору, выходит ошибка: Совместная группировка по периодам с другими выражениями запрещена, убираю Роль период у регистратора и периода - конечный остаток не правильный. Если не добавлять раздел в поля группировки и оставить Роль период как есть, все работает.
19. echo77 1908 28.11.18 15:07 Сейчас в теме
(18) И не нужно группировать регистратор с каким-то еще полем - посмотрите скриншот с настройкой структуры.
20. rom-x 152 28.11.18 15:56 Сейчас в теме
(19) Я хотел сделать также, как на картинке перед заголовком Немного красоты.
21. rom-x 152 28.11.18 18:46 Сейчас в теме
22. echo77 1908 29.11.18 07:43 Сейчас в теме
(21) Это не группировка Регистратор, Раздел. Это детальные записи, в которых выведены эти два поля.
25. German_Tagil 43 07.01.19 00:29 Сейчас в теме
Запомнить - с чем то подобным сталкивался по поводу детальных записей
в консоли все нормально работало-
решил перенести в отчет
часа два ковырялся пока добился нужного результата
теперь немного понятно
26. rozer 311 08.01.21 12:28 Сейчас в теме
Neti сделали по этой теме видос https://youtu.be/6QHBQ7nUxFY
d4rkmesa; triviumfan; echo77; +3 Ответить
27. echo77 1908 08.01.21 12:35 Сейчас в теме
(26) Точно :-) Я вижу, на канале много интересных видосов про особенности использования СКД и не только.
28. CaIIIkaDer 25.01.23 11:35 Сейчас в теме
Низкий Вам, Александр, поклон! Несколько дней (как бы это без нехороших слов) "занятий" решились Вашей весьма компактной, но крайне полезной инструкцией. Спасибо Вам огромное!

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

У меня сложный запрос из четырех разных регистров ОстаткиИОбороты, к одному из них клеится регистр сведений левым соединением. Если выводить группировки без периода, то я добился нужного результата. Но если сделать главным разворот по периоду, то в результате получается полная каша.
И как я только не переделывал отчет, и копий отчетов в разных интерпретациях было несчесть, и какие только речи не произносил...

Ни через ОБЪЕДИНИТЬ ВСЕ, ни через НАБОР ДАННЫХ ОБЪЕДИНЕНИЕ, ни через связи наборов данных, СКД, хоть убей, не считает итоги правильно. Через НАБОР ДАННЫХ ОБЪЕДИНЕНИЕ вообще чушь полная выводилась: например, второй регистр выводил данные там, где не было данных в первом регистре (7 января). И никак его не побороть было, и какие свойства я в настройках только не ставил. Уже даже прямыми запросами через консоль начал периоды сравнивать, подумав, что отличия есть. Если период сделать измерением, то сворачивает нормально и данные показываются правильные, но в итогах чушь (что логично).

В конце мучений я выкрутился так, что вывел все запросы через ОБЪЕДИНИТЬ ВСЕ во вложенный запрос, в шапке которого сгруппировал по измерениям и периоду, ресурсы в суммы. После этого разворот по периодам заработал как надо, но теперь в линейном виде (без периодов) получилась полная каша в итогах. Да и в глобальных масштабах по периодам вылезали небольшие отличия в суммах.

И только метод Александра все поставил на свои места. Хоть линейно, хоть по периодам как угодно (день, неделя, месяц). Еще раз человеческое СПАСИБО!

PS: Статья отлично написана: введение, подробности, конкретика.
29. echo77 1908 25.01.23 11:42 Сейчас в теме
(28) Спасибо. Буду ещё писать статьи о простых решениях непростых вопросов :-)
CaIIIkaDer; +1 Ответить
30. Velostrannik 203 25.01.23 13:39 Сейчас в теме
Вообще крутяк!!!!!
Добавил в избранное.
Может пригодится.
31. aviks__ 01.06.23 16:32 Сейчас в теме
Спасибо, вы мне очень помогли!
32. echo77 1908 01.06.23 16:54 Сейчас в теме
(31) Рад, что вам помог этот опыт
Оставьте свое сообщение