При работе с временными регистрами в платформе 1С 7.7 разработчики часто сталкиваются с неожиданным обслуживанием параметров метода СводныйОстаток(). Разберем типичную ситуацию, когда при детальном отборе по всем измерениям остаток товара присутствуют, а при разворачивании сводного итога без указания одного из измерений (например, склада) метод возвращает нулевое значение.
Рассмотрим пример из практики разработки в конфигурации «Торговля и Склад» (1С 7.7). В регистр остатков добавлено новое измерение Серия. Порядок измерений в регистре следующий: Фирма, Номенклатура, Серия, Склад, ЦенаПродажи.
Выполним четыре последовательных вызова метода СводныйОстаток() в отладчике:
// 1. Не указаны склад и серия (расчет по всей фирме и всем сериям)
Остаток1 = ВремОстаткиТМЦ.СводныйОстаток(ТекФирма, ТекНоменклатура, , , , "Количество"); // Результат: 266
// 2. Указаны все измерения (фирма, номенклатура, серия и склад)
Остаток2 = ВремОстаткиТМЦ.СводныйОстаток(ТекФирма, ТекНоменклатура, ТекСерия, Склад, , "Количество"); // Результат: 1
// 3. Указан склад, но серия пропущена
Остаток3 = ВремОстаткиТМЦ.СводныйОстаток(ТекФирма, ТекНоменклатура, , Склад, , "Количество"); // Результат: 6
// 4. Указана серия, но пропущен склад
Остаток4 = ВремОстаткиТМЦ.СводныйОстаток(ТекФирма, ТекНоменклатура, ТекСерия, , , "Количество"); // Результат: 0
Возникает логичный вопрос: почему при явном наличии 1 штуки товара данной серии на конкретном складе (вызов №2), сводный расчет по той же серии без указания склада (вызов №4) дает результат 0?
Проанализируем математику работы метода СводныйОстаток(). Когда в параметрах метода пропускается конкретное измерение (оставляется пустая позиция между запятыми), платформа 1С 7.7 производит свёртку и суммирует остатки по всем существующим значениям этого пропущенного измерения в разрезе заданных фильтров.
В приведенном примере для вызова №4 произошли следующие вычисления:
Склад1 по заданной серии числится остаток в размере +1 шт.Склад2 из-за ошибки учета, оперативного списания или пересортицы образовался отрицательный остаток по этой же серии в размере -1 шт.+1 + (-1) = 0.Таким образом, нулевой результат — это не сбой платформы и не ошибка вызова метода, а следствие компенсации положительного остатка на одном складе отрицательным остатком на другом.
Для предотвращения и корректного обнаружения подобных ситуаций рекомендуется применять следующие подходы:
Чтобы увидеть реальную картину по каждому складу и выявить «минусы», используйте метод ВыгрузитьИтоги(). Это позволит наглядно детально проанализировать разрезы учета:
ТабОстатков = СоздатьОбъект("ТаблицаЗначений");
// Выгружаем итоги регистра с фильтрацией по номенклатуре и серии
ВремОстаткиТМЦ.ВыгрузитьИтоги(ТабОстатков, 1, 1);
// Теперь в ТабОстатков видны остатки по всем складам отдельно
ТабОстатков.ВыбратьСтроки();
Пока ТабОстатков.ПолучитьСтроку() = 1 Цикл
Сообщить("Склад: " + ТабОстатков.Склад + " | Остаток: " + ТабОстатков.Количество);
КонецЦикла;
При добавлении новых измерений в существующие регистры остатков обязательно проверяйте их свойства в Конфигураторе. Для измерения Серия должно быть включено свойство «Отбор итогов». Это обеспечит корректное построение индексов таблиц итогов и ускорит выполнение свернутых расчетов.
Если для бизнес-логики требуется учитывать только положительные фактические остатки, вместо прямого метода СводныйОстаток() используйте объект Запрос с последующей фильтрацией или обработкой условий в цикле выборки.