Set a doc link of a new document in another DB - lotus-notes

I have an action in one database that will create a new doc in another database. It would be very handy if (at least) the new document contains a doc link to the original document right after saving the new document.
For that purpose I create a calculated RT item on the new doc's form and insert a doc link in the Querysave event by script. But the RT item is always empty. What would be the basic steps to get this working ?
(Notes 8.5)

You can use rtitem.AppendDocLink(doc, "Title") to create the doc link you want.
rtitem is the RichText item of the new created document.
doc is the currently selected document in first database which has the button for creating the new document.
There is a little challenge to get a satisfying solution. If we put the following lines into button which creates the new document
...
Set docSelected = session.DocumentContext
Set docNew = dbTarget.CreateDocument()
Set rtitem = docNew.CreateRichTextItem("Doclink")
Call rtitem.AppendDocLink(docSelected, "Title")
Call docNew.Save(True, True) ' <--- that is necessary :(
...
Call workspace.EditDocument(True, docNew)
then it creates a link in new document and it is visible immediately. BUT, it works only if we save the new document. This might be not a good idea because the document stays in database even when the user just closes the document without saving.
So, we have to look for another solution.
Let's turn in around and let the new document create the doc link after it was saved by user. For this, we have to give the new document the information about database and UniversalID of the link document. We do that in button which creates the new document
Set docNew = dbTarget.CreateDocument()
docNew.LinkDb = session.CurrentDatabase.FilePath
docNew.LinkUniversalID = session.DocumentContext.UniversalID
In new document's form we create a computed RichText field "Doclink". When is a good time to fill the field with the link? As I figured out is the Querysave event too early. The field "Doclink" gets damaged during standard document save. The solution is to wait until Queryclose and to set the link there. But, we should to do it only if user saved the document and only one time. That's why we have to monitor the Querysave event and set a flag there that user saved document. At Queryclose we create the link, delete the fields "LinkDb" and "LinkUniversalID" and save the document again if the save flag is set and document contains field "LinkDb".
Here is the code for form:
(Declarations)
Dim bSaved As Boolean
Sub Initialize
bSaved = False
End Sub
Sub Querysave(Source As Notesuidocument, Continue As Variant)
bSaved = True
End Sub
Sub Queryclose(Source As Notesuidocument, Continue As Variant)
If bSaved Then
Dim session As New NotesSession
Dim doc As NotesDocument
Dim dbLink As NotesDatabase
Dim docLink As NotesDocument
Dim rtitem As NotesRichTextItem
Set doc = Source.Document
If doc.HasItem("LinkDb") Then
Set dbLink = session.GetDatabase(doc.ParentDatabase.Server, doc.LinkDb(0), False)
Set docLink = dbLink.GetDocumentByUNID(doc.LinkUniversalID(0))
doc.RemoveItem("Doclink")
Set rtitem = doc.CreateRichTextItem("Doclink")
Call rtitem.AppendDocLink(docLink, "Link")
doc.RemoveItem("LinkDb")
doc.RemoveItem("LinkUniversalID")
Call doc.Save(True, True)
End If
End If
End Sub
It is important to delete the RichText field and create it new before we add the doc link.

one option is to save the NotesDocumentUNID, the database path and the server from the old document in three fields in the new Document.
Then create in the design of the new document an button, which opens the old Document in the old database over these two fields.
create new document
Dim workspace As New NotesUIWorkspace
Dim session As New NotesSession
Dim oldDB As NotesDatabase
Dim oldDoc As NotesDocument
Dim newDoc As NotesDocument
Dim newDB As NotesDatabase
Set oldDB = session.CurrentDatabase
Set oldDoc = workspace.CurrentDocument.Document
Set newDB = session.GetDatabase("SERVER", "FILE")
Set newdoc =newdb.CreateDocument
newdoc.oldDocUNID= olddoc.UniversalID
newdoc.oldDBpath=oldDB.FilePath
newdoc.oldDBServer = oldDB.Server
Call newdoc.save(True,False,True)
Create Button to open oldDoc
Sub Click(Source As Button)
Dim workspace As New NotesUIWorkspace
Dim session As New NotesSession
Dim newdoc As notesdocument
Dim oldDB As notesdatabase
Dim oldDoc As notesdocument
Set newdoc = workspace.CurrentDocument.Document
Set oldDB = session.GetDatabase(newdoc.oldDBServer(0),newdoc.oldDBpath(0))
Set oldDoc = oldDB.GetDocumentByUNID(newDoc.oldDocUNID(0))
Call workspace.EditDocument(True,oldDoc)
End Sub
DocLink option
Dim workspace As New NotesUIWorkspace
Dim session As New NotesSession
Dim oldDB As NotesDatabase
Dim oldDoc As NotesDocument
Dim newDoc As NotesDocument
Dim newDB As NotesDatabase
Dim rtitem As NotesRichTextItem
Set oldDB = session.CurrentDatabase
Set oldDoc = workspace.CurrentDocument.Document
Set newDB = session.GetDatabase("SERVER", "FILE")
Set newdoc =newdb.CreateDocument
Set rtitem = newdoc.CreateRichTextItem("body")
Call rtitem.AppendDocLink(olddoc, "title")
Call newdoc.save(True,False,True)

Related

Copy document is saved but original not changes status using lotusscript

I have two document which is original and copy document. When I save copy, original will changes status too.
Follow up by my other question Save copy document and change status field for copy document and original document using lotusscript button. Below are my code.
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Dim activeDoc As NotesDocument
Dim view As NotesView
Dim keys(1) As String
'// Set database and doc
Set db = session.CurrentDatabase
Set uidoc = workspace.CurrentDocument
Set doc = uidoc.Document
keys(0) = doc.PTagNo(0)
keys(1) = "Lock"
Set view = db.GetView("Computer")
vpswd = Inputbox$("Pls input code to save :")
If vpswd = "o" Then
Set activeDoc= view.GetDocumentByKey(keys, True)
If Not activeDoc Is Nothing Then
If activeDoc.PStatus(0) = "Lock" Then
activeDoc.DocumetId = doc.UniversalID
Call activeDoc.ReplaceItemValue("PStatus", "Inactive")
Call activeDoc.Save(True, False)
End If
End If
Call uidoc.FieldSetText("PStatus" , "Active")
Call uidoc.FieldSetText("SaveOptions" , "1")
Call uidoc.Save
Call uidoc.Close
Else
Msgbox "Wrong Code"
Exit Sub
End If
End Sub
I already set variable and successfull saved. When I saved, Copy document is saved and change status to Active, but for Current document which currently with "Lock" status, did not change to "Inactive" status. Can anyone help me? Is there any error that I have made inside coding? Your help really appreciate. Thanks!
I've solved this question. For my problem, I do not set TagNo as my first column. So I need to created new view with two column which is TagNo and Status. Set both column as ascending.

Click button to copy document to another view

I have two views which are Computer and Draft. I create a button in computer view and it is to create a copy of computer document to draft view.
Below is my button code. When I click the button, it said "Object variable not set"
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
Dim view As NotesView
Set db = session.CurrentDatabase
Set view = db.GetView( "Draft" )
Set doc = dc.GetFirstDocument()
Set dc = db.AllDocuments
While Not (doc Is Nothing)
Call doc.CopyToDatabase(db)
Set doc = dc.GetNextDocument(doc)
Wend
End Sub
Can anyone help me? And can I ask, do I need to insert any formula inside Draft view? Thanks for any help!
Update Question
I have found the problem and fixed my code. But when I click the button, it copies all document and shows on both views. How can I want a copy of the document in Draft only selected document? For example, the "Active" document only? Thanks!
Views do not "contain" documents. Documents are in a database, and views show selected documents, using a SELECT formula. If your SELECT matches all documents, all documents will show up. That formula decides which documents are part of the view.
If view A contains your document and view B doesn't, you have to adapt the SELECT formula in view B so that it will match the document.
E.g. if you want your current document to show up in view B, you could add a value to the current document, like DocumentViews, and set it to "B", and set the SELECT formula of view B to SELECT DocumentViews="B".
Now, if you want to do something with the document that's currently selected in a view, you can use the NotesDatabase.UnprocessedDocuments property. It contains a list of all selected documents.
Dim ns As New NotesSession
Dim db As NotesDatabase
Set db= ns.CurrentDatabase
Dim dc As NotesDocumentCollection
Set dc= db.UnprocessedDocuments
Dim doc As NotesDocument
Set doc= dc.GetFirstDocument
Dim newdoc As NotesDocument
Do Until doc Is Nothing
' you might have to check the status of the current document before copying...
Set newdoc= doc.CopyToDatabase(db)
Call newdoc.ReplaceItemValue("Status", "Draft")
Call newdoc.Save(True, False)
Set doc= dc.GetNextDocument(doc)
Loop

Set uidoc = workspace.CurrentDocument crash

I try to create pdf file with NotesDocumentCollection(a collection) or a notesuidocument
problem - When i try with a base with NotesDocumentCollection, it
works to create a pdf in the document but i can't extract them... i
can't see
problem - when i try with a base with notesuidocument : it's crash
!!
I want to use the same code with the two type of base...
This is my code :
Public Sub sauverPdfPiecesJointes
Dim s As NotesSession
Dim db As NotesDatabase
Dim colldoc As NotesDocumentCollection
Dim doc As NotesDocument
Dim resultat As String
Dim monRepertoire As Repertoire
Dim monXml As Xml
Dim fichierExiste As Integer
Dim i As Integer
Dim uidoc As NotesUIDocument
Dim workspace As New NotesUIWorkspace
Dim flagUidoc As Integer
Dim nb As String
Dim vue As NotesView
Set s = New NotesSession()
'initialisation de la variable
totalResultat = ""
Set db = s.CurrentDatabase
dbFilePath = db.FilePath
dbFileName = db.FileName
'initialisation du compteur
i = 0
flagUidoc = 0
'creation du pdf du document
Set uidoc = workspace.CurrentDocument <==== CRASH HERE
Set colldoc = db.UnprocessedDocuments
If (uidoc Is Nothing) Then
'plusieurs documents sont sélectionnés
If (colldoc.Count > 0) Then
Set doc = colldoc.GetFirstDocument
While Not doc Is Nothing
(creation du pdf....) (...)
i = i + 1
Set doc = colldoc.GetNextDocument(doc)
Wend
End If
' l'utilisateur est dans le document
Else
flagUidoc = 1
'si l'utilisateur a fait une modification
Set doc = uidoc.Document
nb = doc.Universalid
Call uidoc.Close(true)
Delete uidoc
Set doc = db.Getdocumentbyunid(nb)
(creation du pdf....) (...)
Set vue = db.Getview(nomVue)
Call vue.Refresh()
End If
I will update the question if you post more details based on this answer.
Go to your IBM_TECHNICAL_SUPPORT folder and find the latest NSD.
Open it and look for the word FATAL. This will give you the crash stack. Add that to your question and it will give more details.
To understand in more detail there is a wiki article explains how to determine crashing code (although you are pointing to it, frontEnd classes don't aways behave how you expect them).
As for NotesUIWorkspace. There were issues in earlier versions of Notes (I think R8.0, or possibly R7). The issue was if you opened a Notes client but didn't open a database before executing the code, the NotesUIWorkspace would not initialise fully. It's a edge case, so not obvious.
You can also try using other methods on the NotesUIWorkspace object before touching the document. See if it crashes as well.
Other then this, for your code to work it also needs to have a document in context in the front end. So if you have not selected a document, or have a document open then it should fail (but not crash).
You can also use the LND tool to get more details on the nature of the crash.
After analyzing your code I assume that
it is an agent
with target option "All selected documents" and
shall work on current opened document or on selected documents in view
The usual pattern for this kind of jobs is to look
first for selected documents in view with database.UnprocessedDocuments and if no documents are selected
second for opened document in UI or for marked document in view with session.DocumentContext
This way you don't need a NotesUIDocument and with following code example you have to call your pdf creation code only once:
Dim session As New NotesSession
Dim db As NotesDatabase
Dim col As NotesDocumentCollection
Dim doc As NotesDocument
Set db = session.CurrentDatabase
Set col = db.UnprocessedDocuments
If col Is Nothing Then
Set doc = session.DocumentContext
Else
Set doc = col.GetFirstDocument
End If
While Not doc Is Nothing
'
' create pdf for doc here ....
'
If col Is Nothing Then
Set doc = nothing
else
Set doc = col.GetNextDocument(doc)
End If
Wend

Lotus notes - refering to a doc. from a NotesDocumentCollection

I have a view which on top there is a button called Delete
I want to delete all the selected documents from the view; for this I used:
Dim session As New NotesSession
Dim workspace As New NotesUIWorkspace
Dim database As NotesDatabase
Dim documentCollection As NotesDocumentCollection
Set database=session.CurrentDatabase
Set documentCollection=database.UnprocessedDocuments
If documentCollection.Count=0 Then
Msgbox "No documents selected ",,"warning"
Else
userChoice=Msgbox ("Delete" & Cstr(documentCollection.Count) & " documents?",64+100, _
"Confirm...")
If userChoice=6 Then
Call documentCollection.RemoveAll(True)
Call workspace.ViewRefresh
End if
But, what if I want to delete only some docs ( from all selected docs. from view ) which have let say Value = YES where Value is a text field inside the document?
I tried declaring:
Dim ui As NotesUIDocument
Dim doc As NotesDocument
Set doc=ui.document
But I get the message: Object variable not set. So I guess I have to refer to a document using the NotesDocumentCollection? How?
Thanks for your time!
Your Error Message has nothing to do with your question... The Error Message comes from setting doc form an unitialized uidoc. You need to have a Set ui = ws.CurrentDocumentsomewhere in your code, and of course declare ws: Dim ws as New NotesUIWorkspace
But for your question you don't need an ui- document at all. To delete just some of the selected documents, you cycle through the collection and delete just the documents that match your criteria:
Dim doc as NotesDocument
Dim nextDoc as NotesDocument
Set doc = documentCollection.GetFirstDocument()
While not doc is Nothing
Set nextDoc = documentCollection.GetNextDocument(doc)
if doc.GetItemValue( "Value" )(0) = "Yes" then
call doc.Remove(True)
end if
Set doc = nextDoc
Wend
Or you reduce the collection to just contain the documents that match your criteria and then delete the whole collection:
Call documentCollection.FTSearch("[Value] = Yes",0)
Call documentCollection.RemoveAll()
But take care: The collection is reduced with a FTSearch, that might also get "Yes of course" or "Ye" depending on the setting of the FT Index of the database -> Not very reliable.
You need to loop through the documents in the document collection and then process them individually. Here's an example loop that uses your documentCollection variable:
Dim doc As NotesDocument
Set doc = documentCollection.GetFirstDocument
While Not(doc Is Nothing)
' Do stuff
' Get next document
Set doc = documentCollection.GetNextDocument(doc)
Wend

Filter Process script Library

I have a form called Approver in "Approver" db.
The form has two editable text fields: Office and Group. It also has a dialog list field superior1.
The superior1 dialog list field should show the staff details filtered based on office & group:
if office = TSP & group = HR from the approver form, then shud filter the staffs based on these fields group" & "office" with the "Staff info" view of another database "TSP_Staff" and show in superior1.
But it is not getting filtered for me. :(
I am new to this tech, so I am confused and have no one to help me in this. This is the script I used:
for the superior1 field:
Sub Entering(Source As Field)
Dim s As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim uidoc As NotesUIDocument
Dim doc As Notesdocument
Dim work As New NotesUIWorkspace
Dim workspace As New NotesUIWorkspace
Dim sname As String
Dim consr As String
Dim cview As notesview
Set db = s.CurrentDatabase
Set uidoc = work.CurrentDocument
Set uidocs = workspace.currentdocument
Set cview = db.getview("(Application)")
'etype = uidoc.FieldGetText("Office")
'ftype = uidoc.FieldGetText("Group")
etype = "TSP"
ftype = "TSP1-G"
If(etype <> "" And ftype <> "") Then
Call filter
End If
Set view = db.getview("(x_search_staff)")
Set doc = view.GetDocumentByKey (uidoc.fieldgettext("Superior1"),True)
If doc Is Nothing Then
Msgbox "There is no previous transaction please select new trasaction.", 16, "Information"
Call uidoc.FieldClear("Superior1")
Call uidoc.gotofield ("Group")
Call uidoc.gotofield ("Office")
continue = False
Exit Sub
End If
Call uidoc.Refresh
End Sub
from the script library ...
Sub filter
Dim s As New notessession
Dim w As New notesuiworkspace
Dim uidoc As notesuidocument
Dim doc As notesdocument, newdoc As notesdocument, d As notesdocument, dd As notesdocument
Dim doc1 As NotesDocument, newdoc1 As NotesDocument
Dim dc As notesdocumentcollection
Dim bc As notesdocumentcollection
Dim view As notesview, v As notesview
Dim db As notesdatabase
Dim nextdoc As NotesDocument
Dim cview As notesview
Dim cnview As NotesView
Dim get_db As New notesdatabase(gsserver2, gspath2 & "Master\TSP_Staff.nsf")
Set db = s.currentdatabase
Set view = get_db.getview("(Staff Info)")
Set cview = db.getview("(x_search_staff)")
Set cnview = db.getview("(x_superior)")
Set uidoc=w.CurrentDocument
'To delet searched previous datas from form2 ----------------------------------------
Print "Please wait ..."
key = "Approver2"
Set v = db.getview("(x_delete_2)")
Set dc = v.GetAlldocumentsByKey(key,True)
'Set bc = v.GetAlldocumentsByKey(key,True)
'Call bc.RemoveAll(True)
Call dc.RemoveAll(True)
Call cview.Refresh
Call view.Refresh
Call cnview.Refresh
Call v.Refresh
'To start searching process based on Superior1 --------------------------------------
'f1= uidoc.FieldGetText("Office")
f1= uidoc.FieldGetText("Group")
'f1 = "TSP1-G"
Set dc = view.getalldocumentsbykey(f1, True)
'Set bc = view.getalldocumentsbykey(f2, True)
For b =1 To dc.count
Set doc = dc.getnthdocument(b)
Set newdoc = doc.copytodatabase(db)
'For c =1 To bc.count
'Set doc1 = bc.getnthdocument(b)
'Set newdoc1 = doc.copytodatabase(db)
If doc.form(0) = "Approver" Then
'If doc1.form(0) = "Approver" Then
newdoc.form = "Approver2"
'newdoc1.form = "Approver2"
'End If
End If
newdoc.save True, True
' Next
'newdoc.save True, True
'Next
Call w.viewrefresh
Call cview.Refresh
Call v.Refresh
Call cnview.Refresh
Call view.Refresh
Print "Process Completed....."
End Sub
if u got another way for this requirement temme in stepwise wat to do... or else... chk out ma script for errors... hope u help me :( today due date for this task...
I'm not sure how smart it is to filter the documents shown in a view by deleting documents from a database :)
My suggestion is to first post the code properly. This is simply unreadable.
How to display only subset of documents in your dialog list?
Create a hidden field on your form (you'll fill it with values you want displayed in the list using your code).
And then, on your dialog list field properties, second tab, set choices option to be "Use formula for choices" and set it to be the hidden field name.
Ask if you need more help...
Your code is very hard to follow, but if I understand your intention and parts of the filter function (does it even compile?) you could replace all of the code with this #dblookup-based formula in "use formula for choices" section of superior1 properties:
#dblookup("":"ReCache";"ServerName":"foo\Master\TSP_Staff.nsf";"(Staff Info)";Group;NameOfInterestingField);
You might want to add a #sort and/or #unique around it if the view contain duplicate values, and you might want to add the keyword [FAILSILENT] if some groups should result in an empty list.
An even simpler method could be to configure superior1 to use view dialog for choices.

Resources