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