Автоматический номер

Тема в разделе "Lotus - Программирование", создана пользователем 1KIA, 17 фев 2011.

  1. 1KIA

    1KIA Гость

    Что необходимо исправить:
    Есть вьюха N с полем NN в нем заполняется номер 1, 2, 3, ... 151, 152...
    есть форма с полем Number, которое должно заполнятся автоматически. Оно заполняется в POstOpen
    Код (LotusScript):
        Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim item As NotesItem
    Set db = session.CurrentDatabase
    Set view = db.GetView( "N" )
    Set doc = view.GetFirstDocument

    If (Not(doc Is Nothing) And (source.IsNewDoc) ) Then
    Set item = doc.GetFirstItem( "NN" )
    doc.nm= Int(item.Text )+1
    Call Source.FieldSetText("Number",item.Text )
    End If
    Set note = Source.Document
    Проблема в том, что если пользователи открывают одновременно карточку и заполняют данне, то номера у них одинаковые.
    Как сделать, чтобы номер временно резервировался, т.к. пользователь может 10 минут подумать и закрыть не сохранив документ. В такой ситуации документ не должен создаться и номер должен быть свободен

    Если при сохранении
    Код (Text):
       

    If Source.IsNewDoc Then
    Set item = doc.GetFirstItem( "nm" )
    doc.nm= Int(item.Text )+1
    Call doc.save(True,True)
    то постоянно на 1 больше, если убрать +1, тогда одинаковые номера
     
  2. Gandliar

    Gandliar Well-Known Member

    Регистрация:
    16 фев 2004
    Сообщения:
    222
    Симпатии:
    0
    1. Например получать номер в момент сохранения документа, думаю это правильнее всего.

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

    3. Сделать сложный номер типа 1.1.1 где последний сегмент номер дока от этого пользователя ;)
     
  3. NickProstoNick

    NickProstoNick Статус как статус :)

    Регистрация:
    22 авг 2008
    Сообщения:
    1.766
    Симпатии:
    39
    Считаю что нумерацию вообще надо вынести в серверный агент.
    1. Если у всех документов нумерация сквозная - есть вероятность что пользователь не "увидит" все документы
    2. Если пользователь может передумать и не сохранить документ... следовательно сквозная нумерация нарушится... то почему бы не нумеровать документ после сохранения, а затем информировать пользователя о присвоении номера?
     
  4. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Вы конечно же воспользовались поиском по формум, но ничего не нашли? М.б. исправить поиск? :)
    Но он вроде работает...
     
  5. 1KIA

    1KIA Гость

    2. понмаю, что это именно то что нужно, но слишком сложно
    3. не подходит

    1. т.е. делать все на QuerySave?
     
  6. Gandliar

    Gandliar Well-Known Member

    Регистрация:
    16 фев 2004
    Сообщения:
    222
    Симпатии:
    0
    В момент QuerySave, после проверки всех нужных полей, присваиваете номер, если он еще не присвоен.
    Если пользователю например надо распечатать док с номером - в кнопку печать добавить предупреждение что хотите ли сохранить если номер еще не присвоен.
     
  7. 1KIA

    1KIA Гость

    в такой способ все равно создает одинаковые номера
     
  8. iki

    iki Гость

    Почитайте то что посоветовал turumbay.


    Если хотите простую реализацию без обработки сервером можно добавить в базу небольшой справочник который хранит учетные номера для каждого из возможных видов документа (желательно для каждого вида - свой документ). Добавлять номер надо при сейве. Пишем в справочник. меняем себе, оба сейвим. Можно добавить что-то типо такого чтобы не наткнутся на одновременное сохранение

    Код (Text):
    Do 
    Set docNum = ' получаем документ последнего рег. номера
    lastNum = ' получаем сам рег. номер
    inc = IncreaseNumberByDoc(docNum) ' увеличиваем номер в док-те рег. номера
    Loop While inc = False
    'присваиваем документу номер

    Function IncreaseNumberByDoc(doc As Variant) As Variant
    IncreaseNumberByDoc = False
    Call doc.ReplaceItemValue("LastRegNumber", doc.GetItemValue("LastRegNumber")(0) + 1)
    If doc.Save(False, False) = False Then
    IncreaseNumberByDoc = False
    Else
    IncreaseNumberByDoc = True
    End If 
    End Function
     
  9. Gandliar

    Gandliar Well-Known Member

    Регистрация:
    16 фев 2004
    Сообщения:
    222
    Симпатии:
    0

    Еще раз.

    Имеется ввиду работа с одним сервером.
    Есть документ настройки хранящий номер.

    При попытке сохранения, если док новый, ищем док настройки, добавляем номер+1, пытаемся сохранить flag=docConfig.Save(false, false)
    если flag = true то значит сохранили, записываем номер в текущий док и сохраняем его.
    если flag = false можем попытаться раз 30 считать док заново (чтобы получить новый номер) еще сохранить, если прокатило, то сохраняем если и через 30 раз ниче - то надо выдать мессадж звать разработчика разбираться, в чем дело и док не сохранять.
     
  10. lmike

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

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    -серверный агент и очередь
     
  11. NickProstoNick

    NickProstoNick Статус как статус :)

    Регистрация:
    22 авг 2008
    Сообщения:
    1.766
    Симпатии:
    39
    Нумерацию надо делать через серверный агент!!! у которого есть права на все документы!
     
  12. lmike

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

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    и эта... UNID - тоже номер ;)
     
  13. 1KIA

    1KIA Гость

    если делать серверным агентом, то при QuerySave добавляю
    Код (LotusScript):
            Set agent = db.GetAgent("Number")
    Call agent.RunOnServer(Doc.NoteID)
    а в агенте :
    Код (Text):
    Set doc = db.GetDocumentByID(agent.ParameterDocID)
    Set db = session.CurrentDatabase
    Set view = db.GetView( "N" )
    Set doc = view.GetFirstDocument

    If (Not(doc Is Nothing) And (source.IsNewDoc) ) Then
    Set item = doc.GetFirstItem( "NN" )
    doc.nm= Int(item.Text )+1
    Call Source.FieldSetText("Number",item.Text )
    End If
    т.е. в агент то что было на QuerySave
    или уже необходимо агент делать по другому принципу?
     
  14. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    убрать из агента это:
    получение по ид в агенте вроде с несохраненным документом не прокатывает:
     
  15. lmike

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

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    я не понимаю почему:
    -не использовать UINID (или @Unique) - чем не номер?
    -для синхронизации использовать серверные очереди, а не контроль конфликта (если возникает вопрос как- то лучше не нужно, хотя это не сложно)
     
  16. NickProstoNick

    NickProstoNick Статус как статус :)

    Регистрация:
    22 авг 2008
    Сообщения:
    1.766
    Симпатии:
    39
    Агент надо запускать после сохранения его пользователем иначе возможен конфликт.
    У меня нумерация работает так.
    Есть вид с уже пронумерованными доками, отсортированный "последний сверху"
    Агент берет последний док.. и к номеру +1
     
  17. Xalet

    Xalet Well-Known Member

    Регистрация:
    8 авг 2008
    Сообщения:
    410
    Симпатии:
    0
    Поднять локкинг, создать документы по формам с номерами, искать нужный док, проверять лок, лочить, считывать номер, вписывать следующий, сохранять, снимать лок.
     
  18. 1KIA

    1KIA Гость

    помогите, запуталась просто невероятно
    на поле Numb1 , одно отображает данные номера
    на POstOpen проверяю
    Код (Text):
            If( note.GetItemValue( "Numb1" )(0) = "" ) Then
    Call proceduraNumber()
    End If
    proceduraNumber:
    Код (Text):
    Dim viewNumber As NotesView
    Set viewNumber = db.GetView( "$Number" )

    Dim iNumber As String
    iNumber = GetNewNumber

    'уникаленость
    Dim notUnique As Boolean
    notUnique = True
    Dim existingBug As NotesDocument
    Dim x As Integer

    'Проверка уникальности
    While( notUnique )
    x=x+1

    Set existingBug = viewNumber.GetDocumentByKey( iNumber, True )
    If( existingBug Is Nothing ) Then
    notUnique = False

    If iNumber="" Then
    iNumber = GetNewNumber
    Else
    Call note.ReplaceItemValue( "Number1", iNumber )
    End If

    Else
    issueNumber = GetNewNumber
    End If

    If( x=100 ) Then
    Exit Sub
    End If

    Wend
    GetNewNumber:
    Код (Text):
    Dim item As NotesItem

    Set db = session.CurrentDatabase
    Set view = db.GetView( "$Number" )
    Set doc = view.GetFirstDocument
    If Not(doc Is Nothing) Then
    Set item = doc.GetFirstItem( "Number1" )
    doc.INumber= Int(item.Text )
    GetNewNumber=item.Text
    End If
    ни при открытии , ни при сохранении поле не заполняется
     
  19. Xalet

    Xalet Well-Known Member

    Регистрация:
    8 авг 2008
    Сообщения:
    410
    Симпатии:
    0
    это документ? Если да, то до первого сохранения его не существует. Соответственно

    это вообще не отработает. Надо с уидоком работать либо на постсэйв перевесить. По алгоритмам - похоже на бред... Номер найдется уникальный и впишется в документ. Если тут же не сохоанить, то есть вероятность, что кто-то найдет такой же. На кьюэрисэйв больший шанс сохоанить уникальность, но тоже с вероятными ошибками. И да... Как оно отработает, если пользователи из реплик локальных будут работать?
     
  20. 1KIA

    1KIA Гость

    запуталась окончательно.
    Возвращаюсь назад, а то уже и вовсе ничего не работает
    на QueryOpen
    Код (Text):
        Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim item As NotesItem
    Set db = session.CurrentDatabase
    Set view = db.GetView( "number" )
    Set doc = view.GetFirstDocument

    If (Not(doc Is Nothing) And (source.IsNewDoc) ) Then
    Set item = doc.GetFirstItem( "nn" )
    doc.nm= Int(item.Text )+1
    Call Source.FieldSetText("Number",item.Text )
    End If
    на QuerySave
    Код (Text):
        If Source.IsNewDoc Then
    Dim db As NotesDatabase
    Dim view As NotesView
    Set db = session.CurrentDatabase
    Set view = db.GetView( "number" )
    Set doc = view.GetFirstDocument
    If Not(doc Is Nothing) Then
    Set item = doc.GetFirstItem( "nn" )
    doc.nm= Int(item.Text )+1
    Call doc.save(True,True)
    End If
    почему он здесь не проверяется, вот если 1чел уже сохранил, то 2-й по идее должен сохранять +1 номер

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

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