Вывести сообщение 1с 8.3 сообщить. Сообщения пользователю в управляемых формах (еще раз)

  • 10.01.2022

Но некоторые моменты по работе с объектом "Сообщение пользователю" остались в ней не освещенными. Например, что писать в поле "Поле", если имя

реквизита отличается от именя поля на форме. Что писать в поле "ПутьКДанным". И наконец, самое вкусное, как работать с табличной частью.

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

Все что я пишу ниже проверено на 1С:Предприятие 8.3 (8.3.7.1860). Не самая последняя на сегодняшний день, но пишу как есть.

1. Просто сообщение.

Начнем с простого: просто выведем сообщение в форме, без привязки к полям, данным и прочее.

Об этом я рассказывал ранее, но для целостности статьи напишу еще раз. Тем более с некоторыми дополнениями.

Сообщение1 = новый СообщениеПользователю;
Сообщение1.Текст = "1. просто сообщение без привязок";
Сообщение1.Сообщить();

Этот код можно исполнить как на клиенте, так и на сервере. Это почти полный аналог строки:

Сообщить("1. просто сообщение без привязок");

Почему же правильнее сообщать не процедурой, а объектом. Дело в том, что сообщения выданные в фоновом задании (например при выполнении регламентной процедуры по расписанию) никуда не выводятся. Но то, что сообщено объектом, можно

получить на сервере в клиентском сеансе методом "ПолучитьСообщенияПользователю(...)" пока фоновое задание живо.

Тут я немного соврал Вам, я этого никогда не проверял. Вполне возможно, что сообщения выданные процедурой "Сообщить(...)" тоже можно получить из фонового задания, а может и нельзя. В документации про это не сказано, а значит мы так

делать не будем.

Итак, вывод: теперь всегда делайте сообщения объектом, это типа хороший тон новой платформы, а процедуру забудьте. Если Вам не нравится писать сообщение в три строки, то напишите свою процедуру в общем модуле и радйтесь. Это будет даже

очень хороший тон, т.к. Вы получите целый ряд плюсов:

1. Расширенный функционал нового объекта (подробнее ниже)

2. Возможность выводить сообщения своим способом. Например в текстовое поле или файл, а не в окно сообщений.

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

не сообщала прекратятся навсегда.

2. Сообщение привзанное к реквизиту объекта.

Как я писал в предыдущей статье, для привязки надо заполнить поля "Поле" и "ПутьКДанным". Но тему я в статье подробно не раскрыл.

Итак пример 2й в документе есть реквизит шапки "Клиент", надо на нем спозиционироваться и сообщить что-то в клиентской процедуре. Вот код, который это делает:

Сообщение2 = новый СообщениеПользователю;
Сообщение2.Текст = "2. Сообщение привязанное к реквизиту шапки Клиент";
Сообщение2.Поле = "Клиент";
Сообщение2.ПутьКДанным = "объект";
Сообщение2.Сообщить();

И тут нюансы:

1. Поле - это не поле, т.к. в моем примере элемент управления называется "ПолеКлиент", а реквизит объекта - "Клиент". Со строкой Сообщение2.Поле = "ПолеКлиент" не работает.

2. ПутьКДанным не "Объект.Клиент", а просто "Объект", т.к. нам надо сообщение показать не в форме контрагента, а в форме текущего документа. "Объект.Клиент" - не работает.

3. Это пример работы на клиенте. В серверных процедурах, немного по другому. Это ВАЖНО, не путайте привзяку сообщений на сервере и на клиенте.

Еще один пример я приведу с целью, чтобы Вы прочувствовали, разницу между клиентом и сервером. Дело в том, что у нас в распоряжении есть метод объекта "УстановитьДанные(...)". В синтаксис-помощнике написано "Объект, с которым должно быть

связано сообщение". Это важно. Для примера напишем такой код:

Сообщение3 = новый СообщениеПользователю;
Сообщение3.УстановитьДанные(Объект);
Сообщение3.Текст = "3. Сообщение привязанное к реквизиту шапки Номер, но оно не привяжется, т.к. Объект - это не объект";
Сообщение3.Поле = "Номер";
Сообщение3.Сообщить();

Этот код не сработает, т.к. на клиенте реквизит формы "Объект" это и не объект вовсе а какая-то гадость, вот что нам говорит отладчик про переменную объект:

Точнее, пользователь конечно сообщение увидит, но двойной хлоп по нему не приведет ни к чему.

А теперь попробуем тоже самое, но на сервере. Создадим серверную процедуру "Сообщить4НаСервере()" и вызовем её с клиента

&НаСервере
Процедура Сообщить4НаСервере()
Сообщение4 = новый СообщениеПользователю;
Сообщение4.УстановитьДанные(РеквизитФормыВЗначение("Объект"));
Сообщение4.Текст = "4. Сообщение привязанное к реквизиту шапки Организация";
Сообщение4.Поле = "Организация";
Сообщение4.Сообщить();
КонецПроцедуры

Тут все будет хорошо, единственное замечание по коду это то, что переменную "объект" надо конвертнуть из "ДанныеФормыСтруктура" в реальный объект вызвав процедуру "РеквизитФормыВЗначение(...)".

Вывод: метод "УстановитьДанные(...)" можно использовать только на сервере, т.к. только на сервере есть возможность получить объект.

3. Сообщения привязанные к реквизиту табличной части объекта

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

Сообщение5 = новый СообщениеПользователю;
Сообщение5.Текст = "5. Строка 1 поле количество";
Сообщение5.Поле = "Товары.Количество";
Сообщение5.ПутьКДанным = "объект";
Сообщение5.Сообщить();

Хоть нюансы почти теже, но повторенье мать ученье:

1. Поле - это не имя элемента управления, элемент управления у меня назван "ТоварыКоличество", а не просто "Количество". "Товары" это имя табличной части, а не элемента управления связанного с табличной частью.

2. Путь к данным - объект, просто объект.

3. Номер строки в квадратных скобках - нумерация с нуля и это номер строки, а не идентификатор строки в колекции данных формы. При сдвиге строк, их удалении, идентификатор присвоенный при открытии формы сохраняется, а номера строк пересчитываются заново.

Вот и все на этот раз. Сразу озвучу не раскрытые темы, о которых напишу позже:

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

2. Как привязывать сообщения к форме, где нет объектов

3. Как брать сообщения о статусе выполнения долгофо фонового задания

4. Что такое "КлючДанных" и когда надо им пользоваться

Ниже база с примером, в ней заходите в документ и жмете по очереди три кнопки. Код в модуле формы документа.

В программах на платформе 1С:Предприятие сообщение пользователю можно показать разными способами.

1. Метод ПоказатьПредупреждение .

ПоказатьПредупреждение(< ОписаниеОповещенияОЗавершении> , < ТекстПредупреждения> , < Таймаут> , < Заголовок> )

При использовании этой конструкции окно с предупреждением возникает в центре интерфейса программы.

Параметры:

ОписаниеОповещенияОЗавершении (необязательный)
Тип: ОписаниеОповещения. Содержит описание процедуры, которая будет вызвана после закрытия окна предупреждения со следующими параметрами: ДополнительныеПараметры - значение, которое было указано при создании объекта ОписаниеОповещения. Если параметр не указан, то по завершении никакая процедура вызвана не будет.

ТекстПредупреждения (обязательный)
Тип: Строка; ФорматированнаяСтрока. Текст предупреждения.

Таймаут (необязательный)
Тип: Число. Интервал времени в секундах, в течение которого система будет ожидать ответа пользователя. По истечении интервала окно предупреждения будет закрыто. Если параметр не указан, то время ожидания не ограничено. Если параметр имеет отрицательное значение, будет сгенерировано исключение. Значение по умолчанию: 0.

Заголовок (необязательный)
Тип: Строка. Содержит заголовок окна предупреждения. Описание: Выводит на экран окно предупреждения, но не ожидает его закрытия.

Доступность: Тонкий клиент, веб-клиент, толстый клиент, мобильное приложение(клиент).

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

2. Метод Предупреждение .

Окно с предупреждением возникает в центре интерфейса программы. Однако, если для конфигурации свойство РежимИспользованияМодальности установлено в НеИспользовать , то метод не работает.

Доступность: Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение(клиент).

3. Метод ПоказатьОповещениеПользователя .

ПоказатьОповещениеПользователя(< Текст> , < ДействиеПриНажатии> , < Пояснение> , < Картинка> , < СтатусОповещенияПользователя> , < КлючУникальности> )

При использовании этого метода сообщение появляется в правом нижнем углу интерфейса.

Доступность: Тонкий клиент, веб-клиент, толстый клиент.

4. Метод Сообщить .

Сообщить(< ТекстСообщения> , < Статус> )

Доступность: Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение(клиент), мобильное приложение(сервер).

5. Объект СообщениеПользователю .

Предназначен для хранения параметров сообщения, которые необходимо вывести пользователю. Если сообщение еще не было показано пользователю (такое может быть при работе на стороне сервера, в фоновом задании, внешнем соединении или Web-сервисах), можно получить накопленные сообщения методом ПолучитьСообщенияПользователю .

Свойства: ИдентификаторНазначения (TargetID); КлючДанных (DataKey); Поле (Field); ПутьКДанным (DataPath); Текст (Text).

Методы: Сообщить (Message); УстановитьДанные (SetData).

Сообщение появляется в нижней части интерфейса, в строке.

Сообщение = Новый СообщениеПользователю() ; Сообщение. Текст = "Не хватает номенклатуры " ; Сообщение. Поле = "Номенклатура.Количество" ; Сообщение. УстановитьДанные(ОбъектДанных) ; Сообщение. Сообщить() ;

1С СообщениеПользователю выводит сообщение пользователю (после окончания обработки) или сохраняет его в очередь, если сообщение невозможно вывести «прямо сейчас», например:
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "Привет, мир!";
Сообщение.Сообщить();

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

1С СообщениеПользователю записывает сообщения в «некоторую» очередь, и, после окончания обработки выводит их пользователю, если это возможно. Иначе – весь список сообщений возможно получить с помощью метода ПолучитьСообщенияПользователю().

Чтобы вывести сообщение пользователю с помощью 1С СообщениеПользователю в конкретной, уже открытой форме, дополнительно нужно установить идентификатор формы:
Сообщение.ИдентификаторНазначения = Форма.УникальныйИдентификатор;

Чтобы сообщение 1С СообщениеПользователю было выведено во всплывающем окне у конкретного поля формы, в модуле которой выполняется код, нужно указать «путь» к нему:
Сообщение.Поле = "Наименование"; //где Наименование – это реквизит формы
Сообщение.Поле = "Объект.Наименование"; //где Наименование – это реквизит объекта (т.е. справочника, чья форма редактируется)
Сообщение.Поле = "Товары.Цена"; //где Товары – таб.часть на форме, Цена – колонка этой таб.части

Чтобы сделать то же, но в модуле другого объекта (общем модуле), нужно дополнительно указать объект (СправочникОбъект, ДокументОбъект и т.п.):
Сообщение.Поле = "Наименование"; //где Наименование – это реквизит СправочникОбъект
Сообщение.УстановитьДанные(СправочникОбъект);
//При двойном щелчке на сообщение будет открыта форма объекта со всплывающим сообщением у требуемого поля

Другой способ связать сообщение 1С СообщениеПользователю с данными объекта:
//для справочника, документа..
Сообщение.КлючДанных = СправочникСсылка;
Сообщение.ПутьКДанным = "Объект";

//для записей регистра
Сообщение.КлючДанных = РегистрМенеджерЗаписи.ИсходныйКлючЗаписи; //обычно основной реквизит формы, связанный с регистром
Сообщение.ПутьКДанным = "Запись";

В типовых конфигурациях на управляемых формах для тонкого клиента, например «Управление торговлей, редакция 11» и «Бухгалтерия, редакция 3», в общем модуле ОбщегоНазначенияКлиентСервер имеется функция СообщитьПользователю(), которая «универсализирует» работу с данным объектом. Синтаксис функций в разных конфигурациях – разный.

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

Добрый день.

Сегодня мы поговорим о такой простой вроде бы вещи, как сообщения пользователю.

В 8 перекочевал метод из 7.7 - "Сообщить(...) ". Метод этот очень простой, он открывает окно сообщение, если оно не открыто, и добавляет туда текст сообщения. Как и в 1С 7.7 в нем есть второй параметр, который определяет иконку напротив сообщения. Эта иконка определяет важность сообщения.

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

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

Дело в том, что теперь принято использовать не метод глобального контекста "Сообщить(...)", а объект "СообщениеПользователю ". Этот объект доступен везде, и на клиенте и на сервере. У него есть несколько свойств и пару методов.

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



Сообщение.Сообщить();

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

Основными полями, которые расширяют возможности сообщения являются:

  • КлючДанных
  • Поле

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

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

Поле - это строка с именем поля, которое надо активировать. Причем не важно, откроется форма другого объекта, или мы останемся в текущей форме.

Вот пример, как это работает:

Допустим перед записью элемента справочника в модуле формы мы проверяем уникальность реквизита "Id" и, если такой уже есть, выдаем сообщение:


Если выб.Следующий() Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.КлючДанных = Выб.Ссылка;
Сообщение.Поле = "id";
Сообщение.Текст = "Раздел с таким Id уже существует";
Сообщение.Сообщить();
КонецЕсли;

В данном примере по двойному щелчку откроется элемент справочника с таким же Id, а поле Id будет активно и в нем будет подсказка:

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

для этого меняем свой код следующим образом:

//если есть дубли, в выборке будут данные
Если выб.Следующий() Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.КлючДанных = Объект.Ссылка;
Сообщение.Поле = "id";
Сообщение.Текст = "Раздел с таким Id уже существует";
Сообщение.Сообщить();
КонецЕсли;

Отличие только в том, что в КлючДанных мы передаем ссылку на элемент, который у нас открыт. К сожалению этот код не работает:(По двойному щелчку у нас откроется модальное окно.

Чтобы это заработало, есть нюанс, что нужно заполнить поле "ПутьКДанным ". Не могу точно объяснить зачем, просто это надо запомнить. Открываем другой объект - путь к данным не нужен, позиционируемся внутри текущего - нужен. Вывод - лучше заполнять всегда, не ошибетесь. Добавляем в код строку:

Сообщение.ПутьКДанным = "объект";

И все красиво:

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

Следующий нюанс - у сообщения есть метод - "УстановитьДанные ". Он на основании объекта заполняет поля КлючДанных и ПутьКДанным . Это гораздо удобнее, сделать все в одну строку. Как правило в форме элемента/документа у нас есть объект. Единственно, что на сервере надо писать так:

Сообщение.УстановитьДанные(РеквизитФормыВЗначение("Объект"));

Но в предопределенной процедуре формы ПередЗаписьюНаСервере на самом деле есть уже параметр ТекущийОбъект . А на клиенте мы вообще объект не получим. Еще в модуле объекта (не в форме) нужно писать так:

Сообщение.УстановитьДанные(ЭтотОбъект);

В заключении хочу наговорить гадостей про управляемые формы. Это касается как ТАКСИ, так и обычных УФ. Дело в том, что в УФ очень плохо передаются интерфейсные списки. Таблица, содержащая в себе 1000 строк очень медленно прорисовывается, а в web браузере она может вообще несколько минут открываться. Это относится и к списку сообщений. для эксперимента выведите 1000 сообщений и попробуйте попереключаться между окошками. Система умрет сразу. причем четко видно, как система думает именно над выводом сообщений. Переход в окно с кучей сообщений выглядит так:

Отображается содержимое окна
-что резко мерцает и появляется панель сообщений
-все повисает и вы смотрите, как скрол в окне сообщений ползет вниз

Т.е. как раньше, вывести в панель сообщений лог работы длительной обработки, в котором несколько тысяч записей - нельзя. Я бы советовал ограничиться 10ю сообщениями. Логи надо выводить в многострочную строку, она отображается почти мгновенно не зависимо от количества строк. Конечно, если вы проверяете заполненность реквизита табличной части, строк в ней 1000 и в каждой ошибка, то да, придется потерветь:) Хотя можно в этом случае продумать свой способ отображения сообщений, например в поле HTML документа.