Почему в регистре накопления нет таблицы ОстаткиИОбороты и как правильно работать с границами периода?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе на платформу «1С:Предприятие 8» разработчики часто сталкиваются с ситуацией, когда в конструкторе запросов или в дереве метаданных для регистра накопления отсутствуют привычные виртуальные таблицы. Например, вместо ожидаемой таблицы ОстаткиИОбороты доступны только Обороты. Разберем причины такого поведения платформы, выясним архитектурные различия между регистрами и детально рассмотрим правила работы с границами периодов в запросах.

Причина отсутствия виртуальной таблицы ОстаткиИОбороты

Проанализируем устройство регистров накопления в платформе 1С. При создании регистра в конфигураторе разработчик обязательно задает свойство Вид регистра. Оно определяет, какие физические таблицы создаются в СУБД и какие виртуальные таблицы платформа предоставляет для работы с данными:

  1. Регистр с видом «Остатки». В таком регистре движения всегда имеют признак направления: Приход или Расход. Платформа хранит не только записи движений, но и физическую таблицу итогов, что позволяет рассчитывать сальдо на любую точку времени. Для такого регистра доступны три виртуальные таблицы: Остатки, Обороты и ОстаткиИОбороты.
  2. Регистр с видом «Обороты». Данный регистр предназначен исключительно для накопления объемов (например, объемы продаж, начисленные бонусы, затраты). Записи не имеют признака прихода или расхода. В базе формируется агрегированная таблица оборотов за интервалы времени (как правило, за месяц). В оборотном регистре понятие начального и конечного остатка отсутствует в принципе, поэтому платформа предоставляет для него единственную виртуальную таблицу — Обороты.

Если для регистра накопления недоступна таблица ОстаткиИОбороты, значит, в метаданных ошибочно выбран вид регистра Обороты вместо Остатки. Для исправления ситуации достаточно изменить свойство регистра в конфигураторе.

Особенности передачи границ периода в виртуальные таблицы

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

Рассмотрим, как платформа обрабатывает обычное значение типа Дата:

  1. Виртуальная таблица Остатки. Параметр Период вычисляет остатки строго на начало указанной секунды. Если передать значение даты конца дня, например КонецДня(&Дата) (соответствует времени 23:59:59), то документы и движения, проведенные ровно в эту секунду, в расчет остатка не попадут.
  2. Виртуальные таблицы Обороты и ОстаткиИОбороты. Параметр КонецПериода при передаче значения типа Дата работает иначе: он автоматически включает указанную секунду в расчет.

Выясним, как гарантированно получить остаток с учетом всех движений выбранной секунды или дня. Для этого в платформе 1С предусмотрен специальный объект Граница.

Посмотрим на пример установки параметров для получения остатков на конец дня:


ГраницаКонца = Новый Граница(КонецДня(ТекущаяДата()), ВидГраницы.Включая);

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	ОстаткиНоменклатурыОстатки.Номенклатура,
|	ОстаткиНоменклатурыОстатки.Склад,
|	ОстаткиНоменклатурыОстатки.ВНаличииОстаток КАК Остаток
|ИЗ
|	РегистрНакопления.ОстаткиНоменклатуры.Остатки(&Период, Склад = &Склад) КАК ОстаткиНоменклатурыОстатки";

Запрос.УстановитьПараметр("Период", ГраницаКонца);
Запрос.УстановитьПараметр("Склад", ВыбранныйСклад);

Альтернативный способ для таблицы Остатки без использования объекта Граница — сместить границу на начало следующей секунды или следующего дня (например, передать дату КонецДня(&Дата) + 1, что соответствует времени 00:00:00 следующего дня).

Пример запроса к таблице ОстаткиИОбороты

Разберем типовой пример запроса для получения начальных остатков, прихода, расхода и конечных остатков за выбранный интервал времени. Передачу условий фильтрации всегда следует осуществлять в параметрах самой виртуальной таблицы, а не в предложении ГДЕ, чтобы СУБД отсекала лишние данные еще на этапе выборки.


Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|	ОстаткиНоменклатурыОстаткиИОбороты.Номенклатура КАК Номенклатура,
|	ОстаткиНоменклатурыОстаткиИОбороты.Склад КАК Склад,
|	ОстаткиНоменклатурыОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
|	ОстаткиНоменклатурыОстаткиИОбороты.КоличествоПриход КАК Приход,
|	ОстаткиНоменклатурыОстаткиИОбороты.КоличествоРасход КАК Расход,
|	ОстаткиНоменклатурыОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
|ИЗ
|	РегистрНакопления.ОстаткиНоменклатуры.ОстаткиИОбороты(
|		&НачалоПериода,
|		&КонецПериода,
|		,
|		,
|		Склад = &Склад) КАК ОстаткиНоменклатурыОстаткиИОбороты";

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ВыбНачалоПериода));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ВыбКонецПериода));
Запрос.УстановитьПараметр("Склад", ВыбранныйСклад);

РезультатЗапроса = Запрос.Выполнить();

Обратим внимание: в таблице ОстаткиИОбороты значение КонецДня(...) включает последнюю секунду интервала без дополнительных ухищрений с объектом Граница.

Контроль остатков при проведении документов

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

  1. Проверка перед формированием движений. Для получения остатков строго до проведения документа в параметр Период виртуальной таблицы Остатки передается метод МоментВремени() документа. Он исключает сам проводимый документ, но включает все ранее проведенные документы в этой же секунде.
  2. Проверка после формирования движений. Если движения документа уже записаны в базу данных и требуется проконтролировать отсутствие отрицательных остатков, используется конструкция с включением текущего документа: Новый Граница(МоментВремени(), ВидГраницы.Включая).

Важное правило производительности: если в отчете или алгоритме требуются только конечные остатки или только обороты за период, не используйте таблицу ОстаткиИОбороты. Формирование таблицы ОстаткиИОбороты требует сложных соединений реальных таблиц движений и итогов. Для изолированных задач всегда обращайтесь напрямую к специализированным таблицам Остатки или Обороты — это существенно ускоряет выполнение запросов к СУБД.

← На главную