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