LotusScript. Классы lotus.




Рассмотрим классы Lotus на конкретных примерах.

Для того чтобы создать объект lotus, как правило, используется либо пункт меню New, либо функции получения этого объекта из существующего.

В качестве примера создадим кнопку, которая в текущем открытом документе осуществит выбор каких-то данных из списка и заполнение соответствующих полей текущего документа. Чтобы пример был актуален, начнем делать кнопку, которая будет выбирать список голосующих в приложении форма «Голосование».

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

Необходимо также внести в строку таблицы «Учитывать вес» и поле, в котором будет стоять пометка учитывать вес или нет. Так как это поле просто пометка, то разумно использовать редактируемый чек-бокс с единственным значением.

В итоге должно получиться:

Теперь, в столбце между списком участников и полем, надо вложить вид и связать его с кнопкой, которая будет запрограммирована, на выбор участников.

Код будет следующим:

Sub Click(Source As Button)

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument Set uidoc=ws.currentDocument

Dim doc As NotesDocument Set doc= uidoc.document End Sub

Сначала надо породить объект, который представляет рабочую область и даст потом доступ к тому, что лежит в этой области. Этот объект notesUIWorkspace порождается стандартным способом.

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

Используем свойство CurrentDocument, которое возвращает документ, открытый в рабочей области и возвращает его именно как открытый в рабочей области. Возвращенный объект принадлежит к классу NotesUIDocument. Все классы с префиксом NotesUI - это классы, предоставляющие доступ к объекту в рабочей области.

Чтобы пользоваться информацией, указанной в документе и вносить в него информацию, надо получить доступ к документу в базе. Для этого декларируется переменная класса NotesDocument и берется документ из бакэнда текущего документа

Set doc=uidoc.document.

После этого можно забирать данные из документа, обращаясь к имени поля, например,

doc.weight или doc.Members.

Необходимо помнить, что в поле может храниться как одно значение, так и массив. Поэтому значение поля это фактически всегда МАССИВ. Просто в нем может быть один элемент или более. И если положить значение поля в какую-либо переменную, то это должна быть переменная типа вариант, которая будет массивом той длины, что имеет поле. К реальным значениям поля можно будет потом обращаться по индексу. Самый первый индекс по умолчанию 0. Например,

mems=doc.members dim FirstMember as string Firstmember = Mem(0)

Можно сразу к полю обратиться doc.members(0), но при таком обращении необходимо быть абсолютно уверенным, что такое поле в документе присутствует, потому что иначе результат вызова doc.members даст пустой объект и обращение к элементу массива, которым этот объект не является, даст ошибку.

Что бы избежать подобной ситуации можно просто проверять документ на наличие такого поля:

If doc.HasItem("members") then

firstMember=doc.members(0) End if

Продолжим написание кнопки:

Sub Click(Source As Button)

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument Set uidoc=ws.currentDocument

Dim doc As NotesDocument Set doc= uidoc.document

Dim db As NotesDatabase Set db=doc.parentDatabase

Set coll=ws.PickListCollection(PICKLIST_CUSTOM, True,db.server, db.filePath,"v11","Выберите участников вашего голосования", "Список участников","Активный") End Sub

В результате был порожден объект, текущая база данных. Объект был взят как свойство объекта NotesDocument.ParentDatabase, которое возвращает базу, в которой находится документ.

Далее вызывается на notesUIWorkspace метод pickListCollection, который откроет в диалоговом окне представление и позволит выбрать из него один или несколько документов, в зависимости от флага, переданного вторым параметром.

2,3 и 4 параметры - это сервер, путь к базе и имя представления в этой базе, которые открываются в окне. 5 и 6 параметры - подписи к диалоговому окну. 7-ой параметр - это имя категории. Показывать в окне можно не все документы представления, а только документы, попадающие в определенную категорию. В данном случае создано представление участников голосования с псевдонимом «v11», категорированное по статусам. В нем выбираются только активные участники.

В этом представлении в свойствах обязательно надо снять на второй закладке флаг - Collapse when…, иначе при первом открытии категории будут свернуты, и диалоговое окно будет пустым.

При нажатии на кнопку получается следующее:

Участников голосования может быть много, но в окне видны только те, кто имеют активный статус.

Разработанная кнопка только вызывает окно и ничего пока не делает с тем, что это окно возвращает. А возвращает это окно объект, который называется notesDocumentCollection - это коллекция (набор) документов. Она может быть пустой, если нажать на Cancel, или не выбрать ничего, а может содержать документы.

Коллекция документов устроена следующим образом:

То есть, каждый элемент коллекции содержит ссылку на следующий (и предыдущий), а также собственно на документ, который входит в коллекцию и представлен этим элементом.

Из этой структуры сразу следуют некоторые выводы по выбору оптимальных алгоритмов обхода коллекции: Есть два способа. В HELP, в качестве примера приведен следующий способ:

For i=1 to coll.count

Set doc=coll.GetNthDocument(i)

End for

При использовании такого способа для подсчета каждого элемента, взятого по индексу, происходит обход коллекции от 1-го элемента до i-того. Это не экономно, так как для коллекции из n элементов количество обходов будет (1 + 2 + 3 +… + n-1).

Есть другой способ обхода коллекции, когда используются ссылки между элементами друг на друга и коллекция обходится методом set doc=coll.GetNextDocument(doc). То есть берется следующий документ от текущего. Этот метод работает намного быстрее.

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

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument Set uidoc=ws.currentDocument

Dim doc As NotesDocument Set doc= uidoc.document

Dim db As NotesDatabase Set db=doc.parentDatabase

Dim coll As NotesDocumentCollection

Set coll=ws.PickListCollection(PICKLIST_CUSTOM, True,db.server, db.filePath,"v11","Выберите участников вашего голосования", "Список участников","Активный")

If coll.count=0 Then Exit Sub ' проверяется, что в коллекции не 0 число документов и организуется выход из кода, если пользователь не выбрал ни одного документа.

Dim memberdoc As NotesDocument Set memberdoc=coll.GetFirstDocument

While Not memberdoc Is Nothing ' используется цикл, в котором перебираются элементы коллекции пока не будет достигнут конец. В конце коллекции, когда на последнем элементе будет вызван метод GetNextDocument - следующий элемент будет пуст и поэтому объект NotesDocument, на который смотрит несуществующий элемент коллекции - будет nothing. То есть тот случай, когда ссылка на объект, который смотрит в никуда.

Set memberdoc=coll.GetNextDocument(memberdoc) Wend

Теперь надо из всех документов, по которым была проведена обработка, необходимо извлечь информацию об имени участника и о весе участника в голосовании.

Для примера будет два соответствующих друг другу массива Names_ и Weight_

В момент декларации массивов уже известно, сколько документов в коллекции, но сама коллекция считается динамически, и не известно априори - сколько в коллекции будет элементов, поэтому надо объявить эти массивы динамическими:

Dim memberdoc As NotesDocument

Set memberdoc=coll.GetFirstDocument

Dim n As Integer n=coll.count

Redim weights(1 To n) As Double Redim Names_(1 To n) As String

Dim i As Integer

i=1

While Not memberdoc Is Nothing

weights(i)=memberDoc.weight(0)

Names_(i)=memberDoc.NotesName(0)

Set memberdoc=coll.GetNextDocument(memberdoc)

i=i+1 Wend

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

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

Можете создать поле на документе, не зависимо от того, присутствует оно в форме или нет. Как уже говорилось в самом начале этого документа - реальный документ лежит в базе, а форма, это трафарет, через который этот документ рассматривается. При этом с документом в базе можно выполнять различные операции. С документом, открытым в рабочей области, через форму, можно проводить обработку, обращаясь к полям, но диапазон допустимых действий ограничен логикой формы.

Например, нельзя создать новое поле на NotesUIDocument методом FieldSetText.

Посему присвоение выполняется следующим образом:

Doc.members=names_

Doc.weights=weights_

В результате выполнения предыдущих процедур заполнено поле, которое есть на форме и создано новое для весов. Этого поля на форме нет, а в документе оно будет.

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

Call uidoc.Refresh

Вот конец кода:

Dim i As Integer i=1 While Not memberdoc Is Nothing

weights(i)=memberDoc.weight(0)

Names_(i)=memberDoc.NotesName(0)

Set memberdoc=coll.GetNextDocument(memberdoc)

i=i+1 Wend

doc.members=names_ doc.weights=weights

Call uidoc.refresh

После запуска кода должно получиться после сохранения документа:

Теперь надо сделать кнопку, которая почистит эти поля:

Создаем еще одну кнопку, которая скрыта в режиме чтения. Если в поле members="", ее проще сделать при помощи формул:

field members:="";

field weights:=@unavailable;

@command([ViewRefreshFields]);

@command([RefreshHideFormulas])

Уже рассматривались аналогичные кнопки. Эта кнопка она делает:

1. делает пустым поле members

2. удаляет поле weights

3. обновляет документ

Весьма вероятно, что, попробовав самостоятельно сделать такие же кнопки, вы столкнетесь с одной проблемой:

Когда вы будете писать формулу скрытия для кнопки МИНУС, если вы потом перейдете на кнопку ПЛЮС, то увидите, что та же формула появилась на кнопке ПЛЮС, хотя ее-то нам как раз скрывать не надо, если у нас не выбраны участники. Дело в том, что формула скрытия распространяется на ВСЕ элементы, стоящие в ОДНОЙ строке. Поэтому чтобы избежать распространения формулы, нужно отделить одну кнопку от другой переводом строки. Это касается и полей и прочих элементов. Формулы скрытия это атрибут строки, в которой расположен объект.

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

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

Как уже рассматривалось, доступ к рабочей области осуществляется через класс NotesUIWorkspace. Кроме этого есть ряд UI-классов, которые представляют объекты в рабочей области. Как правило, из этих UI-классов, представляющих объект, открытый в рабочей области, можно получить доступ к этому же объекту в базе данных. Например, NotesUIDocument.Document или notesUIView.View.

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: