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

16.10.26

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

Одиннадцать граблей схем компоновки, которые не видно в конструкторе и не ловит EDT, на реальных отчетах БП КОРП. Формат числа задается в двух местах, и условное оформление варианта перебивает формат поля. Ресурс складывает штуки с часами, и помогает выражение «только когда единица одна». Ресурс пуст в детальных записях, параметр не появляется в шапке без userSettingID, valueListAllowed ломает границы периода, Остатки и СрезПоследних с параметром периода падают с «Несоответствием типов», title без xsi:type дает «Исключение XDTO» при загрузке. В конце код проверки схемы из файла до обновления базы, сводная таблица и чеклист.

Это продолжение серии про разработку на БП КОРП в EDT с ИИ-агентом (первая статья: «Claude Code + EDT на БП КОРП: три месяца, 328 коммитов и 40 правил»). Здесь только отчеты на СКД. В наших блоках их около тридцати, часть схем собрана скриптами-генераторами, часть поправлена правкой Template.dcs мимо конструктора. Каждый случай ниже стоил минимум одного обновления тестовой базы и одного «а почему тут пусто» от пользователя. Имена отчетов обезличены, префиксы заменены на ПРЕФ_.

Формат числа живет в двух местах

Число знаков после запятой в схеме задается на двух уровнях:

  1. У поля набора данных (<field>, блок <appearance>). Действует во всех вариантах сразу.
  2. В условном оформлении варианта настроек (правило с пустым отбором). Действует только в своем варианте, но перебивает формат поля.

Пока вариантов нет или в их оформлении нет правил формата, работает первый уровень, и про второй никто не вспоминает. Проблема начинается, когда в отчете уже есть готовые варианты с правилами. Мы поменяли полю КоличествоВСутки формат на ЧДЦ=3 в наборе данных, обновили базу и увидели прежние два знака. Поле оставалось в общем правиле варианта вместе с остальными числовыми полями, и правило с ЧДЦ=2 выигрывало.

Где живет формат числа

Порядок действий при смене формата одному полю:

  1. Поменять формат у поля набора данных.
  2. Пройти условное оформление каждого варианта.
  3. Если поле перечислено в правиле с другим форматом, убрать его оттуда и добавить ему отдельное правило с нужным форматом и пустым отбором.

Так выглядит отдельное правило в варианте:

<dcsset:item>

    <dcsset:selection>

        <dcsset:item>

            <dcsset:field>КоличествоВСутки</dcsset:field>

        </dcsset:item>

    </dcsset:selection>

    <dcsset:filter/>

    <dcsset:appearance>

        <dcscor:item xsi:type="dcsset:SettingsParameterValue">

            <dcscor:parameter>Формат</dcscor:parameter>

            <dcscor:value xsi:type="v8:LocalStringType">

                <v8:item>

                    <v8:lang>ru</v8:lang>

                    <v8:content>ЧЦ=15; ЧДЦ=3</v8:content>

                </v8:item>

            </dcscor:value>

        </dcscor:item>

    </dcsset:appearance>

</dcsset:item>

Итоги (<totalField>) своего формата не имеют и берут его у поля с тем же dataPath. Отдельно форматировать ресурс не нужно.

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

<dcscor:value xsi:type="xs:string">ЧДЦ=2</dcscor:value>

Отсюда практическое следствие: формат в файле ищите по подстроке ЧДЦ=, а не по конкретной разметке, иначе половину полей не найдете.

Порядок внутри блока поля

<appearance> должен стоять последним в блоке <field>: после <dataPath>, <field>, <title> и <valueType>, если он есть.

<field xsi:type="DataSetFieldField">

    <dataPath>ПлановыйРасходМ3НаРяд</dataPath>

    <field>ПлановыйРасходМ3НаРяд</field>

    <title xsi:type="v8:LocalStringType">

        <v8:item>

            <v8:lang>ru</v8:lang>

            <v8:content>Плановый расход, м3, на ряд</v8:content>

        </v8:item>

    </title>

    <appearance>

        <dcscor:item xsi:type="dcsset:SettingsParameterValue">

            <dcscor:parameter>Формат</dcscor:parameter>

            <dcscor:value xsi:type="xs:string">ЧДЦ=3</dcscor:value>

        </dcscor:item>

    </appearance>

</field>

Вставка между <dataPath> и <field> ломает соответствие XSD. Если правите форматы скриптом, там две ловушки. Первая: внутренний <field>Имя</field> содержит подстроку </field>, и наивный поиск конца блока срабатывает на нем. Конец блока ищется условием «строка, где </field> стоит одна»: ^[ \t]*</field>[ \t]*$. Вторая: <dataPath>Имя</dataPath> есть не только у полей набора, но и в <totalField>. Обрабатывать надо только блоки, открытые тегом <field xsi:type=.

Сколько знаков: два, а удельным величинам три

У нас правило простое: во всех отчетах блоков числа выводятся с двумя знаками после запятой, включая целочисленные поля вроде количества или флага превышения порога. Единый вид чисел во всех отчетах оказался важнее, чем «12» вместо «12,00». Это решение заказчика, а не платформы.

Исключение: удельные величины, которые дальше суммируются или умножаются. Округление такого поля до двух знаков накапливается по строкам и уводит итог. Пример из отчета по поливу: расход на ряд 4,1084747 суммируется по 59 рядам в расход крана.

Знаков Расчет Итог Факт
2 4,11 × 59 242,49 242,4
3 4,108 × 59 242,37 242,4

Пользователь видит в строках 4,11, умножает в уме на 59 и не сходится с итогом. С тремя знаками расхождение уходит в сотые. Три знака у нас получили расход на ряд, норма расхода на гектар (умножается на площадь) и среднесуточное количество (усредняется по периодам). Все остальное, включая площади, стоимости и температуры, осталось с двумя.

Ресурс, который нельзя складывать

Отчет по работам: объем работы в соседней колонке с единицей измерения. Объем объявлен ресурсом с Сумма(ОбъемРаботы). На группировке «Работа» все верно, единица одна. На группировке «Сад» в итог попадают штуки, часы и гектары, и пользователь видит по саду 459 345,10 непонятно чего.

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

ВЫБОР КОГДА КОЛИЧЕСТВО(Различные ЕдиницаИзмеренияРаботы) > 1

    ТОГДА NULL

    ИНАЧЕ Сумма(ОбъемРаботы)

КОНЕЦ

Выражение пишется в <expression> у <totalField>. Где разрез по единице есть, получается обычная сумма. Где единицы смешались, пусто вместо бессмысленного числа. Структуру вариантов трогать не нужно.

Прием не наш. Тот же признак КОЛИЧЕСТВО(Различные Валюта) > 1 стоит в отчетах БИТ.ФИНАНС (план-факт по заявкам) для сумм в разных валютах. Там при нескольких валютах итог подменяется разбивкой по валютам. Валюта там играет ту же роль, что у нас единица измерения.

Где искать такой дефект: вариант, в котором ресурс выводится, а поля-разреза среди группировок нет. Проверять все варианты схемы. В нашем отчете из трех вариантов два были корректны, ошибка жила только в сводном.

Ресурс на разных уровнях

Ресурс в детальных записях пуст

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

Параметр есть, а в шапке его нет

Параметр из dataParameters варианта попадает в быстрые настройки формы, только если у него есть <dcsset:userSettingID> с GUID. Без него отчет работает, но полей ввода в шапке нет, и задать период или отбор пользователь может только через «Настройки».

<dcsset:dataParameters>

    <dcscor:item xsi:type="dcsset:SettingsParameterValue">

        <dcscor:parameter>ГодС</dcscor:parameter>

        <dcscor:value xsi:type="xs:decimal">0</dcscor:value>

        <dcsset:userSettingID>a7f2c8b1-4e3d-4f9a-9b2c-1d4e5f607182</dcsset:userSettingID>

    </dcscor:item>

</dcsset:dataParameters>

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

Рядом стоит <use>Always</use> у необязательного параметра-отбора. В запросе такой параметр написан с пустой веткой:

ГДЕ

    (&СадОтбор = ЗНАЧЕНИЕ(Справочник.ПРЕФ_Сады.ПустаяСсылка)

        ИЛИ Краны.Сад = &СадОтбор)

Без use=Always пользователь снимает флажок отбора, и отчет падает с «Не задано значение параметра».

valueListAllowed только под «В (&Параметр)»

<valueListAllowed>true</valueListAllowed> разрешает передать в параметр список значений. Это нужно только параметрам, которые в запросе стоят под В (&Параметр). У нас флаг стоял у границ диапазона лет, которые используются так:

ГДЕ

    Р.День >= ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), ГОД, &ГодС - 1)

При восстановлении настроек платформа подставляла такому параметру пустой список значений, и запрос падал: «Нельзя сравнивать поля неограниченной длины и поля несовместимых типов». Модуль отчета у нас подменял пустое значение, но это не спасает, когда схему компонуют мимо объекта отчета или когда пользователь сам ввел список. Исправление: valueListAllowed=false у границ.

Виртуальные таблицы с параметром периода

В двух отчетах по урожаю конструкции Остатки(&КонецПериода) регистра накопления и СрезПоследних(&КонецПериода, ) регистра сведений падали при компоновке:

Несоответствие типов (Параметр номер "1")

Общее у этих схем: НачалоПериода и КонецПериода в них не самостоятельные параметры, а выражения от стандартного периода, например КонецПериода(&Период.ДатаОкончания, "День"). При этом Обороты(&НачалоПериода, &КонецПериода, Месяц, ...) регистра бухгалтерии в тех же схемах работал. Почему остатки и срез последних ведут себя иначе, мы до конца не выясняли. Решение нашлось быстрее, чем причина: физическая таблица.

Остатки считаются суммой по виду движения с отбором по периоду и ИМЕЮЩИЕ:

ВЫБРАТЬ

    Движения.Контейнер КАК Контейнер,

    Движения.Место КАК Место,

    СУММА(ВЫБОР

        КОГДА Движения.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)

            ТОГДА 1

        ИНАЧЕ -1

    КОНЕЦ) КАК Остаток

ПОМЕСТИТЬ ВТОстатки

ИЗ

    РегистрНакопления.ПРЕФ_ОстаткиПоМестам КАК Движения

ГДЕ

    Движения.Период <= &КонецПериода

    И Движения.Активность

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

    Движения.Контейнер,

    Движения.Место

ИМЕЮЩИЕ

    СУММА(ВЫБОР

        КОГДА Движения.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)

            ТОГДА 1

        ИНАЧЕ -1

    КОНЕЦ) <> 0

Срез последних: МАКСИМУМ(Период) по ключу во временную таблицу и обратное соединение с регистром по ключу и периоду. Не забудьте Движения.Активность: виртуальная таблица учитывает ее сама, физическая нет.

Схема чистая в EDT, а база ее не загружает

Схема, собранная скриптом, прошла revalidate_objects и get_project_errors без замечаний и упала при выгрузке в базу:

Исключение XDTO при чтении Template.xml

НачалоСвойства: title   Тип: {http://www.w3.org/2001/XMLSchema}anyType

Причина: генератор писал <title> без типа. EDT такой узел пропускает, платформа на нем падает:

<title><v8:item><v8:lang>ru</v8:lang><v8:content>Текст</v8:content></v8:item></title>

Правильно с типом:

<title xsi:type="v8:LocalStringType"><v8:item>...</v8:item></title>

EDT проверяет модель, а не соответствие XDTO-схеме платформы. Поэтому новый узел мы больше не сочиняем, а копируем соседний такой же из этого же файла вместе со всеми атрибутами. Перед выгрузкой сверяем, что у однотипных узлов одинаковый набор атрибутов:

grep -o '<title[^>]*>' Template.dcs | sort | uniq -c

Разнобой в выводе означает найденный дефект. Эту проверку, проверку <title> без xsi:type и проверку порядка <appearance> в поле мы свели в скрипт check_dcs_nodes.py. Он приложен к первой статье серии (ссылка в начале).

EDT не видит правку файла

Вторая сторона правки мимо конструктора: EDT не знает, что Template.dcs изменился на диске. Без F5 (Refresh) на проекте в базу уйдет старая схема, и вы будете искать ошибку в правке, которой там нет.

Мелочь из той же области. Имя варианта в списке вариантов БСП задается в модуле менеджера отчета (НастройкиВарианта.Наименование). Без него все варианты показываются синонимом отчета и выглядят одинаково.

Проверка схемы из файла до обновления базы

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

Чтение = Новый ЧтениеXML;

Чтение.ОткрытьФайл(ПутьКФайлу); // ...\Templates\ОсновнаяСхемаКомпоновкиДанных\Template.dcs

Схема = СериализаторXDTO.ПрочитатьXML(Чтение, Тип("СхемаКомпоновкиДанных"));

Чтение.Закрыть();



Для Каждого Вариант Из Схема.ВариантыНастроек Цикл

    Попытка

        Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;

        Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));

        Компоновщик.ЗагрузитьНастройки(Вариант.Настройки);

        Компоновщик.Восстановить();

        Для Каждого П Из Компоновщик.Настройки.ПараметрыДанных.Элементы Цикл

            Если Строка(П.Параметр) = "Период" Тогда

                П.Значение = Новый СтандартныйПериод(Дата(2025, 8, 1), Дата(2026, 7, 31, 23, 59, 59));

                П.Использование = Истина;

            КонецЕсли;

        КонецЦикла;

        КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

        Макет = КомпоновщикМакета.Выполнить(Схема, Компоновщик.ПолучитьНастройки(), , ,

            Тип("ГенераторМакетаКомпоновкиДанных"));

        Процессор = Новый ПроцессорКомпоновкиДанных;

        Процессор.Инициализировать(Макет);

        Док = Новый ТабличныйДокумент;

        Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;

        Вывод.УстановитьДокумент(Док);

        Вывод.Вывести(Процессор);

        Лог.Добавить(Вариант.Имя + ": строк " + Док.ВысотаТаблицы);

    Исключение

        Лог.Добавить(Вариант.Имя + ": ОШИБКА " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));

    КонецПопытки;

КонецЦикла;

Критерий: все варианты компонуются и выводят строки. Пустой результат за период без данных допустим, исключение означает дефект схемы. Чтение через СериализаторXDTO заодно ловит ту самую ошибку XDTO с <title>, только раньше и без обновления базы. По этому же выводу удобно смотреть время каждого варианта.

Тяжелые пакеты запросов мы профилируем тем же способом, но по частям: пакет режется по ;, каждая временная таблица замеряется отдельно. Так в отчете контроля данных нашлись соединения с табличными частями документов по неиндексированным полям. После замены их на индексированные временные таблицы за период отчет перестал идти 300 секунд.

Сводка и чеклист

Грабля Симптом Решение
Формат в поле и в оформлении варианта правка формата поля не видна убрать поле из правила варианта, дать ему свое правило
<appearance> не последним в поле схема не соответствует XSD порядок dataPath, field, title, valueType, appearance
Два знака у удельной величины строки не сходятся с итогом три знака полям, которые суммируются и умножаются
Ресурс по разным единицам итог по группе складывает штуки и часы КОЛИЧЕСТВО(Различные Единица) > 1 дает NULL
Ресурс в детальных записях колонка пуста во всех строках группировка или снятие с ресурсов
Нет userSettingID параметра нет в шапке отчета GUID у каждого параметра варианта
Нет use=Always у отбора «Не задано значение параметра» <use>Always</use> и пустая ветка в запросе
valueListAllowed у границы «Нельзя сравнивать поля неограниченной длины...» флаг только для параметров под В (&...)
Остатки/СрезПоследних с параметром периода «Несоответствие типов (Параметр номер "1")» физическая таблица
<title> без xsi:type «Исключение XDTO при чтении Template.xml» копировать соседний узел, сверять атрибуты
Правка .dcs на диске в базе старая схема F5 перед выгрузкой

Перед обновлением базы после правки отчета:

  1. Формат числа поменян и у поля набора, и в правилах всех вариантов.
  2. <appearance> последний в каждом блоке поля.
  3. У каждого ресурса проверено, складываются ли его значения по всем вариантам, где он выводится.
  4. У каждого параметра варианта есть userSettingID, у необязательных отборов use=Always.
  5. valueListAllowed=true только у параметров под В (&...).
  6. check_dcs_nodes.py и grep | uniq -c по <title> без замечаний.
  7. F5 на проекте.
  8. Каждый вариант скомпонован из файла с тестовым периодом.

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

Вступайте в нашу телеграмм-группу Инфостарт

СКД схема компоновки данных формат числа условное оформление ресурсы userSettingID valueListAllowed виртуальные таблицы Остатки СрезПоследних XDTO Template.dcs EDT отчеты

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Инструментарий разработчика Роли и права Запросы СКД Разработчик Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3 и 8.5: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

16500 руб.

02.09.2020    285452    1606    423    

1219

Инструментарий разработчика Рефакторинг и качество кода Разработчик 1С:Предприятие 8 Бесплатно (free)

Инструмент для тех, кто устал читать модули по 50 тысяч строк и искать ошибки глазами. MetaVision загружает выгруженные файлы конфигурации и за секунды строит графы функций, находит уязвимости и подсвечивает проблемы производительности. Ключевые возможности: Визуализация логики функций (графы условий, циклов, транзакций и вызовов). Статический аудит безопасности (RCE, SSRF, COM-инъекции, пароли в коде). Поиск проблем производительности (запросы в циклах, вложенные блокировки). Полнотекстовый поиск по всем модулям конфигурации. Статистика по объектам и функциям. Безопасность: Программа работает строго локально. Код вашей конфигурации не отправляется в интернет и не анализируется на сторонних серверах. Попробуйте MetaVision сегодня — узнайте, что скрывает ваш код.

20.04.2026    15490    1483    KHoroshulinAV    64    

95

Инструментарий разработчика СКД Разработчик 1С 8.3 Бесплатно (free)

В этой статье представлен ПовелительОтчетов — общий модуль-обёртка над объектной моделью СКД, который сокращает код в 3-4 раза и делает его читаемым.

29.01.2026    9418    454    shapa_pro    31    

73

СКД Разработчик 1С:Предприятие 8 Бесплатно (free)

Статья написана по результатам проведенного внутреннего обучающего вебинара для разработчиков ГК «СофтБаланс». Если осилить 25 000 знаков - задача для вас непосильная, где-то на бескрайних просторах интернета видео есть (или будет). Но здесь информация точнее. Разберем, чем запрос для СКД принципиально отличается от обычного запроса и как модифицируется в зависимости от настроек. Изучим «базовый рецепт» написания запроса для СКД, сформируем чек-лист. Полезно будет всем – от стажеров до тех. лидов. Всем, кто не снимает галку «автозаполнение» и пишет запросы для отчетов в консоли запросов – читать (вдумчиво) обязательно.

29.10.2025    26981    ovetgana    112    

117

СКД Разработчик 1С:Предприятие 8 Бесплатно (free)

Описан способ заполнения списка доступных значений для полей наборов данных и параметров в схеме компоновки данных для любых конфигураций (с использованием БСП или без).

01.07.2025    15751    krasnoshchekovpavel    7    

68

СКД Разработчик 1С:Предприятие 8 Бесплатно (free)

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

27.02.2025    19809    ovetgana    50    

93

Инструментарий разработчика Рефакторинг и качество кода Разработчик 1С:Предприятие 8 Бесплатно (free)

Расширяемый форматтер структуры модулей 1С. Умеет автоматически расставлять стандартные области и раскидывать по ним процедуры и функции модуля, оформлять стандартные комментарии к методам с помощью ИИ. Также умеет анализировать модуль - извлекать структуру вызовов, используемые поля и т.д. Реализован в виде расширения (.cfe). Можно использовать как платформу для обработки кода в своих задачах автоматизации разработки.

12.02.2025    18118    1109    wonderboy    50    

151

Рефакторинг и качество кода Разработчик Бесплатно (free)

SOLID – принципы проектирования программных структур (модулей). Акроним S.O.L.I.D. образован из первой буквы пяти принципов. Эти принципы делают код более гибким, упрощают разработку. Принято считать, что принципы SOLID применимы только в объектно-ориентированном программировании. Но их можно успешно использовать и в 1С. Расскажем о том, как разобраться в принципах SOLID и начать применять их при работе в 1С.

22.08.2024    24751    alex_sayan    48    

71
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 1146 16.10.26 17:37 Сейчас в теме
У кого-нить возникает такой вопрос: это предыдущие нейрослопщики под новым аккаунтом или их подражатели?
2. Konstmax13 17 19.10.26 13:11 Сейчас в теме
(1) Ни то, ни другое. Аккаунт один, статьи по живому проекту на БП КОРП, который ведём с начала лета. Агент помогает с текстом и кодом, это прямо сказано в первой статье серии. А грабли, цифры и решения наши: каждая из них стоила обновления тестовой базы, а то и дня работы. Если в статье есть ошибка по существу, покажите, исправлю.
Для отправки сообщения требуется регистрация/авторизация