Как программно проверить необходимость открытия периода итогов при 5-дневной периодичности в 1С 7.7

Программист 1С v7.7 Управленческий учет
← На главную

В платформе 1С:Предприятие 7.7 стандартная периодичность хранения итогов по регистрам обычно составляет один месяц. Однако в высоконагруженных базах с интенсивной работой "задним числом" программисты часто переходят на периодичность в 5 дней. Это позволяет значительно ускорить получение остатков, так как системе приходится пересчитывать движения документов за гораздо меньший интервал времени. Рассмотрим подробнее, как штатно определить, наступил ли момент для открытия нового периода, и как автоматизировать этот процесс.

Особенности хранения итогов с периодичностью 5 дней

Прежде чем переходить к коду, проанализируем, как именно 1С 7.7 разбивает календарный месяц на пятидневки. Логика платформы не подразумевает простое деление года на отрезки по 5 дней. Она жестко привязывается к числам месяца:

  1. 1-й период: с 1 по 5 число.
  2. 2-й период: с 6 по 10 число.
  3. 3-й период: с 11 по 15 число.
  4. 4-й период: с 16 по 20 число.
  5. 5-й период: с 21 по 25 число.
  6. 6-й период: с 26 числа по последнее число месяца (30, 31 или 28/29 для февраля).

Как мы видим, последний период месяца может составлять от 3 до 6 дней. Это критически важно учитывать при написании алгоритмов проверки, так как обычное прибавление пяти дней к дате начала периода даст неверный результат на стыке месяцев.

Алгоритм расчета границы текущего периода

Для того чтобы понять, нужно ли открывать период, нам необходимо вычислить дату окончания текущего пятидневного интервала, в котором находится Точка Актуальности (ТА). Разберем математическую формулу, которая позволяет это сделать штатно.

Рассмотрим пример функции, которая вычисляет конец периода для произвольной даты:


Функция ПолучитьКонецПериодаИтогов(ВхДата)
    ДеньМесяца = ДатаЧисло(ВхДата);
    Если ДеньМесяца > 25 Тогда
        // Последний период месяца всегда заканчивается в последний день месяца
        Возврат КонМесяца(ВхДата);
    Иначе
        // Вычисляем конец текущей пятидневки
        // Формула: (Цел((День - 1) / 5) * 5) + 5
        НомерДня = (Цел((ДеньМесяца - 1) / 5) * 5) + 5;
        Возврат Дата(ДатаГод(ВхДата), ДатаМесяц(ВхДата), НомерДня);
    КонецЕсли;
КонецФункции

Проанализируем работу этой формулы. Если мы передадим 12-е число, то Цел((12-1)/5) даст 2. Умножаем на 5, получаем 10, и прибавляем 5 — итог 15-е число. Это корректно. Если же дата больше 25, срабатывает условие КонМесяца, что избавляет нас от проблем с разной длительностью месяцев.

Штатная проверка и автоматическое открытие периода

Теперь объединим расчет границы периода с процедурой проверки системной даты и точки актуальности. Этот код целесообразно разместить в процедуре ПриНачалеРаботыСистемы в Глобальном модуле, чтобы система автоматически предлагала открыть период при входе первого пользователя.


Процедура ПроверитьОткрытиеПериода()
    ДатаТА = ПолучитьДатуТА();
    КонецПериодаТА = ПолучитьКонецПериодаИтогов(ДатаТА);
    
    // Если рабочая дата вышла за пределы рассчитанного периода ТА
    Если РабочаяДата() > КонецПериодаТА Тогда
        Если МонопольныйРежим() = 1 Тогда
            Сообщить("Выполняется автоматическое открытие периода итогов...");
            // Устанавливаем ТА на следующий день после окончания периода 
            // или на рабочую дату
            НоваяДатаТА = Макс(РабочаяДата(), КонецПериодаТА + 1);
            УстановитьТАНа(НоваяДатаТА);
            Сообщить("Новый период успешно открыт. Текущая ТА: " + НоваяДатаТА);
        Иначе
            Предупреждение("Необходимо открыть период итогов! 
            |Запустите программу в монопольном режиме для выполнения этой операции.");
            // В зависимости от политики безопасности можно завершить работу:
            // СтатусВозврата(0); Возврат;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Метод "Пробной проводки" (универсальный способ)

Существует еще один интересный способ проверить, открыт ли период для работы, не вникая в математические расчеты пятидневок. Мы можем попытаться программно создать и провести пустой документ в транзакции. Если проведение не удастся из-за того, что дата документа находится за пределами периода итогов, значит, период закрыт.

Разберем этот алгоритм. Нам понадобится любой документ, участвующий в оперативном учете (например, технический документ ПроверкаПериода):


Функция ПериодОткрытШтатно(ПроверяемаяДата)
    НачатьТранзакцию();
    Док = СоздатьОбъект("Документ.ПроверкаПериода");
    Док.Новый();
    Док.ДатаДок = ПроверяемаяДата;
    Док.Записать();
    
    // Попытка проведения документа. 
    // Если период не открыт, метод Провести() вернет 0.
    Результат = Док.Провести();
    
    // Обязательно отменяем транзакцию, чтобы не мусорить в базе
    ОтменитьТранзакцию();
    Возврат Результат;
КонецФункции

Этот метод хорош тем, что он абсолютно штатный и не зависит от того, какая периодичность установлена в конфигураторе (5 дней, месяц или декада). Система сама знает свои границы и честно ответит, может она провести документ на эту дату или нет.

Влияние на производительность и хранение данных

Выясним, к каким последствиям приводит использование 5-дневного периода. Главный плюс — скорость. В 1С 7.7 итоги хранятся на начало каждого периода. При получении остатка на произвольную дату система берет итоги на начало ближайшего периода и "докручивает" их движениями документов. При 5-дневке системе нужно прочитать максимум 4 дня движений, а при месячной — до 30 дней. Разница в скорости может быть десятикратной.

Однако есть и серьезные минусы, о которых стоит помнить системному администратору:

Таким образом, использование пятидневных периодов — это мощный инструмент оптимизации для 1С 7.7, но он требует автоматизации процесса открытия периодов. Использование приведенных выше формул позволит вам настроить "робота", который будет открывать периоды ночью по расписанию, минимизируя простои пользователей.

← На главную