Войти
 
 
   
 
  
Новости Notes.ру Библиотека Биржа труда Вопрос - ответ Форум Регистрация Поиск О проекте
Разделы
О Notes
Советы
Шаблоны и примеры
Литература
Презентации
 
Всё о задаче AdminP. Часть вторая   Во второй части мы завершаем рассмотрение AdminP. В ней рассмотрены запросы междоменного администрирования и способы управления функциями AdminP с помощью настроек документа сервера, команд консоли сервера, файла Notes.ini и интервалов очистки базы данных. В этой статье предполагается, что вы опытный администратор Domino и прочитали первую часть
О Notes Читать статью
 
Всё о задаче AdminP. Proxy-действия в R5 и Domino 6   Приложение к статье об административном процессе
О Notes Читать статью
 
Всё о задаче AdminP. Часть первая   Перевод классической статьи 2003-его года о задаче административного процесса (AdminP). Очень полезна для понимания работы механизма этой задачи. В первой части статьи описаны компоненты задачи AdminP, как они работают, и как их использование помогает сделать работу администратора Domino проще. Задача AdminP (сакращённо от Administration Process, Административный процесс) работает с базой административных запросов (Administration Requests, admin4.nsf)
О Notes Читать статью
 


О Notes

Главная   Библиотека   О Notes

Разработка приложений для Lotus Notes/Domino в среде Borland Delphi

Гусев А.В., Дмитриев А.Г., Тихонов С.И.

    Вычислительный центр ОАО «Кондопога», КНМЦ СЗО РАМН

    Полный вариант материала размещен: http://www.citforum.ru/programming/delphi/lotus_notes/

    Lotus Notes/Domino – прекрасная платформа для создания мощных корпоративных информационных систем, ориентированных на групповую работу с электронными документами. В своей работе над комплексной медицинской информационной системой «Кондопога» мы на основе тщательного анализа средств разработки и имеющихся на рынке СУБД выбрали Lotus Notes/Domino в качестве основы всей системы. Разработка осуществляется с 1999 года, за это время мы постепенно перешли с версии 4.6 на версию R5, а затем – на R6.
    Lotus Notes/Domino полностью отвечает ключевым требования к созданию медицинской информационной системы по надежности, безопасности, отказоустойчивости и масштабированию. Работа пользователя в этой среде в максимальной степени приближена к привычной работе с документами – фактически, бумага и авторучка у медицинских сотрудников заменена на компьютер. Формы электронных документов могут быть разработаны по аналогии с бумажными формами (при необходимости), а стандартные средства для работы с документами (создание, редактирование, печать, отправка по e-mail, электронная цифровая подпись и т.д.) требуют от пользователя минимального объема обучения.
    Однако, как и в любой информационной технологии, имеется ряд недостатков, с которыми приходится мириться или искать пути их преодоления. Основной их недостатков Lotus Notes/Domino для применения в медицинской сфере – это слабая поддержка таблиц в электронных документах.
    Вместе с тем, в нашей работе поддержка табличного формата хранения информации является неотъемлемой функцией системы. Некоторые документы (лист назначений, например) и некоторые приложения (бухгалтерия, аптека, склад, автоматизация службы питания и т.д.) несравненно более эффективно работают под управлением реляционной СУБД, чем в среде Lotus Notes/Domino. Все это породило необходимость совместного использования Lotus Notes/Domino и реляционной СУБД, в качестве которой был выбран Microsoft SQL Server. В качестве средства разработки в Lotus Notes/Domino используется специальное программное обеспечение Domino Designer, позволяющее создавать мультиплатформенные приложения на VisualBasic-подобном языке LotusScript, @-формулах Java и JavaScript. Это мощное приложение позволяет за очень небольшое время разрабатывать приложения как для выполнения в среде Lotus Notes, так и для работы в обычном браузере Internet. Однако для создания приложения для реляционной СУБД его возможностей явно недостаточно. Поэтому в качестве дополнительного инструментария мы используем Borland Delphi (в настоящее время – версию 6.0).
    Одной из задач, которую необходимо решить при использовании Delphi, является задача доступа к базам данных Lotus Notes/Domino. Для решения этой задачи имеется несколько подходов:
    1. Использование компонентов сторонних производителей (http://www.torry.net/index.htm, http://www.geocities.com/SiliconValley/Peaks/8307/ )
    2. Использование приложения Lotus NotesSQL (http://www-10.lotus.com/ldd)
    3. Разработка собственных компонентов, используя Notes API
    4. Доступ к ресурсам Lotus Notes посредством объектной модели классов OLE/COM.

    Первый подход подразумевает использование компонентов для доступа к Lotus Notes. При этом программы могут обращаться к базам данных и документам, используя инкапсулированные в эти компоненты свойства и методы. Мы апробировали имевшиеся в свое время предложения и не нашли решения, полностью удовлетворяющего наши требования. Использование компонентов вносило нестабильность в создаваемые приложения, которые нам не удавалось быстро локализовать и исправить, т.к. либо с разработчиками не возможно было наладить контакт, либо техническая поддержка требовала дополнительных финансовых затрат и времени.
    Второй подход также, к сожалению, не отвечал требованиям. При этом NotesSQL фактически эмулирует обращение к базе данных Lotus Notes, как к обычной реляционной таблице. Тестирование различных версий NotesSQL показала нестабильность этого программного обеспечения. Особенно ярко недостатки NotesSQL проявлялись при обработке больших объемов информации – в случайные моменты работы программы возникали неустранимые ошибки, которые приводили к полному прекращению работы программ.
    Третий подход является более предпочтительным, однако и от него мы со временем отошли в силу его трудоемкости, большой сложности написания программы, массы низкоуровневого кода и высоких требований к знанию внутренней архитектуры Lotus Notes.
    Первое время доступ к Lotus Notes посредством OLE казался нам неприемлемым вариантом с точки зрения скорости работы. Однако наш 5-летний опыт работы доказал высокую устойчивость программ на основе этого подхода и вполне приемлемую скорость обработки информации.
    Далее мы на примерах покажем, как написать приложение в среде Borland Delphi для баз данных Lotus Notes.

    1. Инициализация сессии
    Основной принцип в написании программ состоит в использовании встроенных классов Lotus Notes в коде программ. Для этого в первую очередь необходимо инициализировать сессию связи с Lotus Notes. Для этого требуется, чтобы клиентское программное обеспечение Lotus Notes было инсталлировано на каждом компьютере, использующим программу и подключено к одному или нескольким серверам Domino.
    Создадим новое приложение. В разделе uses главного окна приложения укажем ComOBJ – это библиотека, позволяющая вызывать и обращаться к OLE-объектам.
    В разделе public объявим переменные, общие для всего приложения:

    public
        { Public declarations }
        MySession : OLEVariant; // текущая сессия Lotus Notes
        MyLNDataBase : OLEVariant; // база данных Lotus Notes


    Теперь необходимо написать обработчик события OnCreate главной формы приложения, в котором мы должны создать объект NotesSession, чтобы, используя его в дальнейшем, иметь возможность в рамках одного приложения обращаться сразу к нескольким базам данных, серверам, документам, представлениям и т.д. Обработчик должен иметь следующий вид:

    procedure TfmMain.FormCreate(Sender: TObject);
    begin
    MySession:= createOLEObject('Notes.Notessession');
    if varisempty(MySession) then
      begin
        ShowMessage('Не могу создать сессию с сервером Lotus Notes');
        Exit;
      end;
    end;

    Следует иметь в виду, что в рамках одного приложения следует только один раз инициализировать объект NotesSession, т.к. каждая последующая инициализация будет закрывать предыдущую сессию, а все объекты, созданные на основе этой сессии, потеряют свою актуальность и их обработка будет невозможна.

    2. Доступ к базе данных
    После того, как выполнена инициализация сессии связи с Lotus Notes, возможно обращение к любым серверам Lotus Domino и базам данных на них. Принципиально получить доступ к БД Lotus Notes можно 2 способами – либо обратиться к текущей базе данных, открытой в Lotus Notes, либо вызвать соответствующий метод NotesSession и открыть любую другую БД. Последний случай является наиболее востребованным, поэтому рассмотрим его:


    procedure TMyButtomClick(Sender: TObject);
    var MyServer: string;
    begin
      // Необходимо вычислить имя сервера, на котором находится необходимая нам БД
      MyServer:=…..
      // Теперь открываем БД – например, откроем адресную книгу сервера
      MyLNDataBase:=MySession.GetDataBase(MyServer, ‘names.nsf’);

    end;

    Мы в своей работе используем реестр Windows, в котором храним имя сервера Domino по умолчанию, к которому подключаются приложения. Для упрощения разработки и администрирования программ мы использую функцию GetDefaultServerName, которая работает по следующему алгоритму:
    1. При вызове функции она проверяет наличие определенного ключа в реестре Windows.
    2. Если этот ключ отсутствует или он содержит пустое значение, функция обращается к файлу notes.ini и считывает из него значение параметра почтового сервера Notes. Имя сервера записывается как значение ключа Windows
    3. Если ключ в реестре Windows имеется и не содержит пустое значение, функция считывает его и возвращает в качестве ответа.
    Таким образом, при первом старте приложения оно самостоятельно выполняет настройку реестра Windows на подключение к текущему серверу Domino. Если в дальнейшем требуется перенаправить работу приложения на другой сервер, то либо пользователь при помощи встроенных в приложение визуальных средств, либо администратор сети вручную меняют значение ключа. Т.о. со следующего запуска начинает обращаться к другому серверу – обеспечивает поддержка мультисерверной конфигурации информационной системы.

    3. Работа с базой данных
    Из программы, написанной в Borland Delphi, доступны практически все свойства и методы, предусмотренные разработчиками Lotus Notes/Domino. В том числе Вы можете осуществлять навигацию по представлениям, осуществлять поиск документов в базе данных, в том числе и гипертекстовый поиск и т.д. Особенностей по работе с базой данных вследствие использования Delphi мы не обнаружили. Поэтому в качестве примера приведем фрагмент кода, осуществляющий последовательный перебор и считывание документов из коллекции документов NotesDocumentCollection базы данных адресной книги сервера.

    procedure TfmMainWindow.BitBtn1Click(Sender: TObject);
    var DocumCount: longint; // количество документов в коллекции
          i : longint; // шаг цикла
          B1: OLEVariant; // переменная для объекта NotesDatabase
          BodyQuery: ansistring;
          C1: OLEVariant; // переменная для объекта NotesDocumentCollection
          D1: OLEVariant; // переменная для объекта NotesDocument
    begin
    DocumCount:=0;
    // Получаем доступ к БД.
    B1:= MySession.GetDatabase(GetDefaultServerName,'names.nsf');
    BodyQuery:='Form = "Person"';
    // Для поиска используем специальную функцию LNSearch
    C1:=LNSearch(MySession,B1,’Пример запроса’,BodyQuery);
    DocumCount:=C1.Count;
    if DocumCount=0 then Exit; // искомые документы не найдены
    D1:=C1.GetFirstDocument;
    for i:=1 to DocumCount do
      begin
          …… - здесь осуществляется обработка документа
          D1:=C1.GetNextDocument(D1);
       end;

    end;

    В этом примере программа обращается к текущему серверу и открывает на нем базу данных адресной книги. Затем, используя вызов прикладной функции LNSearch, производит поиск документов в базе данных. Если не найдено ни одного документа, то работа процедуры завершается. Если какие-то документы найдены, то они последовательно обрабатываются в цикле. Применение функции LNSearch обусловлено тем, что стандартный метод Search в классе NotesDatabase, кроме формулы для поискового запроса, требует передать дату самого старого документа, который этот запрос сможет вернуть в качестве результата. При этом дата должна быть передана не в качестве переменной типа TDate или TDateTime, а в качестве OLEVariant-переменной, созданной как объект класса NotesDataTime.

    function LNSearch(LNSession, LNDataBase: OLEVAriant; Logo: string;query: string):OLEVariant;
    var r1:WideString;
    r2: OLEVariant;
    r3: Smallint;
    C1: OleVariant;
    begin
    r1:=query;
    r2:=LNSession.CreateDateTime( '01.01.1990' ); // здесь может быть любая дата
    r3:=0;
    C1:=LNDataBase.SEARCH(r1,r2,r3);
    Result:=C1;
    end;

    Отметим, что по нашим наблюдениям, при написании программ в Borland Delphi следует стремиться использовать навигацию по представлениям вместо использования метода search. При этом скорость обработки одной и той же коллекции документов, полученной из представления, примерно на 40% выше, чем при обработке документов, полученных поиском в базе данных.

    4. Работа с документами
    В отличие от работы с базами данных, обработка документов Lotus Notes имеет массу подводных камней. При этом в программах приходится выполнять много одинаковых операций, которые целесообразно выделять в отдельные функции. Вначале рассмотрим пример функции считывания текстового значения поля из документа.

    function LNGetFieldStrValue(Document: OLEVariant; FieldName: string; DefaultValue: string): AnsiString;
    var SendValue, RetValue: OLEVariant;
    TmpS: Ansistring;
    MyPos: integer;
    begin
    TmpS:=' ';
    if FieldName<>'' then
    begin
    SendValue:=FieldName;
    if not varisempty(Document) then
    begin
      Try
    RetValue:=Document.HasItem(FieldName);
    except
    begin
    RetValue:=false;
    end; // do
    end;  // Try
    if RetValue then
      begin
    RetValue :=Document.GetFirstItem(SendValue);
    try
            TmpS:=RetValue.Text;
            except
      TmpS:=DefaultValue;
    end;
    end else TmpS:=DefaultValue;
    end else TmpS:=DefaultValue; // varisempty chek
    end else TmpS:=DefaultValue;

    if TmpS='' then TmpS:=DefaultValue;
    Result :=tmpS;
    end;

    Эта простая функция позволяет значительно упростить написание программ, особенно в случае, когда документ содержит большое количество полей, значения которых необходимо считать и обработать. Необходимо отметить, что очень часто в полях документов Lotus Notes хранится несколько значений или значения записаны с символами, препятствующими корректной работе со строками в Borland Delphi. Мы в таком случае используем перегруженную версию представленной функции, которая может возвращать «очищенную» строку или определенную подстроку.
    По аналогии с представленным примером используются и функции обработки числовых полей, а также полей с датой или временем, что представляет особую трудность при написании программ. В таком случае, кроме стандартных проверок на корректность документа, наличия в нем указанного поля, функция может проверить тип возвращаемого значения или выполнить необходимые преобразования. Например, возможна конвертация строкового значения в число или смена символа разделителя разрядов на основании текущих настроек операционной системы.
    Несколько усложненный пример – это считывание значения поля в профайле. Как известно, Lotus Notes, кроме стандартных документов, позволяет поддерживать хранение информации в т.н. профайлах – документах, к которым можно обратиться по имени формы и, как дополнение, по имени текущего пользователя. Для чтения текстового значения из профайла рассмотрим следующую функцию:

    function LNGetProfileField(MySession, MyDBName: OLEVariant; MyServerName,  MyProfileName, MyUserName, MyFieldName: string):string;
    var D1: OLEVariant;
    tmpS: AnsiString;
    begin
    if MyServerName='' then tmpS:= GetDefaultServerName else tmpS:=MyServerName;
    if varisempty(MyDBName) then
    begin
    ShowMessage('Фатальная ошибка! Переданный объект <База данных> пуст. Продолжение невозможно!');
    Exit;
    end;
    D1:=MyDBName.GetProfileDocument( MyProfileName, MyUserName);
    if varisempty(D1) then
    begin
    ShowMessage ('Ошибка при получении профайла '+MyProfileName+' из базе данных '+MyServerName+' / '+MyDBName.Name+' . Продолжение невозможно!');
    Exit;
    end;
    tmpS:=LNGetFieldStrValue(D1,MyFieldName,'',False);
    Result :=tmpS;
    end;

    Как видно из примера, эта функция использует функцию LNGetFieldStrValue, представленную ранее, но перед этим выполняет ряд дополнительных проверок и операций.


    5. Выводы
    Мы используем представленную технологию в практической разработке медицинской информационной системы «Кондопога» вот уже в течение 5 лет. За это время многократно убедились в прекрасной устойчивости и приемлемой скорости работы программ, написанных на Borland Delphi для баз данных Lotus Notes/Domino. Фактически мы убедились, что способны создавать программы на Borland Delphi, которые используют весь арсенал встроенных в Lotus Notes классов.
    Отметим, что со временем в арсенале программиста накапливается самая разнообразная масса готовых функций и процедур, которые целесообразно аккумулировать либо в виде подключаемых библиотек, либо в виде отдельных модулей (pas-файлов). При этом, по нашим наблюдениям, время на разработку новой программы можно сократить в несколько раз именно за счет использования готовых и отлаженных приложений. А это позволяет снизить стоимость разработки и повысить устойчивость приложений, что является уже не столько инструментарием разработчика, сколько экономическим стимулом.
    Постепенно нами была накоплена целая библиотека класса middleware, которая реализует практически весь необходимый функционал для написания программ в Borland Delphi для среды Lotus Notes. Это позволило разработать нашу информационную систему таким образом, что взаимные недостатки реляционных и объектно-ориентированных баз данных фактически полностью компенсируются взаимными достоинствами. Поэтому пользователи ИС «Кондопога» одинаково комфортно используют и возможности совместной работы над электронными документами Lotus Notes и встроенные в базы данных Domino приложения, предоставляющие расширенные возможности работы с таблицами реляционных баз данных, мгновенное построение диаграмм на основе данных из документов Lotus Notes и т.д.


    Литература:
    1. Гусев А.В., Дмитриев А.Г. Microsoft SQL Server против MySQL в медицинских информационных системах. http://citforum.ru/database/articles/msmysql/
    2. Гусев А.В., член-корр. РАМН Дуданов И.П., Романов Ф.А., Дмитриев А.Г. Особенности в проектировании и практической разработке медицинской информационной системы. http://www.citforum.ru/consulting/articles/med/
    3. Ионцев Н.Н., Поляков Е.В., Таранченко О.Г. Программирование в Lotus Domino R5: формулы и функции, язык LotusScript, встроенные классы LotusScript и Java. - М.: Светотон, 2000. – 936 с.
    4. Кэнту М. Delphi 6 для профессионалов. – СПб.: Питер, 2002. – 1088 с.
    5. Интернет проект Notesnet.ru, http://www.notesnet.ru

    Об авторах:
    Гусев Александр Владимирович – к.т.н., ст. инженер-программист вычислительного центра ОАО «Кондопога», e-mail: gusev@kbk.onego.ru
    Дмитриев Александр Геннадьевич – инженер-программист вычислительного центра ОАО «Кондопога», e-mail: admitriev@kbk.onego.ru
    Тихонов Станислав Игоревич – инженер-программист вычислительного центра ОАО «Кондопога», e-mail: tihonov@kbk.onego.ru
     
      Опубликовано — 12/18/2004 |    
Николай Норкин, 17.01.2008:
При наличии отсутствия ядра Notes невозможно использовать функции, работающие с этим ядром Собственно, в этом случае рассматривается возможность работы в web-приложении или использование удалённых вызовов (протоколы DIIOP и CORBA)

Еркебулан Курышбаев, 15.01.2008:
Интересная статейка. Коды набрал на делфи, запустил приложение. Все работает. Но есть вопрос, как заставить такие приложения, там где не установлен клеиент лотуса, то есть как программно на дельфи указать ай пи адрес сервера, как указать айди файл и потом как можно реализовать ввод пароля (ну как при входе на лотус)



Добавить комментарий
Имя * :
e-mail
Комментарий * :
Код подтверждения * :

Мероприятия
Пресс-релизы
Биржа труда
Последнее на форуме
 
А так же:
Как удалить профиль?
16.04.2016 00:08:51
Скопировать в буфер поле документа
24.05.2015 08:55:52
Импорт DXL-описания документов в Lotus Domino. Одноимённые поля
16.04.2015 16:49:58
 
© LOGOSPHERE.RU