« Ytria Domino Tools - Free Keys for the Summer! | Main| DC Notes User Group Meeting This Thursday! »

Reopen Parent Database After Closing Document Opened Via Doclink

QuickImage Category

So you receive that daily automated email from the Task Tracking Notes Database telling you what tasks are assigned to you. Helpfully, it includes a doclink back to each corresponding task document listed in the email. Unfortunately, after you've clicked on a link, done whatever you wanted to that document, and closed it again, you're right back in the email message, when you probably would rather be looking at the Task Tracking db instead. Even better, you'd like to see the document you just closed highlighted in the view.

Years ago I wrote what in retrospect was some overly complex Lotusscript to reopen the database after a document closed, if it had been opened via doclink. More recently, I took another look at the problem and discovered what has to be the most poorly named @Command there is: @GoUpLevel. Ok, so it's not *that* bad, but it's far from obvious what this thing does.

Once I knew what I was looking for, I discovered this little code gem on Notes.net posted by the Late Great Bill Ernest back in 2003:

UNID := @Text(@DocumentUniqueID);
@Command([GoUpLevel]);
@Command([OpenDocument]; "0"; UNID);
@Command([FileCloseWindow])

Update: I tweaked Bill's code a bit to avoid raising an "Entry not found in Index" error if you close a window that is not in the foreground by clicking on the "x" on its tab. For example, with several documents open in my tracking db, but with my Inbox currently displayed, if I try to close one of those documents without first switching to it, the error is raised.

Another Update 9/1/06: With the benefit of some good user testing, I've revised the code even further to trap for more errors, and added comments:

REM {Traps error when new document is closed without saving};
@If(@IsNewDoc; @Return(""); @Success);
UNID := @Text(@DocumentUniqueID);
UpLevel := @Command([GoUpLevel]);
REM {Next line will trap error raised when closing document };
REM {using it's Tab's X, and the db is not currently in focus};
@If(@IsError(UpLevel); @Return(""); @Success);
OpenDoc := @Command([OpenDocument]; "0"; UNID);
REM {Error trapping just in case...};
@If(@IsError(OpenDoc); @Return(""); @Success);
CloseWindow := @Command([FileCloseWindow]);
REM {Error trapping just in case...};
@If(@IsError(CloseWindow); @Return(""); @Success)

Although Bill suggests putting the code behind an Action Button (probably something labeled "Close"), you can also put it in the form's QueryClose event so it works even if you close the document by hitting escape or clicking the "X" on the document's tab.

In addition, I've found the code works well even when the document wasn't opened via a doclink. Say for example you have opened several documents from the same view, and have been switching between them and the view itself. Perhaps you also have other windows open from other databases, your mail, etc. Normally, when you close one of those open documents, what you see next is whatever window was last open. However when this code is used, you will instead be returned to the document's parent database/view, whether still open or not, with the focus on the document just closed. This is probably closer to the behavior most users would naturally expect, and certainly is far more logical in that it maintains the current context so the user doesn't have to fumble around looking for the correct window. Put simply, you may want to make this a standard part of many of your Notes client forms.

I haven't had time to perfect a completely Lotusscript approach to achieve the same effect, which would be useful since many forms already have other Lotusscript code in their QueryClose events. However, this is probably not necessary since you can simply create a special subform with just the @Function code in the Queryclose, and leave your other QueryClose events alone. If you have done this already feel free to share and I'll give you the appropriate credit. I have been able to figure out the "reopen the database if doclink was used" part, but not the document focus aspect. Here's what I have so far:

Sub Queryclose(Source As Notesuidocument, Continue As Variant)
Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim uiview As NotesUIView

Set uiview = ws.CurrentView
If uiview Is Nothing Then
Set db = Source.Document.ParentDatabase
Call ws.OpenDatabase( db.Server, db.FilePath)
End If

End Sub

Summary/Conclusion

Implementation basically boils down to a 2-step procedure:

Step 1: Place the following code in the QueryClose event of a form, or of a special subform that can be dropped on any form:

REM {Traps error when new document is closed without saving};
@If(@IsNewDoc; @Return(""); @Success);
UNID := @Text(@DocumentUniqueID);
UpLevel := @Command([GoUpLevel]);
REM {Next line will trap error raised when closing document };
REM {using it's Tab's X, and the db is not currently in focus};
@If(@IsError(UpLevel); @Return(""); @Success);
OpenDoc := @Command([OpenDocument]; "0"; UNID);
REM {Error trapping just in case...};
@If(@IsError(OpenDoc); @Return(""); @Success);
CloseWindow := @Command([FileCloseWindow]);
REM {Error trapping just in case...};
@If(@IsError(CloseWindow); @Return(""); @Success)

Step 2: WARNING - If you have other Queryclose code (typically Lotusscript) running in other subforms, etc., you MUST put error trapping into those events or you will see the "Entry not found in index error". Here's an example:

Sub Queryclose(Source As Notesuidocument, Continue As Variant)
On Error Goto FINISH
'This code will ensure that upon returning to a view from which this document was opened, the view will refresh
'in order to show/not show and/or update itself based on any edits to this document

Dim ws As New notesuiworkspace

Call ws.Viewrefresh()
FINISH:
End Sub

One concern I have about the this technique is how it will interact with other events like the PostOpen of a database or a view, for example. It can also open additional view windows if you manipulate or switch the view after opening the document. It can also get annoying to be brought back to the view repeatedly if you have several documents to close in rapid succession. You'll need to experiment a bit to see what works in your application. I do think, however, that it should work fine in most cases. If you try it out, please post a comment here to let me know whether or not you ran across any problems.

Comments

1 - I am trying to archive some documents (with the help of a Agent for archiving ) to a database i am using the beloce code but i think i have a problem in the BOLDED line of the code pls look and help
If doc.EffDate_1(0) < 01/01/2005 Then
Set Newdoc = archiveDb.CREATEDOCUMENT
Call doc.CopyToDatabase(NewDoc)
NewDoc.DateCreated = doc.Created
NewDoc.Save True, True
Call doc.Remove(True)
Ctr = Ctr + 1.0
End If

2 - Sure thing Matt. BTW - Check out the subforms in the databases you're using, and you'll actually find a "Reopen Database Subform" already there. I don't think I had put it on the form, but you could simply rip out its existing queryclose code, replace it with what's here, and drop it in. Then you can see the ugly Lotusscript its replacing .

3 - thanks fo that tip, I used to do that in the R3 days (with out the uplevel code).

Thanks for the other info this week regarding structure and planning, I will likely be putting those into production next week


Your Host

KevinPettitt.jpg
Kevin Pettitt View Kevin Pettitt's profile on LinkedIn

Tools I Use

Idea Jam

Subscribe to This Blog

 Full Posts  Comments

MyYahoo
netvibes Add to Netvibes

Contact

Hosted by

OpenNTF

Disclaimer

This site is in no way affiliated, endorsed, sanctioned, supported, nor blessed by Lotus Software nor IBM Corporation, nor any of my past or future clients (although they are welcome to do so). The opinions, theories, facts, etc. presented here are my own and in no way represent any official pronouncement by me on behalf of any other entity.

© 2005-2017 Kevin Pettitt - all rights reserved as listed below.

Creative Commons License
Unless otherwise labeled by its originating author, the content found on this site is made available under the terms of an Attribution / NonCommercial / ShareAlike