Scripts (версия 3.xx)/Обзвон абонентов: различия между версиями

Материал из Call Office Wiki
Перейти к навигации Перейти к поиску
 
(не показано 11 промежуточных версий этого же участника)
Строка 20: Строка 20:
</syntaxhighlight>
</syntaxhighlight>


:Командой '''Script.SetDebug''' включается/отключается режим вывода дополнительных отладочных сообщений во время работы сценария. Как правило, это излишняя информация. Включать данный параметр рекомендуется только в случае, если сценарий выполняется некорректно и надо отправить разработчикам журнал с большим количеством информации.
:Командой '''Script.SetDebug''' включается/отключается режим вывода дополнительных отладочных сообщений во время работы сценария. Как правило, это излишняя информация. Включать данный параметр рекомендуется только в случае, если сценарий выполняется некорректно и надо отправить разработчикам журнал с большим количеством информации. Без передачи параметра (true/false) функция включает режим отображения так, как установлено в конфигурации.
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">


Script.SetDebug (false);
Script.SetDebug ();
</syntaxhighlight>
</syntaxhighlight>


Строка 33: Строка 33:
</syntaxhighlight>
</syntaxhighlight>


:Далее определяется переменная класса '''Device''', отвечающая за управление нашим устройством обзвона (модем, SIP и т.д.). Используется метод [[Объект_Device/Методы/Open|Open]] для устройства с проверкой успешности.
:Далее определяется переменная '''Device''' класса '''CDevice''', отвечающая за управление нашим устройством обзвона (модем, SIP и т.д.). Используется метод [[Объект_Device/Методы/Open|Open]] для устройства с проверкой успешности.


:Устанавливается в единицу переменная '''CycleCount''', отвечающая за количество сеансов обзвона.
:Устанавливается в единицу переменная '''CycleCount''', отвечающая за количество сеансов обзвона.
Строка 45: Строка 45:
</syntaxhighlight>
</syntaxhighlight>


:Определяется класс '''DataRead''', отвечающий за получение данных из источника данных, проверяется переменная '''CycleCount''' на превышение значения. Если переменная не превышает значения, записанного в конфигурации, пишется сообщение в журнал.
:Определяется переменная '''DataRead''' класса '''CDataRead''', отвечающая за получение данных из источника данных, проверяется переменная '''CycleCount''' на превышение значения. Если переменная не превышает значения, записанного в конфигурации, пишется сообщение в журнал о порядковом номере обзвона в текущем сеансе.
 
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">


Строка 53: Строка 54:


         Script.InLogInfo ('Цикл обзвона <b>%s</b>.', CycleCount);
         Script.InLogInfo ('Цикл обзвона <b>%s</b>.', CycleCount);
</syntaxhighlight>
:Определяется переменная '''Database''' класса '''CDatabase''', отвечающая за работу с источником данных. Проверяется соединение с базой данных.
<syntaxhighlight lang="javascript">


         var Database = new CDatabase ();
         var Database = new CDatabase ();


         if (Database.Open ()) {                            // Если соединение с базой данных успешное
         if (Database.Open ()) {                            // Если соединение с базой данных успешное
</syntaxhighlight>


:Определяется переменная '''Info''' класса '''CInfo''', отвечающая за отображение статистики во вкладке [[Запуск конфигурации_(версия_3.xx)|«Журнал»]]. Проводится первый подсчёт статистики на основе выбранных в конфигурации параметров (учитывать/не учитывать успешный дозвон, количество звонков и т.д.)
<syntaxhighlight lang="javascript">
             var Info = new CInfo ();
             var Info = new CInfo ();


             if (Info.Count (Database, DataRead)) {          // Подсчет статистики
             if (Info.Count (Database, DataRead)) {          // Подсчет статистики
</syntaxhighlight>
:Определяется переменная '''Record''', содержащая набор методов и свойств работы с выборкой запроса, делается проверка на её корректность.


<syntaxhighlight lang="javascript">
               var Record = Database.Query (DataRead.Query ());      // Выбор записей в базе данных
               var Record = Database.Query (DataRead.Query ());      // Выбор записей в базе данных


               if (Record) {
               if (Record) {
</syntaxhighlight>


:Определяется переменная '''DataWrite''' класса '''CDataWrite''', отвечающая за запись результатов в базу данных. Проверяется наличие полей в источнике данных, необходимых для чтения и/или записи данных во время выполнения сценария.
<syntaxhighlight lang="javascript">
                   var DataWrite = new CDataWrite ();
                   var DataWrite = new CDataWrite ();


                   if (DataRead.CheckFields (Record) &&
                   if (DataRead.CheckFields (Record) &&
                     DataWrite.CheckFields (Record)) {    // Проверка наличия полей для чтения и записи
                     DataWrite.CheckFields (Record)) {    // Проверка наличия полей для чтения и записи
</syntaxhighlight>
:Запускается цикл обзвона для выбранных записей базы данных.


<syntaxhighlight lang="javascript">
                     while (Record.Fetch ()) {
                     while (Record.Fetch ()) {


Строка 76: Строка 98:


                         Info.DataShow (Record);      // Показываем текущую запись в информационном окне
                         Info.DataShow (Record);      // Показываем текущую запись в информационном окне
</syntaxhighlight>
:Определяется переменная '''Time''' класса '''CTime''', отвечающая за работу с временем и расписание.
:Устанавливается пустое значение для переменной '''Status''', в которую записывается результат звонка.


<syntaxhighlight lang="javascript">
                         var Time = new CTime ();
                         var Time = new CTime ();


Строка 82: Строка 110:


                         var Status = '';
                         var Status = '';
</syntaxhighlight>
:Определяется массив '''Phone''', содержащий номера очередных телефонов из базы данных. Даже если не указан параметр «Несколько номеров в ячейке», всё равно приходит в виде массива.


<syntaxhighlight lang="javascript">
                         var Phone = DataRead.GetPhone (Record);
                         var Phone = DataRead.GetPhone (Record);


Строка 90: Строка 122:
                                                                             // и не достигнут предел количества попыток
                                                                             // и не достигнут предел количества попыток
                               try {
                               try {
</syntaxhighlight>
:Запускается цикл внутри массива '''Phone'''. Добавляется глобальная для сценария переменная '''[Phone]''', заменяемая в выражениях на значение текущего номера телефона.
:Выполняется проверка на остановку сценария пользователем или в результате возникшей ошибки.
<syntaxhighlight lang="javascript">


                                 for (var i in Phone) {
                                 for (var i in Phone) {
Строка 97: Строка 136:
                                     if (!Script.IsStop () &&
                                     if (!Script.IsStop () &&
                                         DataRead.WaitBeforeCall ()) {          // Ожидание перед звонком
                                         DataRead.WaitBeforeCall ()) {          // Ожидание перед звонком
</syntaxhighlight>
:Определяется переменная '''Sound''' класса '''CSound''', отвечающая за воспроизведение абоненту звукового сообщения.
:Выполняются необходимые действия перед набором номера (например, предварительный синтез сообщений). Устанавливается статус текущего звонка в переменной '''PhoneStatus'''.


<syntaxhighlight lang="javascript">
                                       var Sound = new CSound ();
                                       var Sound = new CSound ();


Строка 103: Строка 148:


                                       var PhoneStatus = '';                  // Начало звонка, текущий статус пуст
                                       var PhoneStatus = '';                  // Начало звонка, текущий статус пуст
</syntaxhighlight>
:Набор текущего номера абонента. Определяется переменная '''Result''', содержащая результат [[Объект_Device/Методы/Dial|набора номера]].


<syntaxhighlight lang="javascript">
                                       var Result = Device.Dial (Phone[i]);  // Набираем номер
                                       var Result = Device.Dial (Phone[i]);  // Набираем номер
</syntaxhighlight>
:Определяется переменная '''Options''' класса '''COptions''', отвечающая за параметры дозвона:
:* время дозвона, после которого программа переходит к следующему номеру;
:* время прослушивания сообщения абонентом;
:* дублирование процесса соединения с абонентом на звуковую карту компьютера.


<syntaxhighlight lang="javascript">
                                       var Options = new COptions ();
                                       var Options = new COptions ();
</syntaxhighlight>
:Действия при успешном дозвоне:
:* определение переменной '''StartTime''', содержащей время начала разговора;
:* определение переменной '''Recording''' класса '''CRecording''', отвечающая за запись ответа абонента в звуковой файл;
:* включение записи ответа перед произнесением сообщения, если указано в конфигурации;
:* произнесение сообщения;
:* включение записи ответа после произнесения сообщения, отключение записи и сохранение записанных данных в файл, если указано в конфигурации;
:* проставляется статс по времени прослушивания сообщения абонентом, если указано в конфигурации.
Завершение действий при успешном дозвоне.
<syntaxhighlight lang="javascript">


                                       if (Result == 0) {                    // Если абонент снял трубкy
                                       if (Result == 0) {                    // Если абонент снял трубкy
Строка 122: Строка 191:
                                           PhoneStatus = Options.CheckCallTime (StartTime);      // Текущий статус по времени прослушивания
                                           PhoneStatus = Options.CheckCallTime (StartTime);      // Текущий статус по времени прослушивания
                                       }
                                       }
</syntaxhighlight>
:При неудачном дозвоне причина заносится в переменную статуса текущего звонка '''PhoneStatus'''.
<syntaxhighlight lang="javascript">
                                       else {
                                       else {
                                           PhoneStatus = Device.GetDialErrorText (Result);  // Текущий статус при неудачном дозвоне
                                           PhoneStatus = Device.GetDialErrorText (Result);  // Текущий статус при неудачном дозвоне
                                       }
                                       }
</syntaxhighlight>
:Трубка положена.
:Подготавливается статус для базы данных. Если статус не успешный, заносим в переменную статуса значение статуса текущего звонка '''PhoneStatus'''.


<syntaxhighlight lang="javascript">
                                       Device.HangUp ();
                                       Device.HangUp ();


                                       if (Status != 'OK') Status = PhoneStatus;                // Статус записи
                                       if (Status != 'OK') Status = PhoneStatus;                // Статус записи
</syntaxhighlight>


:Проверяется статус текущего звонка и необходимость звонить по оставшимся номерам в ячейке.
<syntaxhighlight lang="javascript">
                                       if (DataRead.IsRemaining (PhoneStatus)) {
                                       if (DataRead.IsRemaining (PhoneStatus)) {


Строка 136: Строка 220:
                                                           // по оставшимся номерам в ячейке
                                                           // по оставшимся номерам в ячейке
                                       }
                                       }
</syntaxhighlight>


:Выполняется проверка на остановку сценария пользователем. Записывается при необходимости соответствующий статус.
<syntaxhighlight lang="javascript">
                                       if (Script.IsStop ()) break;
                                       if (Script.IsStop ()) break;


                                     } else Status = 'Прервано пользователем.';
                                     } else Status = 'Прервано пользователем.';
</syntaxhighlight>
:Завершение цикла внутри массива '''Phone'''.
<syntaxhighlight lang="javascript">
                                 }
                                 }
                               }
                               }
</syntaxhighlight>
:Действия сценария при возникновении ошибки. Записывается при необходимости соответствующий статус.
<syntaxhighlight lang="javascript">
                               catch (Err) {
                               catch (Err) {
                                 Device.HangUp ();
                                 Device.HangUp ();
Строка 147: Строка 245:
                                 Script.StopError (Err.description);
                                 Script.StopError (Err.description);
                               }
                               }
</syntaxhighlight>
:Сохранение статуса в базу данных. Обновление окна статистики.


<syntaxhighlight lang="javascript">
                               DataWrite.SetStatus (Record, DataRead.GetPhone (Record, true), Status);      // Запись результата звонка
                               DataWrite.SetStatus (Record, DataRead.GetPhone (Record, true), Status);      // Запись результата звонка


Строка 154: Строка 256:
                               if (Script.IsStop ()) break;
                               if (Script.IsStop ()) break;
                           }
                           }
</syntaxhighlight>
:Сообщение в журнал, если пустой номер телефона в базе данных. Проверка на необходимость остановки в случае возникновения некритической ошибки.
<syntaxhighlight lang="javascript">
                         } else Script.StopError ('Номер телефона пуст.');
                         } else Script.StopError ('Номер телефона пуст.');


                         if (Script.IsStop ()) break;
                         if (Script.IsStop ()) break;
</syntaxhighlight>


:Переход к следующей записи базы данных.
<syntaxhighlight lang="javascript">
                         Record.Next ();
                         Record.Next ();
                     }
                     }
                   }                                                              // Отсутствуют необходимые поля базы данных
                   }                                                              // Отсутствуют необходимые поля базы данных
</syntaxhighlight>
:Закрывается соединение с выбранными записями при достижении последней записи или в результате ошибки необходимых полей базы данных.


<syntaxhighlight lang="javascript">
                   Record.Close ();
                   Record.Close ();
               } else Script.InLogError ('Ошибка получения данных для обзвона.');
               } else Script.InLogError ('Ошибка получения данных для обзвона.');
             } else Script.InLogInfo ('Отсутствуют кандидаты на обзвон.');
             } else Script.InLogInfo ('Отсутствуют кандидаты на обзвон.');
</syntaxhighlight>
:Ожидание между звонками, если нет сигнала остановки сценария.


<syntaxhighlight lang="javascript">
             if (!Script.IsStop ()) DataRead.CycleWait ();
             if (!Script.IsStop ()) DataRead.CycleWait ();
</syntaxhighlight>
:Закрывается соединение с базой данных.


<syntaxhighlight lang="javascript">
             Database.Close ();
             Database.Close ();
         }
         }
</syntaxhighlight>
:Увеличивается счётчик циклов текущего сеанса переменная '''CycleCount'''.


<syntaxhighlight lang="javascript">
         CycleCount++;
         CycleCount++;


         if (Script.IsStop ()) break;
         if (Script.IsStop ()) break;
       }
       }
</syntaxhighlight>
:Закрывается устройство, используемое для обзвона.


<syntaxhighlight lang="javascript">
       Device.Close ();
       Device.Close ();
   }
   }
</syntaxhighlight>
:Записывается в журнал описание критической ошибки, возникшей при работе сценария. Закрывается соединение с базой данных. Закрывается устройство.
<syntaxhighlight lang="javascript">
}
}
catch (Err) {
catch (Err) {
Строка 185: Строка 321:
   if (Device  ) Device.Close ();
   if (Device  ) Device.Close ();
}
}
</syntaxhighlight>


:Записывается в журнал сообщение о завершении работы сценария.
<syntaxhighlight lang="javascript">
Script.InLogInfo ('Стоп');
Script.InLogInfo ('Стоп');
</syntaxhighlight>
</syntaxhighlight>


[[Category:Помощь (версия 3.xx)]]
[[Category:Помощь (версия 3.xx)]]

Текущая версия на 09:21, 25 октября 2013

Первая часть скрипта подготавливает классы и объекты, необходимые для работы скрипта. Описание дано в комментариях к каждой строке за исключением класса Script, который отвечает за непосредственное выполнение скрипта.
eval (GetFileContent ('Common\\Classes\\Script.js'));             // необходимо для работоспособности сценария
var Script = new Script ();                                       // необходимо для работоспособности сценария

// =================== Подключение модулей ===================
eval (Script.GetFileContent ('Common\\Classes\\Database.js'));                   // База данных
eval (Script.GetFileContent ('Common\\Classes\\Time.js'));                       // Расписание
eval (Script.GetFileContent ('Common\\Classes\\Sound.js'));                      // Воспроизведение звуков
eval (Script.GetFileContent ('Common\\Classes\\Device.js'));                     // Устройство
eval (Script.GetFileContent ('Common\\Classes\\Recording.js'));                  // Запись разговора
eval (Script.GetFileContent ('Common\\Classes\\DataRead.js'));                   // Чтение данных

// локальные модули для конкретного решения
eval (Script.GetFileContent ('Solutions\\Basic\\OutgoingCall\\Info.js'));        // Информация и статистика
eval (Script.GetFileContent ('Solutions\\Basic\\OutgoingCall\\CDataWrite.js'));  // Запись данных
eval (Script.GetFileContent ('Solutions\\Basic\\OutgoingCall\\COptions.js'));    // Расширенные настройки

// =================== Начало работы сценария ===================
Командой Script.SetDebug включается/отключается режим вывода дополнительных отладочных сообщений во время работы сценария. Как правило, это излишняя информация. Включать данный параметр рекомендуется только в случае, если сценарий выполняется некорректно и надо отправить разработчикам журнал с большим количеством информации. Без передачи параметра (true/false) функция включает режим отображения так, как установлено в конфигурации.
Script.SetDebug ();
Команда Script.InLogInfo позволяет выводить информацию в журнал в интерфейсе программы и одновременно записывать её в системный журнал. В данном случае будет отметка о том, что сценарий загрузил все необходимые данные и запустился.
Script.InLogInfo ('Старт');

try {
Далее определяется переменная Device класса CDevice, отвечающая за управление нашим устройством обзвона (модем, SIP и т.д.). Используется метод Open для устройства с проверкой успешности.
Устанавливается в единицу переменная CycleCount, отвечающая за количество сеансов обзвона.
   var Device = new CDevice ();

   if (Device.Open ()) {                                    // Если устройство открыто успешно

      var CycleCount = 1;
Определяется переменная DataRead класса CDataRead, отвечающая за получение данных из источника данных, проверяется переменная CycleCount на превышение значения. Если переменная не превышает значения, записанного в конфигурации, пишется сообщение в журнал о порядковом номере обзвона в текущем сеансе.
      var DataRead = new CDataRead ();

      while (DataRead.CheckCycle (CycleCount)) {            // Проверка количества попыток обзвона в сеансе

         Script.InLogInfo ('Цикл обзвона <b>%s</b>.', CycleCount);
Определяется переменная Database класса CDatabase, отвечающая за работу с источником данных. Проверяется соединение с базой данных.
         var Database = new CDatabase ();

         if (Database.Open ()) {                            // Если соединение с базой данных успешное
Определяется переменная Info класса CInfo, отвечающая за отображение статистики во вкладке «Журнал». Проводится первый подсчёт статистики на основе выбранных в конфигурации параметров (учитывать/не учитывать успешный дозвон, количество звонков и т.д.)
            var Info = new CInfo ();

            if (Info.Count (Database, DataRead)) {          // Подсчет статистики
Определяется переменная Record, содержащая набор методов и свойств работы с выборкой запроса, делается проверка на её корректность.
               var Record = Database.Query (DataRead.Query ());      // Выбор записей в базе данных

               if (Record) {
Определяется переменная DataWrite класса CDataWrite, отвечающая за запись результатов в базу данных. Проверяется наличие полей в источнике данных, необходимых для чтения и/или записи данных во время выполнения сценария.
                  var DataWrite = new CDataWrite ();

                  if (DataRead.CheckFields (Record) &&
                     DataWrite.CheckFields (Record)) {     // Проверка наличия полей для чтения и записи
Запускается цикл обзвона для выбранных записей базы данных.
                     while (Record.Fetch ()) {

                        Script.WaitPause ();          // Ожидание, если нажали на Паузу

                        Info.DataShow (Record);       // Показываем текущую запись в информационном окне
Определяется переменная Time класса CTime, отвечающая за работу с временем и расписание.
Устанавливается пустое значение для переменной Status, в которую записывается результат звонка.
                        var Time = new CTime ();

                        Time.WaitTime ();             // Ожидаем время начала обзвона, если указано

                        var Status = '';
Определяется массив Phone, содержащий номера очередных телефонов из базы данных. Даже если не указан параметр «Несколько номеров в ячейке», всё равно приходит в виде массива.
                        var Phone = DataRead.GetPhone (Record);

                        if (!empty (Phone)) {            // Если номер телефона не пуст

                           if (!DataRead.CheckIsOK (Record, Phone)) {       // Если статус - не прозвонен
                                                                            // и не достигнут предел количества попыток
                              try {
Запускается цикл внутри массива Phone. Добавляется глобальная для сценария переменная [Phone], заменяемая в выражениях на значение текущего номера телефона.
Выполняется проверка на остановку сценария пользователем или в результате возникшей ошибки.
                                 for (var i in Phone) {

                                    Script.AddVariable ('Phone', Phone[i]);

                                    if (!Script.IsStop () &&
                                        DataRead.WaitBeforeCall ()) {           // Ожидание перед звонком
Определяется переменная Sound класса CSound, отвечающая за воспроизведение абоненту звукового сообщения.
Выполняются необходимые действия перед набором номера (например, предварительный синтез сообщений). Устанавливается статус текущего звонка в переменной PhoneStatus.
                                       var Sound = new CSound ();

                                       Sound.BeforeDial (Record);

                                       var PhoneStatus = '';                  // Начало звонка, текущий статус пуст
Набор текущего номера абонента. Определяется переменная Result, содержащая результат набора номера.
                                       var Result = Device.Dial (Phone[i]);   // Набираем номер
Определяется переменная Options класса COptions, отвечающая за параметры дозвона:
  • время дозвона, после которого программа переходит к следующему номеру;
  • время прослушивания сообщения абонентом;
  • дублирование процесса соединения с абонентом на звуковую карту компьютера.
                                       var Options = new COptions ();
Действия при успешном дозвоне:
  • определение переменной StartTime, содержащей время начала разговора;
  • определение переменной Recording класса CRecording, отвечающая за запись ответа абонента в звуковой файл;
  • включение записи ответа перед произнесением сообщения, если указано в конфигурации;
  • произнесение сообщения;
  • включение записи ответа после произнесения сообщения, отключение записи и сохранение записанных данных в файл, если указано в конфигурации;
  • проставляется статс по времени прослушивания сообщения абонентом, если указано в конфигурации.

Завершение действий при успешном дозвоне.

                                       if (Result == 0) {                     // Если абонент снял трубкy

                                          var StartTime = new Date ();        // Время начала разговора

                                          var Recording = new CRecording ();

                                          Recording.Start (Device);           // Включение записи перед сообщением

                                          Sound.Say (Device, Record);         // Воспроизвести сообщение

                                          Recording.Stop (Device, Record);    // Завершаем запись сообщения

                                          PhoneStatus = Options.CheckCallTime (StartTime);      // Текущий статус по времени прослушивания
                                       }
При неудачном дозвоне причина заносится в переменную статуса текущего звонка PhoneStatus.
                                       else {
                                          PhoneStatus = Device.GetDialErrorText (Result);   // Текущий статус при неудачном дозвоне
                                       }
Трубка положена.
Подготавливается статус для базы данных. Если статус не успешный, заносим в переменную статуса значение статуса текущего звонка PhoneStatus.
                                       Device.HangUp ();

                                       if (Status != 'OK') Status = PhoneStatus;                // Статус записи
Проверяется статус текущего звонка и необходимость звонить по оставшимся номерам в ячейке.
                                       if (DataRead.IsRemaining (PhoneStatus)) {

                                          break;           // Если удачный дозвон
                                                           // и не включен параметр звонить
                                                           // по оставшимся номерам в ячейке
                                       }
Выполняется проверка на остановку сценария пользователем. Записывается при необходимости соответствующий статус.
                                       if (Script.IsStop ()) break;

                                    } else Status = 'Прервано пользователем.';
Завершение цикла внутри массива Phone.
                                 }
                              }
Действия сценария при возникновении ошибки. Записывается при необходимости соответствующий статус.
                              catch (Err) {
                                 Device.HangUp ();
                                 Status = Err.description;
                                 Script.StopError (Err.description);
                              }
Сохранение статуса в базу данных. Обновление окна статистики.
                              DataWrite.SetStatus (Record, DataRead.GetPhone (Record, true), Status);       // Запись результата звонка

                              Info.Update (Status);                              // Обновление статистики

                              if (Script.IsStop ()) break;
                           }
Сообщение в журнал, если пустой номер телефона в базе данных. Проверка на необходимость остановки в случае возникновения некритической ошибки.
                        } else Script.StopError ('Номер телефона пуст.');

                        if (Script.IsStop ()) break;
Переход к следующей записи базы данных.
                        Record.Next ();
                     }
                  }                                                              // Отсутствуют необходимые поля базы данных
Закрывается соединение с выбранными записями при достижении последней записи или в результате ошибки необходимых полей базы данных.
                  Record.Close ();
               } else Script.InLogError ('Ошибка получения данных для обзвона.');
            } else Script.InLogInfo ('Отсутствуют кандидаты на обзвон.');
Ожидание между звонками, если нет сигнала остановки сценария.
            if (!Script.IsStop ()) DataRead.CycleWait ();
Закрывается соединение с базой данных.
            Database.Close ();
         }
Увеличивается счётчик циклов текущего сеанса переменная CycleCount.
         CycleCount++;

         if (Script.IsStop ()) break;
      }
Закрывается устройство, используемое для обзвона.
      Device.Close ();
   }
Записывается в журнал описание критической ошибки, возникшей при работе сценария. Закрывается соединение с базой данных. Закрывается устройство.
}
catch (Err) {

   Script.InLogError ('Ошибка при работe сценария. %s. Код ошибки: %s', Err.description, Err.number);
   if (Database) Database.Close ();
   if (Device  ) Device.Close ();
}
Записывается в журнал сообщение о завершении работы сценария.
Script.InLogInfo ('Стоп');