При разработке и доработке конфигураций на платформе 1С:Предприятие 7.7 разработчики нередко сталкиваются с ситуацией, когда при обращении к регистру остатков метод Остаток() возвращает нулевые значения, хотя в базе данных гарантированно есть движения и остатки. Рассмотрим причины такого поведения, разберем порядок передачи параметров в методы регистров и изучим альтернативные способы извлечения ресурсов.
Проанализируем типовую ситуацию. Предположим, выполняется обход справочника номенклатуры и для каждой позиции запрашивается остаток на складе:
Количество = РегОстаткиТМЦ.Остаток(ТекНоменклатура, ВыбСклад, , , , "Количество");
Если данный вызов возвращает 0, выясним причину. Метод Остаток() ожидает передачу значений измерений в строгом порядке их следования в структуре метаданных регистра (слева направо).
Если в конфигураторе первым измерением регистра ОстаткиТМЦ назначена Фирма, а вторым — Номенклатура, то при вызове метода 1С сопоставляет первый переданный параметр (ТекНоменклатура) с измерением Фирма. Так как элемент справочника номенклатуры не соответствует типу измерения Фирма, система не находит записей и возвращает 0.
Разберем первый способ исправления. Если остаток требуется получить в разрезе конкретной организации (фирмы), передадим ссылку на нее первым параметром, соблюдая порядок измерений регистра:
// Передаем измерения по порядку: Фирма, Номенклатура, Склад...
Количество = РегОстаткиТМЦ.Остаток(ВыбФирма, ТекНоменклатура, ВыбСклад, , , "Количество");
Сообщить("Остаток: " + Количество);
Посмотрим на ситуацию, когда остаток необходимо получить без учета первого измерения (например, общий остаток по всем фирмам сразу) или если нужно пропустить промежуточные измерения. Для этого в платформе 1С 7.7 предусмотрен метод СводныйОстаток().
В методе СводныйОстаток() разрешается оставлять не заполненными любые параметры измерений, в том числе и первое:
// Первое измерение (Фирма) пропускаем, оставляя запятую
Количество = РегОстаткиТМЦ.СводныйОстаток(, ТекНоменклатура, ВыбСклад, , , "Количество");
Сообщить("Сводный остаток по всем фирмам: " + Количество);
Рассмотрим метод Остатки(). В отличие от метода Остаток(), который возвращает числовое значение одного конкретного ресурса (указанного строкой в последнем параметре), метод Остатки() рассчитывает сразу все ресурсы регистра по заданной комбинации измерений.
После вызова метода значения ресурсов считываются как свойства самого объекта регистра. Разберем по шагам:
Остатки() и передаем измерения по порядку без пропусков.
РегОстаткиТМЦ.Остатки(ВыбФирма, ТекНоменклатура, ВыбСклад);
ТекКоличество = РегОстаткиТМЦ.Количество;
ТекСтоимость = РегОстаткиТМЦ.Стоимость;
Сообщить("Количество: " + ТекКоличество + ", Сумма: " + ТекСтоимость);
Если же требуется рассчитать все ресурсы одновременно, но с пропуском отдельных измерений, используем метод СводныеОстатки():
РегОстаткиТМЦ.СводныеОстатки(, ТекНоменклатура, ВыбСклад);
ТекКоличество = РегОстаткиТМЦ.Количество;
ТекСтоимость = РегОстаткиТМЦ.Стоимость;
Проанализируем дополнительные нюансы, которые необходимо учитывать при работе с регистрами:
Остаток(), СводныйОстаток(), Остатки(), СводныеОстатки()) возвращают срез на текущую точку актуальности информационной базы. Если необходимо получить остаток на прошлую дату или документ, перед вызовом методов активируем временный расчет:
РегОстаткиТМЦ.ВременныйРасчет(1);
РассчитатьРегистрыНа(НужнаяДата);
// Либо: РассчитатьРегистрыПо(ТекущийДокумент);
Остаток() или СводныйОстаток() внутри цикла обхода справочника приводит к отдельному запросу к базе данных на каждой итерации. При больших объемах данных это замедляет выполнение обработки. В таких сценариях эффективнее использовать объект Запрос либо предварительно выгружать срез регистра в ТаблицаЗначений с помощью метода ВыгрузитьИтоги().