Временный рассчет регистров в модуле проведенияПри проведении документа "задним числом" часто требуется знать, какие остатки были до его проведения (без учета последующих документов на временной оси). | | Автор статьи: romix | Редакторы: Последняя редакция №3 от 11.03.07 | История URL: http://kb.mista.ru/article.php?id=498 | |
Ключевые слова: УстановитьЗначениеФильтра, ИтогиАктуальны, ВременныйРасчет, РассчитатьРегистрыНа
Создаем объект типа Регистр
Чтобы получать остатки на определенный момент времени, нам потребуется объект типа "регистр".
рег=СоздатьОбъект("Регистр.Остатки");
Ставим фильтры
При наличии фильтров (если они необходимы) временные рассчеты идут быстрее
рег.УстановитьЗначениеФильтра("Фирма",ршФирма);
рег.УстановитьЗначениеФильтра("Склад",ршСклад);
Проверяем, актуальны ли итоги
Временные рассчеты необходимо заключать в проверку их необходимости: как правило, система производит временные расчеты длительное время, и они существенно затормаживают проведение документов. Но они не нужны, если проведение производится со сдвигом ТА (например, в монопольном режиме из меню Операции-Проведение документов), когда итоги актуальны, или оперативно (когда пользователи просто проводят документы "не задним числом"). Чтобы отличить ситуацию, когда итоги актуальны, испольуем одноименный метод:
Если ИтогиАктуальны()=0 Тогда //Проверяем необходимость временного рассчета регистров
КонецЕсли;
Включаем регистры во временный рассчет
Временный рассчет выполняется не для всех, а только для указанных регистров (точнее, объектов типа "регистр").
рег.ВременныйРасчет(1); //Включаем временный рассчет для регистра рег
Выполняем временный рассчет
РассчитатьРегистрыНа(ТекущийДокумент()); //рассчитываем итоги на документ
//Теперь итоги регистра содержат значения на позицию до документа
Получаем итоги из регистра
Для извлечения итогов можно использовать методы ВыбратьИтоги() - ПолучитьИтог().
А можно, например, выгрузить их из регистра в таблицу значений:
рег.УстановитьЗначениеФильтра("Товар",пТовар);
рег.ВыгрузитьИтоги(тз,1);
Все вместе
Процедура ОбработкаПроведения()
рег=СоздатьОбъект("Регистр.Остатки");
//Сначала ставим фильтры, чтобы временные расчеты шли быстрее
рег.УстановитьЗначениеФильтра("Фирма",ршФирма);
рег.УстановитьЗначениеФильтра("Склад",ршСклад);
Если ИтогиАктуальны()=0 Тогда //Неоперативное проведение (юзер что-то правит "задним числом")
Сообщить("Временный расчет регистров...");
рег.ВременныйРасчет(1);
РассчитатьРегистрыНа(ТекущийДокумент());
КонецЕсли;
//Теперь итоги регистра содержат значения на позицию до документа
//...
КонецПроцедуры
Другой способ получить итоги на указанный момент времени
Другим способом получить итоги на позицию документа является запрос.
Запрос можно выполнять за период, обозначенный не только датами, но и (как в данном примере) документами. Переменные ВыбФирма и ВыбСклад - должны содержать значения фирмы и склада, по которым произойдет извлечение остатка товаров из регистра. Функция НачОст получает в данном случае остаток на момент времени до текущего документа.
док=ТекущийДокумент();
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать)
|Период с док по док;
|Фирма = Регистр.Остатки.Фирма;
|Склад = Регистр.Остатки.Склад;
|Товар = Регистр.Остатки.Товар;
|Количество = Регистр.Остатки.Количество;
|Сумма = Регистр.Остатки.Сумма;
|Функция КоличествоНачОст = НачОст(Количество);
|Функция СуммаНачОст = НачОст(Сумма);
|Группировка Товар без упорядочивания без групп;
|Условие(Фирма = ВыбФирма);
|Условие(Склад = ВыбСклад);
|"//}}ЗАПРОС
;
// Если ошибка в запросе, то выход из процедуры
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
Пока Запрос.Группировка(1) = 1 Цикл
Сообщить("Товар: "+Запрос.Товар);
Сообщить("КоличествоНачОст: "+Запрос.КоличествоНачОст);
Сообщить("СуммаНачОст: "+Запрос.СуммаНачОст);
КонецЦикла;
|