User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

Добрый день.

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

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

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

 

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

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

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

Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Раздел с таким Id уже существует";
Сообщение.Сообщить();

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

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

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

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

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

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

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

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

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

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

1С Открытие объекта по ссылке в сообщении

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

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

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

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

1С сообщения

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

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

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

1С сообщение пользователю позиционируется на поле ввода, в котором ошибка

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

1С сообщение пользователю. Поле указано неверно

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

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

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

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

Но я категорически настаиваю стараться обходиться без сообщений в модуле объекта. Конечно, это не всегда удается, но стараться надо.


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

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

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

Авторизуйтесь пожалуйста

Comments   

0 # Антон 2016-04-10 12:03
Что же получается, НаКлиенте недоступен Объект. Метод Сообщение.Устан овитьДанные(Объ ект) не отрабатывает. Просто прописывать Сообщение.ПутьК Данным = "объект"; ?
0 # Антон Филоненко 2016-04-11 06:02
Так точно!
0 # Антон Филоненко 2016-05-27 13:28
Написал более подробную статью с разбором нюансов на эту же тему
http://prosto1s.ru/index.php/59-soobshcheniya-polzovatelyu-v-upravlyaemykh-formakh-eshche-raz о том как в 1С Предприятии в УФ правильно выводить сообщения пользоватею