Почему не выводятся сообщения о днях рождения сотрудников при старте системы в 1С?

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

При разработке алгоритмов оповещения пользователей при начале работы программы разработчики часто сталкиваются с ситуацией, когда процедура отрабатывает без явных синтаксических ошибок, однако метод Сообщить() ничего не выводит на экран, а результирующий массив данных оказывается пустым. Разберем по шагам, почему возникает эта проблема, как быстро локализовать ошибку с помощью встроенных инструментов отладки платформы 1С:Предприятие 8.3 и как правильно переписать алгоритм с точки зрения производительности и стандартов разработки.

Анализ исходного кода и поиск логической ошибки

Рассмотрим типовой пример, когда при запуске приложения в модуле управляемого приложения вызывается экспортная функция общего модуля для формирования списка именинников:


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

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

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

Причина кроется в банальной опечатке в блоке проверки условия:

Если ДРМесяц = ТДМесяц И ДРДень = ТДМесяц Тогда

Вместо сравнения переменной ДРДень с переменной ТДДень выполняется сравнение с переменной ТДМесяц. Таким образом, условие станет истинным только в том редком случае, когда номер текущего дня месяца совпадает с номером текущего месяца (например, 5 мая или 12 декабря). Во все остальные дни условие всегда возвращает Ложь, строка добавления в массив не выполняется, и на клиент возвращается пустая коллекция.

Исправленный вариант условия должен выглядеть следующим образом:


Если ДРМесяц = ТДМесяц И ДРДень = ТДДень Тогда
    Массив.Добавить(Выборка.Наименование);
КонецЕсли;

Как быстро находить подобные ошибки с помощью отладчика

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

  1. Установка точек останова: Поставим точку останова внутри цикла перебора выборки прямо на строке с условием Если, а также внутри самого блока условия на строке Массив.Добавить(...). Если точка останова внутри блока условия не срабатывает ни для одной записи — проверяем логику самого выражения.
  2. Использование панели «Локальные переменные»: В современных версиях платформы 1С:Предприятие 8.3 не обязательно вручную вбивать имена переменных в табло. Достаточно открыть панель «Локальные переменные» в конфигураторе во время отладки и сопоставить значения ДРДень, ДРМесяц, ТДДень и ТДМесяц.
  3. Вычисление выражения: Выделим условие целиком и нажмем Shift + F9 (меню «Отладка» — «Вычислить выражение»). Это позволит сразу увидеть итоговый булев результат вычисления выражения для текущей итерации выборки.

Оптимизация: правильное получение данных через запрос

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

Перепишем функцию с использованием языка запросов 1С и функции ТекущаяДатаСеанса() для корректного учета часового пояса пользователя:


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

Нюансы контекста и отображения сообщений в управляемом приложении

При реализации оповещений в управляемом интерфейсе важно помнить о нескольких ключевых правилах:

  1. Свойства общего модуля: Процедура ПриНачалеРаботыСистемы выполняется исключительно в контексте НаКлиенте. Для того чтобы функция чтения данных из базы была доступна для вызова, в свойствах общего модуля ОбщиеМеханизмы должны быть установлены флаги «Сервер» и «Вызов сервера».
  2. Способ вывода оповещений: Метод Сообщить() выводит текст в системное окно сообщений, которое пользователь может не заметить при открытии начальной страницы. Для вывода всплывающих уведомлений в управляемом интерфейсе эффективнее применять метод ПоказатьОповещениеПользователя():

Процедура ПриНачалеРаботыСистемы()
    
    СписокИменинников = ОбщиеМеханизмы.ПолучитьСписокИменинников();
    
    Для Каждого Сотрудник Из СписокИменинников Цикл
        ПоказатьОповещениеПользователя(
            "День рождения!",
            ,
            "Сегодня празднует день рождения: " + Сотрудник,
            БиблиотекаКартинок.Информация
        );
    КонецЦикла;
    
КонецПроцедуры

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

← На главную