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