Часто пользователи и технические специалисты сталкиваются с загадочным поведением типовых отчетов в 1С: при формировании отчета по всей организации данные по конкретному объекту (например, основному средству) выглядят неполными или некорректными, но стоит установить жесткий отбор по этому самому объекту — и цифры магическим образом «появляются». В данной статье мы подробно разберем, почему так происходит, и научимся диагностировать подобные ситуации на примере отчета Ведомость амортизации ОС в конфигурации 1С:Бухгалтерия предприятия 3.0.
Для начала проанализируем, как строится большинство типовых отчетов. В основе лежит Система компоновки данных (СКД), которая динамически формирует текст SQL-запроса к базе данных. Основная особенность СКД заключается в том, что она оптимизирует запрос в зависимости от установленных пользователем настроек и отборов.
Рассмотрим механизм работы виртуальных таблиц. Когда мы формируем отчет по регистру накопления (например, СтоимостьОС.Обороты), система может накладывать условия двумя способами:
Если в регистрах накопления по одному и тому же объекту существуют записи с незначительными различиями в измерениях (разные подразделения, разные материально-ответственные лица или даже лишние пробелы в инвентарных номерах), то без жесткого отбора СКД может «разнести» данные по разным строкам. При наложении же отбора непосредственно в параметры виртуальной таблицы, механизм агрегации может сработать иначе, визуально «схлопнув» проблему.
Чтобы понять, «откуда растут ноги», нам необходимо получить финальный текст запроса, который отправляет СКД в СУБД. Простой просмотр схемы компоновки в конфигураторе мало что даст, так как текст запроса там содержит расширения языка запросов 1С (фигурные скобки {}).
Воспользуемся консолью запросов или специальными инструментами отладки отчетов. Нам нужно сравнить два варианта запроса:
Проанализируем ситуацию, описанную в сообщениях форума. Если при отсутствии отбора по ОС в результат запроса попадают две строки (одна полная, другая пустая в части сумм увеличения стоимости), значит, в регистрах есть «мусорные» или противоречивые записи. Код запроса в консоли может выглядеть примерно так:
ВЫБРАТЬ
СтоимостьОСОбороты.ОсновноеСредство КАК ОС,
СтоимостьОСОбороты.СтоимостьОборот КАК УвеличениеСтоимости,
СтоимостьОСОбороты.Подразделение КАК Подразделение
ИЗ
РегистрНакопления.СтоимостьОС.Обороты(&НачалоПериода, &КонецПериода, , Организация = &Организация) КАК СтоимостьОСОбороты
Если выполнить такой запрос, мы можем увидеть, что для одного ОсновногоСредства записи разделились, например, из-за того, что в одной строке Подразделение заполнено, а в другой — нет.
Выясним причину «раздвоения» строк. Отчет Ведомость амортизации ОС опирается на данные регистров накопления Стоимость ОС и Амортизация ОС. Основными измерениями здесь являются:
Разберем пример с «Трактором». Если документ Принятие к учету ОС сделал запись по подразделению «Автопарк», а последующий документ Модернизация ОС (который и дает «Увеличение стоимости») был по ошибке проведен по «Центральному складу», то в регистре накопления появятся две разные ветки данных.
При формировании общего отчета без детализации по подразделениям СКД может попытаться сгруппировать данные только по ОС. Но если в настройках отчета (или во вложенных запросах схемы) используются соединения с другими таблицами (например, с регистром сведений Местонахождение ОС), то наличие разных подразделений в оборотах приведет к тому, что суммы «разойдутся» по разным виртуальным группировкам. Одна строка будет содержать начальную стоимость, а другая — только сумму увеличения, причем вторая может не попасть в итоговую выдачу из-за условий соединения.
Проанализируем еще одну специфическую причину, характерную для Бухгалтерии предприятия КОРП 3.0. Отчет часто соединяет таблицу оборотов с регистром сведений СчетаБухгалтерскогоУчетаОС. Это необходимо для корректного отображения счетов 01 и 02 в аналитике.
Если для конкретного ОС в этом регистре записи отсутствуют, повреждены или имеют некорректный период действия, то при выполнении ЛЕВОГО СОЕДИНЕНИЯ в запросе СКД данные могут дублироваться или обрезаться. Рассмотрим, как это выглядит в коде:
ВЫБРАТЬ
Обороты.ОсновноеСредство,
СчетаУчета.СчетУчета,
Обороты.СтоимостьОборот
ИЗ
РегистрНакопления.СтоимостьОС.Обороты(...) КАК Обороты
ЛЕВОЕ СОЕДИНЕНИЕ
РегистрСведений.СчетаБухгалтерскогоУчетаОС.СрезПоследних(...) КАК СчетаУчета
ПО
Обороты.ОсновноеСредство = СчетаУчета.ОсновноеСредство
Если по какой-то причине СрезПоследних выдает две записи на одну дату (что иногда случается при программных ошибках или некорректном переносе данных), то каждая сумма из оборотов будет умножена на количество этих записей, либо, наоборот, отфильтрована, если используется ВНУТРЕННЕЕ СОЕДИНЕНИЕ (хотя в типовых обычно левое).
Для окончательного решения проблемы рекомендуем выполнить следующие действия:
Таким образом, «магия» исчезновения данных при смене отборов почти всегда объясняется тем, что при детальном отборе СКД работает с узким набором данных в виртуальной таблице, игнорируя несоответствия в измерениях, которые «всплывают» при попытке построить отчет по массиву данных всей организации.