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