Здравствуйте.
Сегодня речь пойдет о реализации подсистемы выдачи информационных сообщений пользователю. Стандартный способ проинформировать о чем-либо пользователя – это использование процедуры «Сообщить». Однако в некоторых случаях, хочется создать отдельный список, который не будет замусоривать своим выводом основной список сообщений платформы. Также желательно иметь возможность выделять цветом различные сообщения (в зависимости от их типа, например). В общем, расскажу, как это получилось сделать у меня. Приведенное в статье решение можно встроить в свою программу без какой-либо адаптации.
Предыстория.
В свое время, работая с системой контроля версий 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, а также интерфейс пользователя (форма для редактирования набора профилей подключений)
В общем, думаю, что будет интересно. Еще раз, удачи…
ссылка на оригинал статьи https://habrahabr.ru/post/278521/
Добавить комментарий