Кейсы решения задач на СКД

08.11.21

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

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

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

 

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

 

Нам требуется создать отчет, который будет отображать одновременно данные по виртуальной таблице «ОстаткиИОбороты» одного регистра и «Обороты» другого регистра с периодичностью до регистратора. Это важный момент, из-за которого все и происходит.

 

 

На скриншоте показан отчет, где происходит обращение к двум виртуальным таблицам: красным цветом выделен блок ресурсов одного регистра, зеленым – показатели другого регистра. При стандартном объединении таких таблиц конечный остаток по группировке «Товар» считается неправильно – я покажу, как это можно исправить.

Пример запроса я будут показывать на демонстрационной конфигурации «Управляемое приложение».

 

 

Запрос выглядит следующим образом: объединение двух виртуальных таблиц, «ТоварныеЗапасы.ОстаткиИОбороты» и виртуальной таблицы «Продажи.Обороты».

 

 

На слайде показаны настройки полей СКД – из-за того, что включено автозаполнение полей, система по умолчанию проставила поля измерений, поля периодов и поля расчета остатков (начальный и конечный остаток).

 

 

При таком решении «в лоб», когда мы выполнили объединение двух запросов к виртуальным таблицам «ОстаткиИОбороты» и «Обороты», получаем нехорошую картину – в детальных записях все правильно: есть начальный остаток, приход, расход.

Но поскольку СКД сама рассчитывает значение ресурсов для группировок, в группировке на уровне Товар у нас указаны неправильные остатки. Для товара Bosch1234 у нас должно получиться -1, но СКД нам посчитала 0. И для Bosch15, если вычислить 4-3, то должно быть 1, но СКД тоже посчитала 0.

Почему так происходит? На сайте ИТС описана методика расчета остатков в СКД – там этому посвящена целая страница. Нас интересует единственная ветка алгоритма: расчет остатков по полям с ролью «Измерение» – по полям группировки «Товар». Там написано, что:

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

 

Например, в данном примере первая запись – документ «Корректировка остатка 000000001», по хронологии она первая, значение начального остатка 0, соответственно, на уровне группировки «Товар» у нас в качестве начального остатка тоже получается 0.

В качестве значения конечного остатка на уровне группировки берется значение конечного остатка из последней по хронологии записи. В данном случае у нас последний по хронологии – документ «Продажа 000000014».

Но на уровне группировки «Товар» значение ресурса «КоличествоКонечныйОстаток» здесь тоже 0. Так получается из-за того, что у нас используется объединение запросов. Остатки и обороты мы объединили с продажами, это значение и пошло в значение конечного остатка на уровне группировки по товару.

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

 

 

Чтобы дать СКД эти уникальные разрезы и изменения, мы в каждый запрос объединения вводим еще одно текстовое поле – я его называю «Раздел». В это текстовое поле пишем уникальную для этого запроса последовательность символов. Я обычно называю раздел по названию таблицы, по которой делается запрос. Для запроса 1 у меня в этом поле написано «ТоварныеЗапасы», а для запроса 2 – «Продажи».

 

 

В настройках СКД для нового поля «Раздел» мы обязательно указываем роль «Измерение» и ставим флаг «Обязательное».

Флаг «Обязательное» должен быть установлен, поскольку вы вряд ли будете выбирать в своем отчете поле «Раздел» – оно имеет техническое предназначение, только для решения конкретной задачи, вы его не будете показывать пользователю.

Если вы не установите флаг «Обязательное», то при компоновке компоновщик макетов СКД удалит это поле, и все, что вы сделали, сойдет на нет. Поэтому мы устанавливаем для поля СКД «Раздел» флаг «Обязательное», то при компоновке макета это поле удалено не будет.

 

 

При таком решении начальный и конечный остаток по виртуальной таблице «ОстаткиИОбороты» на уровне группировки «Товар» рассчитывается правильно.

Подведем итоги этому кейсу:

  • СКД сама рассчитывает итоги, это необходимо помнить. Для этого на вкладке «Набор данных» мы прописываем роли – указываем, какое поле является измерением, какое поле является полем периода и объединяем поля начального и конечного остатков в группы.

  • Для решения задачи объединения двух виртуальных таблиц мы добавляем в запросах поле «Раздел» – в моем случае это просто строка.

  • В настройках полей СКД для добавленного поля «Раздел» мы устанавливаем роль «Измерение» и ставим флаг «Обязательное».

 

Наложение отбора в объединении запросов

 

Давайте рассмотрим второй кейс – это проблема наложения отбора в объединении запросов. Причем этот кейс начинает воспроизводиться с 8.3.13 – до этого такой проблемы не было.

 

 

Мы имеем набор данных-запрос, в котором у нас производится объединение двух запросов – к виртуальным таблицам оборотов регистров «Движение денежных средств» и «Денежные средства». Я заранее добавил в это объединение поле «Раздел».

  • В первом запросе есть поля «Счет» и «СтатьяДДС».

  • Во втором запросе есть только «Счет» – поля «СтатьяДДС» в этом запросе нет.

Посмотрим, как поведет себя система, если мы в пользовательском режиме захотим отфильтровать отчет по полям «Счет» и «СтатьяДДС».

 

На слайде показано, как выглядит запрос компоновщика в платформе 8.3.12 – это не исходный запрос, а запрос, который нам скомпоновал компоновщик макета СКД.

Обратите внимание, что при компоновке у нас в параметры виртуальных таблиц накладывается отбор, причем для первого запроса объединения установлен отбор по двум полям – «Счет» и «СтатьяДДС», а для второго запроса объединения установлен отбор только по полю «Счет», поскольку поля «СтатьяДДС» во втором запросе нет.

Теперь давайте посмотрим, как этот механизм работает в версии платформы 8.3.13.

В первом запросе – все то же самое, а во втором запросе объединения все изменилось.

Поскольку поля «Статья ДДС» во втором запросе нет, 1С решили, что при наложении отбора на поле, которого нет в запросе объединения, СКД должна добавить в запрос отбор по условию NULL=значение параметра. То есть, в этом случае из второго запроса объединения никакие данные выбираться не будут.

Это изменение описано на сайте 1С.

Как же быть? Можно попробовать отключить в СКД флаг автозаполнения у набора данных «Запрос» и вручную проставить поля условий (поля, на которые возможно наложить отбор).

На слайде представлен запрос СКД с отключенным автозаполнением. Здесь я для первого запросе объединения на закладке «Компоновка данных» вручную вытаскиваю в условия поля «Счет» и «Статья ДДС», а для второго запроса объединения я вручную вытаскиваю в условия поле «Счет».

 

Но даже в случае отключенного автозаполнения у набора данных и вручную проставленных условий только для нужных полей, если мы компонуем такой запрос с отбором по полям «Счет» и «СтатьяДДС», у нас компоновщик макета упорно добавляет в запросы объединения, во второй запрос этот отбор равен NULL, где NULL=наш второй параметр.

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

Я пробовал выносить второй запрос объединения во временную таблицу, выбирать из временной таблицы – результат остается тем же, данные из второй таблицы в итоговый отчет не выводятся. Действует правило, указанное на сайте 1С: если у вас объединение и удалось наложить отбор в один из запросов объединения, во втором запросе объединения отбор будет также наложен, и вы ничего не получите.

Но пришла платформа 8.3.14, и, к счастью, это поведение изменили – об этом также сказано на сайте 1С.

Пример на слайде я сделал на платформе 8.3.16 с отключенным режимом совместимости (когда поведение платформы уже изменилось).

Здесь для того же набора данных-запрос без использования флага «Автозаполнение» при ручной настройке полей условий, в случае отбора по полю «Счет» и «Статья ДДС» у нас отбор накладывается только в первом запросе объединения.

Еще раз обращаю внимание, что здесь флаг «Автозаполнение» снят и настройка полей условий указана вручную.

Но если включить флаг автозаполнения в наборе данных «Запрос», то на платформе 8.3.16 в случае отбора по полям «Счет» и «СтатьяДДС» компоновщик макета будет пытаться наложить отбор и в первом, и во втором запросе объединения. И мы опять получим ситуацию, когда из второго запроса объединения ни одной записи не будет выбрано.

На нашем YouTube-канале я показываю много интересных кейсов решения задач по СКД.

upd: Начиная с платформе 8.3.18 поведение изменилось – теперь отбор на отсутствующие поля объединения не накладывается.

 

Вопросы

 

Встречали ли вы в типовых конфигурациях отчеты с первым кейсом – объединения двух виртуальных таблиц с выводом записей по регистратору?

В типовых конфигурациях подобного отчета я не видел. Данную задачу я решал при разработке нетипового отчета. Это было в УПП – надо было сравнить остатки и обороты по двум регистрам накопления – «ТоварыНаСкладах» и «ПартииТоваровНаСкладах».

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

Расскажите про ошибку с 8.3.13 – как вы с ней столкнулись?

В 2019-м году, когда была платформа 8.3.13 в ходу, коллега обратился – у него схема объединения двух запросов, накладываем отбор и у нас все записи из второго запроса объединения вообще не выбирается. Начали компоновать схему вручную – и в результате компоновщика макета мы увидели, что СКД добавляет отбор NULL=значение параметра.

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

Можно ли вывести в пользовательском режиме на форму отчета условие отбора «В списке» для условного оформления в настройках СКД?

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

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

Если у вас платформа с версией выше 8.3.13 – решение этого кейса – отключать автозаполнение. Но я ничего страшного в этом не вижу.

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

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

Единственное неудобство может быть, если в запросе появляются новые поля – но и то, здесь главное не забыть.

Другой вопрос – в первом кейсе задублированы вторая и третья строки данных по регистратору. Нельзя ли их объединить?

Поскольку у нас объединение двух виртуальных таблиц по регистрам «ТоварныеЗапасы», то первые две строки не содержат показатель «КоличествоПродажи» – оно берется из регистра «Продажи». А третья строка данных – это уже информация из регистра накопления «Продажи». И здесь нет остатков, здесь есть только продажи. В этом и суть.

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

Сколько времени вы потратили, когда столкнулись с кейсом №2?

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

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

Расскажите подробнее про вкладку «Компоновка данных» в конструкторе запроса и работу с ней.

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

Итак, у нас запрос пакета – здесь все просто, объединение полей. На вкладке «Компоновка данных» мы все поля добавляем – все поля стали выбранными. И на вкладке «Условия» мы в данном случае для каждого запроса объединения добавляем все поля ресурсов.

Обратите внимание, что поля условий прописываются для каждого запроса объединения отдельно (на отдельных вкладках), а поля компоновки – они общие.

 

 

На вкладке «Таблицы» закладки «Компоновка данных» есть кнопка «Параметры виртуальных таблиц». Здесь нам обязательно нужно будет прописать параметры для начала и конца периода, потому что когда мы отключаем флаг «Автозаполнение» у нас параметров «НачалоПериода» и «КонецПериода» не будет совсем. А в поле «Условие» мы добавляем измерения, на которые мы планируем накладывать отбор – и делаем это для обоих запросов объединения.

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

Но есть отдельные случаи работы компоновщика макета компоновки данных, когда флаг «Автозаполнение» нам все портит, и приводит к тому, что в консоли запросов мы видим один результат исполнения запроса, а в консоли СКД мы видим другой результат исполнения запроса.

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

После корректного заполнения закладки «Компоновка данных» мы можем отключить флаг «Автозаполнение» и у нас ничего не потеряется – все настройки, все поля остались.

Может быть, кто-нибудь из старичков помнит объект «Построитель отчета», где дополнительно задавались настройки построителя. Здесь точно так же для компоновки.

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

Без флага «Автозаполнение» подход к созданию схемы становится более сознательным, но он более рискованный – особенно поначалу, пока нет опыта. Потом это становится нормальным. Просто нужно разобраться с поведением – как это работает, что нужно сделать когда новое поле добавляется – куда его нужно добавить и т.д.

 

*************

Данная статья написана по итогам доклада (видео), прочитанного на онлайн-митапе "Практика применения СКД".

 

10 - 12 октября 2024 года состоится конференция INFOSTART TECH EVENT, на которой прозвучит 130+ докладов.

Темы конференции:

  • Приемы, методы разработки и тестирования
  • DevOps-практики, управление инфраструктурой разработки
  • Интеграция и обмен данными
  • Идеи и тренды в разработке 
  • Администрирование серверов 1С и СУБД. HighLoad оптимизация  
  • Развитие технической команды. Личная эффективность разработчика 

INFOSTART TECH EVENT - крупнейшая профессиональная конференция для программистов 1С.


Подробнее о конференции.

 


См. также

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

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

10000 руб.

02.09.2020    140586    772    391    

803

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

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

15.05.2024    5200    implecs_team    6    

43

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

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

3 стартмани

05.02.2024    5565    43    obmailok    21    

78

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

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

1 стартмани

31.01.2024    2577    2    Yashazz    0    

33

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

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

2 стартмани

11.12.2023    9462    21    John_d    25    

124

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

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

05.12.2023    6196    PROSTO-1C    13    

67
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Hatson 533 09.11.21 12:14 Сейчас в теме
Но на уровне группировки «Товар» значение ресурса «КоличествоКонечныйОстаток» здесь тоже 0. Так получается из-за того, что у нас используется объединение наборов данных. Остатки и обороты мы объединили с продажами, это значение и пошло в значение конечного остатка на уровне группировки по товару.


Но речь идет всё же об объединении запросов, а не наборов. Это принципиально разные вещи. В следующем моем посте это важно учитывать.
7. echo77 1865 11.11.21 07:33 Сейчас в теме
(1) Согласен. Спасибо! Поправил
2. Hatson 533 09.11.21 12:17 Сейчас в теме
Как измениться поведение системы если вместо Объединения запросов использовать Объединение наборов? Возможно это поможет.
3. dhurricane 09.11.21 14:45 Сейчас в теме
(2) Пробовал, не помогает.
4. gybson 09.11.21 16:38 Сейчас в теме
(13)А в чем прикол такого отчета, если записи по документам дублируются? И в третьей позиции продажа 102 потерялась
5. dhurricane 09.11.21 20:53 Сейчас в теме
(4)
А в чем прикол такого отчета, если записи по документам дублируются?
Скорее всего автор не использовал группировку по полям периода и регистратора, а оставил детальные записи, дабы читателю нагляднее было, какие данные используются в отчете.
Drivingblind; echo77; +2 Ответить
6. TMV 14 10.11.21 10:15 Сейчас в теме
Я пробовал выносить второй запрос объединения во временную таблицу, выбирать из временной таблицы – результат остается тем же, данные из второй таблицы в итоговый отчет не выводятся
Кажется, надо выносить во временную таблицу именно первый запрос, а не второй.
Оставьте свое сообщение