При работе с отчетами на системе компоновки данных (СКД) на платформе 1С:Предприятие 8.3, особенно когда мы используем виртуальные таблицы, такие как ОстаткиИОбороты регистра бухгалтерии, можем столкнуться с неожиданной проблемой – дублированием строк в детальных записях отчета. Эта ситуация вызывает затруднения, поскольку некорректно отображает данные и мешает правильному анализу.
В этой статье мы подробно рассмотрим причины такого дублирования и предложим несколько проверенных решений, начиная от самого неочевидного, которое помогло автору исходной темы, до более общих диагностических подходов.
Часто проблема дублирования строк в отчете СКД, особенно с использованием виртуальной таблицы ОстаткиИОбороты, кроется в неожиданном месте – настройках оформления отчета. Авторы отчетов и пользователи могут столкнуться с тем, что, несмотря на корректный запрос и правильно настроенные роли полей, детальные записи отчета все равно задваиваются. Выясняется, что виной всему может быть одна неочевидная галочка.
Нам необходимо зайти в настройки отчета, найти раздел, отвечающий за оформление или другие настройки (обычно это вкладка "Настройки" или "Прочие настройки", в зависимости от конфигурации отчета и версии платформы). Среди этих настроек мы ищем параметр, который управляет режимом отображения итогов. Он может называться "Позиция итогов", "Расположение итогов" или аналогично. Часто встречается опция "Сверху и снизу".
Суть проблемы: Когда мы устанавливаем режим отображения итогов "Сверху и снизу", система компоновки данных может генерировать дополнительные внутренние запросы или выполнять агрегации, которые, в свою очередь, приводят к повторному выбору детальных строк для каждой группы или для отчета в целом. Это происходит потому, что СКД пытается подготовить данные для отображения итогов как перед группой, так и после нее, что может вызвать побочный эффект дублирования в детальных записях, даже если нам нужны только детали.
Вместо режима "Сверху и снизу" нам следует выбрать один из следующих вариантов:
После изменения этой настройки и переформирования отчета, во многих случаях дублирование детальных строк исчезает. Это решение оказалось эффективным для автора оригинальной темы и других пользователей.
Виртуальная таблица ОстаткиИОбороты регистра бухгалтерии (или других регистров) имеет свои особенности, которые могут влиять на количество возвращаемых записей и в некоторых случаях создавать иллюзию дублирования, если мы не учитываем ее логику работы.
Важно понимать, что таблица ОстаткиИОбороты по умолчанию включает в себя данные как на начало, так и на конец указанного периода. Для этого она использует поле ПериодСекунда, которое может возвращать записи на первую секунду начала периода и на последнюю секунду конца периода, даже если в эти моменты не было непосредственных движений.
Диагностика: Чтобы проверить, является ли это причиной дублирования, мы можем временно вывести поле ПериодСекунда в отчет. Если мы увидим, что для одного и того же регистратора или набора измерений присутствуют две записи с разными значениями ПериодСекунда (например, одна на 00:00:00 и другая на 23:59:59 для одного и того же дня), то это подтверждает, что ОстаткиИОбороты возвращает данные для обоих временных срезов.
Решение:
&КонецПериода в СКД, он часто неявно приводится к концу дня (например, КонецПериода(&КонецПериода,"День")). Попробуйте изменить это приведение или вовсе убрать его для параметра КонецПериода в СКД, чтобы получить данные только по движениям, если это соответствует нашей задаче.МетодДополнения в настройках виртуальной таблицы в СКД, чтобы управлять тем, как система дополняет данные для обеспечения корректности остатков и оборотов.При использовании ОстаткиИОбороты, если мы выбираем поле Регистратор в запросе, СКД использует его для детализации движений. Однако, если мы выбираем Регистратор, а затем не выводим его в отчет или используем его в сложных левых соединениях с другими таблицами по документам, это может привести к искажению расчетов остатков. СКД может "думать", что нужно детализировать каждую строку по регистратору, даже если нам важны только общие обороты.
Решение:
Регистратор не нужен для детального вывода, попробуйте удалить его из списка выбранных полей в запросе СКД, если это не влияет на логику отчета.Регистратор необходим для связи с другими таблицами, но не для прямого вывода, мы можем пометить его как "Обязательное" поле в ролях полей набора данных СКД. Это гарантирует, что компоновщик макета СКД не удалит это поле из запроса, даже если оно не используется напрямую для отображения, но является важным для корректных расчетов или связей.
ВЫБРАТЬ
ВЫБОР КОГДА ЕПСБУОстаткиИОбороты.Регистратор = НЕОПРЕДЕЛЕНО ТОГДА NULL ИНАЧЕ ЕПСБУОстаткиИОбороты.Регистратор КОНЕЦ КАК Регистратор,
ЕПСБУОстаткиИОбороты.ПериодСекунда,
ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(ЕПСБУОстаткиИОбороты.Регистратор) = ТИП(Документ.ЗаявкаНаКассовыйРасход) ТОГДА "ПЛАТЕЖНОЕ ПОРУЧЕНИЕ" ИНАЧЕ "НАКЛАДНАЯ" КОНЕЦ КАК ВидДокумента,
ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(ЕПСБУОстаткиИОбороты.Регистратор) = ТИП(Документ.ЗаявкаНаКассовыйРасход) ТОГДА ЕПСБУОстаткиИОбороты.Регистратор.НомерПодтверждающегоДокумента ИНАЧЕ ЕПСБУОстаткиИОбороты.Регистратор.НомерПервичногоДокумента КОНЕЦ КАК Номер,
ВЫБОР КОГДА ТИПЗНАЧЕНИЯ(ЕПСБУОстаткиИОбороты.Регистратор) = ТИП(Документ.ЗаявкаНаКассовыйРасход) ТОГДА ЕПСБУОстаткиИОбороты.Регистратор.ДатаПодтверждающегоДокумента ИНАЧЕ ЕПСБУОстаткиИОбороты.Регистратор.ДатаПервичногоДокумента КОНЕЦ КАК Дата,
ЕПСБУОстаткиИОбороты.КВД,
ЕПСБУОстаткиИОбороты.КБК,
ЕПСБУОстаткиИОбороты.СуммаОборотДт,
ЕПСБУОстаткиИОбороты.СуммаОборотКт,
ЕПСБУОстаткиИОбороты.СуммаКонечныйОстаток,
ЕПСБУОстаткиИОбороты.Субконто3 КАК Договор
ИЗ
РегистрБухгалтерии.ЕПСБУ.ОстаткиИОбороты(
&НачалоПериода,
&КонецПериода,
Авто,
Движения,
Счет = &Счет,
,
Субконто2 = &Контрагент И Субконто3 = &Договор
) КАК ЕПСБУОстаткиИОбороты
Настройки ролей полей в СКД играют ключевую роль в том, как компоновщик данных обрабатывает и агрегирует информацию. Некорректное присвоение ролей может привести к неверной группировке, агрегации или, как в нашем случае, к дублированию строк.
Мы часто используем поля, такие как Регистратор и ПериодСекунда, для детализации движений. Важно правильно задать их роли и порядок в свойствах набора данных СКД, на вкладке "Роли полей".
Рекомендация: Если мы хотим сначала группировать по регистратору, а затем по периоду (секунде), то следует установить:
Регистратор: Порядок 1 (т.е., это будет первое поле для детализации или группировки).ПериодСекунда: Порядок 2 (следующее поле после регистратора).Если мы поменяем порядок (например, ПериодСекунда 1, Регистратор 2), это может привести к тому, что система будет создавать отдельные группы или детальные записи для каждой секунды, внутри которой уже будет детализация по регистраторам, что может визуально выглядеть как дублирование, если ПериодСекунда не выведена в отчет.
Для некоторых полей, которые не используются для группировки или агрегации, но присутствуют в запросе, может быть установлена роль "Дополнительное поле" (или "Доп").
Предостережение: Мы должны быть осторожны при установке роли "Дополнительное" для ключевых полей, таких как Регистратор. Если Регистратор используется для вычисляемых полей (как в нашем примере ВидДокумента, Номер, Дата) или для связей, но при этом ему присвоена роль "Дополнительное", СКД может неверно обрабатывать его, что также может способствовать дублированию. Постарайтесь не использовать роль "Дополнительное" для полей, участвующих в логике формирования данных.
Дублирование строк также может возникать, когда в одном из ключевых полей, по которому СКД выполняет группировку или детализацию, присутствуют значения НЕОПРЕДЕЛЕНО (NULL). В запросе автора темы мы видим использование конструкции ВЫБОР КОГДА ЕПСБУОстаткиИОбороты.Регистратор = НЕОПРЕДЕЛЕНО ТОГДА NULL ИНАЧЕ .... Это может стать источником проблем.
СКД по-разному обрабатывает строки, где ключевое поле имеет значение NULL. Такие строки могут быть сгруппированы отдельно или рассматриваться как уникальные, что, в свою очередь, может привести к появлению дополнительных, внешне одинаковых записей в отчете, если по другим полям они идентичны.
Мы можем явно обрабатывать значения НЕОПРЕДЕЛЕНО в запросе, чтобы СКД воспринимала их более предсказуемо:
ЕСТЬNULL() для замены НЕОПРЕДЕЛЕНО на пустую ссылку, пустую строку или какое-либо специальное значение-заполнитель, если это допустимо по логике отчета.
ВЫБРАТЬ
ЕСТЬNULL(ЕПСБУОстаткиИОбороты.Регистратор, ЗНАЧЕНИЕ(Документ.Пустой)) КАК Регистратор,
// ... остальные поля
Или для строкового представления:
ВЫБРАТЬ
ВЫБОР КОГДА ЕПСБУОстаткиИОбороты.Регистратор = НЕОПРЕДЕЛЕНО ТОГДА "НЕОПРЕДЕЛЕННЫЙ ДОКУМЕНТ" ИНАЧЕ ЕПСБУОстаткиИОбороты.Регистратор КОНЕЦ КАК Регистратор,
// ... остальные поля
НЕОПРЕДЕЛЕНО в поле Регистратор не несут ценности для отчета, мы можем исключить их с помощью фильтрации в запросе или на уровне СКД.
ИЗ
// ...
ГДЕ
ЕПСБУОстаткиИОбороты.Регистратор <> НЕОПРЕДЕЛЕНО
Помимо перечисленных, существуют и другие, менее распространенные, но все же возможные причины дублирования строк в отчетах СКД. Мы должны рассмотреть их, если основные методы не помогли:
Если наш запрос использует сложные конструкции с временными таблицами, множественными соединениями (особенно левыми ЛЕВОЕ СОЕДИНЕНИЕ), и выборка из одной и той же таблицы или поля происходит несколько раз без должной агрегации или связывания, это может породить дубликаты. Тщательно проверяйте условия соединений и убедитесь, что каждая запись из основной таблицы не сопоставляется с несколькими записями из присоединенной, если это не предусмотрено логикой.
Совет: Используйте агрегатные функции, такие как МАКСИМУМ(), МИНИМУМ(), СУММА(), ГРУППИРОВАТЬ ПО, если нам нужно схлопнуть повторяющиеся записи до одной, соответствующей нашим критериям.
Мы можем попробовать добавить ключевое слово РАЗЛИЧНЫЕ после ВЫБРАТЬ в запросе. Однако, как показал опыт автора темы, в СКД это не всегда помогает решить проблему дублирования, так как СКД может добавлять свои собственные поля для группировки или агрегации, делая каждую строку "различной" на внутреннем уровне, даже если визуально они кажутся одинаковыми.
ВЫБРАТЬ РАЗЛИЧНЫЕ
// ... наши поля
При включенном флажке "Автозаполнение" в настройках полей схемы СКД, система может автоматически добавлять все доступные поля компоновки данных, независимо от их явного выбора в запросе. Это может привести к дублированию полей в параметрах отбора или к избыточной детализации, что потенциально вызывает дублирование строк. Рекомендуется отключать автозаполнение и явно указывать все необходимые поля на закладке "Компоновка данных".
В редких случаях дублирование данных может быть связано с некорректной работой кеша 1С:Предприятия. Если вы подозреваете эту причину, мы можем попробовать очистить кеш конфигурации или перезапустить клиентское приложение.
Для глубокого анализа причин дублирования мы можем использовать процедуру ПриКомпоновкеДанных в модуле отчета. В этой процедуре мы можем вывести скомпонованный отчет в таблицу значений или просмотреть сформированный запрос, который СКД отправляет в базу данных. Это позволит нам увидеть, какие именно данные и в каком виде СКД получает перед выводом отчета, и на каком этапе возникает дублирование.
Процедура ПриКомпоновкеДанных(ДокументРезультат, СтандартнаяОбработка)
// Пример: Вывести данные в таблицу значений для отладки
// Эта процедура требует дополнительного кода для корректной работы,
// но позволяет получить доступ к данным, которые СКД собирается вывести.
// Обычно для отладки можно использовать Объект.ПолучитьМакетКомпоновкиДанных() и КомпоновщикМакета.Скомпоновать().
КонецПроцедуры
В заключение, проблема дублирования строк в отчете СКД по оборотам может иметь несколько причин. Начните с проверки настроек оформления отчета, как это помогло автору темы. Если это не решит проблему, последовательно пройдите по другим диагностическим шагам, анализируя поведение виртуальной таблицы ОстаткиИОбороты, настройки ролей полей и обработку неопределенных значений. В большинстве случаев тщательный анализ и поэтапное исключение потенциальных проблемных мест позволят нам найти и устранить источник дублирования.