Приветствуем! Задача оперативного уведомления сотрудников о важных событиях, таких как дни рождения клиентов, является классической для систем автоматизации торговли. В этой статье мы подробно разберем, как правильно реализовать этот функционал, исправим типичные ошибки новичков и рассмотрим наиболее эффективные архитектурные подходы в среде 1С:Предприятие 8.3 на управляемых формах.
Для начала проанализируем ситуацию автора. Основная сложность заключается в том, что процедура ПриНачалеРаботыСистемы находится в Модуле управляемого приложения, который выполняется на стороне клиента. Чтобы вызвать из него код, работающий с базой данных, нам необходим Общий модуль с определенными свойствами.
Выясним причину, по которой код автора может не работать. Для того чтобы процедура из общего модуля была доступна для вызова, должны быть соблюдены следующие условия:
Экспорт.Рассмотрим структуру правильного общего модуля (например, с именем РаботаСКлиентамиКлиентСервер):
// Процедура на клиенте для вызова из Модуля управляемого приложения
Процедура ПроверитьДниРожденияКлиентов() Экспорт
// Получаем данные с сервера
СписокИменинников = ПолучитьСписокИменинниковНаСервере();
Если СписокИменинников.Количество() > 0 Тогда
// Формируем текст сообщения
ТекстСообщения = "Сегодня празднуют день рождения:" + Символы.ПС;
Для Каждого Имя Из СписокИменинников Цикл
ТекстСообщения = ТекстСообщения + "- " + Имя + Символы.ПС;
КонецЦикла;
// Выводим уведомление пользователю
ПоказатьПредупреждение(, ТекстСообщения);
КонецЕсли;
КонецПроцедуры
Проанализируем код получения данных, предложенный в исходном сообщении. Использование метода Справочники.Клиенты.Выбрать() в сочетании с перебором всех записей и строковым сравнением дат — это крайне неэффективный подход. Если в вашей базе 10 000 клиентов, система будет "подвисать" при каждом запуске.
Разберем, как сделать это правильно с помощью механизма Запросов. Мы будем сравнивать только день и месяц рождения, что позволит базе данных работать максимально быстро. Посмотрим на пример серверной функции:
Функция ПолучитьСписокИменинниковНаСервере()
Список = Новый Массив;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Клиенты.Наименование КАК Имя
|ИЗ
| Справочник.Клиенты КАК Клиенты
|ГДЕ
| ДЕНЬ(Клиенты.ДатаРождения) = ДЕНЬ(&ТекущаяДата)
| И МЕСЯЦ(Клиенты.ДатаРождения) = МЕСЯЦ(&ТекущаяДата)
| И НЕ Клиенты.ПометкаУдаления";
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Список.Добавить(Выборка.Имя);
КонецЦикла;
Возврат Список;
КонецФункции
Важный момент: использование функций ДЕНЬ() и МЕСЯЦ() в языке запросов позволяет серверу БД эффективно отфильтровать нужные записи без загрузки всего справочника в память.
Теперь перейдем к Модулю управляемого приложения. Процедура ПриНачалеРаботыСистемы выполняется до того, как открывается основной интерфейс программы. Если мы вызовем тяжелое сообщение или форму прямо в ней, это может привести к визуальным задержкам.
Рекомендуется использовать механизм обработчика ожидания. Это позволит программе сначала полностью загрузиться, а затем, через секунду, показать уведомление. Рассмотрим этот метод:
Процедура ПриНачалеРаботыСистемы()
// Подключаем однократный обработчик через 1 секунду после старта
ПодключитьОбработчикОжидания("ВыполнитьПроверкуДнейРождения", 1, Истина);
КонецПроцедуры
Процедура ВыполнитьПроверкуДнейРождения() Экспорт
// Вызываем процедуру нашего общего модуля
РаботаСКлиентамиКлиентСервер.ПроверитьДниРожденияКлиентов();
КонецПроцедуры
Как справедливо заметили участники форума, простое всплывающее окно — не единственный и не всегда лучший способ. Разберем другие варианты:
Рабочей области рабочего стола. Это позволит пользователю видеть информацию в течение всего дня.Подводя итог, отметим, что для качественной реализации задачи необходимо:
Лев(Строка(Формат(...))), заменяя их на типизированные функции работы с датами.Надеемся, эти рекомендации помогут вам сделать работу пользователей в 1С более удобной и эффективной!