OpenOffice Import

I have a .xls file I need to import using Lotusscript. Below is the current script I have. It is based on the quoted script which works for .xls files and Excel. Unfortunately, I cannot use Excel on the server. So, I want to use OpenOffice.

My issue is with finding the range. I found information on some OpenOffice forums that has helped a lot. But, how do I declare a cursor in LotusScript? When the script runs right now, I get “automation object argument type mismatch”. Thanks in advance for your help.

Sub Initialize

'from http://www.openntf.org/Projects/codebin/codebin.nsf/CodeSearch/DCD5A132F75581698625726700715FCA

'Based on v 1.2 code from David Moore david.james.moore@gmail.com

'will import from Excel up to 256 columns by 65,536 rows

'Modified by John Tincher

Dim astrFields As Variant

Dim session As New NotesSession

'Only needed when interacting with user

'Dim uiws As New NotesUIWorkspace

Dim form As NotesForm

Dim db As NotesDatabase

Dim doc As NotesDocument

Dim item As NotesItem

Dim row As Integer

Dim xlFilename As String

Dim xlsApp As Variant

Dim xlsWorkBook As Variant

Dim xlsSheet As Variant

Dim rows As Long

Dim cols As Integer

'Dim x As Integer

Dim itemName As String

Dim flag As Integer

Dim formAlias As String

Dim sortEval As String

Dim sortedList As Variant

Dim indexLo As Long

Dim indexHi As Long

Dim fn As Variant

Dim msg As String

Dim i As Long

Dim formname As String

'Added for OpenOffice

Dim objServiceManager As Variant

Dim objDesktop As Variant

Dim worksheet As Variant

Dim oCell As Variant

Dim cursor As Variant

'On Error GoTo ErrorHandler

Set db = session.CurrentDatabase



Print ("Import documents into the database")



formname = "EmployeeProfile"

If formname= "" Then Exit Sub



'Get the form object so that we can check field names

Set form= db.GetForm(formname)

'If the form has an alias, use it to select the form

If Not IsEmpty(form.Aliases) Then formname = form.Aliases(UBound(form.Aliases))

'Adding code for using OpenOffice in place of Excel

'The service manager is always the starting point

'If there is no office running then an office is started up

Set objServiceManager = CreateObject("com.sun.star.ServiceManager")

'Create the Desktop

Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop")

	Dim args()

Set xlsApp=objDesktop.loadComponentFromURL("file:///c:/EAData/FlintEA.xls","_default", 0,args)

Print “File is open”

Set xlsSheet=xlsApp.Sheets(0)

Set oCell = xlsSheet.getCellByPosition(0,0)

Set cursor = xlsSheet.createCursorByRange(oCell)

Call cursor.gotoEndOfUsedArea(False)

rows = cursor.getRangeAddress().EndRow

cols = cursor.getRangeAddress().EndColumn

'Make sure we start at row 0

row = 0

'Print “Starting import from xls file…”

Do While True

row = row + 1

'Check to make sure we did not run out of rows

If row= rows+1 Then GoTo Done

'field definitions for notes come from first row (row, column)

If row=1 Then

astrFields = form.Fields

ReDim fd(1 To cols) As String

For i=1 To cols

'the replace function used here removes spaces from the field definitions in the first row

fd(i) = xlsSheet.Cells( row, i ).Value

If Len(fd(i)) Then

fd(i)= Replace(fd(i), " ", “”)

'Remove the # in Home Phone #

fd(i)= Replace(fd(i), “#”, “”)

'Remove the / in Full/Part Time

fd(i)= Replace(fd(i), “/”, “”)

If IsNull(ArrayGetIndex(astrFields, fd(i))) Then

	msg="The field name "& fd(i) &" does not appear in the form you have chosen."

If MsgBox(msg, MB_OKCANCEL + MB_ICONEXCLAMATION + MB_DEFBUTTON2) <> 1 Then

GoTo Done

End If

End If 'flag=1

End If

Next 'For i=1 To cols

Else 'row isn’t = 1

'Import each row into a new document

'Create a new doc

Set doc = db.CreateDocument

doc.Form = FormName

For i= 1 To cols

If Len(fd(i)) Then _

Set item = doc.ReplaceItemValue( fd(i), xlsSheet.Cells( row, i ).Value )

Next ’ i= 1 To cols

'Save the new doc

Call doc.Save( True, True )

End If 'Not row = 1 Then

'Print "Processing document number "& CStr(row) & " of " & CStr(rows)

Loop 'Do while true

Done:

On Error Resume Next 'protect against infinite error handing loops

'Print "Disconnecting from Excel..."

If Not xlsWorkbook Is Nothing Then

xlsWorkbook.Close False

End If ’ Not xlsWorkbook Is Nothing

If Not xlsApp Is Nothing Then

xlsApp.DisplayAlerts = False

xlsApp.Quit

Set xlsApp = Nothing

End If 'Not xlsApp Is Nothing

'Clear the status line

'Print

Exit Sub

ErrorHandler:

Select Case Err

Case 184

'MsgBox “No file chosen. Exiting Import.”

'Print “No file chosen. Exiting Import.”

Resume Done

Case 6

'MessageBox “Make sure that you do not have more than 65,536 rows of data to import.” ,MB_OK+MB_ICONINFORMATION,"Error! "

'Print “Too many rows in Excel document. Exiting Import. Disconnecting from Excel…”

Resume Done

Case Else

'MsgBox "Lotus Notes Error # " & Err & “. Please contact your Notes administrator for help. Exiting Import.”

'Print "Error # "& Err & " on line " & Erl & ": " & Error$

Resume Done

End Select

End Sub

Subject: Re: OpenOffice Import

Hi John

I’ve got some code that does’t rely on a cursor, just gets a cell directly. The class below is a semi-complete automation class for handling open office, enjoy

Simon

:

Option Public

Option Declare

Private Const ALPHABET = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”

Public Const OOO_FONT_BOLD = 150

Public Const OOO_HALIGN_NORMAL = 0

Public Const OOO_HALIGN_LEFT = 1

Public Const OOO_HALIGN_CENTER = 2

Public Const OOO_HALIGN_RIGHT = 3

%REM

public const XSHEETCONDITION_OPERATOR_NONE =

public const XSHEETCONDITION_OPERATOR_EQUAL =

public const XSHEETCONDITION_OPERATOR_NOT_EQUAL =

public const XSHEETCONDITION_OPERATOR_GREATER =

public const XSHEETCONDITION_OPERATOR_GREATER_EQUAL =

public const XSHEETCONDITION_OPERATOR_LESS =

public const XSHEETCONDITION_OPERATOR_LESS_EQUAL =

public const XSHEETCONDITION_OPERATOR_BETWEEN =

public const XSHEETCONDITION_OPERATOR_NOT_BETWEEN

public const XSHEETCONDITION_OPERATOR_FORMULA =

%END REM

Public Class OpenOfficeAutomation

Private m_oSM As Variant

Private m_oDesk As Variant

Private m_doc As Variant

Private m_filename As String

Private m_frame As String

Private m_urlFilename As String

Private m_currentSheet As String



'

'Converts a Ms Windows local pathname in URL (RFC 1738)

'

Private Function ConvertToUrl(strFile) As String

	If Left( strFile, 2 ) = "\\" Then strFile = Mid$( strFile, 3 )

	strFile = Replace(strFile, "\", "/")

	strFile = Replace(strFile, ":", "|")

	strFile = Replace(strFile, " ", "%20")

	strFile = "file://" + strFile

	ConvertToUrl = strFile

End Function



'

'A simple shortcut to create a service

'

Public Function CreateUnoService(Byval strServiceName As String) As Variant

	Set CreateUnoService = m_oSM.createInstance(strServiceName)

End Function



'

' The filename to which we will ask OO to load & save

'

Property Get Filename As String

	Filename = m_filename 

End Property



Property Set Filename As String

	m_filename = Filename

	m_urlFilename = ConvertToURL( Filename )

End Property



Property Set Visible As Boolean

	Dim oDocCtrl As Variant

	Dim oDocFrame As Variant

	Dim oDocWindow As Variant

	

	Set oDocCtrl = m_Doc.getCurrentController()

	Set oDocFrame = oDocCtrl.getFrame()

	Set oDocWindow =  oDocFrame.getContainerWindow()

	

	

	oDocWindow.setVisible( Visible ) 

End Property





'

' A URL version of the filename

'

Private Property Get URLFilename As String

	URLFilename = m_urlFilename

End Property





'

' The frame in to which documents are loaded and created

'

Property Get TargetFrame As String

	TargetFrame = m_Frame

End Property



Property Set TargetFrame As String

	m_Frame =	TargetFrame 

End Property



'

' THe current sheet that cell operations are performed on

'

Property Get CurrentSheet As String

	CurrentSheet = m_currentSheet

End Property



Property Set CurrentSheet As String

	m_currentSheet = CurrentSheet

End Property



'

' The constructor

'

Sub New

	Set m_oSM = CreateObject("com.sun.star.ServiceManager")

	Set m_oDesk = CreateUnoService("com.sun.star.frame.Desktop")

	TargetFrame = "_blank"

End Sub



Public Function ObtainStructure( byName As String ) As Variant

	Set obtainStructure = m_oSM.Bridge_GetStruct( byName )

End Function



Private Function MakePropertyValue(cName, uValue) As Variant

	Dim oPropertyValue As Variant

	

	Set oPropertyValue = m_oSM.Bridge_GetStruct("com.sun.star.beans.PropertyValue")

	oPropertyValue.Name = cName

	oPropertyValue.Value = uValue

	

	Set MakePropertyValue = oPropertyValue

End Function



Sub OpenDocument( Byval ReadOnly As Boolean )

	Dim OpenPar(0) As Variant 

	

	Set OpenPar(0) = MakePropertyValue("ReadOnly", ReadOnly)

	

	

	Set m_doc = m_oDesk.loadComponentFromURL(URLFilename, TargetFrame, 0, OpenPar)

	

End Sub





Private Sub CreateOpenOfficeDocument( Byval docType As String )

	Dim arg() As Variant

	Set m_doc = m_oDesk.loadComponentFromURL( docType, TargetFrame, 0, arg() )

End Sub



Public Sub CreateCalc

	CreateOpenOfficeDocument( "private:factory/scalc" )	

	CurrentSheet = "Sheet1"

End Sub





Public Sub CreateWriter

	CreateOpenOfficeDocument( "private:factory/swriter" )

End Sub



Public Sub PrintDocument

	m_doc.print

End Sub



Public Sub SaveDocumentAsPDF

	Dim SaveParam(0) As Variant 'Parameters to save the doc

	

	

	Set SaveParam(0) = MakePropertyValue("FilterName", "writer_pdf_Export")

	Call m_doc.storeToURL( URLFilename & ".pdf", SaveParam )

	

End Sub



Public Function GetCell( Column As Integer, Row As Integer ) As Variant

	Dim oSheet As Variant

	

	Set oSheet = m_doc.Sheets.getByName(CurrentSheet)

	Set GetCell=oSheet.getCellByPosition( Column, Row )

End Function



Public Sub CloseDocument

	m_doc.Close( True )

End Sub



Public Function GetCellValue( Column As Integer, Row As Integer ) As Variant

	Dim oCell As Variant 

	Set oCell = getCell( Column, Row )

	GetCellValue =  oCell.Value

End Function





Public Function GetCellFormula( Column As Integer, Row As Integer ) As String

	Dim oCell As Variant 

	Set oCell = getCell( Column, Row )

	GetCellFormula =  oCell.Formula

End Function





Public Function GetCellString( Column As Integer, Row As Integer ) As String

	Dim oCell As Variant 

	Set oCell = getCell( Column, Row )

	Print oCell.String

	GetCellString =  oCell.String

End Function



Public Function SetCellValue( Column As Integer, Row As Integer, value As Variant ) As Variant

	

	Set SetCellValue = getCell( Column, Row )

	SetCellValue.setValue(value)

	

End Function



Public Function SetCellString( Column As Integer, Row As Integer, value As String ) As Variant

	

	Set SetCellString = getCell( Column, Row )

	SetCellString.setString(value)

End Function



Public Function SetCellFormula( Column As Integer, Row As Integer, value As String ) As Variant

	

	Set SetCellFormula = getCell( Column, Row  )

	SetCellFormula.setFormula value 

	

End Function



Public Sub SaveDocumentAs( szFilename As String )

	filename = szFilename

	SaveDocument

End Sub



Public Sub SaveDocument

	Dim arg() As Variant 

	m_doc.storeAsURL  URLFilename, arg() 

End Sub



Public Function  SelectRange( StartColumn As Integer, StartRow As Integer, EndColumn As Integer, EndRow As Integer ) As Variant

	Dim oSheet As Variant

	Set oSheet = m_doc.Sheets.getByName(CurrentSheet)

	Set selectRange = oSheet.GetCellRangeByPosition( StartColumn, StartRow, EndColumn, EndRow )

End Function



Public Function ProtectDocument( Byval Password As String )  As Boolean

	ProtectDocument = m_doc.Protect( password)

’ ProtectDocument = m_doc.isProtected

End Function



Public Function ProtectSheet( Byval Password As String )  As Boolean

	Dim oSheet As Variant

	

	Set oSheet = m_doc.Sheets.getByName(CurrentSheet)

’ m_doc.protect Password

	ProtectSheet = oSheet.Protect( password)

’ ProtectSheet = oSheet.isProtected

End Function



Public Sub ChangeColumnWidth( Index As Integer, WidthInMM As Long )

	

	Dim oSheet As Variant

	Dim oColumn As Variant 

	

	Set oColumn = getColumn( Index )

	oColumn.Width = WidthInMM * 100

End Sub



Public Function GetColumn( Index As Integer ) As Variant

	Dim oSheet As Variant

	Set oSheet = m_doc.Sheets.getByName(CurrentSheet)

	Set GetColumn = oSheet.columns.getByIndex( Index )

End Function





Public Function GetRow( Index As Integer ) As Variant

	Dim oSheet As Variant

	Set oSheet = m_doc.Sheets.getByName(CurrentSheet)

	Set GetRow = oSheet.Rows.getByIndex( Index )

End Function







Public  Function LongToSpreadSheet( Byval i As Long ) As String

	Dim iResult As Long

	LongToSpreadSheet = ""

	While i >=1

		iResult = i Mod 26

		If iResult = 0 Then iResult = 26

		LongToSpreadSheet = Mid$(  ALPHABET, iResult, 1) & LongToSpreadSheet			

		i = ( i -  iResult )  \ 26

	Wend

End Function

’ Given a sheet number, column number, and row number, returns the standard spreadsheet syntex, :

Public Function ConvertToString( Byval iColumn As Integer, Byval iRow As Integer ) As String

	Dim szSheet As String

	Dim szCol As String

	Dim szRow As String

	Dim iResult As Integer

	

	If ( iColumn < 0 ) Or ( iRow < 0 ) Then

		Stop

	Else

		ConvertToString = LongToSpreadSheet( iColumn + 1 ) & Cstr( iRow + 1 )

	End If			

	

	

End Function

End Class