При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью оповестить пользователя о завершении какого-либо действия, например, о создании нового документа. Однако попытка вызвать метод ПоказатьОповещениеПользователя() напрямую из модуля объекта приводит к ошибке компиляции: «Процедура или функция с указанным именем не определена (Проверка: Сервер)». В этой статье мы подробно разберем, почему возникает эта проблема и какими способами ее можно решить, используя механизмы расширений и Библиотеки стандартных подсистем (БСП).
Проанализируем ситуацию: автор вопроса пытается вызвать процедуру с директивой &НаКлиенте из обработчика ПередЗаписью модуля объекта. Основная причина неудачи заключается в том, что модуль объекта документа всегда выполняется на сервере. В 1С невозможно инициировать интерактивное действие на клиенте напрямую из серверного кода, так как сервер не «знает», какой именно сеанс пользователя вызвал это действие и как передать управление обратно на форму в момент транзакции записи.
Метод ПоказатьОповещениеПользователя() является исключительно клиентским. Рассмотрим основные подходы к решению этой задачи.
Если нам критично вывести информацию именно из модуля объекта (например, когда документ создается не только из формы, но и программно), мы можем использовать объект СообщениеПользователю. Этот метод работает как на сервере, так и на клиенте.
Разберем пример кода для расширения модуля объекта:
&После("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что это новый документ и запись не является загрузкой данных
Если ЭтоНовый() И Не ОбменДанными.Загрузка Тогда
ТекстСообщения = СтрШаблон("Поступили денежные средства от контрагента %1 на сумму %2",
ЭтотОбъект.Контрагент,
ЭтотОбъект.СуммаДокумента);
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ТекстСообщения;
// Указываем путь к объекту, чтобы сообщение «привязалось» к полю формы
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
Важный нюанс: Данный метод выведет сообщение в специальное окно сообщений (обычно внизу или вверху экрана), но это не будет «всплывающим» push-уведомлением в правом нижнем углу. Однако это самый надежный способ передачи информации с сервера на клиент.
Если мы хотим использовать именно всплывающее уведомление ПоказатьОповещениеПользователя(), нам нужно «поймать» момент окончания записи в модуле формы документа. Но как в форме узнать, что документ был именно новым, если после записи метод ЭтоНовый() всегда возвращает Ложь?
Для этого воспользуемся коллекцией ДополнительныеСвойства. Рассмотрим алгоритм действий:
ПередЗаписью устанавливаем флаг.ПослеЗаписи проверяем этот флаг и выводим уведомление.Код в модуле объекта:
&После("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если ЭтоНовый() Тогда
ЭтотОбъект.ДополнительныеСвойства.Вставить("ДокументБылНовым", Истина);
КонецЕсли;
КонецПроцедуры
Затем создадим расширение для модуля формы этого документа:
&После("ПослеЗаписи")
Процедура Расш1_ПослеЗаписи(ПараметрыЗаписи)
// Объект на форме уже записан, проверяем свойства, переданные с сервера
Если Объект.ДополнительныеСвойства.Свойство("ДокументБылНовым") Тогда
Текст = "Документ успешно создан и записан!";
ПоказатьОповещениеПользователя("Успех", , Текст, БиблиотекаКартинок.ИнформационныйШрифт);
КонецЕсли;
КонецПроцедуры
Выясним причину, по которой иногда требуется уведомлять других пользователей. Если ваша конфигурация основана на БСП (например, Бухгалтерия предприятия 3.0), можно использовать типовой регистр сведений НапоминанияПользователя. Это позволяет отправить уведомление не только текущему пользователю, но и любому другому сотруднику.
Проанализируем пример использования программного интерфейса БСП для создания напоминания:
&После("ПриЗаписи")
Процедура Расш1_ПриЗаписи(Отказ)
Если Не ЭтотОбъект.ДополнительныеСвойства.Свойство("ДокументБылНовым") Тогда
Возврат;
КонецЕсли;
// Параметры для напоминания
ПараметрыНапоминания = Новый Структура;
ПараметрыНапоминания.Вставить("Пользователь", Пользователи.ТекущийПользователь()); // Кому напомнить
ПараметрыНапоминания.Вставить("ВремяСобытия", ТекущаяДатаСеанса());
ПараметрыНапоминания.Вставить("СпособУстановкиВремени", Перечисления.СпособыУстановкиВремениНапоминания.ВМоментВремени);
ПараметрыНапоминания.Вставить("Текст", "Создан новый ПКО: " + Строка(ЭтотОбъект.Ссылка));
ПараметрыНапоминания.Вставить("Источник", ЭтотОбъект.Ссылка);
// Вызов процедуры БСП (имена могут отличаться в зависимости от версии БСП)
НапоминанияПользователя.УстановитьНапоминание(ПараметрыНапоминания);
КонецПроцедуры
Преимущества этого метода:
Выбор метода зависит от бизнес-задачи:
ДополнительныеСвойства).СообщениеПользователю).Помните, что использование расширений требует внимательного отношения к директивам компиляции и контексту исполнения кода. Всегда проверяйте доступность методов в синтакс-помощнике для соответствующих типов клиентов.