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