lotus notes domino designer text field contains special characters? - lotus-notes

My Lotus notes field allows special characters to be stored in the text box for example Franco Martínez, José Ramó this name has special character í, é, ó How do i not allow user to paste such character ?
Also, when i create a view can I convert this to a simple string using a method so that it does not contain special characters ?

Over the input validation of an field you can use a #Fomular to post an failure when the User use one of these characters. Use something like this
#If( #Contains(Field_1;"í");#Failure("no í");#Contains(Field_1;"é");#Failure("no é");#Contains(Field_1;"ó");#Failure("no ó");#Success)
If you like to change the characters of exsitings doc, you can use an LS Agent which change characters of the marked documents in a view.
Dim session As New NotesSession
Dim doccol As NotesDocumentCollection
Dim doc As NotesDocument
Dim eval As variant
Set doccol =session.Currentdatabase.Unprocesseddocuments
If doccol.Count =0 Then
MsgBox "please mark docs" ,0, "please mark docs"
Exit sub
End If
Set doc = doccol.Getfirstdocument()
Do Until doc Is Nothing
eval = Evaluate({#Replacesubstring(Field_1;"í":"ó":"é";"i":"o":"e")}, doc)
Call doc.Replaceitemvalue("Field_1", eval)
Call doc.Save(true,false, true)
Set doc = doccol.Getnextdocument(doc)
Loop
To change the characters in a view column just take
#Replacesubstring(columnvalue;"í":"ó":"é";"i":"o":"e")

Related

Change built-in Document properties without opening

I am attempting to run the below line of code in a sub. The purpose of the sub overall is to automatically create agendas for recurring meetings, and notify the relevant people.
'Values for example;
MtgDate = CDate("11/06/2020")
Agenda ="Z:\Business Manual\10000 Management\11000 Management\11000 Communications\Operations Meetings\11335 - OPS CCAR Performance Review Agenda 11.06.20.docx" 'NB it's a string
'and the problematic line:
Word.Application.Documents(Agenda).BuiltinDocumentProperties("Publish Date") = MtgDate
Two questions:
1) Can I assign a document property just like that without opening the document? (bear in mind this vba is running from an excel sheet where the data is stored)
2) Will word.application.documents accept the document name as a string, or does it have to be some other sort of object or something? I don't really understand Word VBA.
Attempts so far have only resulted in
runtime error 427 "remote server machine does not exist or is
unavailable"
or something about a bad file name.
Although Publish Date can be found under Insert > Quick Parts > Document Property it isn't actually a document property. It is a "built-in" CustomXML part, a node of CoverPageProperties, and can be addressed in VBA using the CustomXMLParts collection.
The CustomXML part is only added to the document once the mapped content control is inserted.
Below is the code I use.
As already pointed out for document properties the document must be open.
Public Sub WriteCoverPageProp(ByVal strNodeName As String, ByVal strValue As String, _
Optional ByRef docTarget As Document = Nothing)
'* Nodes: Abstract, CompanyAddress, CompanyEmail, CompanyFax, CompanyPhone, PublishDate
'* NOTE: If writing PublishDate set the content control to store just the date (default is date and time).
'* The date is stored in the xml as YYYY-MM-DD so must be written in this format.
'* The content control setting will determine how the date is displayed.
Dim cxpTarget As CustomXMLPart
Dim cxnTarget As CustomXMLNode
Dim strNamespace As String
If docTarget Is Nothing Then Set docTarget = ActiveDocument
strNodeName = "/ns0:CoverPageProperties[1]/ns0:" & strNodeName
strNamespace = "http://schemas.microsoft.com/office/2006/coverPageProps"
Set cxpTarget = docTarget.CustomXMLParts.SelectByNamespace(strNamespace).item(1)
Set cxnTarget = cxpTarget.SelectSingleNode(strNodeName)
cxnTarget.Text = strValue
Set cxnTarget = Nothing
Set cxpTarget = Nothing
End Sub
You cannot modify a document without opening it. In any event, "Publish Date" is not a Built-in Document Property; if it exists, it's a custom one.
Contrary to what you've been told, not all BuiltinDocumentProperties are read-only; some, like wdPropertyAuthor ("Author"), are read-write.
There are three main ways you could modify a Word document or "traditional" property (which are the ones you can access via .BuiltInDocumentProperties and .CustomProperties):
a. via the Object Model (as you are currently trying to do)
b. for a .docx, either unzipping the .docx, modifying the relevant XML part, and re-zipping the .docx.
c. For "traditional" properties, i.e. the things that you can access via .BuiltInDocumentProperties and .CustomDocumentProperties, in theory you can use a Microsoft .dll called dsofile.dll. But it hasn't been supported for a long time, won't work on Mac Word and the Microsoft download won't work on 64-bit Word. You'd also have to distribute and support it.
But in any case, "Publish Date" is not a traditional built-in property. It's probably, but not necessarily, a newer type of property called a "Cover Page Property". Those properties are in fact pretty much as "built-in" as the traditional properties but cannot be accessed via .BuiltInDocumentProperties.
To modify Cover Page properties, you can either use the object model or method (b) to access the Custom XML Part in which their data is stored. Method (c) is no help there.
Not sure where your error 427 is coming from, but I would guess from what you say that you are trying to see if you can modify the property in a single line, using the fullname of the document in an attempt to get Word to open it. No, you can't do that - you have to use GetObject/CreateObject/New to make a reference to an instance of Word (let's call it "wapp"), then (say)
Dim wdoc As Word.Document ' or As Object
Set wdoc = wapp.Documents.Open("the fullname of the document")
Then you can access its properties, e.g. for the read/write Title property you can do
wdoc.BuiltInDocumentProperties("Title") = "your new title"
wdoc.Save
If Publish Date is the Cover Page Property, once you have a reference to the Word Application and have ensured the document is open you can use code along the following lines:
Sub modPublishDate(theDoc As Word.Document, theDate As String)
' You need to format theDate - by default, Word expects an xsd:dateTime,
' e.g. 2020-06-11T00:00:00 if you only care about the date.
Const CPPUri As String = "http://schemas.microsoft.com/office/2006/coverPageProps"
Dim cxn As Office.CustomXMLNode
Dim cxps As Office.CustomXMLParts
Dim nsprefix As String
Set cxps = theDoc.CustomXMLParts.SelectByNamespace(CPPUri)
If cxps.Count > 0 Then
With cxps(1)
nsprefix = .NamespaceManager.LookupPrefix(CPPUri)
Set cxn = .SelectSingleNode(nsprefix & ":CoverPageProperties[1]/" & nsprefix & ":PublishDate[1]") '/PublishDate[1]")
If Not (cxn Is Nothing) Then
cxn.Text = theDate
Set cxn = Nothing
End If
End With
End If
Set cxps = Nothing
As for this, "Will word.application.documents accept the document name as a string", the answer is "yes", but Word has to have opened the document already. as mentioned above. Word can also accept an integer index into the .Documents collection and may accept just the name part of the FullName string.
Finally, if you do end up using a "traditional Custom Document Property", even after you have set the property and saved the document (approximately as above) you may find that the new property value has not actually saved! If so, that's down to an old error in Word where it won't save unless you have actually visited the Custom Document Property Dialog or have modified the document content in some way, e.g. adding a space at the end.

Lotus Notes Database Search

i am trying to write a code to open VBA and do search based on the cell value in A1 (integer). i managed to write a code up to point where i can open the lotus notes and go to specific database. I tried many online codes but couldn't manage to find the code to search in that database. "Lotus.NotesSession" doesn't work the excel version i use. Could you please help me to finish this code. Code is below:
Sub macro4()
Dim uiWs As Object
Dim dbname As String
Dim serverName As String
Dim db As NotesDatabase
Dim doccol As NotesDocumentCollection
Dim varA As Integer
dbname = "***"
serverName = "***"
Set uiWs = CreateObject("Notes.NotesUIWorkSpace")
Call uiWs.OpenDatabase(serverName, dbname)
Set db = uiWs.GetDatabase(serverName, dbname) ---->where i get the error
varA.Value = Sheets("sheet1").Range("A1").Value
Set doccol = db.FTSearch(varA, Nothing, 0)
End Sub
In Notes there are two "parent"- classes to derive everything from. The NotesUIWorkspace is the class for the "frontend": It contains everything that you SEE in the client. The NotesSession is the class for the backend. NotesDatabase is a backend- class. To correctly get your database, you need to use NotesSession:
Set ses = CreateObject("Notes.NotesSession")
Set db = ses.GetDatabase(serverName, dbname)
You mixed up COM and OLE Integration. The thing you tried to use (Lotus.NotesSession) is for COM only and you need to include Notes in your project to use this.
For your example to work you need to use the OLE integration: Notes.NotesSession
Now to your "Search"- Code:
There are two different ways to search a NotesDatabase:
There is the Fulltextsearch and the "normal" search.
The Fulltextsearch just searches for your value everywhere in all documents and returns a collection. A search for "Tom" in a mailfile will find all mails / calendar entries that where:
sent by Tom
received by Tom
have the word "Tom" in subject or body or an attachment of the mail.
The syntax for FTSearch is:
Set doccol = db.FTSearch( YourSearchValue )
You can restrict the search to one certain field by using a special syntax for your search. e.G. to only search in the "From" field you could write
[From] = "YourSearchValue"
In FTSearch the "=" always means "contains"
The normal search uses a Formula (in #Formula- syntax) to search for a document. It needs the right syntax, otherwise it will not find anything. A formula to search all documents that come from "Tom" would be:
#Contains( From ; "Tom" )
The syntax for search is:
Set doccol = db.Search( YourQueryAsExampleAbove, Nothing, 0 )
With Nothing = Cutoffdate (if given only return documents created or modified after the date) and 0 = max. number of documents to return (0 = return everything).
So your example code for the could be something like:
strQuery = "FieldToSearch = " & Sheets("sheet1").Range("A1").Value
Set doccol = db.Search( strQuery, Nothing, 0 )
After calling OpenDatabase successfully, you can use
set uiDb = uiWS.CurrentDatabase
That will get a NotesUIDatabase object, and then you can use
set db= uiDb.Database
That will get you the NotesDatabase object that you need in order to call the FTSearch method.

Check numeric field lotusscript

I have a field on a form called "fin_Paiement". What I want to do is: the field value to accept only numbers and points and to replace any other character by a point. I did it for alphabetic values with replace funciton but it doesn't work.
I tried this :
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Dim db As NotesDatabase
Set uidoc = workspace.CurrentDocument
Set doc = uidoc.Document
doc.fin_Paiement = Replace(doc.fin_Paiement_Montant(0), "*[a-z,A-Z]*", ".")
I will appreciate your help! Thanks
Create a function which changes all non-digits to dots
Function ToDigitsAndDots(orig As String) As String
Dim i As Integer
Dim char As String
For i=1 To Len(orig)
char = Mid(orig, i, 1)
If Not char Like "#" Then char = "."
JustDigitsAndDots = JustDigitsAndDots & char
Next
End Function
and change your code line to
doc.fin_Paiement = ToDigitsAndDots(doc.fin_Paiement_Montant(0))
LotusScript's Replace method doesn't support regular expressions. You would have to make the second parameter an array of all letters, for example:
doc.fin_Paiement = Replace(
Cstr(doc.fin_Paiement_Montant(0)),
Split("a, b, c, d, e, f, g, h, i, j, you get the idea...", ", "),
"."
)
Note, I haven't tested this but in theory it should do the trick.
Please relieve me of an awful doubt : your field is of type "Number", isn't it ? In which case, no code is needed, it accepts only numbers, and the decimal separator is specified in its properties. By default, the locale settings for a field are those of the Notes client, which, by default, are those of the operating system, so normally not something you should worry about.
Anyway, this is the kind of thing you typically don't do in LotusScript !
Most straightforward is to use #functions in one of the field's events.
Check your Designer Help, here is some hint , and you may want to review this.

Using multiple values field in Lotus Notes

I am trying to write a logging system for a form in Lotus Notes but I am at the part where I am not sure how I can append the information about the fields that are changed in the log fields. There are 3 fields that I use Log_Date (date), Log_User and Log_Actions (Text, allow multiple values).
I thought if I add comma to the log field it will create a new line when displaying the form but I am still getting a type mismatch on the case 2 line.
How can I append the new values to the log fields?
Sub Querysave(Source As Notesuidocument, Continue As Variant)
' Compare the values in the form after it is saved with its original values when the document is not a new document.
Dim doc As NotesDocument
Set doc = Source.Document
Dim session As New NotesSession
Dim user As String
user = session.CommonUserName
If newDoc Then
doc.Log_Date = Now()
doc.Log_User = user
doc.Log_Actions = "New document created."
Else
' Load fields value to the array
lastValues(0) = doc.QCR_No(0)
lastValues(1) = doc.QCR_Mobile_Item_No(0)
lastValues(2) = doc.QCR_Qty(0)
' Compared each value in the array to see if there is any difference
Dim i As Integer
For i = 0 To 2
If lastValues(i) <> originalValues(i) Then
Select Case i
Case 2 : doc.Log_Actions = doc.Log_Actions & "," & "Field QCR_Qty is changed"
End Select
End If
Next
End If
End Sub
doc.Log_Actions returns the notesitem. To access the value you need to use doc.Log_Actions(0)
In LotusScript back-end classes (e.g. NotesDocument, NotesItem), a multi-valued field is represented by an array with one value per element of the array. For setting the value of a field, doc.Log_Actions is shorthand (they call it 'extended syntax' in the Domino Designer help) for assigning the first (i.e., zero subscript) element of the array, but that does not work for getting the value. To get the first value, you have to use doc.Log_Actions(0). To get or set the second value, you have to use doc.Log_Actions(1).
So, your Case 2 code could look like this:
doc.Log_Actions(1) = "Field QCR_Qty is changed"
My guess, however, is that you really want to be able to continually append to the end of the list of values each time this code runs. You are also going to want your code to be robust and not blow up on you if (for any reason!) the Log_Actions item does not exist in the document. For that, you are going to want to do this:
dim actionsItem as NotesItem
if doc.hasItem("Log_Actions") then
set actionsItem = doc.getFirstItem("Log_Actions")
call actionsItem.AppendToTextList("Field QCR_Qty is changed")
end if
Or,
If (Not doc.HasItem("LogActions")) Then
doc.LogActions = "Field QCR_Qty is changed"
Else
doc.LogActions = ArrayAppend(doc.LogActions,"Field QCR_Qty is changed")
End If
This is equivalent to the NotesItem method by rhsatrhs, which you use is matter of preference.

Lotus Notes - Export emails to plain text file

I am setting up a Lotus Notes account to accept emails from a client, and automatically save each email as a plain text file to be processed by another application.
So, I'm trying to create my very first Agent in Lotus to automatically export the emails to text.
Is there a standard, best practices way to do this?
I've created a LotusScript Agent that pretty much works. However, there is a bug - once the Body of the memo exceeds 32K characters, it starts inserting extra CR/LF pairs.
I am using Lotus Notes 7.0.3.
Here is my script:
Sub Initialize
On Error Goto ErrorCleanup
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim uniqueID As Variant
Dim curView As NotesView
Dim docCount As Integer
Dim notesInputFolder As String
Dim notesValidOutputFolder As String
Dim notesErrorOutputFolder As String
Dim outputFolder As String
Dim fileNum As Integer
Dim bodyRichText As NotesRichTextItem
Dim bodyUnformattedText As String
Dim subjectText As NotesItem
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INPUT OUTPUT LOCATIONS
outputFolder = "\\PASCRIA\CignaDFS\CUser1\Home\mikebec\MyDocuments\"
notesInputFolder = "IBEmails"
notesValidOutputFolder = "IBEmailsDone"
notesErrorOutputFolder="IBEmailsError"
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Set db = session.CurrentDatabase
Set curview = db.GetView(notesInputFolder )
docCount = curview.EntryCount
Print "NUMBER OF DOCS " & docCount
fileNum = 1
While (docCount > 0)
'set current doc to
Set doc = curview.GetNthDocument(docCount)
Set bodyRichText = doc.GetFirstItem( "Body" )
bodyUnformattedText = bodyRichText.GetUnformattedText()
Set subjectText = doc.GetFirstItem("Subject")
If subjectText.Text = "LotusAgentTest" Then
uniqueID = Evaluate("#Unique")
Open "\\PASCRIA\CignaDFS\CUser1\Home\mikebec\MyDocuments\email_" & uniqueID(0) & ".txt" For Output As fileNum
Print #fileNum, "Subject:" & subjectText.Text
Print #fileNum, "Date:" & Now
Print #fileNum, bodyUnformattedText
Close fileNum
fileNum = fileNum + 1
Call doc.PutInFolder(notesValidOutputFolder)
Call doc.RemoveFromFolder(notesInputFolder)
End If
doccount = doccount-1
Wend
Exit Sub
ErrorCleanup:
Call sendErrorEmail(db,doc.GetItemValue("From")(0))
Call doc.PutInFolder(notesErrorOutputFolder)
Call doc.RemoveFromFolder(notesInputFolder)
End Sub
Update
Apparently the 32KB issue isn't consistent - so far, it's just one document that starts getting extra carriage returns after 32K.
With regards the 32Kb thing, instead of this:
Set bodyRichText = doc.GetFirstItem( "Body" )
... you might want to consider iterating all "Body" fields in the email document. When dealing with large amounts of rich text, Domino "chunks" said content into multiple rich text fields. Check some documents you're processing: you may well see multiple instances of the "Body" field when you look at document properties.
I'm not sure what is causing the 32K bug, but I know there are lots of limitations in the order of 32K or 64K within Lotus Notes, so perhaps you're running into one of those. I can't imagine what would add extra CR/LFs. Perhaps you could try using the GetFormattedText method on the NotesRichTextItem class and see if it fares better?
It's more complicated, but you might also be able to use the NotesRichTextNavigator class to iterate through all the paragraphs in the memo, outputting them one at a time. Breaking up the output that way might eliminate the CR/LF problem.
Lastly I always suggest Midas' LSX for dealing with rich text in Lotus Notes. They sell an add-on that gives you much more control over rich text fields.
As for best practices, one that comes to mind when I read your code is the looping construct. It is more efficient to get the first document in a view, process it, and then get the next doc and check whether it is equal to Nothing. That sets the loop to run through the view in index order, and eliminates the need to search through the index to find the Nth document each time. It also saves you from maintaining a counter. The gist is as follows:
Set doc = curview.GetFirstDocument()
While Not (doc Is Nothing)
'Do processing here...
Set doc = curview.GetNextDocument(doc)
Wend
The external eMail most likely comes in as MIME. So you could check the document.hasMime and then use the mime classes to get to the content. Then you don't have a 64k limit. Samples are in the help - or reply if you want code.

Resources