• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

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

  • Автор темы 1KIA
  • Дата начала
1

1KIA

Что необходимо исправить:
Есть вьюха N с полем NN в нем заполняется номер 1, 2, 3, ... 151, 152...
есть форма с полем Number, которое должно заполнятся автоматически. Оно заполняется в POstOpen
Код:
	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 минут подумать и закрыть не сохранив документ. В такой ситуации документ не должен создаться и номер должен быть свободен

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

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
1. Например получать номер в момент сохранения документа, думаю это правильнее всего.

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

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

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
Считаю что нумерацию вообще надо вынести в серверный агент.
1. Если у всех документов нумерация сквозная - есть вероятность что пользователь не "увидит" все документы
2. Если пользователь может передумать и не сохранить документ... следовательно сквозная нумерация нарушится... то почему бы не нумеровать документ после сохранения, а затем информировать пользователя о присвоении номера?
 
1

1KIA

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

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

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
2. понмаю, что это именно то что нужно, но слишком сложно
3. не подходит

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

В момент QuerySave, после проверки всех нужных полей, присваиваете номер, если он еще не присвоен.
Если пользователю например надо распечатать док с номером - в кнопку печать добавить предупреждение что хотите ли сохранить если номер еще не присвоен.
 
1

1KIA

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

iki

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


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

Код:
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
 

Gandliar

Lotus Team
16.02.2004
556
26
BIT
40
в такой способ все равно создает одинаковые номера


Еще раз.

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

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

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 933
609
BIT
177
-серверный агент и очередь
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 933
609
BIT
177
и эта... UNID - тоже номер ;)
 
1

1KIA

если делать серверным агентом, то при QuerySave добавляю
Код:
		Set agent = db.GetAgent("Number")
Call agent.RunOnServer(Doc.NoteID)
а в агенте :
Код:
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
или уже необходимо агент делать по другому принципу?
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 933
609
BIT
177
я не понимаю почему:
-не использовать UINID (или @Unique) - чем не номер?
-для синхронизации использовать серверные очереди, а не контроль конфликта (если возникает вопрос как- то лучше не нужно, хотя это не сложно)
 

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
если делать серверным агентом, то при QuerySave добавляю
Код:
		Set agent = db.GetAgent("Number")
Call agent.RunOnServer(Doc.NoteID)
а в агенте :
Код:
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
или уже необходимо агент делать по другому принципу?

Агент надо запускать после сохранения его пользователем иначе возможен конфликт.
У меня нумерация работает так.
Есть вид с уже пронумерованными доками, отсортированный "последний сверху"
Агент берет последний док.. и к номеру +1
 
X

Xalet

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

1KIA

помогите, запуталась просто невероятно
на поле Numb1 , одно отображает данные номера
на POstOpen проверяю
Код:
		If( note.GetItemValue( "Numb1" )(0) = "" ) Then
Call proceduraNumber()
End If
proceduraNumber:
Код:
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:
Код:
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
ни при открытии , ни при сохранении поле не заполняется
 
X

Xalet


это документ? Если да, то до первого сохранения его не существует. Соответственно

Call note.ReplaceItemValue( "Number1", iNumber )

If( note.GetItemValue( "Numb1" )(0) = "" ) Then

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

1KIA

запуталась окончательно.
Возвращаюсь назад, а то уже и вовсе ничего не работает
на QueryOpen
Код:
	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
Код:
	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 номер

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

Обучение наступательной кибербезопасности в игровой форме. Начать игру!