1с сообщение
Давно не писал в рубрики ‘Джуниор 1с’. Сегодня исправим этот недочет и рассмотрим различные способы вывода сообщения в 1с пользователю. Ведь главное это не просто вывести сообщение пользователю, а еще это сделать максимально информативно и своевременно. Итак, начнем.
Самое элементарное что может сделать начинающий программист, это ознакомиться с функцией глобального контекста ‘Сообщить’:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Сообщить("Записываем документ. Все норм!", СтатусСообщения.Информация); //СтатусСообщения. //БезСтатуса (WithoutStatus) //Важное (Important) //Внимание (Attention) //Информация (Information) //Обычное (Ordinary) //ОченьВажное (VeryImportant) КонецПроцедуры &НаСервере Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи) // СтандартныеПодсистемы.УправлениеДоступом УправлениеДоступом.ПослеЗаписиНаСервере(ЭтотОбъект, ТекущийОбъект, ПараметрыЗаписи); // Конец СтандартныеПодсистемы.УправлениеДоступом ОпределитьНоменклатуруТребующуюВводГТД(); // СтандартныеПодсистемы.КонтрольВеденияУчета КонтрольВеденияУчета.ПослеЗаписиНаСервере(ТекущийОбъект); // Конец СтандартныеПодсистемы.КонтрольВеденияУчета Сообщить("Записали документ. Все норм! Сервер!", СтатусСообщения.Важное); КонецПроцедуры |
Конструкция у данной функции элементарная – текст сообщения и статус сообщения. Как мы можем убедиться при выполнении контекста клиента и в контексте сервера выведет на экран сообщению пользователю.
Пока мы не ушли дальше стоит обратить внимание на само окно сообщений (интерфейс ‘Такси’). Если по какой-то причине оно закрылось и вы не успели прочитать все сообщения, то его можно не хитро открыть заново:
Идем дальше, поднимаем немного наши навыки в программирование и начинаем использовать общий объект ‘СообщениеПользователю’:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Процедура Справка() //свойство //ИдентификаторНазначения (TargetID) //- тип: 'УникальныйИдентификатор'. Привязывает сообщение к форме. В случае пустого значения привязывается к текущему объекту. //КлючДанных (DataKey) //- тип: 'Ссылка на объект'. Привязывает сообщение к объекту или ключу записи. //Поле (Field) //- тип: 'строка'. Путь к реквизиту формы. //ПутьКДанным (DataPath) //- тип: 'строка'. Имя реквизита формы (основного), через который мы можем получить реквизиты объекта. //Текст (Text) //- тип: 'Строка'. Текст сообщения пользователю. //Методы //Сообщить (Message) //- Выводит сообщение пользователю. //УстановитьДанные( <Объект> )(SetData) //- устанавливается объект, к которому требуется привязать сообщение. КонецПроцедуры |
В принципе если прочитать справку с первого раза ничего не понятно, поэтому нужны примеры.
Выведем сообщение в форме текущего документа с привязкой к полю формы ‘Контрагент’, при двойном щелчке по сообщению появляется сообщение под полем:
1 2 3 4 5 6 7 8 9 |
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Проверьте Контрагента!"; Сообщение.Поле = "Объект.Контрагент"; //путь к реквизитам формы указывается без "Объект.", к примеру "ИнфоКомментарий" Сообщение.Сообщить(); КонецПроцедуры |
Выведем сообщение в форме текущего документа с привязкой к полю ‘Количество’ табличной части ‘Товары’, при двойном щелчке по сообщению появляется сообщение под полем:
1 2 3 4 5 6 7 8 9 |
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Проверьте количество!"; Сообщение.Поле = "Объект.Товары[0].Количество"; Сообщение.Сообщить(); КонецПроцедуры |
Выведем сообщение в форме текущего документа с привязкой к полю ‘Организация’ и его реквизиту ‘Наименование’ (говорим что необходимо проверить реквизит наименование у организации). При двойном щелчке по сообщению откроется значение из поля ‘Организация’, и появится сообщение под полем ‘Наименование’. Простыми словами мы подготавливаем информацию для сообщения в другой форме, которая откроется по щелчку по сообщению в текущей форме:
1 2 3 4 5 6 7 8 9 10 11 |
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Проверьте наименование организации!"; Сообщение.Поле = "Наименование"; Сообщение.КлючДанных = Объект.Организация; Сообщение.ПутьКДанным = "Объект"; Сообщение.Сообщить(); КонецПроцедуры |
Выведем сообщение из модуля объекта с привязкой к реквизиту объекта ‘МестоХранения’:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Процедура ОбработкаПроведения(Отказ, РежимПроведения) Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Привет из модуля объекта!"; Сообщение.Поле = "МестоХранения"; Сообщение.КлючДанных = ЭтотОбъект.Ссылка; Сообщение.ПутьКДанным = "Объект"; Сообщение.Сообщить(); СформироватьДвиженияПоМестамХранения(); СформироватьБухгалтерскиеДвижения(); КонецПроцедуры |
Выведем сообщение для новой открываемой формы. Откроется форма реквизита ‘Партнер’ с уже сформированный сообщением для пользователя:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
&НаКлиенте Процедура ПередЗаписью(Отказ, ПараметрыЗаписи) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("Ключ", Объект.Партнер); Форма = ОткрытьФорму("Справочник._ДемоПартнеры.Форма.ФормаЭлемента", ПараметрыФормы, ЭтаФорма); Сообщение = Новый СообщениеПользователю; Сообщение.ИдентификаторНазначения = Форма.УникальныйИдентификатор; Сообщение.Текст = "Привет из другой формы!"; Сообщение.Поле = "Объект.Наименование"; Сообщение.Сообщить(); КонецПроцедуры |
В общем вариантов исполнения много. Спасибо материалу с сайта ‘инфостарт’. В идеале можно воспользоваться уже готовым конструктором из ‘БСП’ для формирования сообщения пользователю. В разных вариациях она есть в типовых конфигурациях и зачастую её достаточно что бы с ней работать (ищите в своих конфигурациях и без необходимости не засоряйте своими дублями):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
ОбщегоНазначения.СообщитьПользователю(ТекстОшибки, , "Объект.ФормулаРасчетаКурса"); //ОбщегоНазначения Процедура СообщитьПользователю( Знач ТекстСообщенияПользователю, Знач КлючДанных = Неопределено, Знач Поле = "", Знач ПутьКДанным = "", Отказ = Ложь) Экспорт ЭтоОбъект = Ложь; Если КлючДанных <> Неопределено И XMLТипЗнч(КлючДанных) <> Неопределено Тогда ТипЗначенияСтрокой = XMLТипЗнч(КлючДанных).ИмяТипа; ЭтоОбъект = СтрНайти(ТипЗначенияСтрокой, "Object.") > 0; КонецЕсли; ОбщегоНазначенияСлужебныйКлиентСервер.СообщитьПользователю( ТекстСообщенияПользователю, КлючДанных, Поле, ПутьКДанным, Отказ, ЭтоОбъект); КонецПроцедуры //ОбщегоНазначенияСлужебныйКлиентСервер Процедура СообщитьПользователю( Знач ТекстСообщенияПользователю, Знач КлючДанных, Знач Поле, Знач ПутьКДанным = "", Отказ = Ложь, ЭтоОбъект = Ложь) Экспорт Сообщение = Новый СообщениеПользователю; Сообщение.Текст = ТекстСообщенияПользователю; Сообщение.Поле = Поле; Если ЭтоОбъект Тогда Сообщение.УстановитьДанные(КлючДанных); Иначе Сообщение.КлючДанных = КлючДанных; КонецЕсли; Если НЕ ПустаяСтрока(ПутьКДанным) Тогда Сообщение.ПутьКДанным = ПутьКДанным; КонецЕсли; Сообщение.Сообщить(); Отказ = Истина; КонецПроцедуры |
Так же мы можем использовать и альтернативный вариант общения с пользователем через функции глобального контекста ‘ПоказатьОповещениеПользователя’. Доступно только на клиенте! Плюс здесь в том, что мы не привязываемся к какому-либо объекту формы. Давайте выведем оповещение для пользователя о том что был закрыт документ и при нажатии на оповещение, откроем его:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
&НаКлиенте Процедура ПриЗакрытии(ЗавершениеРаботы) ТекстОповещения = "О, мы что-то сделали!"; ДействиеПриНажатии = ПолучитьНавигационнуюСсылку(Объект.Ссылка); //Тип либо строка с навигационной ссылкой, то будет открыт объект по ссылке //Так же может быть оповещение, которое будет вызвано при нажатии на окно оповещения Пояснение = "Просто пояснение craft1c"; Картинка = БиблиотекаКартинок.Информация32; Статус = СтатусОповещенияПользователя.Важное; КлючУникальности = Неопределено; //КлючУникальности //Если ключ задан и существует открытое оповещение с таким же ключом, то оно будет заменено на новое. //Если параметр не указан или имеет тип Неопределено, то оповещение считается уникальным. //В режимах интерфейса, отличных от Такси, этот параметр игнорируется. //Значение по умолчанию: Неопределено. ПоказатьОповещениеПользователя(ТекстОповещения, ДействиеПриНажатии, Пояснение, Картинка, Статус, КлючУникальности); КонецПроцедуры |
Максимально подробно постарался в комментариях оставить для себя и для вас заметки о параметрах оповещения пользователя. Давайте для примера попробуем использовать в качестве действия оповещение. При изменении организации выведем сообщение пользователю, а нажатие обработаем в оповещении открытие организации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
&НаКлиенте Процедура ОрганизацияПриИзменении(Элемент) ТекстОповещения = "О, мы что-то сделали!"; //ДействиеПриНажатии = ПолучитьНавигационнуюСсылку(Объект.Ссылка); //Тип либо строка с навигационной ссылкой, то будет открыт объект по ссылке //Так же может быть оповещение, которое будет вызвано при нажатии на окно оповещения СтруктураПараметров = Новый Структура; СтруктураПараметров.Вставить("СсылкаНаОбъект", Объект.Организация); ДействиеПриНажатии = Новый ОписаниеОповещения("ОбработкаСообщенияПользователя", ЭтотОбъект, СтруктураПараметров); Пояснение = "Просто пояснение craft1c"; Картинка = БиблиотекаКартинок.Информация32; Статус = СтатусОповещенияПользователя.Важное; КлючУникальности = Неопределено; //КлючУникальности //Если ключ задан и существует открытое оповещение с таким же ключом, то оно будет заменено на новое. //Если параметр не указан или имеет тип Неопределено, то оповещение считается уникальным. //В режимах интерфейса, отличных от Такси, этот параметр игнорируется. //Значение по умолчанию: Неопределено. ПоказатьОповещениеПользователя(ТекстОповещения, ДействиеПриНажатии, Пояснение, Картинка, Статус, КлючУникальности); КонецПроцедуры &НаКлиенте Процедура ОбработкаСообщенияПользователя(ПараметрыОповещения) Экспорт Если ПараметрыОповещения.Свойство("СсылкаНаОбъект") Тогда ОткрытьЗначение(ПараметрыОповещения.СсылкаНаОбъект); КонецЕсли; КонецПроцедуры |
Заметьте, описание оповещения здесь идет с одним параметром ‘ПараметрыОповещения’. Так же оно может располагаться и в общем модуле. Более детально поговорим об описании оповещений в отдельной статье!
Так же мы можем использовать функцию глобального контекста ‘Состояние’ для взаимодействия с пользователем. Этот вывод сообщения мне нравится тем, что в нем можно использовать индикатор прогресса. Все очень просто, с этим вы разберетесь без проблем:
1 2 3 4 5 6 |
&НаКлиенте Процедура ПриЗакрытии(ЗавершениеРаботы) Состояние("Это наше состояние: ", 25, "Пояснение", БиблиотекаКартинок.Информация32); КонецПроцедуры |
Если еще немного покопаться, то можно найти еще пару способов, каким образом можно вывести сообщению пользователю. Один из них это клиентский не модальный метод глобального контекста ‘ПоказатьПредупрежедение’. Фишка в том, что при показе предупреждения клиентский код все равно продолжит свое выполнение. Так же здесь можно использовать при необходимости форматную строку и оповещение, которое будет вызвано после нажатии кнопки ‘ОК’:
1 2 3 4 5 6 7 8 9 10 |
&НаКлиенте Процедура ОрганизацияПриИзменении(Элемент) СтрокаСообщения = Новый ФорматированнаяСтрока(Строка(Объект.Организация),,,, ПолучитьНавигационнуюСсылку(Объект.Организация)); ТекстСообщения = Новый ФорматированнаяСтрока("Изменена организация в документе: """, СтрокаСообщения,""""); ПоказатьПредупреждение(, ТекстСообщения,, "Заголовок сообщения"); //ПоказатьПредупреждение(<Здесь если нужно делаем оповещение>, ТекстСообщения,, "Заголовок сообщения"); КонецПроцедуры |
Ну и пример с оповещением можно сделать для наглядности:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
&НаКлиенте Процедура ОрганизацияПриИзменении(Элемент) СтрокаСообщения = Новый ФорматированнаяСтрока(Строка(Объект.Организация),,,, ПолучитьНавигационнуюСсылку(Объект.Организация)); ТекстСообщения = Новый ФорматированнаяСтрока("Изменена организация в документе: """, СтрокаСообщения,""""); ПараметрыОповещения = Новый Структура; ПараметрыОповещения.Вставить("ТекстУРА", "УРА"); ОписаниеОповещения = новый ОписаниеОповещения("ПредупрежедениеПослеОтображения", ЭтаФорма, ПараметрыОповещения); ПоказатьПредупреждение(ОписаниеОповещения, ТекстСообщения,, "Заголовок сообщения"); КонецПроцедуры &НаКлиенте Процедура ПредупрежедениеПослеОтображения(ПараметрыОповещения) Экспорт Если ПараметрыОповещения.Свойство("ТекстУРА") Тогда Сообщить(ПараметрыОповещения.ТекстУРА); КонецЕсли; КонецПроцедуры |
Давайте еще рассмотрим бонусом интересные моменты, которые на прямую не связаны с выводом текста сообщений пользователю, но помогает нам с ними работать.
Допустим мы в процессе выполнения программного кода наплодили сообщений пользователю на сервере, но еще не показали их в клиентской части. Так вот! Эти сообщения можно получить и при желании удалить до показа непосредственно пользователю используя функцию глобального контекста ‘ПолучитьСообщенияПользователю‘! Давайте в процедуре ‘ОбработкаПроведения’ и процедуре формы ‘ПослеЗаписиНаСервере’ оставим наши сообщения и прочитаем, что же у нас накопилось:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//модуль объекта Процедура ОбработкаПроведения(Отказ, РежимПроведения) СформироватьДвиженияПоМестамХранения(); СформироватьБухгалтерскиеДвижения(); Сообщить("Записываем документ. Все норм!", СтатусСообщения.Информация); КонецПроцедуры //модуль формы &НаСервере Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи) ОпределитьНоменклатуруТребующуюВводГТД(); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Проверьте Контрагента!"; Сообщение.Поле = "Объект.Контрагент"; //путь к реквизитам формы указывается без "Объект.", к примеру "ИнфоКомментарий" Сообщение.Сообщить(); ИсходныеСообщенияПользователю = ПолучитьСообщенияПользователю(Истина); //Ложь - не удаляем полученные сообщения КонецПроцедуры |
И мы видим, что все то, что планируется для показа пользователю есть теперь у нас в массиве! И всего лишь одним параметром процедуры мы можем убрать все сообщения!
Так же все сообщения пользователю можно очистить с экрана с помощью метода ‘ОчиститьСообщения()’:
1 |
ОчиститьСообщения(); |
Казалось бы такая простая тема, но сколько есть тонкостей и возможностей только в одном сообщении пользователю в 1с!
Вот такими вот не сложными способами можно работать с сообщением пользователям в 1с. Надеюсь данная заметка была полезна. Я скорее всего не учел еще парочку нюансов, но для хорошей базы думаю этого будет достаточно. Эти примеры покроют 95 процентов задач с информированием пользователей в 1с! Всем удачи!
Добрый вечер. У меня такая задача: в модуле формы документа “Больничный лист” на сервере сравниваю два значения, полученные в результате запроса, если первое больше второго, необходимо вывести оповещение с текстом “Создать документ Разовое начисление?” с вариантами ответа “Да/нет”, если пользователь отвечает “Да”, то, не выходя из формы Больничного листа открыть форму документа “Разовое начисление”. Застопорилась еще на моменте передачи с серверной процедуры на клиентскую этого оповещения. Можете пример привести, как такое можно реализовать?
Привет. Смотри, вроде все просто: Пишешь функцию серверную, которая в результате вычисления что первое значение больше второго вернет истину, либо ложь. Вызываешь эту функцию с клиента и в результате получаешь значение: либо истина, либо ложь. И уже на клиенте ориентируясь на результат, вызываешь оповещение.
Смотри, можешь этот вопрос задать на моем форуме. Создай тему в разделе программирование. Там можно будет пример кода привести. И если что я смогу ответить тоже с примером форматированного кода. Так будет удобнее.