Pages

Showing posts with label Lotusscript. Show all posts
Showing posts with label Lotusscript. Show all posts

Tuesday, July 19, 2016

Creating text file with lotusscript

Following is a block of lotusscript code that helps one understand how a text file can be created and updated using Freefile and NotesStream concepts

As a catch, the code employs a validation mechanism that check if a given file exists or not and create it only if its not found.

Hope this helps

Function updateLog(logText As String)
      Dim session As New NotesSession
      Dim stream As NotesStream
     
      On Error GoTo errHandler
  Set session = New NotesSession
 
  REM Create stream and display properties
  Set stream = session.CreateStream
 
  'check if log file exists
  If Not stream.Open("C:\\ak\\log.txt") Then
      'if log file doesnot exist then create one and add a time stamp to it
      Dim fileNum As Integer
      fileNum% = FreeFile()
      Open "/ww414/notes/ebcdicfile.txt" For Output As fileNum%
     
      Print #fileNum%, "Created: " ; CStr(Now)
     
      Close fileNum%
      'this should have created the log file. see if it existis now
      If Not stream.Open("C:\\ak\\log.txt") Then
            'if log file has not been created yet then let the user know of the error that blocks the operation
            print "Log file Is inaccessible"
            Exit Function
      End if
  End If

  'update log
  Call stream.WriteText(Chr(13) & Chr(10) & CStr(Now) & "  ::  >  " & logText)
  'close stream/file open in memory
  Call stream.Close()
Exit Function
errHandler:
'display unhandled errors
print Error & " on line " & CStr(Erl)
Exit function

End function

'now try producing some logs with the following statements
updateLog "This is a sample log"
updateLog "This is an other sample log"
updateLog "This is yet an other sample log"
updateLog "I am done logging"
updateLog "forget it bye bye"

'you can view the results on the text file or through browser as follows



Thursday, February 13, 2014

Sort NotesDocumentCollection

Shamelessly copy pasted from http://blog.tjitjing.com/index.php/2006/05/how-to-sort-notesdocumentcollection-in.html. Nice code. Hope it gets reused many times

This Lotusscript function sorts a document collection on one or multiple fields.
I have previously used several other algorithms that use a view to sort the collection, these however have the drawback that they become very inefficient (i.e. slow) as the number of documents in the view used for sorting grows. The solution presented below does not have this problem.
It has been developed and tested in Lotus Notes 6.5.3 but should work in all ND6 (release 6) and possibly earlier Lotus Notes releases too (if you test this successfully or unsuccessfully write a comment to this post and everyone will know).
Example of use:
Dim fieldnames(0 To 2) As String
fieldnames(0) = "SKU"
fieldnames(1) = "OrderDate"
fieldnames(2) = "Client"
Set collection = SortCollection (collection, fieldnames)
Function to sort DocumentCollection:
Function SortCollection(coll As NotesDocumentCollection, fieldnames() As String) As NotesDocumentCollection
' ------------------------------------------------
' --- You may use and/or change this code freely
' --- provided you keep this message
' ---
' --- Description:
' --- Sorts and returns a NotesDocumentCollection
' --- Fieldnames parameter is an array of strings
' --- with the field names to be sorted on
' ---
' --- By Max Flodén 2005 - http://www.tjitjing.com
' ------------------------------------------------
Dim session As New NotesSession
Dim db As NotesDatabase
Dim collSorted As NotesDocumentCollection
Dim doc As NotesDocument
Dim i As Integer, n As Integer
Dim arrFieldValueLength() As Long
Dim arrSort, strSort As String
Dim viewname As String, fakesearchstring As String
viewname = "$All" 'This could be any existing view in database with first column sorted
fakesearchstring = "zzzzzzz" 'This search string must NOT match anything in view
Set db = session.CurrentDatabase
' ---
' --- 1) Build array to be sorted
' ---
'Fill array with fieldvalues and docid and get max field length
Redim arrSort(0 To coll.Count -1, 0 To Ubound(fieldnames) + 1)
Redim arrFieldValueLength(0 To Ubound(fieldnames) + 1)
For i = 0 To coll.Count - 1
Set doc = coll.GetNthDocument(i + 1)
For n = 0 To Ubound(fieldnames) + 1
If n = Ubound(fieldnames) + 1 Then
arrSort(i,n) = doc.UniversalID
arrFieldValueLength(n) = 32
Else
arrSort(i,n) = "" & doc.GetItemValue(fieldnames(n))(0)
' Check length of field value
If Len(arrSort(i,n)) > arrFieldValueLength(n) Then
arrFieldValueLength(n) = Len(arrSort(i,n))
End If
End If
Next n
Next i
'Merge fields into list that can be used for sorting using @Sort function
For i = 0 To coll.Count - 1
If Not strSort = "" Then strSort = strSort & ":"
strSort = strSort & """"
For n = Lbound(fieldnames) To Ubound(fieldnames) + 1
strSort = strSort & Left(arrSort(i,n) & Space(arrFieldValueLength(n)), arrFieldValueLength(n))
Next n
strSort = strSort & """"
Next i
' ---
' --- 2) Sort array
' ---
arrSort = Evaluate("@Sort(" & strSort & ")")
' ---
' --- 3) Use sorted array to sort collection
' ---
Set collSorted = coll.Parent.GetView(viewname).GetAllDocumentsByKey(fakesearchstring)
For i = 0 To Ubound(arrSort)
Set doc = db.GetDocumentByUNID(Right(arrSort(i), 32))
Call collSorted.AddDocument(doc)
Next i
' ---
' --- 4) Return collection
' ---
Set SortCollection = collSorted
End Function

(This article is previously published and has been moved to this blog)

[Update: Instead of using Evaluate and @Sort in section 2 in the code you can of course use any of your favourite sort routines. Or search the Net for one, there are many out there.]

Tuesday, October 1, 2013

Accidentally discovered Mirror Image of L (:P)

Do not expect any serious stuff from this article as expectations might lead to disappointments. Was casually working and happened to punch in a couple of keys by mistake and found a ridiculous character which I have never seen before in the Lotus script editor (Of course I had seen it in other platforms).

I cannot type in that symbol here as I did on the lotusscript editor, so as an alternative I will do the most brilliant thing of showing you a screen shot, rofl.

I guess its easy for you to see what I am speaking about in the image. I must say that I have found some thing different to decorate my multi line comments with :)

Also I tried an msgbox on that. Seems to work. Another discovery - mirror image of L, rofl


Now I can give more meaningful message boxes for my client ;P

Monday, September 30, 2013

Crash Lotus Notes - Oops I did it again

In an attempt to write a fairly complex workflow application, which I originally thought was a so simple I did this. I was dumb enough to have given way for the "out of touch since last two years" concept to ridicule me like this.

I knew that theoretically, I can write custom lotus script classes which can extend native lotus script classes and I can possibly extend/create events like querySave, queryClose etc using some thing like the following

On Event Querysave From customUidoc Call customQuerysave

So I went a head and tried it to discover that I crashed my client. I am great full that I dont posses the talent to corrupt database designs at will. Honestly.

Sometimes the thought scares the hell out of me. I just tried to do the above mentioned stuff. Just tried. And following happened. Note- I am not sure if this would happen always or not, but I think its worth mentioning this. I already had a custom class on the script library where I was trying to build my new custom class and extend NotesUIDocument.


I am on the way persuading about what really guided me to collapse my Lotus Client.  Hope I would find a solution to the same :@  !!!!

Saturday, September 21, 2013

Handling Variants - Becare full about the Type Name or Class Name of Variants refering to Array Objects

Variants now a days are proving more useful to me than before. I stick to the thought that I should not use variants unless its really necessary. One of the most effective advices that I received from developers against using variants is based on the fact that it takes 16bytes memory space for the object where is its less in case of objects for integer, string etc.

I often get the feel that with the current hardware capacities heightened to tera bytes, 16 bytes wont matter that much, if we recyle them properly.

I performed a small test today as my code kept failing and failing and there was not much for me to look for.

I first checked what type of values result in which type of variants. So I did the following in a test button


Eventually, I previewed the button on a client interface and did the MAGIC JOB of clicking it. And there comes my BELOVED BABY popups as to the left.

Now I understood that these are of types "INTEGER", "STRING" and "STRING()"

Is there any soul out there who agrees with me. If so, join the club and clean your eyes/specs and look at the god damn thing properly.

It is actually "STRING( )" and not "STRING()". This screwed me for over 30 minutes. Some time back due to a specific individual in my life, I became of fond of reading and understanding the "LAWS OF STUPIDITY". The fourth law stated that,

"Non-stupid people always underestimate the damaging power of stupid individuals. In particular non-stupid people constantly forget that at all times and places and under any circumstances to deal and/or associate with stupid people always turns out to be costly mistake."

Now my question is who is stupid - Me , the Variant or ***




Saturday, September 14, 2013

Obtain class name of objects in lotusscript

Several months ago, I explored how to create overloaded functions in Lotusscript. I had posted about the same as well. Recently I went through a thought which required me to find a way to get the class name of a lotusscript object in the run time. It really took me some time to eventually recollect that I knew the answer already until I went through my own posts again.

Thought I would make it simpler with a proper titled post dedicated for this issue of finding the class name of a lotusscript object on run time.

The lotusscript key word that does it is "TypeName". Though I had used this for doing the overloaded functions, It took me an hour to recollect it X(. Guess I had grown rusty in the last two years with less coding. Am happy now, that I get enough stuffs to challenge my skills again

In short, following is a little illustration about the way this keyword works. For a quick test, add the following code to a button and test it on Notesclient.

dim doc as NotesDocument
dim uiDoc as NotesUIDocument

msgbox TypeName(doc)
msgbox TypeName(uidoc)

Now when you click on the button, you will receive a couple of prompts saying
"NOTESDOCUMENT" and "NOTESUIDOCUMENT"


Thursday, September 12, 2013

Crash Lotus Notes - Oops I did it again

It has been quite a while since work was such fun. :) I had missed to log a lot of ways by which I ended up crashing lotus notes last year as they seemed obvious and straight forward. This time I think I discovered a new way to do it :P

It is by make a view feel miserable when a document is opened from it. Yep its the queryOpenDocument event of the view.

I just put the following code into it

Sub Queryopendocument(Source As Notesuiview, Continue As Variant)
Dim workspace As New NotesUIWorkspace
Dim session As New NotesSession
Dim currDB As NotesDatabase
Dim selectedDoc As NotesDocument
Dim caret As String
caret=source.CaretNoteID
Set currDB=session.CurrentDatabase
Set selectedDoc=currDB.GetDocumentByID(caret)
Call workspace.SetTargetFrame("*********")  '- dont get any ideas. Just put a valid frame name 

Call workspace.EditDocument(False,selectedDoc)
continue=False
End Sub

This happens even if I comment "continue=False" 

I really dont know about how to fix it rolf :)

Thursday, January 17, 2013

List all ODBC Connections mapped with Lotus Notes using Lotusscript

A while ago I was given a very nice job of finding why a lotus script agent was not able to communicate with a DB2 server. And the nice stupid part about that is I never had acess to even view the log files of the server where the issue occurs. It was kind of frustrating for a while to understand/find the source of the issue with virtually no resources. It was that I was thinking about the most basic of the scenarios like, network problems, lan cable issues etc etc,

So eventually I just wanted to know if there is a way to list down the kind of connections that are prevalent with a lotus domino server and ended up discovering the following. Again I just discovered if for myself. It was always able on the innernet some how of the other.:)

The following code gives you a message box with something like,
 "The usable connections are file, notes, odbc2, oledb"

Atleast this is what I got. Evidently db2 was missing in the list for me and hurray, administrators found it at last that db2 was not mapped properly with the lotusdomino servers after looking at the proof . What ever that means. :P

Dim session As New LCSession
 Dim conName As String
 Dim text_str As String
' list the connectors available
' the parameters for connector code, identity flags, and
' identity names are optional and omitted in this example
 Call session.ListConnector(LCLIST_FIRST, conName)
 text_str = conName
 While session.ListConnector(LCLIST_NEXT, conName)
  text_str = text_str + ", " + conName
 Wend
 Msgbox "The usable Connectors are " & text_str

Friday, April 20, 2012

Overloading functions in Lotusscript

At times I find it difficult with out the ability to over load functions in lotusscript. The following way just helped me do it. Since I dont do this often its like new to me every time I do this :)

Sub new(key As Variant)
     Select Case Typename(key)
     Case "STRING":
           your code for this type
     Case "INTEGER"

          your code for this type
     Case "NOTESDOCUMENT"
          your code for this type
     Case Else
         your code for this
End Select
We have to be wary about the usage of such functions though. One stuff that I found was Typename(Nothing) is object. I least expected that.

I dont think using overloaded functions in lotusscript is a time saver. As a matter of fact I found this and just dropped the idea of using it after trying to use it :P. Cos man..., it was a head ache to me. I couldn't have a dynamic parameter list like how we can do in javascript and definetly can't match the way we do it in java or C or C++ anyway.

So I felt crippled when using this idea. However, this must help in some scenarios. Hope you find this in one such case :)

Thursday, April 12, 2012

Issues adding document items dynamically through lotusscript - "Field is too large (32k) or View's column & selection formulas are too large"

I had a very tough time completing a particular job which involved huge amount of document data through lotusscript. I had to debug through thousands of lines of code which were scattered across multiple agents and script libraries. Honestly I got screwed. Not because of the volume of code I was going through but because of the limitation of the notes documents that wont accept summary data beyond a certain limit - roughly around 60000+ bytes, may be 64 K.

I encountered this because, I wanted to print debug statements to understand the flow and was going though a lot of problems in getting them accumulated in a single document. I tried splitting the data between sever different fields, appendItemValue, richtext etc.. But none seemed to help me as desired. It was then that I identified the forgotten concept of the summary and non summary items. My Research towards this concept gave me an answer with in seconds. I found the following in the ibm site.(lost track of the url :< )

The idea is to save the data to the document and make the items as non summary items. That was the simple answer to what I thought was a so very complicated problem
"Field is too large (32k) or View's column & selection formulas are too large"

Or, in a LotusScript agent the following error message corresponding to error code 4000 occurs:

"Notes error: Field is too large (32k) or View's column & selection formulas are too large"



description of this fix:

Notes/Domino 6.x and later have the following limits regarding Summary fields: 32k per field, 64k per document. Relative to memos: The limit for sending to individual names and locally expanded groups is 15k. In addition, the above restrictions still apply as regards other fields in the memo.

Except for rich text fields, fields are typically flagged as "summary" by default; you can change this with the NotesItem.IsSummary property, but it will be reset to the default if the document is edited using a form that contains that field. Non-text fields (numbers, date-times) are also summary fields, so these limits apply to them also.

Hope this helps :)

Friday, February 17, 2012

Creating simple downloadable text file using lotusscript

Create an agent with the following Lotusscript code in it.

Print "Content-Type:application/octet-stream"

Print "Content-Disposition: Attachment;filename=""sampleDownloadAbleFile.txt"""
Print "this text is from the server"
Print "this has not been saved any where in the server"

Save the agent preview it on the web. You will be able to download a text file



Hope this helps :)

Tuesday, January 3, 2012

Bugs: "Element or Navigator is invalid" error when using NotesRichTextNavigator


-->
Let me dive straight into the point.  Assume that I have few document say five documents with a rich text item in each one of it and all of them are created using same form. So don’t bother about minor variations like missing document items etc… To make things simple let me say that these five documents are design equivalent.

Now let me say that I don’t put any values inside the richtext field in 3 document alone. So on the contrary I have values on all the 4 remaining documents.


Now assume that I have the following sort of code in an agent


On Error Goto errhandler
                …….’some code               
                Set dc=db.UnprocessedDocuments
                Set doc=dc.GetFirstDocument
                Set richStyle = session.CreateRichTextStyle
                richStyle.PassThruHTML = true
                                
                While Not doc Is Nothing
                                itr=itr+1
                               
                                Set richText=doc.GetFirstItem("myRtField")
                                Set rtnav=richText.CreateNavigator
                                                               
                                Call rtnav.FindFirstElement(RTELEM_TYPE_TEXTRUN)
                                Call richText.BeginInsert(rtNav)                   ---------------------à>> when itr=3 this line will error out with error number 4506
                                Call richText.AppendStyle(richStyle)
                                'Call rtnav.GetLastElement(RTELEM_TYPE_TEXTRUN )
                                Call richText.EndInsert
                                Call richText.Update
                                'Call doc.Save(True, False)
                                Set richText=Nothing
                                Set rtnav=Nothing
                                Set doc=dc.GetNextDocument(doc)
                                Print Cstr(itr) & " doc processed"
                Wend
                Exit Sub
errHandler:
                If Err=4506 Then Goto skiploop
                Print Error & " *** occured on line *** " & Cstr(Erl) &"*** with error number *** " & Cstr(Err)
                Exit Sub




As you may understand the since the rich text field in the third document is empty an error with number 4506 will occur.


You can say that one can handle this scenario by using some thing like “IF rtnav Is Nothing Then goto SkipLoop” etc… but it did not work so I managed to loop the control back in my error handler section.


And guess what, the object rtnav becomes unusable. I simply does not set any right values the next time the loop executes and does not accept any values. And so the following error occurs




And alas… the code breaks. Complier does not even make it to the error handler.


So sad L


I think I know a work around for that. So stay tuned

A way to handle "Element or Navigator is invalid" error when using NotesRichTextNavigator


Before attempting to create a rich text navigator, just check if the field is empty or not


                x=doc.GetItemValue("MyTextarea")
                                If isEmpty(x)="" Then
                                                Goto skipLoop2
                                End If


So this is one possible work around for the bug that I was posted earlier


Hope this helps some one J


Tuesday, September 27, 2011

Can a field name exceed 32 characters

Well It just happened on the go. I know the name of a field cant be bigger that 32 characters in lenght. I got a bit curious to see if I can break it. But the designer did not allow me to do it.

So as always 2 over come this I had my step2 - the Lotus Script.
I just created a document Item whose name is 52 characters in length. And yes it can exceed. But I havent tested its limits yet. Following are screen shots that would best describe what I am speaking about



I hope we can over come the designer limitation as well using DXL. Hope this is interesting and useful :)

Wednesday, August 3, 2011

Force UNID on a new document - UNID Hack

Recently I happened to do some thing that required me to force unid on a newly created document. The use cases that I could think about for this kind of scenario are very use ful. Say for example deleting a document by accident may lead to orphan response documents if not taken care of. And if you want to bring them back on association and not screw up things we can use this little tip.

The use is very simple,Following is a lotus script code that will do it for you. Note the way document items are being copied using CopyAllItems command.

Set selDoc=currDB.UnprocessedDocuments.GetFirstDocument

Set newDoc=trgDB.Createdocument
newDoc.UniversalID=selDoc.UniversalID
Call selDoc.CopyAllItems(newDoc)
call newDoc.save(true,false)
 
And the normal rules apply, a multiple documents can't have same unid with in the same database.
 
Excersice caution while using this cos, you might just screw up things if you are not cautios. After all we know the importance of the UNID

Friday, June 3, 2011

Working with HTTP POST in Lotus Notes

Create a form design element as illustrated in the following image. Note the usage of the action parameter that has been added as an attribute to the form tag. The page gets redirected to the url mentioned  as the action attribute when document submit Is triggered. The trick here is to key in your agent url which will enable execution of that agent from the server


Now write an agent with the following lotus script code in it and ensure that this url is mentioned as the action param on the browser


Note the usage of Request_Content and Query_String reserverd fields in the agent code. Now preview the form on the browser , key in a few values and hit submit.


This eventually triggers your agent and you will see the desired out put. Your Post parameters and the Get (Query_String) parameters.


Hope this helps :)

Friday, March 25, 2011

Lotus Script Function to extract all attachements from a Notes Document

Function ExtractFiles (doc As NotesDocument , filePath As String , extract As Boolean) As String
'handle errors in case of abrupt termination
    On Error Goto errorHandler
 
    'declare all the objects and variables necessary for further manipulation
    Dim rtitem As NotesRichTextItem
   
    Dim allFileName As String
    Dim attname As String
    Dim path As String
   
    Dim dirCreated As Boolean
    Dim tempDoc As NotesDocument
    Dim session As New NotesSession
   
    Set tempDoc  = New NotesDocument(session.CurrentDatabase)
   
    Call doc.CopyAllItems(tempDoc)
   
    Call tempDoc.Save(True,False)
   
    allFileName =""
    dirCreated = False
   
    Set rtitem = tempDoc.GetFirstItem( "Body")
   
    'Mantis Issue: 7106 Type Mismatch Error Logged in LNCNSFlog.txt File During Export of Message
    'the following check will verify whether the document has en embedded object
    If ( tempDoc.HasEmbedded ) Then  ' code added by Rajesh Kumar
       
        While Not rtitem Is Nothing
            Forall eo In rtitem.EmbeddedObjects
                If (eo.Type = EMBED_ATTACHMENT) Then
                    ' If Name and Source are different, Name is a random name assigned by Domino...
                    If eo.Name <> eo.Source Then
                          ' take advantage of the random Name & add extension of the Source...
                        Call LogWrite ("ExtractFileNames - --Name = " + eo.Name + " Source = " + eo.source)
                        allFileName = allFileName + "~~##~~" + eo.source + "||" + eo.Name
                        attname = eo.source + "-~~##~~-" + eo.Name
                    Else
                          ' No random name was assigned, so it is safe to use Source...
                        allFileName = allFileName + "~~##~~" + eo.source
                        attname = eo.source
                        Call LogWrite ("ExtractFileNames - Extracting ------" + attname)
                        Call LogWrite ("ExtractFileNames - --Source Only= " + eo.Source)
                    End If
                    If (extract) Then
                    'if the directory is created then
                        If (Not dirCreated ) Then
                            path = filePath + Cstr(doc.NoteID)
                            Call LogWrite ("ExtractFileNames - The path is Extract File Names : "+ path)
                        'create a directory
                            Mkdir ( path )
                        'set the value to true
                            dirCreated = True
                        End If
                        Call LogWrite ("ExtractFileNames - Extracting to path : " + path + "\" + attname)
                        Call eo.ExtractFile( path + "\" + attname)
                    End If
                End If
            End Forall
        'remove the current attachment
            Call rtitem.Remove
        'get the handle to the next document which is the first document ,since the previous doc is removed
            Set rtitem = tempDoc.GetFirstItem( "Body")
        Wend   
    Else
          ' code added by Rajesh Kumar
        Call LogWrite ("ExtractFileNames - No Attachment found in the Document")
    End If
    ExtractFiles = allFileName
   
    Call tempDoc.Remove ( True)
   
    Call LogWrite ("ExtractFileNames - Exiting the function")
    Exit Function
'log the error that resulted in abrupt termination       
errorHandler:
    Call LogWrite ("ExtractFileNames - Exiting the function Got error  for doc :" & Cstr(doc.UniversalID) & "   " & Error$ & " on line " & Cstr(Erl))
    ExtractFiles = allFileName
    If Not tempDoc Is  Nothing Then
        Call tempDoc.Remove ( True)
    End If
    Exit Function
End Function

Thursday, February 10, 2011

An elegant way to get the current time (say a time stamp) in Lotus Script

The following lotusscript command gives a very good way of obtaining a the current time alone.

Format(Now, "Long Time")


hope this helps :)

Tuesday, January 4, 2011

Export view contents to excel using LotusScript on web

The following stuff was obtained from "http://www.botstation.com/code/view2excelweb.php". This proved to be very useful to me... Saved a lot of time ofcourse. A Nice Tool

This LotusScript agent exports all documents from a Domino view to Excel. It can be triggered from web browser so the user can immediately see the results in his Excel application.
User can specify what view he wants to export by appending a view name as an URL parameter to the agent.
Set agent to be run as "Web User" in order to prevent accessing reader-protected documents unavailable to regular users.

/***************************************************/
Sub Initialize
'This agent export any view to excel using web browser interface.


'To select a default view to export, change the view name in the code below.
'You can also provide view name as parameter to the agent. As the agent runs
'with authority of it's signer make sure the agent can not access the views which
'are not supposed to be exported. Use this function at own risk or remove it, so 
'the agent always uses the default view. 
'Example of appending a view name parameter to the agent:
'http://intranet.company.com/applications/mydb.nsf/ExportViewAgent?open&expview=ExportAllPeople


'Warning: to avoid errors on columns containing multivalue fields, use following
'column formula to combine multivalues: @Implode(MVField;",")
'Columns containing icons are not exported.
'Columns used for counting totals are not exported. 


'Copyright Botstation (www.botstation.com)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView 
Dim doc As NotesDocument
Dim colcounter As Integer, currentcol As Integer
Dim expview As String, filename As String 
Dim colnames
Dim colnumbers 


Redim colnumbers (0 To 100) As Integer
Set db=session.currentdatabase
Set doc=session.DocumentContext


filename="Excel "+db.Title+" "+Format(Now, "yyyy-mmm-d hh-mm")+".xls" 'file name which will be suggested to user to save the resulting Excel file 
tmp=""


If Instr(doc.query_string_decoded(0),"expview=")=0 Then ' find out if view is supplied as URL parameter to this agent
Set view = db.GetView("ExportToExcel") ' no view supplied as parameter, use your default export view
Else
expview=Strright(doc.query_string_decoded(0),"expview=")
If Instr(expview,"&")>0 Then expview=Strleft(expview,"&")
Set view = db.GetView(expview) ' get the view passed as parameter to the agent
End If
If view Is Nothing Then
Print "Export Error - Export view does not exist" 
Exit Sub
End If
colcounter=0
currentcol=0 'starting column number. 0=first column
Forall c In view.Columns 
If c.isIcon<>True Then ' do not include icon columns
If c.Formula<>"""1""" And c.Formula<>"1" Then 'do not include columns which are counting docs (Total)
colnumbers(colcounter)=currentcol 'put into array what columns are valid for exporting
tmp=tmp+"<th>"+c.Title+"</th>" 
colcounter=colcounter+1 'total nr of valid columns
End If
End If
currentcol=currentcol+1 'increment counter of columns with 1
End Forall


If colcounter=0 Then 
Print "Export Error - No valid columns to export"
Exit Sub
End If
Redim Preserve colnumbers (0 To colcounter-1) As Integer 'remove unused array values
' ---- output browser header ------
Print |Content-Type:application/vnd.ms-excel| 'You can also try with "application/octet-stream"
Print |Content-Disposition: Attachment; filename="|+filename+|"| 'Triggers the save/open browser prompt instead of embedding the spreadsheet in the browser
Print ""
' --------------------------------
Print "<table border=1>" 'set border to 1 pixel, otherwise Excel shows no cell separators.
Print tmp 'output view column headers
Set doc = view.GetFirstDocument
While Not ( doc Is Nothing ) 'process all documents in view
tmp=""
tmp=tmp+"<tr>" 'begin a new table row
Forall colnr In colnumbers 'process all previously validated columns
colvalue= doc.ColumnValues(colnr)
tmp=tmp+"<td>"+CStr(colvalue)+" </td>" 'make a new table cell
End Forall
tmp=tmp+"</tr>" 'close row
Print tmp 'output values to browser after each row/document
Set doc = view.GetNextDocument (doc)
Wend 
Print "</table>"


End Sub 
/***************************************************/

Hope this helps :)

Thursday, December 16, 2010

Array Base Index and Base in Lotusscript (Option Base 0|1)

I happened to stumble upon the base index of arrays when a colleague of mine came up with a doubt in Base command in lotus script

It was interesting to find the following,

Create a couple of buttons and put the following fragments of code in each of them

option base 0
dim myArray[10] as string
msgbox cstr(lbound(myArray)) '--> this would prompt 0

This means now the array can contain 11 string values, where the index varies from 0 to 10

option base 1
dim myArray[10] as string
msgbox cstr(lbound(myArray)) '--> this would prompt 1

And this means the array can contain 10 string values, where the index varies from 1 to 10

Inference :

Option Base 1 in lotus script implies that the arrays will have a lower bound of 1 as is the case with Formula language

Extra Note :
In case of Java, an array of the following sort say,
String[] x= new String[10]

x shall hold 10 values with indices varying from 1 to 10

Hope this helps :)