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