Lotus Script Как Проверить На Уникальность Поля?

Тема в разделе "Lotus - Программирование", создана пользователем diga, 10 июл 2014.

  1. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    Lotus Script как проверить на уникальность поля?

    имеется поле OrgID

    для событии Querysave написал следующий скрипт:

    Код (LotusScript):
    Sub Querysave(Source As Notesuidocument, Continue As Variant)
    Dim doc As NotesDocument
    Set doc = source.Document
    Dim db As NotesDatabase
    Set db = doc.ParentDatabase
    Dim ndc As NotesDocumentCollection
    Dim var As String
    If ( source.FieldGetText( "OrgTitle" ) = "" ) Then
    Messagebox( "Заполните поле наименование организации" )
    Call source.GotoField( "OrgTitle" )
    continue = False
    Else
    If ( source.FieldGetText( "OrgID" ) = "" ) Then
    Messagebox( "Отсутствует краткое наименование организации" )
    Call source.GotoField( "OrgID" )
    continue = False
    Else
    'var = doc.getItemValue("OrgID")(o)
    Set ndc = db.Search("456", Nothing, 0)
    numDocs& = ndc .Count
    If (numDocs& >1) Then
    Messagebox( "Такое краткое наименование существует!" )
    Call source.GotoField( "Org ID" )
    continue = False
    Else
    Messagebox( "Данные успешно сохранены" )
    End If
    End If
    End If
    End Sub
    не могу исправить ошибки, а именно как сделать так, чтоб при поиске "456" в результате выдавалась ошибка что такое имя уже существует. При этом надо проверить на условие что найденный документ (например если он нашел только одну) редактируемый данный документ или другой, если другой то выдать сообщение об ошибке. С помощью кода
    Код (LotusScript):
    var = doc.getItemValue("OrgID")(o)
    хотел присвоить значения поля в переменную и уже производить поиск
    Код (LotusScript):
    Set ndc = db.Search(var, Nothing, 0)
    Но выдает ошибку.

    Буду рад любой помощи! Спасибо большое!
     
  2. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    так-ссс...
    1. db.Search для таких целей очень долго, не оправдано долго.
    2. Неверная формула отбора, параметр var должен быть сформирован как формула отбора в представлении.
    Пример: db.Search({Form = "MainTopic"}, Nothing, 0) тогда в ndc попадут все документы по форме MainTopic
    3. Решение вопроса есть, да и не редкость.

    Если вкратце:
    1. Делаете служебное представление, в первую колонку вставляете вывод значения поля или ключа, по которому проверяете уникальность. У вас это OrgID.
    2. Делаете эту колонку сортированной, это обязательно.
    3. На событии QuerySave вешаем код, который по данной вьюхе получает коллекцию документов.
    Set ndc = view.GetAllDocumentsByKey(doc.getItemValue("OrgID")(0), True)
    Далее проверяем коллекцию и текущий документ по циклу:
    Код (LotusScript):
    'currDoc - текущий документ на экране
    Set doc = dc.GetFirstDocument
    While Not doc Is Nothing
    If doc.UniversalID <> currDoc.UniversalID Then
    Msgbox "Документ с таким названием уже существует.",16
    Goto endh
    End If
    Set doc = dc.GetNextDocument(doc)
    Wend
    Есть минусы: если документы ограничены readers полями и пользователь не видит их - проверка не сработает.
     
  3. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    если сделать исполнение кода под админом (проверки или редактором), а поля ридерс для них задавать в доках всегда (например ролями) - можно нивилировать минус
     
  4. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    1. Делаете служебное представление, в первую колонку вставляете вывод значения поля или ключа, по которому проверяете уникальность. У вас это OrgID.
    2. Делаете эту колонку сортированной, это обязательно.

    что - то это не совсем понял что тут делать? то есть у меня будет допустим представление: "Служебное" Как вы сказали сделаю вывод значения поля. Для чего мы его сортируем? и если сортировать то каким именно образом это сделать? как он будет влиять если не будет сортировки

    Спасибо
     
  5. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    >diga Для чего мы его сортируем? и если сортировать то каким именно образом это сделать
    1) Для получения этого: Set ndc = view.GetAllDocumentsByKey(currdoc.getItemValue("OrgID")(0), True), где view - созданное представление, currdoc - текущий открытый док.
    2) Любым, порядок сортировки колонки для данной задачи не имеет значения.
    Остальные ваши вопросы обычно решаются путем вдумчивого прочитывания ответа savl и хелпа дизайнера (создание представления для отбора GetAllDocumentsByKey).
    При очень больших проблемах в понимании - просите помощь "зала" - старших товарищей (вы же не единственный лотусист в организации?).
     
  6. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    GetAllDocumentsByKey работает по первой сортированной колонке, по ней она будет искать документы. если колонка не будет сортирована, то функция ничего не вернет. Подробнее написано в help к дизайнеру.
    В дизайнере, при создании представления, в свойствах колонки на второй закладке выставляется сортировка.
     
  7. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    Goto endh

    что за команда? в хелпе не находит
     
  8. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    хех)
    Goto - это переход на метку, да в лотусе это есть)
    endh - метка.

    Goto Endh можно заменить на Exit Sub или Exit Function, все зависит где данная строка.
    Так как это в QuerySave, то можно Exit Sub
     
  9. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    и так же как он понимает что именно по OrgID надо проверить уникальность?

    создал структуру как посоветовали сортировал, но результата никакого
    может я что то не дописал?

    Код (LotusScript):
    Sub Querysave(Source As Notesuidocument, Continue As Variant)
    Dim doc As NotesDocument
    Set doc = source.Document
    Dim db As NotesDatabase
    Set db = doc.ParentDatabase
    Set doc = dc.GetFirstDocument
    Dim ndc As NotesDocumentCollection
    Dim var As String
    If ( source.FieldGetText( "OrgTitle" ) = "" ) Then
    Messagebox( "Заполните поле наименование организации" )
    Call source.GotoField( "OrgTitle" )
    continue = False
    Else
    If ( source.FieldGetText( "OrgID" ) = "" ) Then
    Messagebox( "Отсутствует краткое наименование организации" )
    Call source.GotoField( "OrgID" )
    continue = False
    Else
    While Not doc Is Nothing
    If doc.UniversalID <> currDoc.UniversalID Then
    Msgbox "Документ с таким названием уже существует.",16
    End If
    Set doc = dc.GetNextDocument(doc)
    Wend
    Messagebox( "Данные успешно сохранены" )
    End If
    End If
    End Sub
    на
    Код (LotusScript):
    Goto endh
    ругался пришлось убрать его.
    Спасибо
     
  10. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Пичаль... Ничего в коде не смущает?
    Set doc = dc.GetFirstDocument - убрать строку, зачем второй раз переопредляете объект, да еще и с ошибкой, объекта dc же нет.
    Не дописал, получения документа из представления по GetAllDocumentsByKey.
    Объект currDoc не инициализирован.
    После Msgbox "Документ с таким названием уже существует.",16должно быть continue = False
    После каждого continue = False надо ставить Exit Sub иначе документ все равно сохраняется.

    Товарищ, данный код - не работает и будет выдавать ошибки. Не проверяли?
    Стажер на обучении?
     
  11. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0


    скорее практику прохожу в универе) дали кучу книг и задание, никакого обучения нет. вот и возникают некоторые трудности

    Добавлено:


    скорее практику прохожу в универе) дали кучу книг и задание, никакого обучения нет. вот и возникают некоторые трудности
     
  12. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    diga
    "Некоторые трудности"...
    0. Строим нормальный алгоритм, на бумаге. Сначала общий, затем подробнее.
    1. Добавляем обработчик ошибок:
    Код (LotusScript):
    Sub Querysave(Source As Notesuidocument, Continue As Variant)
    On Error Goto handler
    Const FuncName = {Sub "Querysave" }
    Dim ErrStr As String

    ' Ваш код

    Goto Endh
    handler:
    ErrStr = FuncName & ": " & Err &", в стр " & Erl & nLine & Error$
    Msgbox ErrStr, 16, "Error!"
    Resume endh
    Endh:
    End Sub
    2. Исправляем ошибки, чтобы они не возникали. Работать верно не будет, но главное поймете как их исправлять и что какая значит.
    3. Читаем про объекты NotesDocument (получение/изменение полей, сохранения), NotesUIDocument (в частности события), NotesView (как получать документы), NotesDatabase (как получать представления). Книги надеюсь есть на русском? Help с нуля читать на английском трудно, сам проходил.
    4. Применяем полученные знания к алгоритму для решения задачи.

    Практика, практика, практика.
     
  13. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    не могли бы вы помочь и написать правильную реализацию? Спасибо большое.
     
  14. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    diga
    Помочь могу, но писать не буду, тем более что это часть обучения.
    Советы я написал, далее желание.
     
  15. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    сейчас попробую) спасибо за советы
     
  16. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    Сделал следующим образом, все вроде как работает как надо.
    Код (LotusScript):
    Sub Querysave(Source As Notesuidocument, Continue As Variant)
    Dim db As NotesDatabase 'переменная класса базы данных
    Dim doc As NotesDocument 'переменная класса документ базы данных
    Dim currDoc As NotesDocument 'переменная класса документ базы данных
    Dim view As notesView ' класс вид
    Dim ws As New NotesUIWorkspace 'текущий открытый документ
    Dim ndc As NotesDocumentCollection 'переменная класса колекции документов
    Set doc = source.Document 'получаем ссылку на текущий документ "заднего плана"
    Set db = doc.ParentDatabase 'получаем ссылку на текущую БД
    If ( source.FieldGetText( "OrgTitle" ) = "" ) Then
    Messagebox( "Заполните поле наименование организации" )
    Call source.GotoField( "OrgTitle" )
    continue = False
    Else
    If ( source.FieldGetText( "OrgID" ) = "" ) Then
    Messagebox( "Отсутствует краткое наименование организации" )
    Call source.GotoField( "OrgID" )
    continue = False
    Else
    Set view=ws.CurrentDatabase.Database.GetView("Main View")
    Set currDoc=view.GetDocumentByKey(source.FieldGetText( "OrgID" ))
    If (Not currDoc Is Nothing)  Then
    Msgbox "Документ с таким названием уже существует.",16
    continue = False
    Exit Sub
    End If
    Messagebox( "Данные успешно сохранены" )
    End If
    End If
    End Sub
    то теперь возник другой вопрос, как теперь можно проверить уникальность в рамках одной формы? то есть, у нас имеется форма "организация", которая создает новую форму "подразделение" надо проверить уникальность поля "DepID" в форме "подразделение"в рамках организации. Как я понимаю в рамках организации это поле должно быть уникальна, но есть различные организации где могут быть подразделения с таким же названием. если же таким же методом
    Код (LotusScript):
    Set view=ws.CurrentDatabase.Database.GetView("Main View")
    Set currDoc=view.GetDocumentByKey(source.FieldGetText( "DepID" ))
    то получаем все DepID во всех организация. Каким образом сделать так чтоб он проверял именно в текущей Организации, несмотря на то что мы находимся в форме Подразделение? Спасибо.
     
  17. ty3uk

    ty3uk Well-Known Member

    Регистрация:
    31 мар 2008
    Сообщения:
    169
    Симпатии:
    0
    UPD: Переправил ответ полностью....
    1) в вашем алгоритме, при повторном сохранении документа будет в 100% случаев выдавать что такая организация уже существует! (выше приводиться алгоритм, который проверяет найденый документ на соотвествие UniversalID документа). Подправте данный момент...
    + для GetDocumentByKey, крайне рекомендуется, второй параметр, ставить в true
    2) по второму, уже написали ответ...
     
  18. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    diga
    молодец) Но ошибки логики все же есть, не все советы видимо внял.
    Ну ничего страшного, ниже немного модифицированная версия. Проверять не проверял, но думаю без особых ошибок будет.
    Лучше проверять документы на уникальность в цикле, тут много причин. почему так лучше.
    И да, обработчик ошибок - нужен и должен быть написан самым первым, иначе черт ногу сломит при поиске ошибок.

    По поводу подразделений: можно проверять точно также, только ключ поиска изменится.
    А вот как измениться надо подумать. Можно оставить одну колонку и сделать составной ключ: OrgID + {~} + DeptID и искать по нему.
    А можно сделать 2 колонки (вторую тоже надо отсортировать) и посылать уже 2 ключа для поиска.
    Код (LotusScript):
    dim sKey(1) as variant
    sKey(0) = source.FieldGetText( "OrgID " )
    sKey(1) = source.FieldGetText( "DeptID " )
    Set nDc = view.GetAllDocumentsByKey(skey, true)
    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">модифицированная версия</div></div><div class="sp-body"><div class="sp-content">
    Код (LotusScript):
    Dim db As NotesDatabase 'переменная класса базы данных
    Dim doc As NotesDocument 'переменная класса документ базы данных
    Dim currDoc As NotesDocument 'переменная класса документ базы данных
    Dim view As notesView ' класс вид
    Dim ws As New NotesUIWorkspace 'текущий открытый документ
    Dim ndc As NotesDocumentCollection 'переменная класса колекции документов

    Set doc = source.Document 'получаем ссылку на текущий документ "заднего плана"
    Set db = doc.ParentDatabase 'получаем ссылку на текущую БД
    If ( source.FieldGetText( "OrgTitle" ) = "" ) Then
    Messagebox( "Заполните поле наименование организации" )
    Call source.GotoField( "OrgTitle" )
    continue = False
    Exit sub
    End if
    If ( source.FieldGetText( "OrgID" ) = "" ) Then
    Messagebox( "Отсутствует краткое наименование организации" )
    Call source.GotoField( "OrgID" )
    continue = False
    Exit sub
    End if

    Set view=ws.CurrentDatabase.Database.GetView("Main View")
    Set nDc = view.GetAllDocumentsByKey(source.FieldGetText( "OrgID" ),true)
    If nDc.Count > 1 then
    Set currDoc= ndc.GetFirstDocument
    Do While not currDoc is nothing
    if currDoc.UniversalID <> doc.UniversalID then
    Msgbox "Документ с таким названием уже существует.",16
    continue = False
    Exit Sub
    end if

    Set currDoc= ndc.GetNextDocument(currDoc)
    Loop
    End if
    Messagebox( "Данные успешно сохранены" )
     
  19. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    >Set view=ws.CurrentDatabase.Database.GetView("Main View")
    так получать БД не надо. Есть ньюансы с CurrentDatabase. Лучше из документа (или из сессии, если это текущая БД) Set db вы сделали просто так, для увеличения кол-ва строчек? ;)
     
  20. diga

    diga Member

    Регистрация:
    10 июл 2014
    Сообщения:
    20
    Симпатии:
    0
    разве не больше 0 должно быть? Иначе он может сохранить документ с таким названием 2 раза
     
Загрузка...

Поделиться этой страницей