Как реализовать периодические напоминания (каждую неделю и месяц) в мобильном приложении 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке мобильных приложений на платформе 1С часто возникает задача создания системы напоминаний, которая должна работать автономно, без постоянного соединения с центральной базой и без использования регламентных заданий, которые недоступны в мобильном клиенте. В данной статье мы подробно разберем, как использовать объект ДоставляемоеУведомление для реализации периодических задач, таких как уведомления каждый вторник или каждое 5-е число месяца.

Основы локальных уведомлений

Для начала проанализируем, почему мы используем именно локальные уведомления. В отличие от Push-уведомлений, локальные уведомления планируются внутри самого устройства и срабатывают даже в том случае, если приложение закрыто или отсутствует интернет-соединение. За их выполнение отвечает операционная система (Android или iOS). Рассмотрим базовый программный код для создания простого уведомления:


&НаКлиенте
Процедура СоздатьПростоеУведомление()
    #Если МобильноеПриложениеКлиент Тогда
        Уведомление = Новый ДоставляемоеУведомление;
        Уведомление.Заголовок = "Напоминание";
        Уведомление.Текст = "Пора выполнить задачу!";
        Уведомление.ДатаПоявленияУниверсальноеВремя = УниверсальноеВремя(ТекущаяДата() + 60); // Через минуту
        Уведомление.ЗвуковоеОповещение = ЗвуковоеОповещение.ПоУмолчанию;
        
        ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
    #КонецЕсли
КонецПроцедуры

Реализация еженедельных уведомлений

Разберем ситуацию, когда нам нужно, чтобы уведомление срабатывало каждый вторник в 10:00. Для этого нам необходимо решить две задачи: вычислить дату ближайшего вторника и установить правильный интервал повтора. Выясним, как вычислить дату ближайшего нужного дня недели, используя функцию ДеньНедели().

Допустим, сегодня четверг. Чтобы найти ближайший вторник, мы можем использовать следующий алгоритм:


// НужныйДень - число от 1 (понедельник) до 7 (воскресенье)
НужныйДень = 2; // Вторник
ТекущийДень = ДеньНедели(ТекущаяДата());

Если ТекущийДень < НужныйДень Тогда
    РазницаДней = НужныйДень - ТекущийДень;
ИначеЕсли ТекущийДень > НужныйДень Тогда
    РазницаДней = 7 - (ТекущийДень - НужныйДень);
Иначе // Сегодня вторник
    Если Час(ТекущаяДата()) < 10 Тогда
        РазницаДней = 0; // Сработает сегодня
    Иначе
        РазницаДней = 7; // Сработает на следующей неделе
    КонецЕсли;
КонецЕсли;

ДатаСрабатывания = НачалоДня(ТекущаяДата()) + (РазницаДней * 86400) + (10 * 3600); // 10:00 утра

После того как мы определили ДатаСрабатывания, установим свойство ИнтервалПовтора. Для еженедельного повторения это значение составляет 604 800 секунд (7 дней * 24 часа * 3600 секунд). Посмотрим на итоговый код:


Уведомление.ДатаПоявленияУниверсальноеВремя = УниверсальноеВремя(ДатаСрабатывания);
Уведомление.ИнтервалПовтора = 86400 * 7; 
ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);

Проблема ежемесячных уведомлений

Рассмотрим более сложный случай: уведомление должно приходить каждое 5-е число месяца. Основная сложность заключается в том, что в месяцах разное количество дней (28, 29, 30 или 31). Если мы просто укажем интервал в секундах (например, 30 * 86400), то дата уведомления неизбежно «поплывет».

Решение 1: Серия уведомлений. Проанализируем стратегию создания очереди. Поскольку 1С и мобильные ОС позволяют планировать множество уведомлений вперед, мы можем создать цикл на 12 месяцев:


БазоваяДата = '20191205100000'; // 5 декабря 10:00
Для Счетчик = 0 По 11 Цикл
    Уведомление = Новый ДоставляемоеУведомление;
    ДатаМесяца = ДобавитьМесяц(БазоваяДата, Счетчик);
    Уведомление.ДатаПоявленияУниверсальноеВремя = УниверсальноеВремя(ДатаМесяца);
    Уведомление.Текст = "Ежемесячный отчет за " + Формат(ДатаМесяца, "ДФ='ММММ гггг'");
    ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
КонецЦикла;

Решение 2: Пересчет при срабатывании. Мы можем запрограммировать систему так, чтобы при получении текущего уведомления она автоматически планировала следующее. Для этого используется обработчик в модуле управляемого приложения.

Обработка полученных уведомлений

Чтобы система знала, что делать при активации уведомления пользователем или при его получении, нам нужно подключить обработчик. Это делается в процедуре ПриНачалеРаботыСистемы:


Процедура ПриНачалеРаботыСистемы()
    #Если МобильноеПриложениеКлиент Тогда
        ДоставляемыеУведомления.ПодключитьОбработчикУведомлений("ПриПолученииУведомления");
    #КонецЕсли
КонецПроцедуры

Процедура ПриПолученииУведомления(Уведомление, Локальное, Показано, Параметры) Экспорт
    Если Локальное Тогда
        // Здесь можно реализовать логику перепланирования следующего уведомления
        // Или открыть конкретную форму документа/задачи
        Сообщить("Сработало напоминание: " + Уведомление.Текст);
    КонецЕсли;
КонецПроцедуры

Важные технические нюансы

При работе с уведомлениями необходимо учитывать специфику мобильных платформ:

  1. Универсальное время: Операционные системы требуют указывать время в формате UTC. Всегда используйте функцию УниверсальноеВремя(), чтобы избежать сдвигов из-за часовых поясов.
  2. Ограничения iOS: На устройствах Apple существует лимит в 64 локальных уведомления на одно приложение. Если вы планируете уведомления на год вперед для множества задач, следите за этим лимитом.
  3. Энергосбережение: В ОС Android (начиная с версии 6.0) существует режим Doze. Если устройство долго неподвижно, система может объединять уведомления и выдавать их не мгновенно, а «пачками» для экономии заряда.
  4. Идентификаторы: Чтобы иметь возможность удалить или обновить конкретное уведомление (например, если пользователь удалил напоминание в интерфейсе), используйте свойство Имя объекта ДоставляемоеУведомление как уникальный ключ.

Таким образом, мы выяснили, что наиболее надежным способом реализации сложных периодических напоминаний в 1С является сочетание точного расчета даты первого срабатывания и планирование серии уведомлений либо использование логики «цепочки», где каждое следующее уведомление создается программно в момент обработки предыдущего.

← На главную