1с сообщение об ошибке программно

Попытка
  //Некоторые действия
Исключение
  //Действия при ошибке
КонецПопытки;

Показ сообщения об ошибке

Для вывода сообщения об ошибке нужно использовать функцию ОписаниеОшибки();

Пример:

Попытка
    НаборЗаписей.Записать(Истина);
Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;

Для выдачи структуированной информации об ошибке в версии 8.2 служит функция ИнформацияОбОшибке().

    Инфо = ИнформацияОбОшибке();
    Сообщить("Описание='" + Инфо.Описание + "'");
    Сообщить("ИмяМодуля='" + Инфо.ИмяМодуля + "'");
    Сообщить("НомерСтроки=" + Инфо.НомерСтроки);
    Сообщить("ИсходнаяСтрока='" + Инфо.ИсходнаяСтрока + "'");

Вызов исключения

В 1С:Предприятие 7.7 оператор ВызватьИсключение; служит для повторного вызова исключения из блока Исключение-КонецПопытки. Для вызова из других частей программы можно использовать внешнюю компоненту или деление на 0, например а=1/0.

В 1С:Предприятие версии 8 есть оператор ВызватьИсключение:

ВызватьИсключение "Текст сообщения об ошибке";

Если Ваша конфигурация применяет БСП, то рекомендуется использовать процедуры БСП для вывода сообщений пользователям.

Примеры вывода сообщений

Если обращение «с сервера», то для вывода сообщения пользователю можно применять следующую процедуру БСП:

ОбщегоНазначения.СообщитьПользователю(«Текст сообщения»);

Если обращение «с клиента», то для вывода сообщения пользователю можно применять следующую процедуру БСП:

ОбщегоНазначенияКлиент.СообщитьПользователю(«Текст сообщения»);

Устаревшая процедура, но которая еще используется в конфигурациях на предыдущих версиях БСП:

ОбщегоНазначенияКлиентСервер.СообщитьПользователю(«Текст сообщения»);

Пример вывода сообщения об ошибке:

Попытка
    ФайлCSV.Прочитать(ПутьКФайлу);
Исключение
    ОбщегоНазначенияКлиент.СообщитьПользователю(«Не удалось загрузить файл: « + ПутьКФайлу + Символы.ПС + ОписаниеОшибки());
КонецПопытки;

Общий синтаксис процедуры:

// Формирует и выводит сообщение, которое
может быть связано с элементом управления формы.
//
// Параметры:
// 
ТекстСообщенияПользователю — Строка — текст сообщения.
// 
КлючДанных — ЛюбаяСсылка — объект или ключ записи информационной базы, к
которому это сообщение относится.
// 
Поле — Строка — наименование реквизита формы.
// 
ПутьКДанным — Строка — путь к данным (путь к реквизиту формы).
// 
Отказ — Булево — выходной параметр, всегда устанавливается в значение
Истина.

Процедура СообщитьПользователю(
    Знач ТекстСообщенияПользователю,
    Знач КлючДанных = Неопределено,
    Знач Поле = «»,
    Знач ПутьКДанным = «»,
    Отказ = Ложь) Экспорт

Примеры:

// 1. Для вывода сообщения у поля
управляемой формы, связанного с реквизитом объекта:
ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр(«ru = ‘Сообщение об ошибке.'»), , «ПолеВРеквизитеФормыОбъект», «Объект»);

// Альтернативный вариант использования в
форме объекта:
ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр(«ru = ‘Сообщение об ошибке.'»), , «Объект.ПолеВРеквизитеФормыОбъект»);

// 2. Для вывода сообщения рядом с полем
управляемой формы, связанным с реквизитом формы:
ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр(«ru = ‘Сообщение об ошибке.'»), , «ИмяРеквизитаФормы»);

// 3. Для вывода сообщения связанного с
объектом информационной базы:
ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр(«ru = ‘Сообщение об ошибке.'»), ОбъектИнформационнойБазы, «Ответственный»,,Отказ);

// 4. Для вывода сообщения по ссылке на
объект информационной базы:
ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр(«ru = ‘Сообщение об ошибке.'»), Ссылка, , , Отказ);

Случаи некорректного использования:

1. Передача одновременно параметров КлючДанных и ПутьКДанным.

2. Передача в параметре КлючДанных значения типа отличного от допустимого.

3. Установка ссылки без установки поля (и/или пути к данным).

Если Вам понравилась статья, пожалуйста, поставьте лайк, сделайте репост или оставьте комментарий. Если у Вас есть какие-либо замечания, также пишите комментарии.

  • Главная
  • О сайте
  • Главная
  • Содержание

Рукопашный бой Карташ

Категории

—>

рубрики: Язык программирования 1С | Дата: 2 марта, 2017

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




Попытка

	//Выполняемый код

Исключение

	//Обработка исключительной ситуации:
	//- Сообщение пользователю;
	//- Запись лога в файл;
	//- Отправка сообщения по электронной почте;
	//- Фиксация ошибки путем присвоения переменной соответствующего значения

КонецПопытки;

Рассмотрим все вышесказанное на элементарном примере. Для начала искусственно создадим ситуацию с ошибкой. Сделаем это очень просто — путем деления на ноль.




&НаКлиенте
Процедура ВыполнитьДеление(Команда)

	Частное = 1 / 0;

КонецПроцедуры

При выполнении этого кода выводится вот такое системное сообщение об ошибке:

А теперь доработаем нашу процедуру с использованием Попытки




&НаКлиенте
Процедура ВыполнитьДеление(Команда)

	Попытка

		Частное = 1 / 0;

	Исключение

		Сообщить("Произошла ошибка при попытке деления");

	КонецПопытки;

КонецПроцедуры

Снова запустим на выполнение нашу процедуру. В этот раз системное сообщение об ошибке показано не будет, а будет выведено наше собственное сообщение, которое мы прописали в исключении. В исключении можно получить дополнительную информацию об ошибке с помощью метода ОписаниеОшибки(). Вот таким образом




Сообщить("Произошла ошибка при попытке деления" + ОписаниеОшибки());

В этом случае в момент выполнения деления в окне сообщений появится следующий текст



Произошла ошибка при попытке деления{ВнешняяОбработка.ПопыткаИсключение.Форма.Форма.Форма(34)}: Деление на 0

Попытки могут быть вложенными одна в другую. То есть вполне допустимым является следующая конструкция




Попытка

	//Код

	Попытка
		//Код
	Исключение
		//Обработка исключения
	КонецПопытки;

	Попытка
		//Код
	Исключение
		//Обработка исключения
	КонецПопытки;

Исключение
	//Обработка исключения
КонецПопытки;

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

Конечно не стоит злоупотреблять использованием конструкции Попытка Исключение. По сути ее использование целесообразно в следующих случаях

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

В 1С предполагается, что СообщениеПользователю выводятся для того, чтобы сообщить пользователю об ошибках. 

А для информирования о выполняемом действии рекомендуется использовать метод встроенного языка ПоказатьОповещениеПользователя().


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

Пример вывода сообщения на клиенте:

Код 1C v 8.3

 Если ЗначениеЗаполнено(объект.ИнтернетМагазин) Тогда		
// Все заполнено, обрабатываем
Иначе
сбп=Новый СообщениеПользователю;
сбп.Текст = "Укажите интернет-магазин данные которого Вы загружаете!";
сбп.Поле="ИнтернетМагазин";
сбп.ПутьКДанным = "Объект";
сбп.Сообщить();
КонецЕсли;

При обработке на сервере:

Необходимо зарегистрировать в системе соответствие объекта и имени реквизита формы. Для этого в глобальном контексте реализована функция УстановитьСоответствиеОбъектаИРеквизитаФормы(). Сделать это можно следующим образом:

Код 1C v 8.3

  &НаСервере
Процедура ПроцедураВызываемаяСКлиента(ОбъектДанных)   
    Документ = ДанныеФормыВЗначение(Объект, Тип("ДокументОбъект.ПоступлениеТМЦ"));    // Преобразования данных формы в объект
    УстановитьСоответствиеОбъектаИРеквизитаФормы(Документ, "Объект");    // Установка соответствия
    ДействиеСОбъектом(Документ);    // Действия над объектом, в процессе работы которых может возникнуть необходимость вывода сообщений
КонецПроцедуры

В данном фрагменте выполняется преобразование объекта из данных формы в реальный объект и устанавливается его соответствие с реквизитом формы по имени «Объект».

Если в дальнейшем требуется создать сообщение, можно сделать это следующим образом:

Код 1C v 8.3

  &НаСервере
Процедура ДействиеСОбъектом(ОбъектДанных)
    // Какие либо действия, которые требуют создания сообщения

    // Создание сообщения
    Сообщение = Новый СообщениеПользователю();
    Сообщение.Текст = "В строке 11 табличной части ""Номенклатура"" не хватает " + 
                      НедостающееКоличество + " " + ЕдиницаИзмеренияНоменклатуры;
    Сообщение.Поле = "Номенклатура[10].Количество";

    // Привязка объекта к реквизиту формы произойдет за счет
    // установленного выше по стеку соответствия методом
    // УстановитьСоответствиеОбъектаИРеквизитаФормы
    Сообщение.УстановитьДанные(ОбъектДанных);
    // Теперь у сообщения заполнено поле ПутьКДанным (установлено имя реквизита формы, до этого была пустая строка),
    // и свойство КлючДанных (установлена ссылка на документ, до этого было Неопределено)

    // Сообщение выводится пользователю
    Сообщение.Сообщить();
    // в дальнейшем сообщение будет показано в форме и привязано к
    // элементу управления связанного с полем Количество 
    // в 11-й строке табличной части Номенклатура.
КонецПроцедуры;

В этом фрагменте создается новый объект СообщениеПользователю, в котором запоминается Текст сообщения и указывается Поле объекта, ошибка в данных которого вызвала необходимость вывода сообщения. Информация о том, как объект расположен в форме берется из предварительно запомненной пары «Объект/ИмяРеквизитаФормы». В дальнейшем сообщение будет выведено в окно сообщений формы и привязано к соответствующему элементу управления.

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

Реквизит ИмяРеквизита Контрагент
Табличная часть ИмяТабличнойЧасти Скидки
Реквизит табличной части ИмяТабличнойЧасти[ИндексСтроки].ИмяРеквизита Номенклатура[10].Количество
Реквизит набора записей [ИндексСтроки].ИмяРеквизита [10].Курс

ТипШаблонПример

Еще примеры:

Код 1C v 8.3

 &НаКлиенте
Процедура ДействиеСОбъектомНаКлиенте(ОбъектДанных)
     // Какие либо действия, которые требуют создания сообщения
    // Создание сообщения
    Сообщение = Новый СообщениеПользователю();
    Сообщение.Текст = "В строке 11 табличной части ""Номенклатура"" не хватает " + 
                      НедостающееКоличество + " " + ЕдиницаИзмеренияНоменклатуры;
    Сообщение.Поле = "Номенклатура[10].Количество";

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

    // Сообщение выводится пользователю
    Сообщение.Сообщить();
КонецПроцедуры;

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

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

// Показываем сообщение из документа
// КлючДанных - пустой, ПутьКДанным заполнится автоматически
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Поле = "Товары[0].Количество";
    Сообщение.Текст = "Не заполнено количество товара в первой строке!";
    Сообщение.УстановитьДанные(ЭтотОбъект);
    Сообщение.Сообщить();

////////////////////  КОД для ТИПОВЫХ конфигураций, БСП:
//в модуле объекта
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(“Текст ошибки”,                
                        ЭтотОбъект,
                        "Договор",,
                        Отказ);
//в форме объекта
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(НСтр("ru = 'Дублирование пременной'"), ,
"Запросы["+ИдентификаторСтроки+"].ИмяПеременнойЗапроса",//путь к данным
 "Объект", Отказ);   


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

Код 1C v 8.3

 ПоказатьОповещениеПользователя(НСтр("ru = 'Выполнение:'"), ПолучитьНавигационнуюСсылку(Объект), "Выгрузка завершена, все ОК!", БиблиотекаКартинок.ПолнотекстовыйПоискДалее);   

Код 1C v 8.3

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

&НаСервереБезКонтекста
Функция ПолучитьДатуЗапретаРедактирования()
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Константы.ДатаЗапретаРедактирования
|ИЗ
| Константы КАК Константы";
РезультатЗапроса = Запрос.Выполнить();
Возврат РезультатЗапроса.Выгрузить()[0].ДатаЗапретаРедактирования;
КонецФункции  

Время на прочтение
32 мин

Количество просмотров 29K


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

Предыстория.

В свое время, работая с системой контроля версий 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с синтаксическая ошибка неверное имя текущей таблицы
  • 1с сервер ошибка установки соединения
  • 1с сервер ошибка при выполнении файловой операции
  • 1с сервер ошибка получения параметров информационной базы