|
|||
pedagog
23.11.22 — 13:44 |
в документах и справочниках проверка срабатывает при записи, а как сделать в обработке, чтобы при нажатии на кнопку срабатывала проверка реквизитов, для которых стоит «выдавать ошибку»? |
||
vicof
1 — 23.11.22 — 13:47 |
Ты не поверишь… |
||
pedagog
2 — 23.11.22 — 13:49 |
желающих поумничать прошу пройти мимо. |
||
Гений 1С
3 — 23.11.22 — 13:51 |
(0) написать код, не? |
||
Гений 1С
4 — 23.11.22 — 13:52 |
Совсем обленились новички, 77 не нюхали. Везде им галочки подавай |
||
НафНаф
5 — 23.11.22 — 13:53 |
есть же метод ПроверитьЗаполнение() |
||
pedagog
6 — 23.11.22 — 13:54 |
я написала Если НЕ ЗначениеЗаполнено(Объект.ФайлДанных) Тогда |
||
Ryzeman
7 — 23.11.22 — 13:59 |
(6) Может, любви, может, нормального асинхронного вызова, может, вывести сообщение возле элемента через ОбщегоНазначенияКлиент.СообщитьПользователю() Не проще у него спросить?) Видел (2), но не удержался, извини |
||
Kassern
8 — 23.11.22 — 14:02 |
(6) Какая конфа? Может вы на сервере пытались ПоказатьПредупреждение?) |
||
Kassern
9 — 23.11.22 — 14:04 |
Опять же, лучше собрать массив из ошибок и вывести их все, желательно с привязкой к объекту заполнения. 1ска это позволяет через метод СообщениеПользователю |
||
Ryzeman
10 — 23.11.22 — 14:08 |
(8) Я не верю что кроме найтхантераливингстара есть хоть 1 программист который не проверяет выполнение своего кода) Я так понимаю у неё всё работает, но РП не нравится |
||
ass1c
11 — 23.11.22 — 14:10 |
Просто РП хочет проверить на знание типовых механизмов //Процедура кнопки на форме
&НаКлиенте //Модуль объекта: Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) |
||
pedagog 12 — 23.11.22 — 15:34 |
спасибо, все получилось |
В этой статье я рассмотрю основные механизмы платформы 1С 8.3, которые обеспечивают проверку заполнения реквизитов.
Проверка заполнения реквизита объекта 1С
У любого реквизита объекта 1С можно настроить проверку заполнения, когда нельзя сохранить новый элемент объекта, не заполнив этот реквизит. Выйдет ошибка.
Для того, чтобы у реквизита объекта осуществлялась проверка заполнения, достаточно в свойстве реквизита «Проверка заполнения» указать значение «Выдавать ошибку».
При таком конфигурировании реквизита, если это реквизит не заполнен, то при попытке записи элемента, выйдет соответствующая ошибка, и запись элемента не будет осуществлена.
Данная проверка будет осуществляться независимо от того, сгенерирована эта форма платформой 1С 8.3 автоматически, или используется форма созданная разработчиком.
Проверка заполнения табличной части в 1С
Помимо реквизитов у объектов можно проверять заполнение табличной части. Для этого у табличных частей объектов имеется свойство «Проверка заполнения», в которое также необходимо установить значение «Выдавать ошибку».
Если в этом случае мы попытаемся записать элемент, в котором будет табличная часть без строк, то выйдет ошибка, и записать элемент не получится.
В тоже время, мы спокойно сможем записать элемент, у которого имеется строка табличной части с пустыми полями.
Если мы хотим проверять реквизиты табличной части, то у них нужно заполнить аналогичное свойство.
Проверка заполнения программно в 1С
Иногда возникает необходимость проверить программно заполнение объекта в 1С. Для этих целей предназначен метод ПроверитьЗаполнение(), который имеется у большинства объектов 1С (справочники, документы и т.д.).
Например, во время программного создания элемента справочника, мы можем проверить заполнение реквизитов этого справочника, перед его записью.
НовОбъект = Справочники.Номенклатура.СоздатьЭлемент(); НовОбъект.Наименование = "Товар"; Если НовОбъект.ПроверитьЗаполнение() Тогда НовОбъект.Записать(); КонецЕсли;
В этом случае, элемент справочника не будет записан, если у него имеются реквизиты, у которых в свойстве ПроверкаЗаполнения установлено значение «Выдавать ошибку».
Иногда, нужно проверить заполнение реквизита, у которого в свойстве «Проверка заполнения» установлено значение «Не проверять». Например, у реквизита Артикул справочника Номенклатура.
Если нам нужно осуществлять проверку этого реквизита (например, по какой-то определенной логике), то необходимо в модуле объекта создать метод ОбработкаПроверкиЗаполнения.
У этого метода, который является процедурой, имеется параметр ПроверяемыеРеквизиты. Этот параметр массив, в котором содержится список имен реквизитов, которые нужно проверять. Если в этот список мы добавим название реквизита, то при сохранении элемента будет осуществляться проверка на то, заполнен этот реквизит или нет.
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) ПроверяемыеРеквизиты.Добавить("Артикул"); КонецПроцедуры
Также, мы можем удалить реквизит из проверяемых, если по какой-то причине нет необходимости в проверке заполнения этого реквизита.
Например, удалим из проверяемых реквизит ПолноеНаименование.
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) Индекс = ПроверяемыеРеквизиты.Найти("ПолноеНаименование"); Если Индекс <> 0 Тогда ПроверяемыеРеквизиты.Удалить(Индекс); КонецЕсли; КонецПроцедуры
Тогда мы сможем спокойно записать элемент с незаполненным реквизитом ПолноеНаименование.
Если мы хотим проверить программно, что заполнен реквизит табличной части объекта, то необходимо добавить этот реквизит в массив ПроверяемыеРеквизиты по такому формату: [НазваниеТабличнойЧасти].[НазваниеРеквизита] .
Например:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) ПроверяемыеРеквизиты.Добавить("СписокСвойств.НазваниеСвойства"); КонецПроцедуры
В этом случае, будет осуществляться проверка заполнения реквизита табличной части.
Проверка заполнения формы 1С
Иногда нужно проверить заполнение реквизитов формы. Разберем небольшую задачу: будем на форме умножать два числа друг на друга, если они заполнены. Создадим на форме реквизиты с типом Число — Множитель1, Множитель2 и Сумма. У реквизитов Множитель1 и Множитель2 установим в свойство «Проверка заполнения» значение «Выдавать ошибку».
При выполнении команды Посчитать, произведем расчет только в том случае, если реквизиты заполнены. Проверку заполнения будем выполнять при помощи метода ПроверитьЗаполнение.
&НаКлиенте Процедура Посчитать(Команда) Если ПроверитьЗаполнение() Тогда Сумма = Множетель1 * Множетель2; КонецЕсли; КонецПроцедуры
Теперь мы не сможем посчитать сумму, если один из множителей не заполнен.
Более подробно и основательно начальные вопросы программирования в 1С есть вы можете изучить в
Книга «Программировать в 1С за 11 шагов»
Изучайте программирование в 1С в месте с моей книгой «Программировать в 1С за 11 шагов»
Книга написана понятным и простым языком — для новичка.
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Научитесь понимать архитектуру 1С;
- Станете писать код на языке 1С;
- Освоите основные приемы программирования;
- Закрепите полученные знания при помощи задачника.
О том как разрабатывать под управляемым приложением 1С, читайте в книге Книга «Основы разработки в 1С: Такси»
Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.
- Очень доступный и понятный язык изложения
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Поймете идеологию управляемого приложения 1С
- Узнаете, как разрабатывать управляемое приложение;
- Научитесь разрабатывать управляемые формы 1С;
- Сможете работать с основными и нужными элементами управляемых форм
- Программирование под управляемым приложением станет понятным
Промо-код на скидку в 15% — 48PVXHeYu
Эти книги, плюс книга по программированию оперативного учета имеются в едином комплекте: комплект книг по разработке в 1С.
Только для читателей моего блога,
промо-код на скидку в 300 рублей на весь комплект: blog
Если Вам понравился этот урок, был полезен или помог решить какую-нибудь проблему, то Вы можете поддержать мой проект, перечислив любую сумму.
можно оплатить вручную:
Яндекс.Деньги — 410012882996301
Web Money — R955262494655
Вступайте в мои группы:
Вконтакте: https://vk.com/1c_prosto
Фейсбуке: https://www.facebook.com/groups/922972144448119/
ОК: http://ok.ru/group/52970839015518
Твиттер: https://twitter.com/signum2009
О чем эта статья
Статья продолжает цикл статей «Первые шаги в разработке на 1С».
В ней мы рассмотрим способы информирования пользователя, которые присутствуют в платформе «1С:Предприятие» 8, а также акцентируем ваше внимание на некоторых особенностях работы этих механизмов, эти особенности связаны с режимом использования модальности.
Применимость
В статье рассматривается функциональность:
- Интерфейса в варианте «Версии 8.2» для конфигурации, разработанной на платформе «1С:Предприятие» 8.2.19.130
- Интерфейса «Такси» для конфигурации, разработанной на платформе «1С:Предприятие» 8.3.4.496 до 8.3.9+
- Интерфейса «Такси» для конфигурации, разработанной на платформе «1С:Предприятие» 8.3.10-8.3.11
Как в 1С вывести сообщение пользователю
- Ознакомительные сообщения
- Механизм оповещений
- Терминирующие сообщения
- Особенности использования модальных окон в Платформе 8.3
- Класс СообщениеПользователю
- Уведомление о состоянии процесса
Вывод сообщений в пользовательском режиме решает ряд задач:
- отражение хода выполнения текущего процесса (показ стадии выполнения процесса; показ расчетных значений, полученных в ходе работы алгоритма);
- выдача ошибок пользователю для возможного их исправления;
- выдача рекомендаций;
Типы сообщений:
- терминирующие, которые останавливают выполнение программы и не дают продолжить ее, пока пользователь не ознакомится с этим сообщением и не выполнит определенные действия. Например, на экран пользователю будет выдан вопрос, на который нужно будет ответить Да или Нет. Пока пользователь не ответит – программа не выполняет дальнейшие действия;
- ознакомительные сообщения, которые просто выводятся для пользователя и позволяют работать дальше (т.е. используются в режиме оповещения).
Терминирующими сообщениями должны быть сообщения об ошибках, а ознакомительными: рекомендации, сообщения о текущем этапе процесса и показ расчетных значений (отладочная печать).
Ознакомительные сообщения
Ознакомительные сообщения предназначены для того, чтобы выдать пользователю некоторую информацию.
Необходимо, чтобы пользователь с ней обязательно ознакомился и, возможно, предпринял какие-то действия, которые описаны в этом сообщении.
Очень важно, чтобы пользователь действительно читал эти сообщения, поэтому они должны содержать только важную информацию.
Тестовые и отладочные сообщения выдавать пользователю не стоит, т.к. рано или поздно он начнет игнорировать абсолютно все сообщения.
В концепции управляемого интерфейса несколько изменился подход к выдаче сообщения. Оно теперь привязано к форме, в которой возникло. Его уже нельзя закрыть так, чтобы текст было совсем невидно.
Открепить от формы окно с сообщением нельзя.
Синтаксис функции:
Сообщить (<Текст сообщения>, <Статус>)
Т.е. первым параметром является сам текст.
Второй параметр (статус сообщения) является необязательным. Для статуса можно указывать значения: Обычное, Важное, ОченьВажное и т.д.
От данного значения зависит, какой значок будет расположен рядом с сообщением. Однако это работает только в обычном интерфейсе.
В концепции управляемого интерфейса значок всегда в виде восклицательного знака, переопределить его нельзя.
Дело в том, что если сообщение будет формироваться в момент записи элемента справочника, может произойти следующая ситуация.
Пользователь нажимает на кнопку Записать и закрыть, в этом случае сообщение выводится в соответствующее окно (справа формы).
Но форма моментально закрывается, и пользователь не увидит, что для него выводилась какая-то информация.
Поэтому в концепции управляемого приложения ознакомительные сообщения рекомендуется выводить с помощью так называемых оповещений. Пример неправильного использования функции Сообщить представлен на рисунке.
Тем не менее, функция Сообщить может использоваться для вывода информации о некоторых ошибках, например в момент проведения документа.
В этом случае системе можно сообщить, что форму закрывать не нужно, и показать пользователю, какие ошибки возникают при проведении документа.
Функция Сообщить полностью поддерживается в Платформе 8.3. Ее можно использовать, и она будет работать (и в файловом варианте, и в клиент-серверном).
Но также следует отметить, что у функции Сообщить есть дальнейшее развитие – это класс сообщения пользователю, который позволяет помимо того, что выводить сообщение, привязывать его контекстно к каким-либо элементам формы.
Например, сообщение об ошибке можно привязать к элементу формы, что для пользователя очень наглядно. Несколько позже к рассмотрению этого вопроса мы вернемся. У функции Сообщить есть интересная особенность.
Так, программный код в Платформе 8.3 может быть исполнен как на стороне Клиента, так и на стороне Сервера.
При этом клиентский программный код отвечает за взаимодействие с пользователем, т.е. на стороне клиента открываются формы, выводятся отчеты.
Различные диалоговые документы также отображаются только на клиенте. На сервере они не могут быть исполнены, поскольку сервер не имеет возможности взаимодействия с пользователями.
Но функция Сообщить может быть исполнена как на стороне Клиента, так и на стороне Сервера. При этом использование метода Сообщить на Сервере вовсе не означает, что сообщение будет выводиться именно на Сервере, там их просто некуда выводить.
Это означает, что если мы в серверной процедуре будем выводить сообщение с помощью этого метода, они будут накапливаться в некотором буфере и выведутся они на экран только тогда, когда серверная процедура закончится и произойдет возврат на Клиента.
В этот момент система запросит данные из буфера и выведет их на экран.
Эта же особенность касается и класса СообщениеПользователю. На рисунке приведен пример использования метода Сообщить на стороне Сервера.
Дело в том, что если сообщение будет формироваться в момент записи элемента справочника, может произойти следующая ситуация.
Пользователь нажимает на кнопку Записать и закрыть, в этом случае сообщение выводится в соответствующее окно (справа формы).
Но форма моментально закрывается, и пользователь не увидит, что для него выводилась какая-то информация.
Поэтому в концепции управляемого приложения ознакомительные сообщения рекомендуется выводить с помощью так называемых оповещений. Пример неправильного использования функции Сообщить представлен на рисунке.
Тем не менее, функция Сообщить может использоваться для вывода информации о некоторых ошибках, например в момент проведения документа.
В этом случае системе можно сообщить, что форму закрывать не нужно, и показать пользователю, какие ошибки возникают при проведении документа.
Функция Сообщить полностью поддерживается в Платформе 8.3. Ее можно использовать, и она будет работать (и в файловом варианте, и в клиент-серверном).
Но также следует отметить, что у функции Сообщить есть дальнейшее развитие – это класс сообщения пользователю, который позволяет помимо того, что выводить сообщение, привязывать его контекстно к каким-либо элементам формы.
Например, сообщение об ошибке можно привязать к элементу формы, что для пользователя очень наглядно. Несколько позже к рассмотрению этого вопроса мы вернемся. У функции Сообщить есть интересная особенность.
Так, программный код в Платформе 8.3 может быть исполнен как на стороне Клиента, так и на стороне Сервера.
При этом клиентский программный код отвечает за взаимодействие с пользователем, т.е. на стороне клиента открываются формы, выводятся отчеты.
Различные диалоговые документы также отображаются только на клиенте. На сервере они не могут быть исполнены, поскольку сервер не имеет возможности взаимодействия с пользователями.
Но функция Сообщить может быть исполнена как на стороне Клиента, так и на стороне Сервера. При этом использование метода Сообщить на Сервере вовсе не означает, что сообщение будет выводиться именно на Сервере, там их просто некуда выводить.
Это означает, что если мы в серверной процедуре будем выводить сообщение с помощью этого метода, они будут накапливаться в некотором буфере и выведутся они на экран только тогда, когда серверная процедура закончится и произойдет возврат на Клиента.
В этот момент система запросит данные из буфера и выведет их на экран.
Эта же особенность касается и класса СообщениеПользователю. На рисунке приведен пример использования метода Сообщить на стороне Сервера.
В результате использования метода Сообщить на стороне Сервера вывелись сообщения на экран на стороне Клиента.
Механизм оповещений
Механизм оповещений нужен, чтобы информировать пользователя о том, что в системе “что-то” произошло и это “что-то” требует внимания пользователя. Оповещения создаются двумя сценариями:
- Самой платформой при интерактивной записи или изменении объекта
- Разработчиком при вызове в коде метода ПоказатьОповещениеПользователя().
Само оповещение представляет собой небольшое окошко, которое появляется, как правило, в нижнем правом углу и сообщает о совершенном действии. В течение нескольких секунд оно постепенно гаснет и пропадает. При этом, если навести на оповещение курсор мышки, оно не гаснет и можно внимательно его прочитать.
Кроме того, к оповещениям можно обратиться в соответствующей области информационной панели (кнопка “История” слева внизу формы приложения в варианте интерфейса «Версии 8.2»).
Чтобы создавать свои собственные оповещения, необходимо использовать метод глобального контекста ПоказатьОповещениеПользователя(). Его синтаксис до редакции 8.3.10 представлен ниже:
ПоказатьОповещениеПользователя (<Текст>, <НавигационнаяССылка>, <Пояснение>, <Картинка>)
В первом параметре передается текст, который будет выводиться в оповещении.
Далее вторым параметром можно передать некую навигационную ссылку на какой-либо элемент информационной базы (тот элемент, который соответствует тексту нашего сообщения). При нажатии пользователем на оповещение будет выполнен переход по этой ссылке.
С помощью третьего параметра можно передать пояснение для сообщения, т.е. какое-то расширенное описание.
Также можно присвоить картинку, отображающую статус оповещения.
Следует отметить, что все эти параметры являются необязательными для заполнения. Ниже приведен пример использования данного метода (в конфигураторе и в пользовательском режиме в варианте интерфейса «Версии 8.2»).
В редакции платформы 8.3.10.216 для интерфейса в варианте «Такси» механизм оповещений был существенным образом доработан с целью повышения удобства работы как в тонком, так и в веб-клиенте. По этой причине изменились и передаваемые параметры в метод ПоказатьОповещениеПользователя(). Теперь синтаксис выглядят так:
ПоказатьОповещениеПользователя(<Текст>, <ДействиеПриНажатии>, <Пояснение>, <Картинка>, <СтатусОповещенияПользователя>, <КлючУникальности>)
Видно, что второй параметр, ранее называемый НавигационнаяСсылка, получил новое имя ДействиеПриНажатии. Это связано с тем, что теперь в него стало возможным передавать не только строку с навигационной ссылкой, но и описание оповещения. Это проиллюстрировано скриншотом ниже:
Как видно из примера, у нас появилась возможность программным образом обрабатывать нажатие на окно с оповещением, согласно той логике, которая необходима.
Следующий параметр СтатусОповещенияПользователя появился впервые. В нем указывается статус оповещения (Информация или Важное).
В случае варианта Важное, если пользователь не отреагировал на сообщение, то после того, как оно будет скрыто с экрана, его можно будет прочитать через Центр оповещений (о нем ниже). В случае же варианта Информация, оповещение удаляется без запоминания в этом центре. Давайте перепишем код из нашего примера, как показано ниже:
После выполнения команды получим приблизительно такой вид окна приложения:
В панели инструментов появилась кнопка с пиктограммой звонка, по которой вызывается упомянутый выше Центр оповещений. В нем накапливаются новые важные оповещения, на которые пользователь пока никак не отреагировал.
Если в Центре есть какие-то оповещения, то рядом с ним появляется маленькая оранжевая точка, чтобы привлечь внимание пользователя. Пользователь может открыть Центр оповещений, прочитать текст и, если необходимо, выполнить какие-то действия.
Из Центра оповещение убирается нажатием на кнопку очистки, однако если с оповещением связано какое-то действие, то, как только пользователь щелкнет мышью по тексту сообщения, оно тоже пропадет.
И наконец, последним добавленным параметром стал КлючУникальности. С его помощью можно найти отображенное на экране оповещение и изменить его. Если же оповещения с таким параметром нет, то будет показано новое оповещение.
Как видим, возможностей, предоставляемых соответствующим методом, стало еще больше! Но это не все изменения в механизме оповещений.
Как вы уже, наверное, успели заметить, изменился их внешний вид. Теперь оповещения выглядят более современно и эргономично, но их нельзя перемещать по экрану и изменять их размер. Обратите внимание, в нашем примере, текст оповещения попросту не поместился целиком в самом окне, и прочитать его полностью пользователь сможет, только открыв Центр Оповещений. Поэтому не стоит в текст оповещения писать большое количество текста.
Также к новым возможностям относится и одновременное отображение на экране до трех оповещений.
На этом завершим наше знакомство с программным формированием оповещений. Однако вспомним, что оповещения формируются не только разработчиком программно, но и самой платформой в момент интерактивной записи или изменения объекта. И часто этот факт вызывает непонимание в первую очередь у начинающих пользователей: зачем нужны эти служебные оповещения, которые, кстати, нельзя отключить?
Давайте представим такую простую ситуацию: пользователь установил фильтр в каком-то списке для удобства. Допустим, он сделал это в форме списка справочника Номенклатуры. Потом, через какое-то время, решил ввести новый элемент с наименованием “Стул”, который не соответствует установленному ранее фильтру. Вводит его, записывает и…? И не видит его в списке. Что будет делать среднестатистический пользователь? Конечно, введет его второй раз, но опять не увидит. Дальше может последовать третий, четвертый, пятый раз. Когда ему надоест вводить одно и тоже, он, наконец, спросит у вас: а куда все пропадает?
Вот именно поэтому платформа и отображает эти служебные оповещения, информируя пользователя о том, что его действие выполнено. В нашем примере в момент интерактивной записи пользователь увидит следующее оповещение:
Терминирующие сообщения
Терминирующие сообщения – это те сообщения, которые не позволят работать, пока пользователь не произведет определенные действия, т.е. пока он не обработает сообщение.
О возможности использования терминирующих сообщений в Платформе 8.3 мы поговорим немного позже (в последнее время их стараются не использовать, поэтому рассмотренный пример больше касается Платформы 8.2).
Существуют два метода для выдачи терминирующих сообщений Предупреждение и Вопрос. Предупреждение отличается от Вопроса тем, что у него есть единственная кнопка ОК.
В вопросе могут определяться разные наборы вариантов ответов (ДаНет, ДаНетОтмена, ОК, ОКОтмена, ПовторитьОтмена, ПрерватьПовторитьПропустить), которые задаются с помощью параметра.
Выведем какое-нибудь предупреждение с помощью строки (например, в модуле управляемого приложения):
Предупреждение(“Сейчас будет открыта база”);
Чтобы открыть модуль управляемого приложения, следует в дереве конфигурации выбрать объект Конфигурация, вызвать контекстное меню и выбрать пункт Открыть модуль управляемого приложения.
Механизм оповещений
Механизм оповещений нужен, чтобы информировать пользователя о том, что в системе “что-то” произошло и это “что-то” требует внимания пользователя. Оповещения создаются двумя сценариями:
- Самой платформой при интерактивной записи или изменении объекта
- Разработчиком при вызове в коде метода ПоказатьОповещениеПользователя().
Само оповещение представляет собой небольшое окошко, которое появляется, как правило, в нижнем правом углу и сообщает о совершенном действии. В течение нескольких секунд оно постепенно гаснет и пропадает. При этом, если навести на оповещение курсор мышки, оно не гаснет и можно внимательно его прочитать.
Кроме того, к оповещениям можно обратиться в соответствующей области информационной панели (кнопка “История” слева внизу формы приложения в варианте интерфейса «Версии 8.2»).
Чтобы создавать свои собственные оповещения, необходимо использовать метод глобального контекста ПоказатьОповещениеПользователя(). Его синтаксис до редакции 8.3.10 представлен ниже:
ПоказатьОповещениеПользователя (<Текст>, <НавигационнаяССылка>, <Пояснение>, <Картинка>)
В первом параметре передается текст, который будет выводиться в оповещении.
Далее вторым параметром можно передать некую навигационную ссылку на какой-либо элемент информационной базы (тот элемент, который соответствует тексту нашего сообщения). При нажатии пользователем на оповещение будет выполнен переход по этой ссылке.
С помощью третьего параметра можно передать пояснение для сообщения, т.е. какое-то расширенное описание.
Также можно присвоить картинку, отображающую статус оповещения.
Следует отметить, что все эти параметры являются необязательными для заполнения. Ниже приведен пример использования данного метода (в конфигураторе и в пользовательском режиме в варианте интерфейса «Версии 8.2»).
В редакции платформы 8.3.10.216 для интерфейса в варианте «Такси» механизм оповещений был существенным образом доработан с целью повышения удобства работы как в тонком, так и в веб-клиенте. По этой причине изменились и передаваемые параметры в метод ПоказатьОповещениеПользователя(). Теперь синтаксис выглядят так:
ПоказатьОповещениеПользователя(<Текст>, <ДействиеПриНажатии>, <Пояснение>, <Картинка>, <СтатусОповещенияПользователя>, <КлючУникальности>)
Видно, что второй параметр, ранее называемый НавигационнаяСсылка, получил новое имя ДействиеПриНажатии. Это связано с тем, что теперь в него стало возможным передавать не только строку с навигационной ссылкой, но и описание оповещения. Это проиллюстрировано скриншотом ниже:
Как видно из примера, у нас появилась возможность программным образом обрабатывать нажатие на окно с оповещением, согласно той логике, которая необходима.
Следующий параметр СтатусОповещенияПользователя появился впервые. В нем указывается статус оповещения (Информация или Важное).
В случае варианта Важное, если пользователь не отреагировал на сообщение, то после того, как оно будет скрыто с экрана, его можно будет прочитать через Центр оповещений (о нем ниже). В случае же варианта Информация, оповещение удаляется без запоминания в этом центре. Давайте перепишем код из нашего примера, как показано ниже:
После выполнения команды получим приблизительно такой вид окна приложения:
В панели инструментов появилась кнопка с пиктограммой звонка, по которой вызывается упомянутый выше Центр оповещений. В нем накапливаются новые важные оповещения, на которые пользователь пока никак не отреагировал.
Если в Центре есть какие-то оповещения, то рядом с ним появляется маленькая оранжевая точка, чтобы привлечь внимание пользователя. Пользователь может открыть Центр оповещений, прочитать текст и, если необходимо, выполнить какие-то действия.
Из Центра оповещение убирается нажатием на кнопку очистки, однако если с оповещением связано какое-то действие, то, как только пользователь щелкнет мышью по тексту сообщения, оно тоже пропадет.
И наконец, последним добавленным параметром стал КлючУникальности. С его помощью можно найти отображенное на экране оповещение и изменить его. Если же оповещения с таким параметром нет, то будет показано новое оповещение.
Как видим, возможностей, предоставляемых соответствующим методом, стало еще больше! Но это не все изменения в механизме оповещений.
Как вы уже, наверное, успели заметить, изменился их внешний вид. Теперь оповещения выглядят более современно и эргономично, но их нельзя перемещать по экрану и изменять их размер. Обратите внимание, в нашем примере, текст оповещения попросту не поместился целиком в самом окне, и прочитать его полностью пользователь сможет, только открыв Центр Оповещений. Поэтому не стоит в текст оповещения писать большое количество текста.
Также к новым возможностям относится и одновременное отображение на экране до трех оповещений.
На этом завершим наше знакомство с программным формированием оповещений. Однако вспомним, что оповещения формируются не только разработчиком программно, но и самой платформой в момент интерактивной записи или изменения объекта. И часто этот факт вызывает непонимание в первую очередь у начинающих пользователей: зачем нужны эти служебные оповещения, которые, кстати, нельзя отключить?
Давайте представим такую простую ситуацию: пользователь установил фильтр в каком-то списке для удобства. Допустим, он сделал это в форме списка справочника Номенклатуры. Потом, через какое-то время, решил ввести новый элемент с наименованием “Стул”, который не соответствует установленному ранее фильтру. Вводит его, записывает и…? И не видит его в списке. Что будет делать среднестатистический пользователь? Конечно, введет его второй раз, но опять не увидит. Дальше может последовать третий, четвертый, пятый раз. Когда ему надоест вводить одно и тоже, он, наконец, спросит у вас: а куда все пропадает?
Вот именно поэтому платформа и отображает эти служебные оповещения, информируя пользователя о том, что его действие выполнено. В нашем примере в момент интерактивной записи пользователь увидит следующее оповещение:
Терминирующие сообщения
Терминирующие сообщения – это те сообщения, которые не позволят работать, пока пользователь не произведет определенные действия, т.е. пока он не обработает сообщение.
О возможности использования терминирующих сообщений в Платформе 8.3 мы поговорим немного позже (в последнее время их стараются не использовать, поэтому рассмотренный пример больше касается Платформы 8.2).
Существуют два метода для выдачи терминирующих сообщений Предупреждение и Вопрос. Предупреждение отличается от Вопроса тем, что у него есть единственная кнопка ОК.
В вопросе могут определяться разные наборы вариантов ответов (ДаНет, ДаНетОтмена, ОК, ОКОтмена, ПовторитьОтмена, ПрерватьПовторитьПропустить), которые задаются с помощью параметра.
Выведем какое-нибудь предупреждение с помощью строки (например, в модуле управляемого приложения):
Предупреждение(“Сейчас будет открыта база”);
Чтобы открыть модуль управляемого приложения, следует в дереве конфигурации выбрать объект Конфигурация, вызвать контекстное меню и выбрать пункт Открыть модуль управляемого приложения.
В данном случае, при запуске приложения, будет выводиться окно, которое является модальным. Модальное окно перекрывает собой все окна, которые существуют в приложении. Пока мы не обработаем это окно, дальнейшие действия невозможны.
Аналогичным образом работает и функция Вопрос.
Синтаксис:
Вопрос(<ТекстВопроса>,<Кнопки>,<Таймаут>,<КнопкаПоУмолчанию>,<Заголовок>,
<КнопкаТаймаута>);
Обязательными являются только первые два параметра. Для второго параметра тип данных составной (РежимДиалогаВопрос или СписокЗначений). Третий параметр (<Таймаут>) характеризует интервал времени в секундах, в течение которого система будет ожидать ответа пользователя.
По истечении интервала окно вопроса будет закрыто. Аналогичный параметр(<Таймаут>) есть и у функции Предупреждение.
В качестве примера использования функции Вопрос можно использовать следующий код, записанный в модуле управляемого приложения:
Обращаю Ваше внимание, что данные методы (Предупреждение и Вопрос) не доступны на Сервере. И это логично, потому что интерфейсные методы не могут быть выполнены на Сервере, где нет пользователя.
Особенности использования модальных окон в Платформе 8.3
В платформе 8.3 существуют режимы работы с использованием и без использования модальности. По умолчанию стоит настройка Не использовать режим модальности.
В этом случае использование терминирующих сообщений невозможно. В случае необходимости использования терминирующих сообщений (функции Предупреждение и Вопрос) следует изменить значение свойства конфигурации Режим использования модальности на Использовать.
Модальное окно выводится на самый верх и блокирует работу с другими окнами до завершения действий с модальным окном. Кроме того, останавливается выполнение программного кода на том месте, где происходит вызов этого окна. Выполнение кода продолжится только после закрытия модального окна.
Во-первых, проблемы по использованию модальных окон возникают для мобильного приложения. Во-вторых, в браузере модальность окон реализуется с помощью отдельных всплывающих окон.
В настройках браузера по умолчанию всплывающие окна зачастую запрещены. Пользователя приходится заставлять устанавливать разрешение на эти окна.
Браузеры для планшетных компьютеров и для телефонов в большинстве случаев вообще не поддерживают всплывающие окна.
Для замены функций Вопрос и Предупреждение разработаны новые методы: ПоказатьВопрос, ПоказатьПредупреждение.
Эти методы позволяют вызывать окно, но не останавливать выполнение программного кода. Технически это реализуется формированием псевдоокна внутри родительского окна. Псевдоокно не перекрывает родительское окно. После открытия такого окна код продолжает выполняться.
Получение и обработка введенных пользователем значений осуществляется в отдельной процедуре, которая вызывается при закрытии диалогового окна.
Синтаксис функции ПоказатьПредупреждение:
ПоказатьПредупреждение(<ОписаниеОповещенияОЗавершении>, <ТекстПредупреждения>, <Таймаут>, <Заголовок>)
Параметр <ОписаниеОповещенияОЗавершении> (необязательный)
Тип данных: ОписаниеОповещения.
Содержит описание процедуры, которая будет вызвана после закрытия окна предупреждения.
Синтаксис функции ПоказатьВопрос:
ПоказатьВопрос(<ОписаниеОповещенияОЗавершении>, <ТекстВопроса>, <Кнопки>, <Таймаут>, <КнопкаПоУмолчанию>, <Заголовок>, <КнопкаТаймаута>)
Обязательными являются первые три параметра.
Ниже приведен пример использования функции.
Класс СообщениеПользователю
Основное удобство класса сообщений СообщениеПользователю заключается в том, что это контекстное сообщение (в отличии от методов Предупреждение и Вопрос).
Сообщения могут быть привязаны к конкретному экранному элементу. Этот объект доступен и на Сервере.
Следует обратить внимание, что, во-первых, данный объект нужно создавать. Например: Сообщение = Новый СообщениеПользователю;
Таким образом мы создаем экземпляр данного объекта.
Во-вторых, нужно прописывать текст сообщения в отдельном свойстве.
В-третьих, в свойстве Поле можно указать, к какому элементу формы данное сообщение должно быть привязано.
Внимание! Для привязки к нужному полю формы обратите внимание на инициализацию свойств ПутьКДанным и КлючДанных. Применительно для документа при размещении кода в модуле объекта можно писать:
Сообщение.ПутьКДанным = “Объект”;
Сообщение.КлючДанных = ЭтотОбъект.Ссылка;
Чтобы открыть модуль документа, следует в окне редактирования объекта (документа) на закладке Прочее нажать на кнопку Модуль объекта.
Для эксперимента в модуле объекта какого-либо документа разместим код.
Класс СообщениеПользователю
Основное удобство класса сообщений СообщениеПользователю заключается в том, что это контекстное сообщение (в отличии от методов Предупреждение и Вопрос).
Сообщения могут быть привязаны к конкретному экранному элементу. Этот объект доступен и на Сервере.
Следует обратить внимание, что, во-первых, данный объект нужно создавать. Например: Сообщение = Новый СообщениеПользователю;
Таким образом мы создаем экземпляр данного объекта.
Во-вторых, нужно прописывать текст сообщения в отдельном свойстве.
В-третьих, в свойстве Поле можно указать, к какому элементу формы данное сообщение должно быть привязано.
Внимание! Для привязки к нужному полю формы обратите внимание на инициализацию свойств ПутьКДанным и КлючДанных. Применительно для документа при размещении кода в модуле объекта можно писать:
Сообщение.ПутьКДанным = “Объект”;
Сообщение.КлючДанных = ЭтотОбъект.Ссылка;
Чтобы открыть модуль документа, следует в окне редактирования объекта (документа) на закладке Прочее нажать на кнопку Модуль объекта.
Для эксперимента в модуле объекта какого-либо документа разместим код.
Ниже представлен полученный в пользовательском режиме результат для Платформы 8.3.
Следует отметить, что сообщения, выводимые с помощью нового объекта системы СообщениеПользователю в общем случае не являются терминирующими. Т.е. система позволит пользователю продолжить дальнейшие действия не отреагировав на выводимые сообщения.
Но, во-первых, данные сообщения достаточно заметны. Во-вторых, обычно сообщения пользователю выводятся в момент записи элементов справочников или проведения документов, т.е., когда выполняются какие-то проверки. И если были обнаружены ошибки, то пользователь увидит эти самые сообщения.
Соответственно, в момент обнаружения ошибок отменяется транзакция, т.е. запрещается запись элемента справочника, либо запрещается проведение документа.
Таким образом, происходит своего рода эмуляция терминирующего сообщения. Потому что действие отменяется, пока пользователь не отреагирует на вводимое сообщение, завершить действие, например, провести документ, будет нельзя.
Но, с другой стороны, есть возможность закрыть документ без проведения, никак не прореагировав на сообщение. Поэтому данные сообщения пользователю не являются терминирующими.
Уведомление о состоянии процесса
Существует специальная функция, с помощью которой можно отображать примерный ход выполнения какого-либо процесса.
Синтаксис: Состояние(<ТекстСообщения>, <Прогресс>, <Пояснение>, <Картинка>)
Параметры: <ТекстСообщения> и <Пояснение> – не обязательные, тип – Строка.
Текст выводится на специальную панель состояния.
<Прогресс> параметр тоже необязательный, но наглядный.
Тип: Число. Значение индикатора прогресса (от 1 до 100).
<Картинка> тоже необязательный параметр.
При обработке какого-либо события могут использоваться периодические вызовы функции типа:
Следует отметить, что сообщения, выводимые с помощью нового объекта системы СообщениеПользователю в общем случае не являются терминирующими. Т.е. система позволит пользователю продолжить дальнейшие действия не отреагировав на выводимые сообщения.
Но, во-первых, данные сообщения достаточно заметны. Во-вторых, обычно сообщения пользователю выводятся в момент записи элементов справочников или проведения документов, т.е., когда выполняются какие-то проверки. И если были обнаружены ошибки, то пользователь увидит эти самые сообщения.
Соответственно, в момент обнаружения ошибок отменяется транзакция, т.е. запрещается запись элемента справочника, либо запрещается проведение документа.
Таким образом, происходит своего рода эмуляция терминирующего сообщения. Потому что действие отменяется, пока пользователь не отреагирует на вводимое сообщение, завершить действие, например, провести документ, будет нельзя.
Но, с другой стороны, есть возможность закрыть документ без проведения, никак не прореагировав на сообщение. Поэтому данные сообщения пользователю не являются терминирующими.
Уведомление о состоянии процесса
Существует специальная функция, с помощью которой можно отображать примерный ход выполнения какого-либо процесса.
Синтаксис: Состояние(<ТекстСообщения>, <Прогресс>, <Пояснение>, <Картинка>)
Параметры: <ТекстСообщения> и <Пояснение> – не обязательные, тип – Строка.
Текст выводится на специальную панель состояния.
<Прогресс> параметр тоже необязательный, но наглядный.
Тип: Число. Значение индикатора прогресса (от 1 до 100).
<Картинка> тоже необязательный параметр.
При обработке какого-либо события могут использоваться периодические вызовы функции типа:
При этом могут меняться надписи, а могут изменяться значения параметра Прогресс.
Функция может вызываться как из одной процедуры (функции), так и из нескольких. Таким образом можно отслеживать состояние выполнения процесса.
Если вы хотите ознакомиться с механизмом уведомления более подробно, то прямо сейчас прервитесь и прочтите нашу новую статью Отображение прогресса длительных операций в 8.3.10. В ней уже не на уровне новичка объясняются все тонкости и подводные камни работы этого механизма.
Мы же завершаем знакомство со способами информирования пользователя. Надеемся, что у вас сложилось понимание, в каких ситуациях следует применять тот или иной способ.
Хочется еще раз акцентировать ваше внимание на том факте, что если ваша конфигурация (версии 8.3.3+) предполагает работу с помощью веб-клиента, то:
- на уровне конфигурации должна быть установлена настройка режима модальности «Не использовать»
- в коде должны использоваться методы асинхронной модели взаимодействия с пользователем. Такие методы начинаются со слов Показать или Начать.
Более подробно об отказе от использования модальных окон в платформе 1С:Предприятие 8.3 можно почитать в финальной статье цикла. А мы идем дальше и, наконец, приступаем к изучению долгожданного интерфейса «Такси», который уже не раз упоминался в наших материалах.
Если вы хотите ознакомиться с механизмом уведомления более подробно, то прямо сейчас прервитесь и прочтите нашу новую статью Отображение прогресса длительных операций в 8.3.10. В ней уже не на уровне новичка объясняются все тонкости и подводные камни работы этого механизма.
Мы же завершаем знакомство со способами информирования пользователя. Надеемся, что у вас сложилось понимание, в каких ситуациях следует применять тот или иной способ.
Хочется еще раз акцентировать ваше внимание на том факте, что если ваша конфигурация (версии 8.3.3+) предполагает работу с помощью веб-клиента, то:
- на уровне конфигурации должна быть установлена настройка режима модальности «Не использовать»
- в коде должны использоваться методы асинхронной модели взаимодействия с пользователем. Такие методы начинаются со слов Показать или Начать.
Более подробно об отказе от использования модальных окон в платформе 1С:Предприятие 8.3 можно почитать в финальной статье цикла. А мы идем дальше и, наконец, приступаем к изучению долгожданного интерфейса «Такси», который уже не раз упоминался в наших материалах.
PDF-версия статьи для участников группы ВКонтакте
Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.
Если Вы еще не вступили в группу – сделайте это сейчас и в блоке ниже (на этой странице) появятся ссылка на скачивание материалов.
Полезные ссылки:
Ссылка доступна для зарегистрированных пользователей)
Ссылка доступна для зарегистрированных пользователей)
Ссылка доступна для зарегистрированных пользователей)
Если Вы уже участник группы – нужно просто повторно авторизоваться в ВКонтакте, чтобы скрипт Вас узнал. В случае проблем решение стандартное: очистить кеш браузера или подписаться через другой браузер.
Здравствуйте.
Сегодня речь пойдет о реализации подсистемы выдачи информационных сообщений пользователю. Стандартный способ проинформировать о чем-либо пользователя – это использование процедуры «Сообщить». Однако в некоторых случаях, хочется создать отдельный список, который не будет замусоривать своим выводом основной список сообщений платформы. Также желательно иметь возможность выделять цветом различные сообщения (в зависимости от их типа, например). В общем, расскажу, как это получилось сделать у меня. Приведенное в статье решение можно встроить в свою программу без какой-либо адаптации.
Предыстория.
В свое время, работая с системой контроля версий Perforce, а именно с ее графическими клиентами, я обратил внимание на удобный элемент интерфейса – многострочное поле вывода сообщений внизу главного окна программы. После того, как пользователь выполнял какие-то обращения к серверу системы, в это поле добавлялись текстовые сообщения, описывающие процесс взаимодействия клиента с сервером (какие конкретно действия выполнялись, и результат их выполнения). Не знаю, почему именно Perforce произвел на меня такое впечатление, хотя абсолютно ту же систему я наблюдал до и после в различных графических IDE (Delphi, C++ и т.д.) – окно вывода сообщений той консольной программы (компилятор или клиент системы контроля версий), в качестве оболочки которой выступает графическая программа. Но впрочем, статья вовсе не про Perforce, просто я считаю удобным способ многострочного вывода сообщений в процессе выполнения какой-то длительной работы. Получить большой список сообщений гораздо лучше (информативнее), чем одиночный MessageBox в самом конце этой работы. Подобный подход мы, кстати, видим и в антивирусных программах.
На создание собственной подсистемы сообщений меня натолкнула необходимость реализации программы, которая выполняет относительно длительный процесс обработки данных (т.е. пользователь нажал кнопку «Выполнить», а потом может, условно говоря, несколько минут ждать, пока процесс выполняется). Подобные программы (обработки) есть и в типовых конфигурациях 1С (в основном это различные выгрузки-загрузки). Стандартное окно сообщений платформы (то, куда выводится информация процедурой «Сообщить») меня не устраивало. Я хотел, чтобы сообщения, связанные с моей обработкой были сгруппированы, и не смешивались ни с какими другими сообщениями. Также я хотел, чтобы список сообщений можно было как-то сохранять на всякий случай (в текстовый файл, как это сделано в антивирусах). Ну и главное, я планировал сделать сообщения разного типа (информационные, предупреждения, сообщения об ошибках). Ну и соответственно раскрашивать их в различные цвета.
В рассматриваемом примере таблица вывода сообщения (элемент интерфейса ТабличноеПоле) выглядит примерно так:
Описание реализации.
В общем, опишу здесь то, что получилось. Для реализации буду опять использовать свою технологию «ООП в 1С» (метод подробно описан здесь). Соответственно будет создан «класс»: «СообщенияПрограммы».
В дальнейшем при объяснениях будем считать, что делаем внешнюю обработку.
Нам понадобятся иконки для отображения статусов сообщений. Загрузим из соответствующих BMP-файлов (прилагаются к данной статье) в ресурсы (макеты типа «Двоичные данные»)
Изображение | Название исходного файла | Название макета |
---|---|---|
statok.bmp | КартинкаСообщениеСтатусОК | |
statwarning.bmp | КартинкаСообщениеСтатусПредупреждение | |
staterror.bmp | КартинкаСообщениеСтатусОшибка |
Затем нужно будет как-то эти картинки загрузить для использования – превратим их в ресурсы.
Определим в главном модуле глобальную переменную «КоллекцияКартинок» в виде структуры из объектов стандартного класса «Картинка». Напишем подпрограмму «СформироватьКоллекциюКартинок», которая будет инициализировать коллецию. Будем вызывать эту подпрограмму в инициализирующей секции модуля.
Также наши сообщения будут иметь некоторые числовые типы – уровни. Номер уровня будет влиять на количество отступов из пробельных символов слева при выводе сообщения в интерфейс или файл (как бы наглядно показываем уровень вложенности сообщений друг в друга).
Название | Описание | Числовое значение |
---|---|---|
ТИПСООБЩ_НЕОПРЕД | Неопределенное значение | 0 |
ТИПСООБЩ_УРОВЕНЬ1 | Уровень вложенности 1 | 1 |
ТИПСООБЩ_УРОВЕНЬ2 | Уровень вложенности 2 | 2 |
ТИПСООБЩ_УРОВЕНЬ3 | Уровень вложенности 3 | 3 |
У каждого сообщения есть определенный статус, показывающий, чем именно является сообщение.
Название | Описание | Числовое значение |
---|---|---|
СТАТСООБЩ_НЕОПРЕД | Неопределенное значение | 0 |
СТАТСООБЩ_ОК | Уровень вложенности 1 | 1 |
СТАТСООБЩ_ПРЕДУПР | Уровень вложенности 2 | 2 |
СТАТСООБЩ_ОШИБКА | Уровень вложенности 3 | 3 |
Представим типы и статусы в виде числовых констант, как это делается в С/С++ (#define) или Pascal (const). В 1С будем имитировать константы вставкой их в глобальную переменную-структуру (ключ элемента структуры – это символьное имя константы, а значение элемента структуры – это численное значение константы).
Функция ИнициализацияПрочихКонстант()
Проч = Новый Структура;
// Типы сообщений
Проч.Вставить("ТИПСООБЩ_НЕОПРЕД", 0); // Тип неопределен
Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ1", 1); // Сообщение уровня 1
Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ2", 2); // Сообщение уровня 2
Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ3", 3); // Сообщение уровня 3
// Статусы сообщений
Проч.Вставить("СТАТСООБЩ_НЕОПРЕД", 0); // Статус неопределен
Проч.Вставить("СТАТСООБЩ_ОК", 1); // Статус "ОК"
Проч.Вставить("СТАТСООБЩ_ПРЕДУПР", 2); // Статус "Предупреждение"
Проч.Вставить("СТАТСООБЩ_ОШИБКА", 3); // Статус "Ошибка"
Возврат Проч
КонецФункции
Еще нам нужно будет получать текущее значение времени в миллисекундах. Используем для этого машину JavaScript в виде глобальной переменной COM-объекта.
Вот что получилось в главном модуле:
Исходный текст
////////////////////////////////////////////////////////////////////////////////
// ПРОЧИЕ КОНСТАНТЫ
Перем Проч Экспорт; // Структура с константами
Перем КоллекцияКартинок Экспорт; // Набор иконок интерфейса
////////////////////////////////////////////////////////////////////////////////
// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
Перем JavaScript; // Машина для работы с JavaScript
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// П О Д П Р О Г Р А М М Ы И Н И Ц И А Л И З А Ц И И К О Н С Т А Н Т
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// Инициализирует набор констант общего назначения
//
// Параметры:
// НЕТ.
//
// Возврат:
// Структура с полями - константами общего назначения
//
Функция ИнициализацияПрочихКонстант()
Проч = Новый Структура;
// Типы сообщений
Проч.Вставить("ТИПСООБЩ_НЕОПРЕД", 0); // Тип неопределен
Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ1", 1); // Сообщение уровня 1
Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ2", 2); // Сообщение уровня 2
Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ3", 3); // Сообщение уровня 3
// Статусы сообщений
Проч.Вставить("СТАТСООБЩ_НЕОПРЕД", 0); // Статус неопределен
Проч.Вставить("СТАТСООБЩ_ОК", 1); // Статус "ОК"
Проч.Вставить("СТАТСООБЩ_ПРЕДУПР", 2); // Статус "Предупреждение"
Проч.Вставить("СТАТСООБЩ_ОШИБКА", 3); // Статус "Ошибка"
Возврат Проч
КонецФункции
// Формирует набор картинок, на основании изображений, сохраненных в двоичных
// макетах обработки.
//
// Параметры:
// НЕТ.
//
// Возврат:
// Структура с полями - объектами типа Картинка с загруженными картинками
//
Функция СформироватьКоллекциюКартинок()
КоллекцияКартинок = Новый Структура;
КоллекцияКартинок.Вставить("СообщениеСтатусОК", Новый Картинка(ПолучитьМакет("КартинкаСообщениеСтатусОК")));
КоллекцияКартинок.Вставить("СообщениеСтатусПредупреждение", Новый Картинка(ПолучитьМакет("КартинкаСообщениеСтатусПредупреждение")));
КоллекцияКартинок.Вставить("СообщениеСтатусОшибка", Новый Картинка(ПолучитьМакет("КартинкаСообщениеСтатусОшибка")));
Возврат КоллекцияКартинок
КонецФункции
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// П О Д П Р О Г Р А М М Ы И Н И Ц И А Л И З А Ц И И Г Л О Б А Л Ь Н Ы Х П Е Р Е М Е Н Н Ы Х
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// Создает объект JavaScript и возвращает его в качестве значения
// Формирует набор картинок, на основании изображений, сохраненных в двоичных
// макетах обработки.
//
// Параметры:
// НЕТ.
//
// Возврат:
// Ссылка на машину JavaScript или Неопределено, если машина не создана
//
Функция СоздатьОбъектJavaScript()
Рез = Неопределено;
Попытка
Рез = Новый COMОбъект("MSScriptControl.ScriptControl");
Рез.Language = "javascript";
Исключение
КонецПопытки;
Возврат Рез
КонецФункции
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// П О Д П Р О Г Р А М М Ы О Б Щ Е Г О Н А З Н А Ч Е Н И Я
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// Расширяет строку до заданной ширины пробелами, добавляя их слева
//
// Параметры:
// Стр - исходная строка
// Ширина - кол-во символов до которого нужно расширить строку
// Возврат:
// Полученная строка
//
Функция РасширСтрЛев(Стр, Ширина)
Рез = Стр;
Инд = Ширина - СтрДлина(Рез);
Пока Инд > 0 Цикл
Рез = " " + Рез;
Инд = Инд - 1
КонецЦикла;
Возврат Рез
КонецФункции
// Расширяет строку до заданной ширины пробелами, добавляя их справа
//
// Параметры:
// Стр - исходная строка
// Ширина - кол-во символов до которого нужно расширить строку
// Возврат:
// Полученная строка
//
Функция РасширСтрПрав(Стр, Ширина)
Рез = Стр;
Инд = Ширина - СтрДлина(Рез);
Пока Инд > 0 Цикл
Рез = Рез + " ";
Инд = Инд - 1
КонецЦикла;
Возврат Рез
КонецФункции
// Возвращает текущую дату и время в миллисекундах
//
// Параметры:
// НЕТ
// Возврат:
// Числовое значение или 0, если значение определить не удалось
//
Функция ПолучитьТекущееВремяВМиллисекундах() Экспорт
Время = 0;
Если JavaScript <> Неопределено Тогда
Время = JavaScript.Eval("new Date().getTime()");
КонецЕсли;
Возврат Время;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ - НАЧАЛЬНАЯ ИНИЦИАЛИЗАЦИЯ
// ИНИЦИАЛИЗАЦИЯ КОНСТАНТ
// Константы общего назначения
Проч = ИнициализацияПрочихКонстант();
// Коллекция картинок
КоллекцияКартинок = СформироватьКоллекциюКартинок();
// ИНИЦИАЛИЗАЦИЯ ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ
// Создать машину JavaScript
JavaScript = СоздатьОбъектJavaScript();
Набор сообщений существует в виде таблицы значений (стандартный класс ТаблицаЗначений) со следующими колонками:
Название колонки | Тип данных | Назначение |
---|---|---|
ТипСообщ | Число | Тип сообщения (уровень) – одна из констант ТИПСООБЩ_ |
СтатусСообщ | Число | Статус сообщения – одна из констант СТАТСООБЩ_ |
ТекстСообщ | Строка | Основной текст сообщения. Здесь обычно указываем, какое действие выполняется длительным процессом в данный момент. |
КомментарийСообщ | Строка | Дополнительный текст сообщения. Здесь обычно указываем результат выполнения действия, описанного в колонке ТекстСообщ. Если действие завершилось ошибкой, то сообщение об ошибке приводим в этой же колонке |
Эта таблица значений уже может отображаться в каких-то элементах интерфейса пользователя (например в объекте класса TaбличноеПоле).
Набор сообщений будет реализован в виде класса, имеющего следующие методы:
Заголовок метода | Описание |
---|---|
Функция Сообщения_Конструктор() | Начальное создание объекта. Возвращает объект класса «Сообщения». |
Процедура Сообщения_УстАтриб(Сообщ, Форма, ТабПоле, ТабЗнач) | Установка атрибутов объекта. Нужно передать: — ссылку на форму (Форма), на которой будет отображаться список сообщений; — элемент формы типа ТабличноеПоле (ТабПоле), в который будут выводится сообщения; — ТаблицаЗначений (ТабЗнач), в которой будет храниться собственно список сообщений. |
Процедура Сообщения_Инициализация(Сообщ) | Будет проинициализирована ТаблицаЗначений (ранее установленная процедурой Сообщения_УстАтриб) |
Процедура Сообщения_Обновить(Сообщ) | Выполняет принудительную отрисовку списка сообщений на форме (ранее установленная процедурой Сообщения_УстАтриб) |
Функция Сообщения_Добавить(Сообщ, ТипСообщ, ТекстСообщ, СтатусСообщ=Неопределено, КомментСообщ=Неопределено) | Добавляет в набор новое сообщение с соответствующими атрибутами. Возвращает идентификатор сообщения с помощью которого, к данному сообщению можно будет обращаться в дальнейшем. |
Процедура Сообщения_Изменить(Сообщ, ИдСообщ, ТипСообщ=Неопределено, ТекстСообщ=Неопределено, СтатусСообщ=Неопределено, КомментСообщ=Неопределено) | Изменяет атрибуты уже существующего сообщения с указанным идентификатором. |
Процедура Сообщения_Удалить(Сообщ, ИдСообщ) | Удалить ранее добавленное сообщение с соответствующим идентификатором. |
Процедура Сообщения_Очистить(Сообщ) | Удалить все сообщения набора. |
Функция Сообщения_ПолучитьТип(Сообщ, ИдСообщ) | Получить атрибут «Тип» для существующего сообщения с указанным идентификатором. |
Процедура Сообщения_УстановитьТип(Сообщ, ИдСообщ, ТипСообщ) | Установить атрибут «Тип» для существующего сообщения с указанным идентификатором. |
Функция Сообщения_ПолучитьСтатус(Сообщ, ИдСообщ) | Получить атрибут «Статус» для существующего сообщения с указанным идентификатором. |
Процедура Сообщения_УстановитьСтатус(Сообщ, ИдСообщ, СтатусСообщ) | Установить атрибут «Статус» для существующего сообщения с указанным идентификатором. |
Функция Сообщения_ПолучитьТекст(Сообщ, ИдСообщ) | Получить атрибут «Текст сообщения» для существующего сообщения с указанным идентификатором. |
Процедура Сообщения_УстановитьТекст(Сообщ, ИдСообщ, ТекстСообщ) | Установить атрибут «Текст сообщения» для существующего сообщения с указанным идентификатором. |
Функция Сообщения_ПолучитьКоммент(Сообщ, ИдСообщ) | Получить атрибут «Комментарий» для существующего сообщения с указанным идентификатором. |
Процедура Сообщения_УстановитьКоммент(Сообщ, ИдСообщ, КомментСообщ) | Установить атрибут «Комментарий» для существующего сообщения с указанным идентификатором. |
Функция Сообщения_ЦветТекста(ТипСообщ, СтатусСообщ) | Определить цвет текста сообщения для указанного статуса. Используется при раскраске сообщений в интерфейсе. |
Функция Сообщения_ЦветКомментария(ТипСообщ, СтатусСообщ) | Определить цвет дополнительного текста (комментария) сообщения для указанного статуса. Используется при раскраске сообщений в интерфейсе. |
Функция Сообщения_Картинка(ТипСообщ, СтатусСообщ) | Определить иконку для сообщения с указанным статусом. Используется при выводе сообщений в интерфейсе. |
Функция Сообщения_СохранитьВФайл(Сообщ) | Сохранить набор сообщений в текстовый файл (имя файла запрашивает у пользователя). |
Итак, полный текст главного модуля обработки:
Текст модуля
//////////////////////////////////////////////////////////////////////////////// // ПРОЧИЕ КОНСТАНТЫ Перем Проч Экспорт; // Структура с константами Перем КоллекцияКартинок Экспорт; // Набор иконок интерфейса //////////////////////////////////////////////////////////////////////////////// // ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ Перем JavaScript; // Машина для работы с JavaScript /////////////////////////////////////////////////////////////////////////////////////////////////// // // П О Д П Р О Г Р А М М Ы И Н И Ц И А Л И З А Ц И И К О Н С Т А Н Т // /////////////////////////////////////////////////////////////////////////////////////////////////// // Инициализирует набор констант общего назначения // // Параметры: // НЕТ. // // Возврат: // Структура с полями - константами общего назначения // Функция ИнициализацияПрочихКонстант() Проч = Новый Структура; // Типы сообщений Проч.Вставить("ТИПСООБЩ_НЕОПРЕД", 0); // Тип неопределен Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ1", 1); // Сообщение уровня 1 Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ2", 2); // Сообщение уровня 2 Проч.Вставить("ТИПСООБЩ_УРОВЕНЬ3", 3); // Сообщение уровня 3 // Статусы сообщений Проч.Вставить("СТАТСООБЩ_НЕОПРЕД", 0); // Статус неопределен Проч.Вставить("СТАТСООБЩ_ОК", 1); // Статус "ОК" Проч.Вставить("СТАТСООБЩ_ПРЕДУПР", 2); // Статус "Предупреждение" Проч.Вставить("СТАТСООБЩ_ОШИБКА", 3); // Статус "Ошибка" Возврат Проч КонецФункции // Формирует набор картинок, на основании изображений, сохраненных в двоичных // макетах обработки. // // Параметры: // НЕТ. // // Возврат: // Структура с полями - объектами типа Картинка с загруженными картинками // Функция СформироватьКоллекциюКартинок() КоллекцияКартинок = Новый Структура; КоллекцияКартинок.Вставить("СообщениеСтатусОК", Новый Картинка(ПолучитьМакет("КартинкаСообщениеСтатусОК"))); КоллекцияКартинок.Вставить("СообщениеСтатусПредупреждение", Новый Картинка(ПолучитьМакет("КартинкаСообщениеСтатусПредупреждение"))); КоллекцияКартинок.Вставить("СообщениеСтатусОшибка", Новый Картинка(ПолучитьМакет("КартинкаСообщениеСтатусОшибка"))); Возврат КоллекцияКартинок КонецФункции /////////////////////////////////////////////////////////////////////////////////////////////////// // // П О Д П Р О Г Р А М М Ы И Н И Ц И А Л И З А Ц И И Г Л О Б А Л Ь Н Ы Х П Е Р Е М Е Н Н Ы Х // /////////////////////////////////////////////////////////////////////////////////////////////////// // Создает объект JavaScript и возвращает его в качестве значения // Формирует набор картинок, на основании изображений, сохраненных в двоичных // макетах обработки. // // Параметры: // НЕТ. // // Возврат: // Ссылка на машину JavaScript или Неопределено, если машина не создана // Функция СоздатьОбъектJavaScript() Рез = Неопределено; Попытка Рез = Новый COMОбъект("MSScriptControl.ScriptControl"); Рез.Language = "javascript"; Исключение КонецПопытки; Возврат Рез КонецФункции /////////////////////////////////////////////////////////////////////////////////////////////////// // // П О Д П Р О Г Р А М М Ы О Б Щ Е Г О Н А З Н А Ч Е Н И Я // /////////////////////////////////////////////////////////////////////////////////////////////////// // Расширяет строку до заданной ширины пробелами, добавляя их слева // // Параметры: // Стр - исходная строка // Ширина - кол-во символов до которого нужно расширить строку // Возврат: // Полученная строка // Функция РасширСтрЛев(Стр, Ширина) Рез = Стр; Инд = Ширина - СтрДлина(Рез); Пока Инд > 0 Цикл Рез = " " + Рез; Инд = Инд - 1 КонецЦикла; Возврат Рез КонецФункции // Расширяет строку до заданной ширины пробелами, добавляя их справа // // Параметры: // Стр - исходная строка // Ширина - кол-во символов до которого нужно расширить строку // Возврат: // Полученная строка // Функция РасширСтрПрав(Стр, Ширина) Рез = Стр; Инд = Ширина - СтрДлина(Рез); Пока Инд > 0 Цикл Рез = Рез + " "; Инд = Инд - 1 КонецЦикла; Возврат Рез КонецФункции // Возвращает текущую дату и время в миллисекундах // // Параметры: // НЕТ // Возврат: // Числовое значение или 0, если значение определить не удалось // Функция ПолучитьТекущееВремяВМиллисекундах() Экспорт Время = 0; Если JavaScript <> Неопределено Тогда Время = JavaScript.Eval("new Date().getTime()"); КонецЕсли; Возврат Время; КонецФункции // Преобразует массив чисел из объекта COMSafeArray в строку символов // // Параметры: // ОбъектCOMSafeArray - ссылка на массив чисел типа COMSafeArray // (размерность массива должна быть 1) // Возврат: // Полученная строка или "", если операцию выполнить не удалось // Функция COMSafeArrayВСтроку(ОбъектCOMSafeArray) Экспорт Рез = ""; Если ТипЗнч(ОбъектCOMSafeArray) = Тип("COMSafeArray") И (ОбъектCOMSafeArray.GetDimensions() = 1) И (ОбъектCOMSafeArray.GetLength(0) > 0) Тогда Массив = ОбъектCOMSafeArray.Выгрузить(); Для Каждого КодСимв Из Массив Цикл Если ТипЗнч(КодСимв) = Тип("Число") Тогда // Перекодировка символа из Windows-1251 в UTF-8 Если (КодСимв >= 192) И (КодСимв <= 223) Тогда // А - Я КодСимв = КодСимв + 848 ИначеЕсли (КодСимв >= 224) И (КодСимв <= 239) Тогда // а - п КодСимв = КодСимв + 848 ИначеЕсли (КодСимв >= 240) И (КодСимв <= 255) Тогда // р - я КодСимв = КодСимв + 848 ИначеЕсли (КодСимв = 184) Тогда // ё КодСимв = 1105 ИначеЕсли (КодСимв = 168) Тогда // Ё КодСимв = 1025 ИначеЕсли (КодСимв = 185) Тогда // № КодСимв = 8470 КонецЕсли; // Добавить символ к строке Рез = Рез + Символ(КодСимв) КонецЕсли КонецЦикла КонецЕсли; Возврат Рез КонецФункции /////////////////////////////////////////////////////////////////////////////////////////////////// // // К Л А С С Ы О Б Щ Е Г О Н А З Н А Ч Е Н И Я // /////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Реализация класса СообщенияПрограммы (Сообщения) // Создание полей объекта в виде структуры. // // Параметры: // Нет. // Возврат: // Возвращает созданную структуру // Функция Сообщения_СоздатьОбъект() Экспорт Сообщ = Новый Структура; // Общие параметры сущности Сообщ.Вставить("Форма", Неопределено); // Форма с табличным полем Сообщ.Вставить("ТабПоле", Неопределено); // Табличное поле на форме Сообщ.Вставить("ТабЗнач", Неопределено); // Таблица значений с сообщениями Сообщ.Вставить("ВремяПредОбновл", Неопределено); // Время последн. обновл. формы, мс (INT) Возврат Сообщ; КонецФункции // Имитирует конструктор объекта. // // Параметры: // НЕТ // Возврат: // (Структура) - Структура с полями объекта // Функция Сообщения_Конструктор() Экспорт Сообщ = Сообщения_СоздатьОбъект(); Возврат Сообщ; КонецФункции // Имитирует деструктор объекта - освобождает память. // // Параметры: // Сообщ - ссылка на объект // Процедура Сообщения_Деструктор(Сообщ) Экспорт КонецПроцедуры // Устанавливает основные атрибуты для вывода сообщений. // // Параметры: // Сообщ - ссылка на объект // Форма - ссылка на форму, на которой расположено табличное поле списка // ТабПоле - ссылка табличное поле списка для вывода сообщений // ТабЗнач - таблица значений с сообщениями // Процедура Сообщения_УстАтриб(Сообщ, Форма, ТабПоле, ТабЗнач) Экспорт Сообщ.Форма = Форма; Сообщ.ТабПоле = ТабПоле; Сообщ.ТабЗнач = ТабЗнач КонецПроцедуры // Инициализирует таблицу сообщений. Добавляет недостающие колонки // // Параметры: // Сообщ - ссылка на объект // Процедура Сообщения_Инициализация(Сообщ) Экспорт Если Сообщ.ТабЗнач <> Неопределено Тогда КЧ = Новый КвалификаторыЧисла(10, 0); КС = Новый КвалификаторыСтроки(); МассивТипов = Новый Массив; МассивТипов.Добавить(Тип("Число")); ОписаниеТиповЧисла = Новый ОписаниеТипов(МассивТипов, , ,КЧ); МассивТипов.Очистить(); МассивТипов.Добавить(Тип("Строка")); ОписаниеТиповСтроки = Новый ОписаниеТипов(МассивТипов, , КС); // Колонка "ТипСообщ" Если Сообщ.ТабЗнач.Колонки.Найти("ТипСообщ") = Неопределено Тогда Сообщ.ТабЗнач.Колонки.Добавить("ТипСообщ", ОписаниеТиповЧисла, "Тип", 30) КонецЕсли; // Колонка "СтатусСообщ" Если Сообщ.ТабЗнач.Колонки.Найти("СтатусСообщ") = Неопределено Тогда Сообщ.ТабЗнач.Колонки.Добавить("СтатусСообщ", ОписаниеТиповЧисла, "Статус", 30) КонецЕсли; // Колонка "ТекстСообщ" Если Сообщ.ТабЗнач.Колонки.Найти("ТекстСообщ") = Неопределено Тогда Сообщ.ТабЗнач.Колонки.Добавить("ТекстСообщ", ОписаниеТиповСтроки, "Текст", 200) КонецЕсли; // Колонка "КомментарийСообщ" Если Сообщ.ТабЗнач.Колонки.Найти("КомментарийСообщ") = Неопределено Тогда Сообщ.ТабЗнач.Колонки.Добавить("КомментарийСообщ", ОписаниеТиповСтроки, "Комментарий", 200) КонецЕсли КонецЕсли КонецПроцедуры // Выполняет овновление формы, на которой размещено табличное поле // Тем самым вызывает прорисовку сообщений. // Выполняет это не чаще заданного интервала, мс // // Параметры: // Сообщ - ссылка на объект // Процедура Сообщения_Обновить(Сообщ) Экспорт Если Сообщ.Форма <> Неопределено Тогда Интервал = 500; // Интервал обновлений (не чаще), мс ВремяТекущОбновл = ПолучитьТекущееВремяВМиллисекундах(); Если (Сообщ.ВремяПредОбновл = Неопределено) ИЛИ (Сообщ.ВремяПредОбновл = 0) ИЛИ (ВремяТекущОбновл - Сообщ.ВремяПредОбновл >= Интервал) Тогда // Выполняем обновление Сообщ.ВремяПредОбновл = ВремяТекущОбновл; Сообщ.Форма.Обновить() КонецЕсли КонецЕсли КонецПроцедуры // Добавляет новое сообщение в таблицу значений // // Параметры: // Сообщ - ссылка на объект; // ТипСообщ - тип добавляемого сообщения; // ТекстСообщ - текст добавляемого сообщения; // СтатусСообщ - статус добавляемого сообщения; // КомментСообщ - комментарий к добавляемому сообщению // Возврат: // Уникальный идентификатор добавленного сообщения. Используется для дальнейшего обращения к сообщению с целью // его редактирования. По сути представляет собой порядковый номер строки в таблице Сообщ.ТабЗнач // Функция Сообщения_Добавить(Сообщ, ТипСообщ, ТекстСообщ, СтатусСообщ=Неопределено, КомментСообщ=Неопределено) Экспорт ИдСообщ = Неопределено; Если (Сообщ.ТабЗнач <> Неопределено) И (ТипСообщ <> Неопределено) И (ТипСообщ >= Проч.ТИПСООБЩ_УРОВЕНЬ1) И (ТипСообщ <= Проч.ТИПСООБЩ_УРОВЕНЬ3) И (ТекстСообщ <> Неопределено) Тогда НоваяСтрока = Сообщ.ТабЗнач.Добавить(); НоваяСтрока.ТипСообщ = ТипСообщ; // Преобразовать текст Если ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ1 Тогда ИначеЕсли ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ2 Тогда ТекстСообщ = " " + ТекстСообщ ИначеЕсли ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ3 Тогда ТекстСообщ = " " + ТекстСообщ КонецЕсли; // Установить текст НоваяСтрока.ТекстСообщ = ТекстСообщ; Если (СтатусСообщ <> Неопределено) И (СтатусСообщ >= Проч.СТАТСООБЩ_ОК) И (СтатусСообщ <= Проч.СТАТСООБЩ_ОШИБКА) Тогда НоваяСтрока.СтатусСообщ = СтатусСообщ; Иначе НоваяСтрока.СтатусСообщ = Проч.СТАТСООБЩ_НЕОПРЕД; КонецЕсли; НоваяСтрока.КомментарийСообщ = КомментСообщ; Если Сообщ.ТабПоле <> Неопределено Тогда // Изменение текущей строки табличного поля на добавляемую, // чтобы пользователь видел, что добавляется в список в данный момент Сообщ.ТабПоле.ТекущаяСтрока = НоваяСтрока; КонецЕсли; Сообщения_Обновить(Сообщ); ИдСообщ = Сообщ.ТабЗнач.Индекс(НоваяСтрока); КонецЕсли; Возврат ИдСообщ КонецФункции // Изменяет атрибуты сообщения с идентификатором ИдСообщ. Те, значение которых не "Неопределено" // // Параметры: // Сообщ - ссылка на объект; // ИдСообщ - идентификатор сообщения (порядковый номер строки); // ТипСообщ - тип добавляемого сообщения; // ТекстСообщ - текст добавляемого сообщения; // СтатусСообщ - статус добавляемого сообщения; // КомментСообщ - комментарий к добавляемому сообщению // Процедура Сообщения_Изменить(Сообщ, ИдСообщ, ТипСообщ=Неопределено, ТекстСообщ=Неопределено, СтатусСообщ=Неопределено, КомментСообщ=Неопределено) Экспорт Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) Тогда ФлагИзменения = Ложь; // Признак того, что что-то изменили (хоть один атрибут) Если ТипСообщ <> Неопределено Тогда Если (ТипСообщ <> Сообщ.ТабЗнач[ИдСообщ].ТипСообщ) И (ТипСообщ >= Проч.ТИПСООБЩ_УРОВЕНЬ1) И (ТипСообщ <= Проч.ТИПСООБЩ_УРОВЕНЬ3) Тогда Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = ТипСообщ; ФлагИзменения = Истина КонецЕсли КонецЕсли; Если ТекстСообщ <> Неопределено Тогда Если ТекстСообщ <> Сообщ.ТабЗнач[ИдСообщ].ТекстСообщ Тогда // Преобразовать текст Если Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ1 Тогда ИначеЕсли Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ2 Тогда ТекстСообщ = " " + ТекстСообщ ИначеЕсли Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ3 Тогда ТекстСообщ = " " + ТекстСообщ КонецЕсли; // Установить текст Сообщ.ТабЗнач[ИдСообщ].ТекстСообщ = ТекстСообщ; ФлагИзменения = Истина КонецЕсли КонецЕсли; Если СтатусСообщ <> Неопределено Тогда Если СтатусСообщ <> Сообщ.ТабЗнач[ИдСообщ].СтатусСообщ Тогда Если (СтатусСообщ <> Неопределено) И (СтатусСообщ >= Проч.СТАТСООБЩ_ОК) И (СтатусСообщ <= Проч.СТАТСООБЩ_ОШИБКА) Тогда Сообщ.ТабЗнач[ИдСообщ].СтатусСообщ = СтатусСообщ; Иначе Сообщ.ТабЗнач[ИдСообщ].СтатусСообщ = Проч.СТАТСООБЩ_НЕОПРЕД; КонецЕсли; ФлагИзменения = Истина КонецЕсли КонецЕсли; Если КомментСообщ <> Неопределено Тогда Если КомментСообщ <> Сообщ.ТабЗнач[ИдСообщ].КомментарийСообщ Тогда Сообщ.ТабЗнач[ИдСообщ].КомментарийСообщ = КомментСообщ; ФлагИзменения = Истина КонецЕсли КонецЕсли; Если ФлагИзменения = Истина Тогда // Прорисовка, если реально було обновление Сообщения_Обновить(Сообщ) КонецЕсли КонецЕсли КонецПроцедуры // Удаляет сообщение с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // Процедура Сообщения_Удалить(Сообщ, ИдСообщ) Экспорт Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) Тогда Сообщ.ТабЗнач.Удалить(ИдСообщ); Сообщения_Обновить(Сообщ) КонецЕсли КонецПроцедуры // Удаляет все сообщения из таблицы // // Параметры: // Сообщ - ссылка на объект // Процедура Сообщения_Очистить(Сообщ) Экспорт Если (Сообщ.ТабЗнач <> Неопределено) И (Сообщ.ТабЗнач.Количество() > 0) Тогда Сообщ.ТабЗнач.Очистить(); Сообщения_Обновить(Сообщ) КонецЕсли КонецПроцедуры // Возвращает тип сообщения с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // Возврат: // Тип сообщения или Неопределено, если сообщение не найдено // Функция Сообщения_ПолучитьТип(Сообщ, ИдСообщ) Экспорт Рез = Неопределено; Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) Тогда Рез = Сообщ.ТабЗнач[ИдСообщ].ТипСообщ КонецЕсли; Возврат Рез КонецФункции // Устанавливает тип сообщения с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // ТипСообщ - тип сообщения // Процедура Сообщения_УстановитьТип(Сообщ, ИдСообщ, ТипСообщ) Экспорт Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) И (ТипСообщ <> Сообщ.ТабЗнач[ИдСообщ].ТекстСообщ) И (ТипСообщ >= Проч.ТИПСООБЩ_УРОВЕНЬ1) И (ТипСообщ <= Проч.ТИПСООБЩ_УРОВЕНЬ3) Тогда Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = ТипСообщ; Сообщения_Обновить(Сообщ) КонецЕсли; КонецПроцедуры // Возвращает статус сообщения с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // Возврат: // Статус сообщения или Неопределено, если сообщение не найдено // Функция Сообщения_ПолучитьСтатус(Сообщ, ИдСообщ) Экспорт Рез = Неопределено; Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) Тогда Рез = Сообщ.ТабЗнач[ИдСообщ].СтатусСообщ КонецЕсли; Возврат Рез КонецФункции // Устанавливает статус сообщения с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // СтатусСообщ - статус сообщения // Процедура Сообщения_УстановитьСтатус(Сообщ, ИдСообщ, СтатусСообщ) Экспорт Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) И (СтатусСообщ <> Сообщ.ТабЗнач[ИдСообщ].СтатусСообщ) Тогда Если (СтатусСообщ <> Неопределено) И (СтатусСообщ >= Проч.СТАТСООБЩ_ОК) И (СтатусСообщ <= Проч.СТАТСООБЩ_ОШИБКА) Тогда Сообщ.ТабЗнач[ИдСообщ].СтатусСообщ = СтатусСообщ; Иначе Сообщ.ТабЗнач[ИдСообщ].СтатусСообщ = Проч.СТАТСООБЩ_НЕОПРЕД; КонецЕсли; Сообщения_Обновить(Сообщ) КонецЕсли КонецПроцедуры // Возвращает текст сообщения с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // Возврат: // Текст сообщения или Неопределено, если сообщение не найдено // Функция Сообщения_ПолучитьТекст(Сообщ, ИдСообщ) Экспорт Рез = Неопределено; Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) Тогда Рез = Сообщ.ТабЗнач[ИдСообщ].ТекстСообщ КонецЕсли; Возврат Рез КонецФункции // Устанавливает текст сообщения с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // ТекстСообщ - текст добавляемого сообщения; // Процедура Сообщения_УстановитьТекст(Сообщ, ИдСообщ, ТекстСообщ) Экспорт Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) И (ТекстСообщ <> Неопределено) И (ТекстСообщ <> Сообщ.ТабЗнач[ИдСообщ].ТипСообщ) Тогда // Преобразовать текст Если Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ1 Тогда ИначеЕсли Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ2 Тогда ТекстСообщ = " " + ТекстСообщ ИначеЕсли Сообщ.ТабЗнач[ИдСообщ].ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ3 Тогда ТекстСообщ = " " + ТекстСообщ КонецЕсли; // Установить текст Сообщ.ТабЗнач[ИдСообщ].ТекстСообщ = ТекстСообщ; Сообщения_Обновить(Сообщ) КонецЕсли КонецПроцедуры // Возвращает комментарий к сообщению с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // Возврат: // Комментарий сообщения или Неопределено, если сообщение не найдено // Функция Сообщения_ПолучитьКоммент(Сообщ, ИдСообщ) Экспорт Рез = Неопределено; Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) Тогда Рез = Сообщ.ТабЗнач[ИдСообщ].КомментарийСообщ КонецЕсли; Возврат Рез КонецФункции // Устанавливает комментарий к сообщению с идентификатором ИдСообщ // // Параметры: // Сообщ - ссылка на объект // ИдСообщ - идентификатор сообщения (порядковый номер строки) // КомментСообщ - комментарий к сообщению // Процедура Сообщения_УстановитьКоммент(Сообщ, ИдСообщ, КомментСообщ) Экспорт Если (Сообщ.ТабЗнач <> Неопределено) И (ИдСообщ <> Неопределено) И (ИдСообщ >= 0) И (ИдСообщ < Сообщ.ТабЗнач.Количество()) И (КомментСообщ <> Сообщ.ТабЗнач[ИдСообщ].КомментарийСообщ) Тогда Сообщ.ТабЗнач[ИдСообщ].КомментарийСообщ = КомментСообщ; Сообщения_Обновить(Сообщ) КонецЕсли КонецПроцедуры // В зависимости от типа сообщения и статуса определяет цвет текста сообщения // // Параметры: // ТипСообщ - тип сообщения // СтатусСообщ - статус сообщения // Возврат: // Цвет текста сообщения // Функция Сообщения_ЦветТекста(ТипСообщ, СтатусСообщ) Экспорт Рез = Неопределено; Если ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ1 Тогда Рез = WebЦвета.Черный ИначеЕсли ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ2 Тогда Рез = WebЦвета.Черный ИначеЕсли ТипСообщ = Проч.ТИПСООБЩ_УРОВЕНЬ3 Тогда Рез = WebЦвета.Черный КонецЕсли; Возврат Рез КонецФункции // В зависимости от типа сообщения и статуса определяет цвет текста комментария // // Параметры: // ТипСообщ - тип сообщения // СтатусСообщ - статус сообщения // Возврат: // Цвет текста комментария // Функция Сообщения_ЦветКомментария(ТипСообщ, СтатусСообщ) Экспорт Рез = Неопределено; Если СтатусСообщ = Проч.СТАТСООБЩ_ОК Тогда Рез = WebЦвета.Зеленый ИначеЕсли СтатусСообщ = Проч.СТАТСООБЩ_ПРЕДУПР Тогда Рез = WebЦвета.Оранжевый ИначеЕсли СтатусСообщ = Проч.СТАТСООБЩ_ОШИБКА Тогда Рез = WebЦвета.Красный КонецЕсли; Возврат Рез КонецФункции // В зависимости от типа сообщения и статуса определяет картинку статуса сообщения // // Параметры: // ТипСообщ - тип сообщения // СтатусСообщ - статус сообщения // Возврат: // Картинка статуса сообщения // Функция Сообщения_Картинка(ТипСообщ, СтатусСообщ) Экспорт Рез = Неопределено; Если СтатусСообщ = Проч.СТАТСООБЩ_ОК Тогда Рез = КоллекцияКартинок.СообщениеСтатусОК ИначеЕсли СтатусСообщ = Проч.СТАТСООБЩ_ПРЕДУПР Тогда Рез = КоллекцияКартинок.СообщениеСтатусПредупреждение ИначеЕсли СтатусСообщ = Проч.СТАТСООБЩ_ОШИБКА Тогда Рез = КоллекцияКартинок.СообщениеСтатусОшибка КонецЕсли; Возврат Рез КонецФункции // Запрашивает имя файла и сохраняет набор сообщений в текстовый файл // // Параметры: // Сообщ - ссылка на объект // Возврат: // Истина, если сохранение выполнено и Ложь - в противном случае // Функция Сообщения_СохранитьВФайл(Сообщ) Экспорт Рез = Ложь; // Еще ничего не сохранили Если Сообщ.ТабЗнач = Неопределено Тогда // Неверные параметры Возврат Рез КонецЕсли; // Создать диалог и выбрать файл для сохранения ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение); ДиалогВыбораФайла.Фильтр = "Текстовые файлы (*.txt)|*.txt" + "|Все файлы (*.*)|*.*"; ДиалогВыбораФайла.Заголовок = "Сохранение сообщений"; ДиалогВыбораФайла.МножественныйВыбор = Ложь; ДиалогВыбораФайла.ПредварительныйПросмотр = Ложь; ДиалогВыбораФайла.Расширение = "txt"; ДиалогВыбораФайла.ИндексФильтра = 0; ДиалогВыбораФайла.ПроверятьСуществованиеФайла = Истина; Если ДиалогВыбораФайла.Выбрать() Тогда // Выполнить сохранение Попытка // Открыть файл ЗаписьТекста = Новый ЗаписьТекста(ДиалогВыбораФайла.ПолноеИмяФайла, КодировкаТекста.ANSI); // Сформировать и записать в файл строки сообщений // Выяснить максимальные длины строк в сообщениях ДлинаТекстаМакс = 0; ДлинаКомментМакс = 0; Для Каждого СтрокаТЗ Из Сообщ.ТабЗнач Цикл ДлинаТекстаТек = СтрДлина(СтрокаТЗ.ТекстСообщ); Если ДлинаТекстаТек > ДлинаТекстаМакс Тогда ДлинаТекстаМакс = ДлинаТекстаТек; КонецЕсли; ДлинаКомментТек = СтрДлина(СтрокаТЗ.КомментарийСообщ); Если ДлинаКомментТек > ДлинаКомментМакс Тогда ДлинаКомментМакс = ДлинаКомментТек; КонецЕсли; КонецЦикла; // Выполнить запись строк Для Каждого СтрокаТЗ Из Сообщ.ТабЗнач Цикл Дист = " "; // Разделитель элементов строки Стр = ""; // Записать в строку статус сообщения Если (СтрокаТЗ.СтатусСообщ <> Неопределено) И (СтрокаТЗ.СтатусСообщ <> Проч.СТАТСООБЩ_НЕОПРЕД) Тогда СтатусСтр = ""; Если СтрокаТЗ.СтатусСообщ = Проч.СТАТСООБЩ_ОК Тогда СтатусСтр = "ОК"; ИначеЕсли СтрокаТЗ.СтатусСообщ = Проч.СТАТСООБЩ_ПРЕДУПР Тогда СтатусСтр = "ПРЕДУПРЕЖДЕНИЕ"; ИначеЕсли СтрокаТЗ.СтатусСообщ = Проч.СТАТСООБЩ_ОШИБКА Тогда СтатусСтр = "ОШИБКА"; КонецЕсли; Если Стр <> "" Тогда Стр = Стр + Дист КонецЕсли; Стр = Стр + РасширСтрПрав(СтатусСтр, 14); КонецЕсли; // Записать в строку текст сообщения Если (СтрокаТЗ.ТекстСообщ <> Неопределено) И (СтрокаТЗ.ТекстСообщ <> "") Тогда Если Стр <> "" Тогда Стр = Стр + Дист КонецЕсли; Стр = Стр + РасширСтрПрав(СтрокаТЗ.ТекстСообщ, ДлинаТекстаМакс); КонецЕсли; // Записать в строку текст комментария Если (СтрокаТЗ.КомментарийСообщ <> Неопределено) И (СтрокаТЗ.КомментарийСообщ <> "") Тогда Если Стр <> "" Тогда Стр = Стр + Дист КонецЕсли; Стр = Стр + РасширСтрПрав(СтрокаТЗ.КомментарийСообщ, ДлинаКомментМакс); КонецЕсли; // Записать строку в файл Если Стр <> "" Тогда ЗаписьТекста.ЗаписатьСтроку(Стр) КонецЕсли КонецЦикла; // Закрыть файл ЗаписьТекста.Закрыть(); Рез = Истина // Операция выполнена успешно Исключение // Сообщение об ошибке Предупреждение("Ошибка сохранения сообщений:" + Символы.ПС + ИнформацияОбОшибке().Описание); КонецПопытки КонецЕсли; Возврат Рез КонецФункции //////////////////////////////////////////////////////////////////////////////// // ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ - НАЧАЛЬНАЯ ИНИЦИАЛИЗАЦИЯ // ИНИЦИАЛИЗАЦИЯ КОНСТАНТ // Константы общего назначения Проч = ИнициализацияПрочихКонстант(); // Коллекция картинок КоллекцияКартинок = СформироватьКоллекциюКартинок(); // ИНИЦИАЛИЗАЦИЯ ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ // Создать машину JavaScript JavaScript = СоздатьОбъектJavaScript();
Обратите внимание на то, что при выполнении длительного процесса в цикле, интерфейс пользователя блокируется, и поэтому факт добавления или изменения сообщений не будет виден пользователю – прорисовки не будет. Для принудительного выполнения прорисовки, нужно вызвать метод Обновить() формы, отображающей сообщения. Но частый вызов этого метода затормозит работу, поэтому вызывать его нужно лишь иногда (хоть и с небольшим интервалом, чтобы пользователь не заметил лагов – в данной реализации интервал обновления не чаще чем 1 раз в 0,5сек). Для реализации обновления служит метод класса Сообщения_Обновить.
Пример использования.
В данном примере форма, отображающая набор сообщений выглядит вот так:
Вместо кнопки «Запустить процесс», в реальности должно быть что-то более полезное – какой-то пользовательский интерфейс. Кнопка «Запустить процесс» имитирует заполнение списка сообщений, демонстрируя то, как могли бы выводиться сообщения в процессе реального выполнения какого-либо длительного действия.
В качестве реквизитов формы создана ТаблицаЗначений — «Сообщения». Мы ее никак не инициализируем, а просто передаем в качестве параметров соответствующим методам класса «Сообщения_», а они уже создают нужные колонки:
ОбъектСообщ = Сообщения_Конструктор();
Сообщения_УстАтриб(ОбъектСообщ, ЭтаФорма, ЭлементыФормы.ТабличноеПолеСообщения, Сообщения);
Сообщения_Инициализация(ОбъектСообщ);
Для отображения ТаблицыЗначений «Сообщения», на форме размещен визуальный компонент типа «ТабличноеПоле» — «ТабличноеПолеСообщения». При создании колонок в ТабличномПоле, учитываем следующие колонки ТаблицыЗначений (описывались ранее):
— ТипСообщ;
— СтатусСообщ;
— ТекстСообщ;
— КомментарийСообщ.
Текст модуля главной формы обработки (отображающей сообщения):
Текст модуля формы
//////////////////////////////////////////////////////////////////////////////// // ОСНОВНОЕ ОКНО ПРОГРАММЫ Перем ОбъектСообщ; // Объект для вывода сообщений в таблицу знач. и отобр. в табл. поле //////////////////////////////////////////////////////////////////////////////// // ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ // Процедура - обработчик события "При открытии" формы. Данное событие // возникает при открытии формы, до показа окна пользователю. // // Параметры: // Нет. // Процедура ПриОткрытии() // Создание объекта сообщений и инициализация таблицы сообщений ОбъектСообщ = Сообщения_Конструктор(); Сообщения_УстАтриб(ОбъектСообщ, ЭтаФорма, ЭлементыФормы.ТабличноеПолеСообщения, Сообщения); Сообщения_Инициализация(ОбъектСообщ); КонецПроцедуры // Процедура - обработчик события "При закрытии" формы. Данное событие // возникает после закрытия формы. // Освобождение занятых ресурсов. // // Параметры: // Нет. // Процедура ПриЗакрытии() // Завершить работу с объектом вывода сообщений Сообщения_Деструктор(ОбъектСообщ) КонецПроцедуры // Процедура - обработчик события "Нажатие" кнопки КнопкаЗапуститьПроцесс. // Имитирует операцию, в процессе выполнения которой выводятся сообщения. // // Параметры: // Элемент - кнопка. // Процедура КнопкаЗапуститьПроцессНажатие(Элемент) // Подготовка данных к началу операции ГСЧ = Новый ГенераторСлучайныхЧисел(); ВсегоОбъектов = ГСЧ.СлучайноеЧисло(1, 100); // Запросить согласие пользователя на выполнение операции РезВопр = Вопрос("Выполнить обработку данных?", РежимДиалогаВопрос.ДаНет, , , "Обработка данных"); Если РезВопр = КодВозвратаДиалога.Да Тогда // Подготовка интерфейса к запуску процесса ErrMsg = ""; Сообщения_Очистить(ОбъектСообщ); // Сообщение о начале операции Сообщения_Добавить(ОбъектСообщ, Проч.ТИПСООБЩ_УРОВЕНЬ1, "*** НАЧАЛО ОБРАБОТКИ ДАННЫХ ***"); Рез = Ложь; КолОбрОб = 0; Попытка // Выполнять обработку объектов Для Инд=1 По ВсегоОбъектов Цикл // Вывести сообщение о том, что началась обработка очередного объекта ИдСообщУр2 = Сообщения_Добавить(ОбъектСообщ, Проч.ТИПСООБЩ_УРОВЕНЬ2, "Обработка объекта " + Формат(Инд, "ЧГ=0; ЧН=''")); // ****************************** // Здесь собственно выполняется сама операция над текущим объектом Если ГСЧ.СлучайноеЧисло(0, ВсегоОбъектов) > 0 Тогда // Считаем, что операция над текущим объектом выполнена успешно Рез = Истина Иначе // Считаем, что операция над текущим объектом выполнена с ошибкой Рез = Ложь КонецЕсли; // ****************************** // Установить результат операции над текущим объектом в окне сообщений СтатСообщ = Проч.СТАТСООБЩ_НЕОПРЕД; КоммСообщ = ""; Если Рез Тогда // Операция завершена удачно СтатСообщ = Проч.СТАТСООБЩ_ОК; КоммСообщ = "ОК" Иначе // Ошибки при выполнении операции СтатСообщ = Проч.СТАТСООБЩ_ОШИБКА; КоммСообщ = "ОШИБКА" КонецЕсли; Сообщения_Изменить(ОбъектСообщ, ИдСообщУр2, , , СтатСообщ, КоммСообщ); // Анализируем результат текущей итерации Если НЕ Рез Тогда // Ошибка - прервать работу Прервать КонецЕсли; КолОбрОб = КолОбрОб + 1 КонецЦикла Исключение // Возникло исключение - ошибка ErrMsg = ИнформацияОбОшибке().Описание; Рез = Ложь КонецПопытки; // Сообщение об окончании операции Если Рез Тогда // Операция завершена успешно Сообщения_Добавить(ОбъектСообщ, Проч.ТИПСООБЩ_УРОВЕНЬ1, "*** ОБРАБОТКА ДАННЫХ ЗАВЕРШЕНА ***"); Иначе // Операция прервана Сообщения_Добавить(ОбъектСообщ, Проч.ТИПСООБЩ_УРОВЕНЬ1, "*** ОБРАБОТКА ДАННЫХ ПРЕРВАНА ***", Проч.СТАТСООБЩ_ОШИБКА, ErrMsg) КонецЕсли; // Установка интерфейса по окончанию загрузки ТекстСообщ = ""; Если Рез Тогда ТекстСообщ = "Обработка выполнена успешно" Иначе ТекстСообщ = "Обработка выполнена с ошибками" КонецЕсли; ТекстСообщ = ТекстСообщ + Символы.ПС; ТекстСообщ = ТекстСообщ + "Обработано " + Формат(КолОбрОб, "ЧГ=0; ЧН=''") + " объектов."; Предупреждение(ТекстСообщ, , "Обработка данных") КонецЕсли КонецПроцедуры // Процедура - обработчик события "ПриВыводеСтроки" табличного поля // ТабличноеПолеСообщения. Данное событие происходит при выводе каждой строки. // // Параметры: // Элемент - табличное поле; // ОформлениеСтроки - объект настройки визуального оформления строки // ДанныеСтроки - набор данных строки табличного поля. // Процедура ТабличноеПолеСообщенияПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) // Оформление ячейки "Статус" ОформлениеСтроки.Ячейки.КолонкаСтатусСообщения.ОтображатьТекст = Ложь; КартинкаСтатуса = Сообщения_Картинка(ДанныеСтроки.ТипСообщ, ДанныеСтроки.СтатусСообщ); Если КартинкаСтатуса <> Неопределено Тогда ОформлениеСтроки.Ячейки.КолонкаСтатусСообщения.ОтображатьКартинку = Истина; ОформлениеСтроки.Ячейки.КолонкаСтатусСообщения.Картинка = КартинкаСтатуса; КонецЕсли; // Оформление ячейки "Текст" Если (ДанныеСтроки.ТекстСообщ <> Неопределено) И (ДанныеСтроки.ТекстСообщ <> "") Тогда ЦветТекста = Сообщения_ЦветТекста(ДанныеСтроки.ТипСообщ, ДанныеСтроки.СтатусСообщ); Если ЦветТекста <> Неопределено Тогда ОформлениеСтроки.Ячейки.КолонкаТекстСообщения.ЦветТекста = ЦветТекста КонецЕсли КонецЕсли; // Оформление ячейки "Комментарий" Если (ДанныеСтроки.КомментарийСообщ <> Неопределено) И (ДанныеСтроки.КомментарийСообщ <> "") Тогда ЦветКомментария = Сообщения_ЦветКомментария(ДанныеСтроки.ТипСообщ, ДанныеСтроки.СтатусСообщ); Если ЦветКомментария <> Неопределено Тогда ОформлениеСтроки.Ячейки.КолонкаКомментарийСообщения.ЦветТекста = ЦветКомментария КонецЕсли КонецЕсли КонецПроцедуры // Процедура - обработчик события "Нажатие" кнопки КнопкаСообщенияОткрытьВНовомОкне. // Открывает текущий список сообщений в новом окне. // // Параметры: // Элемент - кнопка. // Процедура КнопкаСообщенияОткрытьВНовомОкнеНажатие(Элемент) ФормаПросмотраСообщений = ЭтотОбъект.ПолучитьФорму("ФормаПросмотраСообщений", ЭтаФорма); ФормаПросмотраСообщений.ShowMessagesDlg(ОбъектСообщ) КонецПроцедуры // Процедура - обработчик события "Нажатие" кнопки КнопкаСообщенияСохранить. // Сохранить текущий набор сообщений в файл. // // Параметры: // Элемент - кнопка. // Процедура КнопкаСообщенияСохранитьНажатие(Элемент) Сообщения_СохранитьВФайл(ОбъектСообщ); КонецПроцедуры
Форма просмотра сообщений.
Также имеется отдельное окно просмотра списка сообщений (соответствующей ТаблицыЗначений). Оно предназначено для того, чтобы можно было более удобно проанализировать большой список (так как в основном диалоговом окне ТабличноеПоле сообщений сильно растянуть по высоте не удастся – будет мешать другие элементы интерфейса).
Выглядит форма примерно следующим образом:
Код модуля формы совсем несложный. Вот такой:
Текст модуля формы
//////////////////////////////////////////////////////////////////////////////// // ДИАЛОГ ДЛЯ ОТОБРАЖЕНИЯ СПИСКА СООБЩЕНИЙ В ОТДЕЛЬНОМ ОКНЕ Перем ОбъектСообщ; // Объект для работы с сообщениями //////////////////////////////////////////////////////////////////////////////// // ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ // Процедура - обработчик события "Действие" элемента меню КоманднаяПанельМенюСохранитьВФайл. // Сохранить текущий набор сообщений в файл. // // Параметры: // Кнопка - элемент меню. // Процедура КоманднаяПанельМенюСохранитьВФайл(Кнопка) Сообщения_СохранитьВФайл(ОбъектСообщ); КонецПроцедуры // Процедура - обработчик события "ПриВыводеСтроки" табличного поля // ТабличноеПолеСообщения. Данное событие происходит при выводе каждой строки. // // Параметры: // Элемент - табличное поле; // ОформлениеСтроки - объект настройки визуального оформления строки // ДанныеСтроки - набор данных строки табличного поля. // Процедура ТабличноеПолеСообщенияПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) // Оформление ячейки "Статус" ОформлениеСтроки.Ячейки.КолонкаСтатусСообщения.ОтображатьТекст = Ложь; КартинкаСтатуса = Сообщения_Картинка(ДанныеСтроки.ТипСообщ, ДанныеСтроки.СтатусСообщ); Если КартинкаСтатуса <> Неопределено Тогда ОформлениеСтроки.Ячейки.КолонкаСтатусСообщения.ОтображатьКартинку = Истина; ОформлениеСтроки.Ячейки.КолонкаСтатусСообщения.Картинка = КартинкаСтатуса; КонецЕсли; // Оформление ячейки "Текст" Если (ДанныеСтроки.ТекстСообщ <> Неопределено) И (ДанныеСтроки.ТекстСообщ <> "") Тогда ЦветТекста = Сообщения_ЦветТекста(ДанныеСтроки.ТипСообщ, ДанныеСтроки.СтатусСообщ); Если ЦветТекста <> Неопределено Тогда ОформлениеСтроки.Ячейки.КолонкаТекстСообщения.ЦветТекста = ЦветТекста КонецЕсли КонецЕсли; // Оформление ячейки "Комментарий" Если (ДанныеСтроки.КомментарийСообщ <> Неопределено) И (ДанныеСтроки.КомментарийСообщ <> "") Тогда ЦветКомментария = Сообщения_ЦветКомментария(ДанныеСтроки.ТипСообщ, ДанныеСтроки.СтатусСообщ); Если ЦветКомментария <> Неопределено Тогда ОформлениеСтроки.Ячейки.КолонкаКомментарийСообщения.ЦветТекста = ЦветКомментария КонецЕсли КонецЕсли КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // ПОДПРОГРАММЫ ВНЕШНЕГО ИНТЕРФЕЙСА // Вызов диалога просмотра списка сообщений // // Параметры: // ОбъектСообщения - объект для работы с сообщениями. // Процедура ShowMessagesDlg(ОбъектСообщений) Экспорт; Если ОбъектСообщений <> Неопределено Тогда // Выполнить начальную установку параметров ОбъектСообщ = ОбъектСообщений; ЭлементыФормы.ТабличноеПолеСообщения.Значение = ОбъектСообщ.ТабЗнач; // Вызвать диалог ЭтаФорма.ОткрытьМодально() КонецЕсли КонецПроцедуры
Скачать исходные тексты подсистемы сообщений и рассмотренный пример (обработка для 1С 8.2) можно здесь.
На этом все. Всем удачи. До встречи.
P.S.
В следующей статье я планирую рассказать о работе с сервером (базами) FireBird из 1С.
Мы выясним:
— как корректно подключаться к серверу (базе) и отключаться;
— как выполнять запросы: передавать и получать данные;
— как работать с бинарными полями и строками в различной кодировке;
— как вызывать хранимые процедуры и получать результаты их работы;
— как обойти такую неприятность, как автоматический разрыв клиентского соединения со стороны сервера FireBird (простой и понятный способ, который почему-то нигде не описан в Интернете).
Мы создадим обособленные и переносимые наборы подпрограмм («классов»):
— для подключения к базе (сможем подключаться к серверу, базе и выполнять запросы);
— для работы с параметрами запроса (можно будет задавать и устанавливать параметры почти как в Delphi);
А также:
— для работы с множествами целых чисел и строк (удобно задавать множественные параметры для запросов);
— удобное хранилище профилей подключений к различным базам FireBird, а также интерфейс пользователя (форма для редактирования набора профилей подключений)
В общем, думаю, что будет интересно. Еще раз, удачи…
Содержание:
1. Свойство 1С «Проверка заполнения»
2. Процесс проверки заполнения реквизита
Приветствую, коллеги! В данной статье я расскажу, как проводить программную проверку заполнения реквизита в режиме конфигуратора в 1С. Для начала мы рассмотрим общие понятия, после чего будет показан пример программного кода с комментариями. Также я расскажу, как проводить проверку на заполнение реквизита при помощи специального свойства и в каком случае это работает лучше, чем программная проверка. Всё описанное будет проиллюстрировано на вполне конкретном примере.
1. Свойство 1С «Проверка заполнения»
Чтобы проверить заполнение реквизита в 1С используется специальное свойство – Проверка заполнения. Для всех объектов метаданных, которые имеют типы, а также для реквизитов, которые выступают в стандартном формате, и таблиц, которые обязательно должны быть заполнены, для свойства «Проверка заполнения» должно быть определено значение «Выдавать ошибку».
В некоторых случаях проводить документацию, в которой не заполнены значения в реквизитах и таблицах – не является уместным, так как во время учётов документ не будет иметь отображения. Как пример, рассмотрим документ «Заказ клиента», по сути – это запрос клиента для поставки некоторой продукции в некотором количестве. Согласно определению, не сложно понять, что документ, в котором не заполнены обязательные реквизиты «Клиент» и таблица «Товары» не является корректным и в свойстве «Проверка заполнения» нужно выставить «Выдавать ошибку».
Во время установки свойства «Проверка заполнения» обязательно опираться на то, что все возможные ограничения и сверки нужно прописывать в метаданных внутри конфигурации. Так что когда хоть один из возможных вариантов требует заполнения всех реквизитов, свойство «Проверка заполнения» будет установлено в «Выдавать ошибку». В случае отсутствия обязательных к заполнению реквизитов подобные сценарии должны быть прописаны внутри обработчика «ОбработкаПроверкиЗаполнения».
Стоит отметить, что не нужно создавать противоположную схему: когда свойство «Проверка заполнения» установлено в «Не проверять», а в обработчике «ОбработкаПроверкиЗаполнения» дописаны некоторые проверки по заполнению, так как подобный план станет лишь путать логику в работе в режиме конфигурации 1С.
2. Процесс проверки заполнения реквизита
Бывают случаи, когда при работе в режиме конфигуратора приходится вручную произвести проверку заполнения реквизитов. Когда реквизит имеет специальное свойство «Проверка значения» и при этом имеет значение «Выдавать ошибку», необходимо удалить данный реквизит в массиве проверяемых реквизитов, после чего нужно сверить заполнение реквизита документа при помощи программы, так как это более точный способ. В случае, если проверки в реквизите по умолчанию не было, то стоит программно добавить заданный реквизит в общий массив тех реквизитов, которые подлежат проверке заполнения реквизита.
Проверка по заполнению реквизитов в 1С происходит в обработчике «ОпработкаПроверкиЗаполнения()». Данный обработчик необходимо разместить внутри модуля соответствующего объекта. Его можно вызвать автоматически, когда проводим документацию или сохраняем форму.
Для проверки необходимо запустить модуль документа «ОказаниеУслуги» и поместить в него следующую процедуру:
Рис. 1 Осуществление проверки заполнения реквизита в 1С
Теперь рассмотрим, что именно происходит в данной процедуре.
В начале нам нужно найти и получить реквизит из части таблицы «НаборСвойств», которая находится в массиве «ПроверяемыеРеквизиты». Данный массив будет передан к самому обработчику – в нём и содержатся те реквизиты, которые подлежат проверке. Для всех реквизитов внутри данного реквизита нужно выставить свойство «Проверка заполнения» для значения «Выдавать ошибку». В случае, если он будет распознан и найден, нужно будет удалить его, ведь проверка заполнения реквизитов будет выполняться полностью вручную.
Далее в цикле нужно будет обойти строки внутри табличной части нужного документа, а также провести формировку сообщения, которое будет выводить ошибку лишь для тех случаев, когда данное наименование номенклатуры – это материал, в котором заполнен столбец по набору свойств.
В параметре «Отказ» нужно выставить значение в виде «Истина». Так как данное значение подтверждает, что конкретный документ не подлежит проведению, в случае, когда будет найден хотя бы один реквизит, который не будет заполненным, определится «НабрСвойств», ведь он является материалом. Если сделать комментарий на параметр, то документ будет проводится, но также будут всплывать сообщения об ошибке.
Также вместо «ПереченьНоменклатуры» и «ВидНоменклатуры» можно использовать запросы.
Специалист компании «Кодерлайн»
Айдар Фархутдинов
Проверка заполнения реквизитов
В информационной системе данные могут вноситься множеством различных способов, и часто они могут быть некорректны. Поэтому при разработке решения бывает необходимо прилагать много усилий на реализацию проверки правильности вводимых данных и уведомления пользователя о некорректности введенной информации.
Механизм проверки заполнения позволяет существенно упростить процесс разработки конфигураций.
Платформа поддерживает автоматическую проверку указанных реквизитов прикладных объектов и форм, а также позволяет выполнить процесс проверки в модуле. Для управления проверкой заполнения реквизита служит свойство Проверка заполнения. Если свойство установлено в значение Не проверять – платформа не проверяет заполнение реквизита. Значение Выдавать ошибку указывает на необходимость выполнять проверку.
Платформа выполняет автоматическую проверку заполнения:
● констант;
● справочников, документов, отчетов, обработок, планов видов характеристик, планов счетов, планов видов расчета, бизнес-процессов, задач:
● реквизитов и стандартных реквизитов,
● табличных частей,
● реквизитов и стандартных реквизитов табличных частей;
● наборов записей регистров бухгалтерии, регистра сведений, регистра накопления, регистра расчета, перерасчетов, последовательностей:
● измерений,
● ресурсов,
● реквизитов и стандартных реквизитов;
● реквизитов форм;
● реквизитов форм отчетов;
● реквизитов форм обработок.
ПРИМЕЧАНИЕ. Проверка заполнения реквизитов выполняется аналогично функции ЗначениеЗаполнено(). Проверка заполнения табличных частей подразумевает, что табличная часть считается заполненной, когда в ней присутствует хотя бы одна строка.
Проверка заполнения может быть вызвана двумя способами:
● вызовом метода ПроверитьЗаполнения() (у объекта или формы);
● автоматически.
ВНИМАНИЕ! Если свойство конфигурации Режим совместимости установлено в значение Версия 8.1, то автоматическая проверка заполнения не работает.
Установки по умолчанию
Свойство реквизита Проверка заполнения по умолчанию устанавливается в значение Выдавать ошибку для следующих стандартных реквизитов:
● ПланОбмена – Наименование;
● Справочник – Владелец, Наименование;
● Документ – Дата;
● ПланВидовХарактеристик – Наименование;
● ПланСчетов – Код, Наименование;
● ПланСчетов.ВидыСубконто – ВидСубконто;
● ПланВидовРасчета – Наименование;
● ПланВидовРасчета.ВедущиеВидыРасчета – ВидРасчета;
● ПланВидовРасчета.БазовыеВидыРасчета – ВидРасчета;
● ПланВидовРасчета.ВытесняющиеВидыРасчета – ВидРасчета;
● РегистрСведений – Период;
● РегистрНакопления – Период;
● РегистрБухгалтерии – Период;
● РегистрРасчета – ПериодРегистрации, ВидРасчета, ПериодДействияНачало, ПериодДействияКонец;
● БизнесПроцесс – Дата;
● Задача – Наименование.
Порядок работы
Автоматическая проверка заполнения вызывается расширением формы перед интерактивной записью всех объектов, кроме документов, бизнес-
процессов, отчетов и обработок. Для этих объектов определено следующее поведение:
● для документов:
● проверка заполнения вызывается расширением формы перед проведением, если свойство Проведение установлено в значение Разрешить;
● проверка заполнения вызывается расширением формы перед записью, если свойство Проведение установлено в значение Запретить;
● для бизнес-процессов проверка заполнения вызывается расширением формы перед стартом;
● для отчетов проверка заполнения вызывается расширением формы при нажатии кнопки Сформировать;
● для обработок проверка заполнения вызывается расширением формы в случаях, если нажаты кнопки, связанные со стандартными командами формы OK, Да, Повторить, Пропустить.
Если реквизит является основным реквизитом формы следующих типов: СправочникОбъект, ДокументОбъект, ОтчетОбъект,
ПланВидовХарактеристикОбъект, ПланСчетовОбъект, ПланВидовРасчетовОбъект, БизнесПроцессОбъект, ЗадачаОбъект, то для значения такого реквизита
также будет вызвана проверка заполнения.
Для вызова проверки заполнения системой необходимо, чтобы у формы (с которой происходит работа) было установлено свойство Проверять заполнение автоматически. В этом случае вначале будет вызван обработчик ОбработкаПроверкиЗаполненияНаСервере() формы, а затем обработчик ОбработкаПроверкиЗаполнения() модуля объекта.
ВНИМАНИЕ! Если у формы свойство Проверять заполнение автоматически установлено в значение Истина при выполнении стандартных команд Записать (Провести для документов и т. д.), а также стандартных команд формы OK, Да, Повторить, Пропустить, будет вызван метод ПроверитьЗаполнение(). В противном случае проверка заполнения не вызывается ни для формы, ни для объекта.
Процесс проверки заполнения происходит следующим образом:
● Формируется список имен реквизитов формы, для которых возможна проверка заполнения и для которых свойство ПроверкаЗаполнения установлено в значение ВыдаватьОшибку. В этот список не будут включены имена реквизитов, тип которых не поддерживает проверку заполнения (например, СправочникОбъект), но будет включено имя основного реквизита формы.
В автоматически формируемый список реквизитов не будут включены реквизиты формы, отключенные с помощью функциональных опций.
● Вызывается обработчик события формы ОбработкаПроверкиЗаполненияНаСервере, в котором разработчик может описать свой алгоритм проверки заполнения или изменить состав проверяемых реквизитов. В обработчик будет передан сформированный список имен реквизитов. Если в обработчике необходимо добавить к списку какие-либо реквизиты, это можно сделать только для реквизитов вышеперечисленных типов (для
которых возможна проверка заполнения в форме) и основного реквизита. Добавление в список имен реквизитов объектного типа (например, СправочникОбъект) вызовет исключение при дальнейшей автоматической проверке. Добавление в список имени несуществующего реквизита вызовет исключение при дальнейшей автоматической проверке.
● После завершения работы обработчика события механизм проверки заполнения получает обратно список имен, проверяемых реквизитом (который, возможно, был изменен в обработчике). Система анализирует список реквизитов и проверяет заполненность каждого реквизита. Если реквизиттявляется основным реквизитом объектного типа (например, Объект типа СправочникОбъект), будет вызвана проверка заполнения самого объекта.
Если реквизит является реквизитом объектного типа, но не основным, будет вызвано исключение.
Разработчик имеет возможность влиять на процесс проверки путем определения в модуле объекта, набора записей и в модуле формы обработчика события ОбработкаПроверкиЗаполнения.
Определив обработчик события, разработчик получает полный контроль над проверкой заполнения. В параметре ПроверяемыеРеквизиты обработчик получает массив реквизитов, для которых в режиме Конфигуратор указано, что они должны проверяться. Разработчик может произвольно модифицировать этот массив:
● удалять те реквизиты, проверку заполнения которых он реализует сам или считает, что их не нужно проверять в данный момент;
● добавлять необходимые реквизиты, для которых должна выполниться проверка заполнения.
В случае если разработчика не устраивает стандартная процедура проверки, он может написать алгоритм проверки сам и, используя объект СообщениеПользователю, сообщить об имеющихся проблемах пользователю.
Если в процессе проверки разработчик вывел пользователю сообщения об ошибках, необходимо установить параметр Отказ в значение Истина, чтобы уведомить платформу о том, что текущее действие не может быть завершено.
Параметр события ПроверяемыеРеквизиты содержит имена атрибутов в следующем формате:
● для реквизитов и констант – ИмяРеквизита, например, Поставщик;
● для табличных частей – ИмяТабличнойЧасти, например, Товары;
● для реквизитов табличных частей – ИмяТабличнойЧасти.ИмяРеквизита, например, Товары.Номенклатура;
● для реквизитов форм – ИмяРеквизита, например, ДокументОбъект.
Для реквизитов, входящих в состав функциональных опций без параметров, значение опции учитывается при проверке заполнения. Если функциональная опция включена, то реквизит будет включен в список проверяемых реквизитов; если опция выключена, реквизит не будет включен в список проверяемых реквизитов. Это значит, что отключенное поле не будет передано через параметры ПроверяемыеРеквизиты в
ОбработкаПроверкиЗаполнения.
Реквизиты, входящие в состав функциональной опции с параметрами , всегда включаются в список проверяемых реквизитов (параметр ПроверяемыеРеквизиты). Удаление реквизита из списка проверяемых реквизитов в таких случаях необходимо выполнять в обработчике ОбработкаПроверкиЗаполнения. Для этого следует получить значение функциональной опции, указав в качестве параметров необходимые данные
объекта.
Правила отображения отметки незаполненного
На отображение отметки незаполненного влияют следующие свойства элементов конфигурации:
● свойство Проверка заполнения реквизита или стандартного реквизита объекта метаданных;
● свойство Проверка заполнения реквизита формы;
● свойство Автоотметка незаполненного элемента формы;
● свойство ОтметкаНезаполненного элемента формы (доступно только для программного изменения).
Свойство элемента формы Автоотметка незаполненного может быть установлено в значение:
● Авто – отметка будет отображаться, если у реквизита формы или реквизита (стандартного реквизита) объекта метаданных свойство Проверка заполнения установлено в значение Выдавать ошибку и реквизит, связанный с элементом формы, содержит пустое значение.
● Да – отметка будет отображаться для незаполненного элемента вне зависимости от того, в каком состоянии находится свойство Проверка
заполнения.
● Нет – отметка не будет отображаться для незаполненного элемента вне зависимости от того, в каком состоянии находится свойство Проверка заполнения.
При начале интерактивного изменения поля ввода отметка незаполненного перестает отображаться, при этом значение свойства ОтметкаНезаполненного не изменяется. Отображение отметки восстанавливается (если это необходимо) после того, как в поле ввода завершено интерактивное редактирование или установлено значение. При этом свойство ОтметкаНезаполненного может быть изменено системой в том случае, если
свойство АвтоОтметкаНезаполненного установлено в значение Истина:
● если значение в поле не заполнено, то свойство ОтметкаНезаполненного будет установлено в значение Истина;
● если в поле значение заполнено, то свойство ОтметкаНезаполненного будет установлено в значение Ложь.
ПРИМЕЧАНИЕ. Если свойство ОтметкаНезаполненного установлено у таблицы, то для таблицы, в которой нет строк, будет подсвечена первая строка, а для заполненной таблицы – все строки.
Кроме того, отметка незаполненного также будет отображена, если в окне сообщений есть сообщение , связанное с конкретным полем формы, вне зависимости от установленных свойств элемента формы и связанных с ним реквизитов. После очистки окна сообщений отметка незаполненного снимается у тех элементов формы, значение свойства ОтметкаНезаполненного которых равно значению Ложь.