Книга: Windows Script Host для Windows 2000/XP

Многозадачный сценарий для работы с записной книжкой

В качестве примера рассмотрим сценарий для работы с записной книжкой в XML-формате (структура файла book.xml, в котором хранится записная книжка, описана в предыдущей главе), в котором будут реализованы следующие функции:

? просмотр всех записей в алфавитном порядке;

? поиск записей по фамилии;

? добавление и удаление записей.

Каждая из этих задач реализуется в виде отдельного задания в файле PhoneBook.wsf (листинг 7.1).

Листинг 7.1. Схема многозадачного файла PhoneBook.wsf

<package>
 <!-- ****************** Просмотр всех записей ******************* -->
 <job>
  …
 </job>
 <!-- *************** поиск записей по фамилии ************** -->
 <job>
  …
 </job>
 <!-- *************** удаление записи по фамилии *************** -->
 <job>
  …
 </job>
 <!-- *************** добавление записи *************** -->
 <job>
  …
 </job>
</package>

Некоторые функции (например, настройка пути к XML-файлу) должны присутствовать во всех заданиях, поэтому такие общие функции мы вынесем в отдельный файл Usage.js, который будет подключаться в каждом из заданий следующим образом:

<script language="JScript" src="Usage.js"/>

В файл Usage.js помещены следующие функции:

? конструктор объекта Person (одна запись из книжки);

? функция GetTagVal(obj, tgName), которая возвращает значения тега tgName XML-элемента obj;

? функция PersonToArray(XNode), которая заполняет поля экземпляра PersonRec объекта Person данными из соответствующих XML-элементов и добавляет сформированную запись в массив PersonArr;

? функции TopReport(Mess) и BottomReport(Mess), с помощью которых в выходной файл печатается заголовок отчета и итоговая информация соответственно;

? функция PrintPerson(PersRec), в которой происходит вывод данных из полей объекта PersonRec в выходной файл;

? функция MakeOut(), которая обеспечивает запуск Блокнота и открывает в нем выходной файл;

? функция InitPath(), в которой строятся пути к XML-файлу, содержащему данные, и выходному файлу.

Usage.js объявляются глобальные переменные и константы. Полностью содержимое файла Usage.js приведено в листинге 7.2.

Листинг 7.2. Общие функции для работы с записной книжкой

/*******************************************************************/
/* Имя: Usage.js                                                   */
/* Язык: JScript                                                   */
/* Описание: Общие функции для записной книжки                     */
/*******************************************************************/
//Объявляем переменные
var
 WshShell,FSO,
 BasePath,     //Путь к текущему каталогу
 PathBook,     //Путь к файлу с данными
 PathOut,      //Путь к выходному файлу
 FBook,        //Файл с данными
 FOut,         //Выходной файл
 NomRec=0,     //Счетчик количества записей
 PersonRec,    //Объект для хранения данных об одном человеке
 PersonArr;    //Массив для хранения объектов PersonRec
 ForWriting=2; //Константа для создания выходного файла
//Инициализируем константы для диалоговых окон
var vbYesNo=4,vbQuestion=32,vbInformation=64,vbYes=6,vbOkOnly=0;
//Конструктор объекта Person
function Person(LastName,Name,Phone,Street,House,App,Note) {
 this.LastName=LastName; //Фамилия
 this.Name=Name;         //Имя
 this.Phone=Phone;       //Телефон
 this.Street=Street;     //Улица
 this.House=House;       //Дом
 this.App=App;           //Квартира
 this.Note=Note;         //Примечание
}
//Определение значения тега tgName XML-элемента obj
function GetTagVal(obj, tgName) {
 var ElemList;
 //Создаем коллекцию дочерних для obj элементов, которые
 //задаются тегом tgName
 ElemList=obj.getElementsByTagName(tgName);
 //Проверяем, есть ли в коллекции ElemList элементы
 if (ElemList.length>0)
  //Возвращаем значение тега tgName
  return ElemList.item(0).text
 else return "";
}
//Заполнение нового элемента массива
function PersonToArray(XNode) {
 //Создаем новый экземпляр PersonRec объекта Person
 PersonRec=new Person();
 //Заполняем поля объекта PersonRec
 PersonRec.LastName=GetTagVal(XNode,"LastName");
 PersonRec.Name=GetTagVal(XNode,"Name");
 PersonRec.Phone=GetTagVal(XNode,"Phone");
 PersonRec.Street=GetTagVal(XNode,"Street");
 PersonRec.House=GetTagVal(XNode,"House");
 PersonRec.App=GetTagVal(XNode,"App");
 PersonRec.Note=GetTagVal(XNode,"Note");
 //Сохраняем объект PersonRec в массиве
 PersonArr[PersonArr.length]=PersonRec;
}
//Запись в выходной файл заголовка отчета
function TopReport(Mess) {
 FOut.WriteLine(Mess);
 FOut.WriteLine("--------------------");
 FOut.WriteLine("");
}
//Запись в выходной файл итоговой информации
function BottomReport(Mess) {
 FOut.WriteLine(Mess);
}
//Запись данных из объекта Person в выходной файл
function PrintPerson(PersRec) {
 FOut.WriteLine("Фамилия: "+PersRec.LastName);
 FOut.WriteLine("Имя: "+PersRec.Name);
 FOut.WriteLine("Телефон: "+PersRec.Phone);
 FOut.WriteLine("Улица: "+PersRec.Street);
 FOut.WriteLine("Дом: "+PersRec.House);
 FOut.WriteLine("Кв.: "+PersRec.App);
 FOut.WriteLine("Заметки: "+PersRec.Note);
 FOut.WriteLine("*********************************");
 NomRec++;
}
//Просмотр содержимого выходного файла в Блокноте
function MakeOut() {
 //Закрываем выходной файл
 FOut.Close();
 //Открываем выходной файл в Блокноте
 WshShell.Run("notepad "+PathOut,1);
}
//Построение путей к файлам
function InitPath() {
 BasePath=WshShell.CurrentDirectory+"";
 //Путь к файлу с данными
 PathBook=BasePath+"book.xml",
 //Путь к выходному файлу
 PathOut=BasePath+"out.txt";
}
/*************  Конец *********************************************/

Также в отдельный файл WSHInputBox.vbs мы поместим функцию WSHinputBox(Message, Title) на языке VBScript, с помощью которой из JScript-сценариев будет выводиться диалоговое окно со строкой ввода (напомним, что ни язык JScript, ни объектная модель WSH такой функции не предоставляют):

Function WSHInputBox(Message,Title)
 'Выводим диалоговое окно со строкой ввода
 WSHInputBox = InputBox(Message,Title)
End Function

Сами задания из файла PhoneBook.wsf составлены (с некоторыми изменениями, на которых мы подробно останавливаться не будем) из одиночных сценариев, которые были рассмотрены в предыдущей главе: см. листинг 6.3 (просмотр всех записей в алфавитном порядке), листинг 6.4 (добавление записей) и листинг 6.5 (поиск записей по фамилии и удаление записей).

В листинге 7.3 приводится полный текст сценария PhoneBook.wsf.

Листинг 7.3. Многозадачный сценарий PhoneBook.wsf для работы с записной книжкой

<package>
<!-- ******************  Просмотр всех записей ******************* -->
<job>
<script language="JScript" src="usage.js"/>
<script language="JScript">
//Создание массива объектов Person
function FileToArray() {
 var XML,Root,NomRec,CurrNode,ex,i;
 //Создаем массив PersonArr
 PersonArr=new Array();
 //Создаем объект XML DOM
 XML = WScript.CreateObject("Msxml.DOMDocument");
 //Загружаем XML-документ из файла
 XML.load(PathBook);
 //Сохраняем в переменной Root ссылку на корневой элемент
 //документа
 Root=XML.documentElement;
 //Перебираем все дочерние элементы первого уровня вложенности
 //для корневого элемента
 for (i=1; i<=Root.childNodes.length-1;i++) {
  //Выделяем в коллекции XML-элементов i-й элемент
  CurrNode=Root.childNodes.item(i);
  //Добавляем новый элемент в массив объектов Person
  PersonToArray(CurrNode);
 }
}
//Сортировка массива и вывод его содержимого в выходной файл
function ListPersonArray() {
 var i;
 //Сортировка массива по фамилии
 PersonArr.sort(SortLastName);
 //Цикл по всем элементам массива PersonArr
 for (i=0;i<=PersonArr.length-1;i++) {
  //Запись информации в выходной файл
  PrintPerson(PersonArr[i]);
 }
}
//Функция для сортировки массива по фамилии
function SortLastName(Pers1,Pers2) {
 if (Pers1.LastName<Pers2.LastName) return -1;
 else if (Pers1.LastName==Pers2.LastName) return 0;
 else return 1;
}
//Основная запускная функция
function Main() {
 //Создаем объект WshShell
 WshShell = WScript.CreateObject("WScript.Shell");
 //Определяем пути к файлам
 InitPath();
 //Создаем объект FileSystemObject
 FSO=WScript.CreateObject("Scripting.FileSystemObject");
 //Открываем выходной файл для записи
 FOut=FSO.OpenTextFile(PathOut,ForWriting,true);
 //Печатаем заголовок отчета
 TopReport("Список всех записей, сортировка по фамилии");
 //Считываем данные из файла в массив
 FileToArray();
 //Записываем информацию из массива в выходной файл
 ListPersonArray();
 //Печатаем итоговую информацию
 BottomReport("Всего записей: "+PersonArr.length);
 //Открываем выходной файл в Блокноте
 MakeOut();
}
//Запускаем основную функцию
Main();
</script>
</job>
<!-- ***************  Поиск записей по фамилии ************** -->
<job>
<script language="VBScript" src="WSHInputBox.vbs"/>
<script language="JScript" src="usage.js"/>
<script language="JScript">
//Поиск в XML-файле нужных записей и сохранение их в
//массиве PersonArr
function RecordsToArray(LastName) {
 var XMLDoc,Root,sSelect,i,Parent,NodeList;
 //Создаем массив PersonArr
 PersonArr=new Array();
 //Создаем объект DOMDocument
 XMLDoc = WScript.CreateObject("Msxml.DOMDocument");
 //Загружаем XML-файл
 XMLDoc.load(PathBook);
 //Сохраняем в переменной Root ссылку на корневой элемент
 //документа
 Root=XMLDoc.documentElement;
 //Формируем строку для поиска фамилии
 sSelect="Person/LastName[text()='"+LastName+"']";
 //Создаем коллекцию NodeList всех элементов LastName,
 //значение которых совпадает со значением переменной LastName
 NodeList=XMLDoc.documentElement.selectNodes(sSelect);
 if (NodeList.length==0) {//Коллекция NodeList пуста
  //Выводим диалоговое окно с сообщением
  WshShell.Popup("Фамилия "+ LastName+ " не найдена!", 0,
   "Записная книжка",vbInformation+vbOkOnly);
  //Завершаем выполнение задания
  WScript.Quit();
 } else  {  //Требуемая фамилия найдена
  //Цикл по всем найденным элементам LastName
  for (i=0;i<=NodeList.length-1;i++) {
   //Определяем родительский элемент (Person) для найденного
   //элемента LastName
   Parent=NodeList.item(i).parentNode;
   //Добавляем новый элемент в массив объектов Person
   PersonToArray(Parent);
  }
 }
}
//Вывод в выходной файл информации о найденных записях
function PrintAllFind() {
 var i;
 for (i=0;i<PersonArr.length;i++) {
  PrintPerson(PersonArr[i]);
 }
}
//Основная запускная функция
function Main() {
var LastName; 
 //Создаем объект WshShell
 WshShell = WScript.CreateObject("WScript.Shell");
 //Определяем пути к файлам
 InitPath();
 //Создаем объект FileSystemObject
 FSO=WScript.CreateObject("Scripting.FileSystemObject");
 //Открываем выходной файл для записи
 FOut=FSO.OpenTextFile(PathOut,ForWriting,true);
 //Печатаем заголовок отчета
 TopReport("Поиск записей");
 //Вводим фамилию для поиска
 LastName=WSHInputBox("Введите фамилию для поиска:","Записная книжка")
 //Ищем в XML-файле нужные записи и сохраняем их в массиве PersonArr
 RecordsToArray(LastName);
 //Выводим все найденные записи из массива PersonArr в выходной файл
 PrintAllFind(LastName);
 //Печатаем итоговую информацию
 BottomReport("Всего найдено: "+PersonArr.length);
 //Открываем выходной файл в Блокноте
 MakeOut();
}
//Запускаем основную функцию
Main();
</script>
</job>
<!-- ***************  Удаление записи по фамилии *************** -->
<job>
<script language="VBScript" src="WSHInputBox.vbs"/>
<script language="JScript" src="usage.js"/>
<script language="JScript">
//Поиск фамилии в записной книжке и удаление всех
//реквизитов, относящихся к этой фамилии
function FindAndDelRecord(LastName) {
 var Root,sSelect,i,Parent,NodeList;
 //Создаем объект DOMDocument
 XMLDoc = WScript.CreateObject("Msxml.DOMDocument");
 //Загружаем XML-файл
 XMLDoc.load(PathBook);
 //Сохраняем в переменной Root ссылку на корневой элемент
 //документа
 Root=XMLDoc.documentElement;
 //Формируем строку для поиска фамилии
 sSelect="Person/LastName[text()='"+LastName+"']";
 //Создаем коллекцию NodeList всех элементов LastName,
 //значение которых совпадает со значением переменной LastName
 NodeList=XMLDoc.documentElement.selectNodes(sSelect);
 if (NodeList.length==0) //Коллекция NodeList пуста
  //Выводим диалоговое окно с сообщением
  WshShell.Popup("Фамилия "+LastName+ " не найдена!", 0,
   "Записная книжка",vbInformation+vbOkOnly);
 else { //Требуемая фамилия найдена
  //Цикл по всем найденным элементам LastName
  for (i=0;i<=NodeList.length-1;i++) {
   //Определяем родительский элемент (Person) для найденного
   //элемента LastName
   Parent=NodeList.item(i).parentNode;
   //Удаляем элемент Person вместе со всеми его дочерними элементами
   Root.removeChild(Parent);
   //Выводим диалоговое окно с сообщением
   WshShell.Popup("Запись удалена!",0,
    "Записная книжка",vbInformation+vbOkOnly);
  }
  //Сохраняем содержимое XML-файла на диске
  XMLDoc.save(PathBook);
 }
}
//Основная запускная функция
function Main() {
 var LastName,Res; 
 //Создаем объект WshShell
 WshShell = WScript.CreateObject("WScript.Shell");
 //Определяем пути к файлам
 InitPath();
 LastName=WSHInputBox("Введите фамилию для удаления:","Записная книжка")
 //Запрос на удаление записи
 Res=WshShell.Popup("Удалить фамилию "+LastName+ " из n"+PathBook+"?",0,
  "Записная книжка",vbQuestion+vbYesNo);
 if (Res==vbYes) { //Нажата кнопка Да
  //Ищем в книжке нужную фамилию и удаляем относящуюся к
  //ней запись
  FindAndDelRecord(LastName);
 }
}
//Запускаем основную функцию
Main();
</script>
</job>
<!-- ***************  Добавление записи *************** -->
<job>
<script language="VBScript" src="WSHInputBox.vbs"/>
<script language="JScript" src="Usage.js"/>
<script language="JScript">
//Ввод значений полей объекта PersonRec
function MakePersonRec() {
 //Создаем новый экземпляр PersonRec объекта Person
 PersonRec=new Person();
 //Вводим значения полей добавляемой записи с помощью диалогового
 //окна со строкой ввода
 PersonRec.LastName=WSHInputBox("Введите фамилию","Добавление записи");
 PersonRec.Name=WSHInputBox("Введите имя","Добавление записи");
 PersonRec.Phone=WSHInputBox("Введите телефон","Добавление записи");
 PersonRec.Street=WSHInputBox("Введите улицу","Добавление записи");
 PersonRec.House=WSHInputBox("Введите дом","Добавление записи");
 PersonRec.App=WSHInputBox("Введите квартиру","Добавление записи");
 PersonRec.Note=WSHInputBox("Введите примечание","Добавление записи");
}
//Сохранение данных из объекта PersonRec в XML-файле
function RecordToFile(PersRec) {
 var Root,NewElem,s;
 //Создаем объект DOMDocument
 XMLDoc = WScript.CreateObject("Msxml.DOMDocument");
 //Загружаем XML-файл
 XMLDoc.load(PathBook);
 //Сохраняем в переменной Root ссылку на корневой элемент
 //документа
 Root=XMLDoc.documentElement;
 //Создаем XML-элемент Person
 NewElem=XMLDoc.createElement("Person");
 //Добавляем новый элемент в XML-файл
 Root.appendChild(NewElem);
 //Сохраняем в переменной Root ссылку на последний добавленный
 //элемент Person
 Root=Root.lastChild;
 //Создаем элемент LastName
 NewElem=XMLDoc.createElement("LastName");
 //Добавляем новый элемент в XML-файл (внутри элемента Person)
 Root.appendChild(NewElem);
 //Подставляем в качестве содержимого элемента LastName
 //значение поля LastName объекта PersRec
 Root.lastChild.text=PersRec.LastName;
 //Создаем элемент Name
 NewElem=XMLDoc.createElement("Name");
 //Добавляем новый элемент в XML-файл (внутри элемента Person)
 Root.appendChild(NewElem);
 //Подставляем в качестве содержимого элемента Name
 //значение поля Name объекта PersRec
 Root.lastChild.text=PersRec.Name;
 //Создаем элемент Phone
 NewElem=XMLDoc.createElement("Phone");
 //Добавляем новый элемент в XML-файл (внутри элемента Person)
 Root.appendChild(NewElem);
 //Подставляем в качестве содержимого элемента Phone
 //значение поля Phone объекта PersRec
 Root.lastChild.text=PersRec.Phone;
 //Создаем элемент Street
 NewElem=XMLDoc.createElement("Street");
 //Добавляем новый элемент в XML-файл (внутри элемента Person)
 Root.appendChild(NewElem);
 //Подставляем в качестве содержимого элемента Street
 //значение поля Street объекта PersRec
 Root.lastChild.text=PersRec.Street;
 //Создаем элемент House
 NewElem=XMLDoc.createElement("House");
 //Добавляем новый элемент в XML-файл (внутри элемента Person)
 Root.appendChild(NewElem);
 //Подставляем в качестве содержимого элемента House
 //значение поля House объекта PersRec
 Root.lastChild.text=PersRec.House;
 //Создаем элемент App
 NewElem=XMLDoc.createElement("App");
 //Добавляем новый элемент в XML-файл (внутри элемента Person)
 Root.appendChild(NewElem);
 //Подставляем в качестве содержимого элемента App
 //значение поля House объекта PersRec
 Root.lastChild.text=PersRec.App;
 //Создаем элемент Note
 NewElem=XMLDoc.createElement("Note");
 //Добавляем новый элемент в XML-файл (внутри элемента Person)
 Root.appendChild(NewElem);
 //Подставляем в качестве содержимого элемента App
 //значение поля House объекта PersRec
 Root.lastChild.text=PersRec.Note;
 //Сохраняем содержимое XML-файла на диске
 XMLDoc.save(PathBook);
}
//Добавление новой записи в книжку
function AddRecord() {
 //Заполняем поля объекта PersonRec
 MakePersonRec();
 //Сохраняем данные из объекта PersonRec в XML-файл
 RecordToFile(PersonRec);
}
//Построение путей к файлам
function InitPath() {
 BasePath=WshShell.CurrentDirectory+"";
 //Путь к файлу с данными
 PathBook=BasePath+"book.xml";
}
//Основная запускная функция
function Main() {
 var Res;
 //Создаем объект WshShell
 WshShell = WScript.CreateObject("WScript.Shell");
 //Определяем пути к файлам
 InitPath();
 //Запрос на создание нового ключа
 Res=WshShell.Popup("Добавить запись в n"+PathBook+"?",0,
  "Записная книжка",vbQuestion+vbYesNo);
 if (Res==vbYes) { //Нажата кнопка Да
  //Добавляем новую запись в книжку
  AddRecord();
  //Выводим информацию на экран
  WshShell.Popup("Новая записьnn"+PersonRec.LastName+" "+
   PersonRec.Name+"n"+PersonRec.Phone+"n"+
   PersonRec.Street+", "+PersonRec.House+"-"+PersonRec.App+"nn"+
   "добавлена!",0, "Записная книжка",vbInformation+vbOkOnly);
 }
}
//Запускаем основную функцию
Main();
</script>
</job>
</package>

Итак, у нас теперь имеется многозадачный WS-файл PhoneBook.wsf, обеспечивающий необходимую функциональность для работы с записной книжкой, и следующая задача состоит в организации более или менее удобного диалога с пользователем для запуска заданий из этого файла.

Оглавление книги


Генерация: 2.422. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз