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