Desenvolvimento de Sistemas
Autor: Arnaldo Nizer do Vale - GSR
DESENVOLVIMENTO NOTES - EVITANDO CONFLITO DE GRAVAÇÃO
Muitas vezes já foi questionado se existe alguma maneira de o Notes mostrar um aviso quando se tenta editar um documento que outra pessoa já esteja editando. Até o momento, não existe nenhum modo de saber se um outro usuário está editando o documento antes de se tentar salvá-lo. Em determinados casos, seria muito útil se uma mensagem avisasse que o documento está sendo editado, quem é o editor e quanto tempo já se passou desde o início da operação.
Embora os tradicionais sistemas de informação evitem o conflito de gravação através do Lock de registro, isto é difícil de implementar em um ambiente distribuído, como o Notes. Para amenizar este problema, a Lotus resolveu deixar uma marca no documento resultante de um conflito para que o gerente da base possa resolver este conflito.
Como existem situações onde documentos precisam ser editados por mais de uma pessoa, esta programação em Lotus Script visa prevenir para que duas pessoas não editem o mesmo documento no Notes, evitando assim conflitos de gravação.
Para tanto, foi criado um banco de dados (Lockdb.nsf) que manterá os documentos atualmente reservados para edição. A idéia é a seguinte: Quando a 1ª pessoa acessa um documento, um script no evento PostOpen cria um documento correspondente na base Lockdb, armazenando seu UniqueID, o nome de quem reservou e a hora que isto ocorreu. Adicionalmente, toda vez que um documento estiver para ser aberto, um script verificará se este se encontra na lista dos "reservados". Caso não se encontre, ele será aberto normalmente. Caso contrário, o usuário recebe uma mensagem dizendo que o documento está sendo editado e não habilita o modo de edição. Somente quando o 1º usuário terminar sua edição, outro evento marca este documento como "liberado", podendo outro usuário então alterá-lo. Para finalizar, deverá existir um agente na base Lockdb para fazer a limpeza desta base, deletando os documentos já liberados.
A base Lockdb.nsf deve ter um formulário (locdoc) com quatro campos: dbTitle, SavedReplicaId, SavedUNID, EXPIRED.
Código:
Evento: PostOpen do documento que estiver sendo editado:
- Sub Postopen(Source As Notesuidocument)
If source.editmode Then
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set doc = source.Document
Set db = doc.ParentDatabase
Dim locdb As New NotesDatabase (db.Server, "Lockdb.nsf")
If locdb.IsOpen Then
Dim locdoc As New NotesDocument (locdb)
Dim coldoc As New NotesDocument (locdb)
Dim collection As NotesDocumentcollection
Dim locdoctime As New NotesDateTime("")
Dim coldoctime As New NotesDatetime("")
Dim expirydate As New NotesDateTime("")
Dim cutoffdate As New NotesDateTime("01/01/97")
'Cria o documento de Lock
Dim authorsitem As New NotesItem(locdoc, "userid", _
session.CommonUserName, AUTHORS)
locdoc.dbtitle = db.Title
locdoc.savedReplicaID = db.ReplicaID
locdoc.savedUNID = doc.UniversalID
locdoc.form = "locdoc"
Call locdoc.save(True, False)
locdoctime.LSLocalTime = locdoc.created
'Encontra documentos não expirados para este documento
searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _
+ """ & savedReplicaID = """ + db.ReplicaID + """ & @Text(EXPIRED) =''"
Set collection = locdb.Search(searchformula$, cutoffdate, 0)
Call expirydate.SetNow
For i = 1 To collection.Count
Set coldoc = collection.GetNthDocument(i)
If Not(coldoc.userid(0) = session.CommonUserName) Then
locdoc.Expired = expirydate.LocalTime
Call locdoc.Save(True, False)
source.editmode = False
coldoctime.LSLocalTime = coldoc.created
diff& = locdoctime.TimeDifference (coldoctime)
Messagebox (coldoc.userid(0) + " reservou este documento para edição há " _
+ Cstr(diff&) + " segundos, em " + Cstr(coldoctime.LSLocalTime))
Exit For
End If
Next
End If
End If
End Sub
Evento: Querymodechange do documento que estiver sendo editado:
- Sub Querymodechange(Source As Notesuidocument, Continue As Variant)
Continue = True
If Not(source.editmode) Then
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set doc = source.Document
Set db = doc.ParentDatabase
Dim locdb As New NotesDatabase(db.Server, "Lockdb.nsf")
If locdb.IsOpen Then
Dim locdoc As New NotesDocument (locdb)
Dim coldoc As New NotesDocument (locdb)
Dim collection As NotesDocumentcollection
Dim locdoctime As New NotesDateTime("")
Dim coldoctime As New NotesDatetime("")
Dim expirydate As New NotesDatetime("")
Dim cutoffdate As New NotesDateTime("01/01/97")
'Cria o locdoc
Dim authorsitem As New NotesItem(locdoc, "userid", _
session.CommonUserName, AUTHORS)
locdoc.dbtitle = db.Title
locdoc.savedReplicaID = db.ReplicaID
locdoc.savedUNID = doc.UniversalID
locdoc.form = "locdoc"
Call locdoc.save(True, False)
locdoctime.LSLocalTime = locdoc.created
'Encontra locdocs para este documento
searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _
+ """ & savedReplicaID = """ + db.ReplicaID + """ & @Text(EXPIRED) = '' "
Set collection = locdb.Search(searchformula$, cutoffdate, 0)
'Verifica locdocs para outros usuários
Call expirydate.SetNow
For i = 1 To collection.Count
Set coldoc = collection.GetNthDocument(i)
If Not(coldoc.userid(0) = session.CommonUserName) Then
locdoc.Expired = expirydate.LocalTime
Call locdoc.Save(True, False)
Continue = False
coldoctime.LSLocalTime = coldoc.created
diff& = locdoctime.TimeDifference (coldoctime)
Messagebox (coldoc.userid(0) + " reservou este documento para edição há " _
+ Cstr(diff&) + " segundos, em " + Cstr(coldoctime.LSLocalTime))
Exit For
End If
Next
End If
End If
End Sub
Evento: Postmodechange do documento que estiver sendo editado:
- Sub Postmodechange(Source As Notesuidocument)
If Not(source.editmode) Then
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set doc = source.Document
Set db = doc.ParentDatabase
Dim locdb As New NotesDatabase(db.Server, "Lockdb.nsf")
If locdb.IsOpen Then
Dim coldoc As New NotesDocument (locdb)
Dim collection As NotesDocumentcollection
Dim expirydate As New NotesDateTime("")
Dim cutoffdate As New NotesDateTime("01/01/97")
'Marca estes documentos como expirados para este documento
searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _
+ """ & savedReplicaID = """ + db.ReplicaID + """ & userid = """ _
+ session.CommonUserName + """ & @Text(EXPIRED) = '' "
Set collection = locdb.Search(searchformula$, cutoffdate, 0)
Call expirydate.SetNow
For i = 1 To collection.Count
Set coldoc = collection.GetNthDocument(i)
coldoc.Expired = expirydate.LocalTime
Call coldoc.Save(True, False)
Next
End If
End If
End Sub
Evento: Terminate do documento que estiver sendo editado:
- Sub Terminate
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Set uidoc = workspace.CurrentDocument
If uidoc.editmode Then
Dim session As New NotesSession
Dim doc As NotesDocument
Set doc = uidoc.Document
Dim db As NotesDatabase
Set db = doc.ParentDatabase
Dim locdb As New NotesDatabase(db.Server, "Lockdb.nsf")
If locdb.IsOpen Then
Dim coldoc As New NotesDocument (locdb)
Dim collection As NotesDocumentcollection
Dim expirydate As New NotesDateTime("")
Dim cutoffdate As New NotesDateTime("01/01/97")
searchformula$ = "form = ""locdoc"" & savedUNID = """ + doc.UniversalID _
+ """ & savedReplicaID = """ + db.ReplicaID + """ & userid = """ _
+ session.CommonUserName + """ & @Text(EXPIRED) = '' "
Set collection = locdb.Search(searchformula$, cutoffdate, 0)
Call expirydate.SetNow
For i = 1 To collection.Count
Set coldoc = collection.GetNthDocument(i)
coldoc.Expired = expirydate.LocalTime
Call coldoc.Save(True, False)
Next
End If
End If
End Sub
Agente de Limpeza da Base de Reservas (lockdb.nsf)
- Sub Initialize
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Dim doc As NotesDocument
Dim collection As NotesDocumentcollection
Set collection = db.UnprocessedDocuments
'Remover documentos expirados desta base
For i = 1 To collection.Count
Set doc = collection.GetNthDocument(i)
If doc.HasItem("Expired") And doc.Form(0) = "locdoc" Then
Call doc.remove(True)
End If
Next
End Sub