Как реализовать вывод сообщения о днях рождения клиентов при начале работы системы в 1С:Розница?

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

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

Разбор проблемы и настройка общего модуля

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

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

  1. У общего модуля в свойствах должны быть установлены флаги Клиент (управляемое приложение) и Вызов сервера.
  2. Процедура внутри модуля должна быть объявлена с ключевым словом Экспорт.

Рассмотрим структуру правильного общего модуля (например, с именем РаботаСКлиентамиКлиентСервер):


// Процедура на клиенте для вызова из Модуля управляемого приложения
Процедура ПроверитьДниРожденияКлиентов() Экспорт
    
    // Получаем данные с сервера
    СписокИменинников = ПолучитьСписокИменинниковНаСервере();
    
    Если СписокИменинников.Количество() > 0 Тогда
        // Формируем текст сообщения
        ТекстСообщения = "Сегодня празднуют день рождения:" + Символы.ПС;
        Для Каждого Имя Из СписокИменинников Цикл
            ТекстСообщения = ТекстСообщения + "- " + Имя + Символы.ПС;
        КонецЦикла;
        
        // Выводим уведомление пользователю
        ПоказатьПредупреждение(, ТекстСообщения);
    КонецЕсли;
    
КонецПроцедуры

Оптимизация запроса к базе данных

Проанализируем код получения данных, предложенный в исходном сообщении. Использование метода Справочники.Клиенты.Выбрать() в сочетании с перебором всех записей и строковым сравнением дат — это крайне неэффективный подход. Если в вашей базе 10 000 клиентов, система будет "подвисать" при каждом запуске.

Разберем, как сделать это правильно с помощью механизма Запросов. Мы будем сравнивать только день и месяц рождения, что позволит базе данных работать максимально быстро. Посмотрим на пример серверной функции:


Функция ПолучитьСписокИменинниковНаСервере()
    
    Список = Новый Массив;
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Клиенты.Наименование КАК Имя
        |ИЗ
        |	Справочник.Клиенты КАК Клиенты
        |ГДЕ
        |	ДЕНЬ(Клиенты.ДатаРождения) = ДЕНЬ(&ТекущаяДата)
        |	И МЕСЯЦ(Клиенты.ДатаРождения) = МЕСЯЦ(&ТекущаяДата)
        |	И НЕ Клиенты.ПометкаУдаления";
    
    Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        Список.Добавить(Выборка.Имя);
    КонецЦикла;
    
    Возврат Список;
    
КонецФункции

Важный момент: использование функций ДЕНЬ() и МЕСЯЦ() в языке запросов позволяет серверу БД эффективно отфильтровать нужные записи без загрузки всего справочника в память.

Правильный вызов при старте системы

Теперь перейдем к Модулю управляемого приложения. Процедура ПриНачалеРаботыСистемы выполняется до того, как открывается основной интерфейс программы. Если мы вызовем тяжелое сообщение или форму прямо в ней, это может привести к визуальным задержкам.

Рекомендуется использовать механизм обработчика ожидания. Это позволит программе сначала полностью загрузиться, а затем, через секунду, показать уведомление. Рассмотрим этот метод:


Процедура ПриНачалеРаботыСистемы()
    
    // Подключаем однократный обработчик через 1 секунду после старта
    ПодключитьОбработчикОжидания("ВыполнитьПроверкуДнейРождения", 1, Истина);
    
КонецПроцедуры

Процедура ВыполнитьПроверкуДнейРождения() Экспорт
    // Вызываем процедуру нашего общего модуля
    РаботаСКлиентамиКлиентСервер.ПроверитьДниРожденияКлиентов();
КонецПроцедуры

Альтернативные и более продвинутые решения

Как справедливо заметили участники форума, простое всплывающее окно — не единственный и не всегда лучший способ. Разберем другие варианты:

  1. Информационная панель на рабочем столе: Вместо назойливых окон можно создать небольшую форму со списком именинников и добавить её в состав Рабочей области рабочего стола. Это позволит пользователю видеть информацию в течение всего дня.
  2. Использование БСП (Библиотеки стандартных подсистем): В конфигурации "1С:Розница" есть встроенная подсистема Текущие дела. Программист может интегрировать проверку дней рождения именно туда, и тогда уведомление появится в стандартном виджете на главной странице.
  3. Регламентные задания: Чтобы не нагружать клиентское приложение, проверку можно выполнять на сервере по расписанию (например, в 8:00 утра) и записывать результат в специальный регистр сведений, из которого клиентская часть будет просто считывать готовый список при запуске.

Подводя итог, отметим, что для качественной реализации задачи необходимо:

Надеемся, эти рекомендации помогут вам сделать работу пользователей в 1С более удобной и эффективной!

← На главную