Our Domino developer told us that it is "technologically impossible" to move subdocuments between documents. Is this true?
Earlier this year he wrote for us a course registration system with the following database diagram:
Now we asked him how to move waitlisted registrants from the full training sessions to those sessions that are not. He said it is impossible. He said we need to re-enter (recreate, copy and paste manually) the waitlist records because Domino cannot move attendees from one session to another.
We ha开发者_如何学Cve over 1000 attendees in our waitlists.
Is he correct? Is this for real? We hope for a solution.
How to do it depends on the way the documents are linked. But in any case it should be possible to relink the documents using code (formula/lotusscript/java).
The help of the Lotus designer contains a lot of information about application development. Another resource is IBM developerworks
There are numerous Lotus related blogs
From the Lotus Designer help: MakeResponse: Makes one document a response to another document. The two documents must be in the same database.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim docA As NotesDocument
Dim docB As NotesDocument
Set db = session.CurrentDatabase
Set view = db.GetView( "All documents" )
Set docA = view.GetFirstDocument
Set docB = view.GetNextDocument( docA )
Call docB.MakeResponse( docA )
docB.Form = "Response"
Call docB.Save( True, True )
There are 2 ways that documents can be linked: - via keys, the soft way - hierarchically, using a document-response link (i.e. parent-child)
If there is only the logical link, using keys, you only have to adapt the key fields. If there is a "physical", document-response link, you can easily break and recreate that link. In LotusScript there is the NotesDocument.MakeResponse method to attach any document to a new parent. If both methods are used, redundant of course but practical when you need to recover some links, you need to do both changes. Usually, some key fields are repeated from parent to child
Just for testing purposes, you could try this: - select a response document that you want to hang elsewhere - Ctrl-X - select the new parent document - Ctrl-V
Do this in a test database, for the key fields won't be updated automatically. By the way: code can be written to repair the keys after pasting such a response document.
If you want to keep existing documents you could programmatically copy/duplicate them. It's quite easy using copyAllItems method.
Look Domino help (with example) here
You could iterate documents with notesView object (getFirstDocument() / getNextDocument() methods), iterate responses on notesdocument.responses method...
Trust us, it's possible, Domino is flexible :-)
There are basically 2 ways this data is linked in the data model you describe. If the data is linked through response document hierarchies it will be slightly different from key based document structures.
Show this to your developer and, he should literally be able to plug in the code to enable the "move attendees" requirements that you're talking about.
A few things to note.
- I am assuming that all the data you need to manipulate is in one database.
- I am taking your diagram you've provided literally.
For key based document structures, you'll need to check the view and key values used o find attendee documents. Specifically check these 2 lines in the "MoveAttendeesKeyBased" sub:
Set vwAttendeesByCourseID = db.GetView("(LkupAllAttendeesByCourseID)")
Set dcAttendees = vwAttendeesbyCourseID.GetAllDocumentsByKey(docCourseFrom.CourseID(0), True)
The code is designed to look at a field called "CourseID", "Status" and the value of "Wait Listed" for the status value of attendees to be moved.
It took about 20 minutes to write both versions of this function.
For response based document structures
Sub MoveAttendeesResponseBased(docCourseFrom As notesDocument, docCourseTo As NotesDocument)
%REM
A simple move attendees function if the relationship between courses and attendees is based on
response document hierarchies
%END REM
On Error Goto errHandle
Dim dcAttendees As notesDocumentCollection
Dim docAttendee As notesDocument
Dim iAvailablePlaces As Integer
Dim bMoved As Boolean
If Not (docCourseFrom Is Nothing Or docCourseTo Is Nothing) Then
iAvailablePlaces = docCourseTo.availablePlaces(0)
If 0 < iAvailablePlaces Then
bMoved = False
Set dcAttendees = docCourseFrom.Responses
Set docAttendee = dcAttendees.GetFirstDocument
While Not docAttendee Is Nothing And 0 < iAvailablePlaces
If Ucase(Trim(docAttendee.Status(0)))= "WAIT LISTED" Then
Call docAttendee.MakeResponse(docCourseTo)
If docAttendee.Save(True,True) Then
iAvailablePlaces = iAvailablePlaces - 1
bMoved = True
End If
End If
Set docAttendee = dcAttendees.GetNextDocument(docAttendee)
Wend
If bMoved Then
docCourseTo.availablePlaces = iAvailablePlaces
Call docCourseTo.Save(True,False)
End If
End If
End If
Exit Sub
errHandle:
Messagebox Lsi_info(2) + " - " + Str(Err) + " : " + Error(Err) + ", at line " + Str(Erl)
Exit Sub
End Sub
For key based document structures
Sub MoveAttendeesKeyBased(docCourseFrom As notesDocument, docCourseTo As notesDocument)
%REM
A simple move attendees function if the relationship between courses and attendees uses
(non-response) key based documents
%END REM
On Error Goto errHandle
Dim session As New notesSession
Dim dcAttendees As notesDocumentCollection
Dim docAttendee As notesDocument
Dim iAvailablePlaces As Integer
Dim bMoved As Boolean
' a view that lists attendees by Course ID
Dim vwAttendeesByCourseID As notesView
Dim db As notesDatabase
If Not (docCourseFrom Is Nothing Or docCourseTo Is Nothing) Then
iAvailablePlaces = docCourseTo.availablePlaces(0)
If 0 < iAvailablePlaces Then
Set db = session.CurrentDatabase
' do a lookup of all attendees based on the CourseFrom document course id
Set vwAttendeesByCourseID = db.GetView("(LkupAllAttendeesByCourseID)")
' this is the collection of all attendees under the CourseFrom document
Set dcAttendees = vwAttendeesbyCourseID.GetAllDocumentsByKey(docCourseFrom.CourseID(0), True)
bMoved = False
Set docAttendee = dcAttendees.GetFirstDocument
' While there are attendee documents to process and there are available places to goto
While Not docAttendee Is Nothing And 0 < iAvailablePlaces
' if the attendee's status is "Wait Listed" then move them
If Ucase(Trim(docAttendee.Status(0)))= "WAIT LISTED" Then
' Update the course ID for the Attendee
docAttendee.CourseID = docCourseTo.CourseID(0)
If docAttendee.Save(True,True) Then
' decrement the available places
iAvailablePlaces = iAvailablePlaces - 1
bMoved = True
End If
End If
Set docAttendee = dcAttendees.GetNextDocument(docAttendee)
Wend
If bMoved Then
' available places may be >= 0. Just update the available places so you don't over book the course
docCourseTo.availablePlaces = iAvailablePlaces
Call docCourseTo.Save(True,False)
End If
End If
End If
Exit Sub
errHandle:
Messagebox Lsi_info(2) + " - " + Str(Err) + " : " + Error(Err) + ", at line " + Str(Erl)
Exit Sub
End Sub
Key based documents are a little more work but I think are a better structure because you can easily move documents in databases and restore from backups, copy and paste. With response documents you may have issues restoring backups becasue response documents use parent document UNID's to associate themselves to, and also if you move an attendee by accident, it would be impossible to know which course to put the attendee back onto without the original course information, thus leading you back to a key based structure for documents.(But that's just my opinion).....
精彩评论