Domino 6.5 - close document in frameset - closes app - lotus-domino

I'm working on a Domino Client application that opens documents up in a frameset.
When I click the save button it does some lotus script validation, adds to history field and etc then finally does a save:
Sub Click(Source As Button)
Dim validate1 As Validation
Dim ws As New NotesUIworkspace
Dim s As New NotesSession
Dim uidoc As NotesUIDocument
Dim approverNames As String
Dim workflow1 As Workflow
Dim name1 As String
Dim names1 As String
Dim item1 As NotesItem
Dim history1 As History
Set uidoc = ws.CurrentDocument
Call uidoc.refresh
'===============================================
'Validation
'===============================================
Set validate1 = New Validation()
Call validate1.checkCustomer(uidoc.FieldGetText("Customer"))
Call validate1.checkEndUser(uidoc.FieldGetText("EndUser"))
Call validate1.checkShortProjectDescription(uidoc.FieldGetText("ShortProjectDescription"))
Call validate1.checkProjectName(uidoc.FieldGetText("ProjectName"))
Call validate1.checkProjectLocation(uidoc.FieldGetText("ProjectLocation"))
Call validate1.checkOperationCenter(uidoc.FieldGetText("BusinessUnit"))
Call validate1.checkSalesCenter(uidoc.FieldGetText("SalesCenter"))
Call validate1.checkMarketSegment(uidoc.FieldGetText("MarketSegment"))
Call validate1.checkSAPDate(uidoc.FieldGetText("SAPDate"))
Call validate1.checkRevision(uidoc.FieldGetText("Revision"))
Call validate1.checkValidityDate(uidoc.FieldGetText("ValidityDate"))
Call validate1.checkDateApproval(uidoc.FieldGetText("DateApproval"))
Call validate1.checkCurrencyUSD(uidoc.FieldGetText("CurrencyUSD"))
Call validate1.checkMargin(uidoc.FieldGetText("Margin"))
If validate1.displayErrorMessages() = 0 Then
'========================================================================
Call uidoc.FieldSetText("WhoHasApproved","")
Call uidoc.FieldSetText("ApproversNotified","")
Call uidoc.FieldSetText("SubmitDate",Cstr(Now))
Call uidoc.FieldSetText("Status","In Process")
'Add calls to workflow here....
Set workflow1 = New workflow("SAPFCD")
'Update History Field - Submitted for Processing by
Set history1 = New History(uidoc.Document)
Call history1.addTo("Submitted for Processing", uidoc.FieldGetText("CreatedBy"))
Set item1 = uidoc.Document.ReplaceItemValue("History" , history1.getDescription())
'Set ApproverList
names1 = workflow1.setApproverList(uidoc)
Call uidoc.FieldSetText("ApproverList",names1)
uidoc.Refresh
name1 = workflow1.setNextApprover(uidoc)
Call uidoc.FieldSetText("NextApprover", name1)
'========================================================================
'Add calls to workflow here....
Call uidoc.FieldSetText("Status","1st Peer")
uidoc.Save
uidoc.Close(True)
uidoc.Close(True)
End If
End Sub
and then proceeds to close the entire database and returns user to workspace.
What I want is to have the document saved and then return the user to a specified page in the frame set.
I attempted to add code like this to the QuerySave event, but does not work:
Sub Queryclose(Source As Notesuidocument, Continue As Variant)
Dim ws As New NotesUIworkspace
ws.OpenFrameSet("MainFrame")
ws.SetTargetFrame("Main")
ws.OpenPage("Saved")
End Sub
Any ideas on how I can save/close a UI document that is in a frame set without it closing the entire database.
Derek

Any specific reason why you have the document open within a frame of a frameset?
Usually you have a frameset for the outline and view and documents open on their own tab/window, this way when the code you have runs it only closes the doc.
**Update
Did some more testing and you can insert this after the uidoc.save and remove uidoc.close
Call ws.SetTargetFrame("your frame name here")
Call ws.ComposeDocument("","","your form name here",,,False)
I forgot to mention you should set the target frame back to "" when exiting the app, if you don't users might get error when other apps try to open up a frameset.

It should work fine if you only include one uidoc.close event instead of the two you have showing.
Also make sure none of the Form events PostSave/PostClose or QuerySave/QueryClose call a close event.

Related

Outlook Custom Form Script Won't Run

Since the most recent security update for Outlook my code won't run. Using Outlook 2010. Have a contact form with custom code behind. I click a custom button to open a post item in the History folder. The post item has custom code behind it to write information to a text file. Very important for this to run. Since a few days ago the code on the post item doesn't run anymore. But if I save the post item, close it and reopen it the code runs fine. What is happening and how do I fix it?
'this is the code on the contact form
Sub CallFromButton
'get the folder
Dim HistFolder
Set HistFolder = Application.Session.GetDefaultFolder(18).Folders("History")
'add a post item
Dim blgItem 'PostItem
Set blgItem = HistFolder.Items.Add("IPM.Post.ClientHistory2")
'set some information
blgItem.BillingInformation = "60000"
blgItem.UserProperties("ClientName") = item.FullName
blgItem.UserProperties("blgDate") = Now
blgItem.Display
'... more code
End Sub
'this is the code behind the post item
Sub Item_Open()
Dim LogPage
Set LogPage = Item.GetInspector.ModifiedFormPages("Log Item")
LogPage.Controls("ResumeBtn").Visible = False
LogPage.Controls("BoxDesc").SetFocus
Item.UserProperties("blgFileName") = "C:\Temp\12345.txt"
'... more code
End Sub
Function Item_Write()
'... more code
End Function
A recent Windows update caused this. You can either uninstall it, or wait for a fix from Microsoft: https://social.technet.microsoft.com/Forums/office/en-US/e6147cb8-fe1c-4d90-a65a-33b8a7b22a6d/june-security-patch-and-issue-with-custom-forms?forum=outlook

System.UnauthorizedAccessException only using multithreading

I wrote a code to parse some Web tables.
I get some web tables into an IHTMLElementCollection using Internet Explorer with this code:
TabWeb = IE.document.getelementsbytagname("table")
Then I use a sub who gets an object containing the IHTMLElementCollection and some other data:
Private Sub TblParsing(ByVal ArrVal() As Object)
Dim WTab As mshtml.IHTMLElementCollection = ArrVal(0)
'some code
End sub
My issue is: if I simply "call" this code, it works correctly:
Call TblParsing({WTab, LiRow})
but, if I try to run it into a threadpool:
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing), {WTab, LiRow})
the code fails and give me multiple
System.UnauthorizedAccessException
This happens on (each of) these code rows:
Rws = WTab(RifWT("Disc")).Rows.Length
If Not IsError(WTab(6).Cells(1).innertext) Then
Ogg_W = WTab(6).Cells(1).innertext
My goal is to navigate to another web page while my sub perform parsing.
I want to clarify that:
1) I've tryed to send the entire HTML to the sub and get it into a webbrowser but it didn't work because it isn't possible to cast from System.Windows.Forms.HtmlElementCollection to mshtml.IHTMLElementCollection (or I wasn't able to do it);
2) I can't use WebRequest and similar: I'm forced to use InternetExplorer;
3) I can't use System.Windows.Forms.HtmlElementCollection because my parsing code uses Cells, Rows and so on that are unavailable (and I don't want to rewrite all my parsing code)
EDIT:
Ok, I modified my code using answer hints as below:
'This in the caller sub
Dim IE As Object = CreateObject("internetexplorer.application")
'...some code
Dim IE_Body As String = IE.document.body.innerhtml
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {IE_Body, LiRow})
'...some code
'This is the called sub
Private Sub TblParsing_2(ByVal ArrVal() As Object)
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(ArrVal(0))
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
'...some code
I get no errors but I'm not sure that it's all right because I tryed to use IE_Body string into webbrowser and it throws errors in the webpage (it shows a popup and I can ignore errors).
Am I using the right way to get Html from Internet Explorer into a string?
EDIT2:
I changed my code to:
Dim IE As New SHDocVw.InternetExplorer
'... some code
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(IE.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {html, LiRow})
'... some code
Private Sub TblParsing_2(ByVal ArrVal() As Object)
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(ArrVal(0))
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
But I get an error PopUp like (I tryed to translate it):
Title:
Web page error
Text:
Debug this page?
This page contains errors that might prevent the proper display or function properly.
If you are not testing the web page, click No.
two checkboxes
do not show this message again
Use script debugger built-in Internet Explorer
It's the same error I got trying to get Html text into a WebBrowser.
But, If I could ignore this error, I think the code could work!
While the pop is showing I get error on
Dim domDoc As New mshtml.HTMLDocument
Error text translated is:
Retrieving the COM class factory for component with CLSID {25336920-03F9-11CF-8FD0-00AA00686F13} failed due to the following error: The 8,001,010th message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)).
Note that I've alredy set IE.silent = True
Edit: There was confusion as to what the OP meant by "Internet Explorer". I originally assumed that it meant the WinForm Webbrowser control; however the OP is creating the COM browser directly instead of using the .Net wrapper.
To get the browser document's defining HTML, you can cast the document against the mshtml.IHTMLDocument3 interface to expose the documentElement property.
Dim ie As New SHDocVw.InternetExplorer ' Proj COM Ref: Microsoft Internet Controls
ie.Navigate("some url")
' ... other stuff
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(ie.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML
End Edit.
The following is based on my comment above. You use the WebBrowser.DocumentText property to create a mshtml.HTMLDocument.
Use this property when you want to manipulate the contents of an HTML page displayed in the WebBrowser control using string processing tools.
Once you extract this property as a String, there is no connection to the WebBrowser control and you can process the data in any thread you want.
Dim html As String = WebBrowser1.DocumentText
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(html)
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim tables As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
' ... do something
' cleanup COM objects
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(body)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(tables)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc2)

NotesDocument.save() causing loss of rich text formatting

I have following code in an lotusscript agent that removes attachments from NotesDocuments. But NotesDocument.save() causes loss of rich text formatting (font, color). Is there any way to retain the formatting?
Sub removeAttachments_v2(doc As NotesDocument)
Dim session As NotesSession
Dim rtitem As Variant
Dim filename As String
Dim ans As Variant
Set session = New NotesSession
Dim richstyle As NotesRichTextStyle
Set richstyle = session.CreateRichTextStyle
richstyle.NotesColor = COLOR_BLUE
If doc.HasEmbedded Then
Set rtitem = doc.getfirstitem("Body")
If (rtitem.type = RICHTEXT) Then
ForAll object In rtitem.EmbeddedObjects
If (object.Type = EMBED_ATTACHMENT) Then
filename = object.source
Call object.remove
Call rtitem.AddNewLine( 2 )
Call rtitem.AppendStyle(richstyle)
Call rtitem.AppendText( "Attachemnt removed: " & filename )
Call doc.Save( True, True , True )
End If
End ForAll
End If
End If
End sub
Edit1: Initialize function
Sub Initialize
Dim db As New NotesDatabase("","")
Dim col As NotesDocumentCollection
Dim doc As NotesDocument
Call db.Open("", "C:\this\is\db\dir\test.nsf")
Set col = db.Alldocuments
Set doc = col.Getfirstdocument()
While Not ( doc Is Nothing )
Call RemoveAttachments_v2(doc)
Call doc.Save(False, False, False)
Set doc = col.GetNextDocument( doc )
Wend
End Sub
Despite of the fact, that you save the document for every attachment I cannot find any reason, why this should happen. I just copied your code in an agent, and it removes the attachments as desired and appends the text in blue...
No formatting is lost...
The error has to be somewhere else in your code, probably in the calling function.
OLD ANSWER (wrong due to own tests, just kept here as history):
The Problem here most probably is: you defined rtitem as Variant. And
getfirstitem gets you a NotesItem instead of a NotesRichtextItem, so
when saving, it is converted to a "plain Text" item.
Most probably you used Variant instead of NotesRichtextItem, because
there are Mime- mails where defining the variable as NotesRichtextItem
will cause an "Type Missmatch" or similar error. As long as you do not
write anything back this is OK.
As Mime Mails need complete different handling to achieve your goal,
you should first fix the code for pure NotesRichtextItems by using the
right type, and then write another code- branch for handling Mime-
items

lotus notes start session

I'm looking for a way to start Lotus Notes and control its utilisation from a vb.net project.
By controlling I mean litle things like getting the window position, closing active document and other stuff.
But the main objective is to start a session.
I'm confused because I tried to use the Lotus Notes Automation Classes dll and nothing worked well...
If anyone had some tips for me, I would apreciate a lot!
Thanks! (by the way, sorry english is not my main language)
In Notes speak, a session is a backend object, not a UI object. What you describe (changing window position, closing active window, etc) is UI functionality.
Notes supports COM, and you have full access to all backend classes. But you don't have access to the UI classes.
Why would you want to automate the actual Notes client? If you describe what you are ultimately wanting to do, perhaps we can help. I am sure that the correct way to solve what you are trying to do is to use the backend classes...
I found a way to start Notes, I needed to use process:
Private Sub StartNotes()
Dim p As Process = New Process()
p.StartInfo.FileName = "C:\Program Files\Notes\notes.exe"
p.StartInfo.Arguments = ""
p.Start()
End Sub
I automate it after using backend classes from lotus and domino dll
Sub Send_Email_via_Lotus_Notes()
Dim Maildb As Object
Dim MailDoc As Object
Dim Body As Object
Dim Session As Object
'Start a session of Lotus Notes
Set Session = CreateObject("Lotus.NotesSession")
'This line prompts for password of current ID noted in Notes.INI
Call Session.Initialize
'or use below to provide password of the current ID (to avoid Password prompt)
'Call Session.Initialize("<password>")
'Open the Mail Database of your Lotus Notes
Set Maildb = Session.GETDATABASE("", "D:\Notes\data\Mail\eXceLiTems.nsf")
If Not Maildb.IsOpen = True Then Call Maildb.Open
'Create the Mail Document
Set MailDoc = Maildb.CREATEDOCUMENT
Call MailDoc.REPLACEITEMVALUE("Form", "Memo")
'Set the Recipient of the mail
Call MailDoc.REPLACEITEMVALUE("SendTo", "Ashish Jain")
'Set subject of the mail
Call MailDoc.REPLACEITEMVALUE("Subject", "Subject Text")
'Create and set the Body content of the mail
Set Body = MailDoc.CREATERICHTEXTITEM("Body")
Call Body.APPENDTEXT("Body text here")
'Example to create an attachment (optional)
Call Body.ADDNEWLINE(2)
Call Body.EMBEDOBJECT(1454, "", "C:\dummy.txt", "Attachment")
'Example to save the message (optional) in Sent items
MailDoc.SAVEMESSAGEONSEND = True
'Send the document
'Gets the mail to appear in the Sent items folder
Call MailDoc.REPLACEITEMVALUE("PostedDate", Now())
Call MailDoc.SEND(False)
'Clean Up the Object variables - Recover memory
Set Maildb = Nothing
Set MailDoc = Nothing
Set Body = Nothing
Set Session = Nothing
End Sub

how to refer back to created browser instance

I create a browser like so, and manually navigate to the web page I need to be. I intend to automatically pull certain elements once I get to the page I need to be on via a seperate macro
Sub Test()
Set CAS = New SHDocVw.InternetExplorer ' create a browser
CAS.Visible = True ' make it visible
CAS.navigate "http://intraneturl"
Do Until CAS.readyState = 4
DoEvents
Loop
This works fine, then I do
Public Sub Gather
Set HTMLDoc2 = CAS.document.frames("top").document
Call Timer1
With HTMLDoc2
.getElementById("tab4").FirstChild.Click
End With
Call Timer2
Dim fir, las, add1, add2, cit, stat, zi As String
Dim First As Variant
Dim Last As Variant
Dim addr1 As Variant
Dim addr2 As Variant
Dim city As Variant
Dim Thisstate As Variant
Dim Zip As Variant
Call Timer2
Set HTMLDoc = CAS.document.frames("MainFrame").document
Call Timer2
With HTMLDoc
First = .getElementsByName("IndFirst")
Last = .getElementsByName("IndLast")
addr1 = .getElementsByName("txtAdd_Line1")
addr2 = .getElementsByName("txtAdd_Line2")
city = .getElementsByName("txtAdd_City")
Thisstate = .getElementsByName("cmb_Add_State")
Zip = .getElementsByName("txtAdd_Zip")
End With
fir = First.Value
las = Last.Value
add1 = addr1.Value
add2 = addr2.Value
cit = city.Value
stat = Thisstate.Value
zi = Zip.Value
'navigate back to start page
With HTMLDoc2
.getElementById("tab3").FirstChild.Click
End With
End Sub
This works the first time, but after the first time, I get "Object variable or with block variable not set" when trying to run the gather() sub again, on a different web page that contains similar information. Any Ideas as to what im doing wrong?
"The error "object variable or with block variable not set" occurs on: Set HTMLDoc2 = CAS.document.frames("top").document the second time i try running Gather()."
This is probably one of three things:
CAS is no longer an object
To check this, set a breakpoint on the line, press ctr+G in the VBA Editor and type ?CAS Is Nothing in the Immediate Window; the result should be False; if it is True CAS is no longer an object
Like Daniel Dusek suggested, make sure CAS.document.frames("top") is an actual element on the page.
To check this, open the webpage you are trying to script, press F12 in Internet Explorer, click on the arrow in the toolbar and click on the "top" frame element in the webpage, switch back to the Developer Tool and look at the line highlighted. Make sure the frame element is named "top".
The HTML hasn't fully loaded when you try to reference the frame element. Set a longer delay or a loop.
i.e. (untested):
Do Until HtmlDoc2 Is Nothing = false
Set HTMLDoc2 = CAS.document.frames("top").document
Loop
Maybe the more important question is why manually navigate to another page? Can't you automate that part of your process too?