35. 객체용 LotusScript(7) 가져오기 Excel

Microsoft Office는 대부분의 기업에서 사용할 수 있는 가장 광범위한 사무용 소프트웨어입니다.이 중 Excel은 직관적이고 편리하여 많은 회사들이 Excel 파일 형식으로 저장하고 있다.하나의 LotusNotes 응용 프로그램은 많은 상황에서 Excel 파일을 가져와야 한다. 예를 들어 프로그램이 초기화될 때 역사 데이터를 가져오고 설정 데이터를 대량으로 가져오며 인공 입력이나 다른 시스템에서 가져온 Excel 파일을 정기적으로 가져와야 한다.Excel 파일을 가져오는 기능은 원리적으로 복잡하지 않습니다. Excel 워크시트의 데이터를 읽어서 Notes 문서로 저장하는 것입니다.대상을 향한 사상을 응용하고 좋은 디자인을 더하면 통용성이 좋고 사용하기 편리한 Excel 파일을 가져오는 클래스인 Excel Importer를 쓸 수 있다.
이 클래스를 호출하는 실례를 보십시오.
Public Function Import
	Dim importer As New ExcelImporter()
	Call importer.Import("fmRecord")		
End Function

Excel Importer 클래스의 인스턴스를 만들고 Import () 메서드를 호출하면 가져오기가 완료됩니다.전송해야 할 유일한 매개 변수는 문서를 만드는 데 사용되는 폼 이름입니다.문서의 필드와 작업표열의 대응 관계라는 메타데이터는 서로 다른 방식으로 얻을 수 있다.하나의 방안은 가져올 때 하나의 보기를 지정하는 것이다. 이 보기의 각 열의 값은 상수와 공식이 없는 필드에서 나온다.작업표의 열과 보기 열이 일일이 대응한다.Excel 열의 값은 뷰의 열에 연관된 필드에 저장됩니다.두 번째 방안은 이러한 대응 관계를 Excel에 현저하게 쓰는 것이다.일반 작업표의 첫 번째 줄은 열 제목이고, 우리는 두 번째 줄에 대응하는 필드 이름을 기입한다.두 가지를 비교하면 보기를 만들고 조정하는 것은 더욱 번거롭고 색인 자원을 소모하기 때문에 Excel Importer 클래스는 두 번째 방안을 채택했다.
어떤 경우, Notes 문서의 일부 필드 값은 워크시트에 대응하는 칸의 데이터를 간단하게 복사할 수 없으며, 다른 필드나 설정된 문서에 따라 계산해야 한다.이러한 구체적인 상황에 따라 바뀌어야 하는 코드는 Excel Importer 클래스에 쓸 수 없습니다. 그렇지 않으면 통용성을 잃게 됩니다.이 경우도 에서 디자인한 이벤트 메커니즘을 응용하여 해결할 수 있다.이를 위해 Excel Importer 클래스는 EventPublisher 클래스를 계승하여 코드를 호출하여 함수를 등록하고 문서를 저장하기 전에 발생하는 이벤트에 응답합니다. 이 함수에서 현재 문서의 임의의 필드에 대한 임의의 계산을 완성할 수 있습니다.다음 예에서 SaveRecord() 함수는 Excel Importer 인스턴스를 호출하는 여러 가지 방법으로 현재 워크시트, 행, 문서 등의 정보를 얻어 Description 필드의 값을 계산합니다.LocalLib은 이 코드가 있는 스크립트 라이브러리의 이름입니다.
	Public Function Import
		Set importer=New ExcelImporter()
		Call importer.AddEventHandler("QuerySaveDoc", {Use"LocalLib":SaveRecord})
		Call importer.Import("fmRecord")		
	End Function
	
	Public Function SaveRecord()
		On Error GoTo EH
		Dim sheet As Variant
		Set sheet=importer.GetSheet()
		Dim rowNum As Integer
		rowNum=importer.GetRowNum()
		Dim doc As NotesDocument 'current imported document
		Set doc=importer.GetCurrentDoc()
		
		'from code to desc
		Dim account As String, desc As Variant
		account=sheet.Cells(rowNum, 4).Value
		Call doc.Replaceitemvalue("Account", CStr(account))
		desc=DBLookUp("vwAccount", account, 1, "")
		If Not IsEmpty(desc) Then
			Call doc.Replaceitemvalue("Description", desc)
		End If
		Exit Function
EH:
		MsgBox GetErrorMsg()
		Exit Function 
	End Function

다음은 ExcelImporter 클래스의 코드입니다.
Class ExcelImporter As EventPublisher
	Private session As NotesSession
	Private ws As NotesUIWorkspace
	Private db As NotesDatabase
	Private doc As NotesDocument 'current imported document
	
	Private xlFileName As String
	Private xlApp As Variant
	Private xlWork As Variant
	Private xlSheet As Variant
	
	Private docForm As String
	Private colNum As Integer	'column numbers in the imported Excel file
	Private rowNum As Integer	'current row number in the worksheet 
	
	Private ImportTime As String
	Public Debug As Boolean

	Sub New()
		Set session = New NotesSession
		Set ws = New NotesUIWorkspace
		Set db = session.CurrentDatabase
		
		colNum = 0
		'import from the 3rd line. The first two lines are the column title and the corresponding field name.
		rowNum = 3
		xlFileName = ""
		ImportTime = Format( Now(), "yyyy-mm-dd hh:mm:ss" )   'The time used to mark the imported documents.
	End Sub

	'The entry function. docForm is the form used to create documents.
	Public Function Import(docForm As String) As Integer
		If Not Debug Then On Error GoTo QuitApp
		Import = False
		Me.docForm = DocForm
		If Not CreateExcelObject() Then Exit Function
		Call GetColumns()
		Call ImportData()
		
		Import = True
		xlApp.Quit
		Print " "
		Exit Function
QuitApp:
		MsgBox GetErrorMsg
		If Not (xlApp Is Nothing) Then xlApp.Quit
		Exit Function
	End Function
	
	'Create an Excel COM object.
	Private Function CreateExcelObject() As Boolean
		CreateExcelObject = False
		Dim result As Variant
		result=ws.Openfiledialog(False, "Lotus Notes", "Excel files|*.xlsx|Excel 97-2003 files|*.xls")
		If IsEmpty(result) Then Exit Function
		
		me.xlFileName=result(0)
		Print "  Excel ..."
		Set xlApp = CreateObject("Excel.Application")
		If xlApp Is Nothing Then Error 6503,"  Excel.Application , Excel。"
		
		xlApp.Visible = False
		Set xlWork = xlApp.Workbooks.Open( xlFileName )
		Set xlSheet = xlWork.ActiveSheet
		
		CreateExcelObject = True
	End Function
	
	'Calculate the numbers of the effective (non-empty) columns in the Excel worksheet. 
	Private Function GetColumns
		While xlSheet.Cells(1, 1+colNum).Value><""
			colNum=colNum+1
		Wend
	End Function

	'Import the data. 10 continual rows which are empty in the first column are treated as the end of the file. 
	Private Function ImportData()
		Dim BlankRow As Integer
		
		BlankRow = 0
		While (BlankRow < 10)
			Print "  " & rowNum & " "
			If xlSheet.Cells(rowNum,1).Value = "" Then
				BlankRow = BlankRow + 1
			Else
				BlankRow = 0 
				Call ImportLine()				
			End If
			rowNum = rowNum + 1
		Wend
	End Function
	
	'Import one line of data.
	Private Function ImportLine()
		Call OnEvent("QueryCreateDoc")
		If (Not EventResult) Then Exit Function		
		
		Set doc = db.CreateDocument
		doc.Form = Me.docForm
		Dim Field As String, value As Variant
		Dim i As Integer
		
		For i = 1 To colNum
			'value=xlSheet.Cells(rowNum,i).Value 
			Call doc.ReplaceItemValue( xlSheet.Cells(2, i).Value, xlSheet.Cells(rowNum,i).Value )
		Next
		doc.ImportTime = ImportTime  'Mark all the document with the preset time.
		
		Call doc.ComputeWithForm( False, False )
                Call OnEvent("QuerySaveDoc")
		Call doc.Save( True, False )
	End Function

	%REM
		Property method. Get the current row in the Excel worksheet.
	%END REM
	Public Function GetRowNum() As Integer
		GetRowNum=rowNum
	End Function
	
	%REM
		Property method. Get the current Excel worksheet.
	%END REM
	Public Function GetSheet() As Variant
		Set GetSheet=me.xlSheet
	End Function
	
	%REM
		Property method. Get the current document.
	%END REM
	Public Function GetCurrentDoc() As NotesDocument
		Set GetCurrentDoc=me.doc
	End Function

End Class

ExcelImporter 클래스는 QueryCreateDoc 이벤트도 시뮬레이션한 것으로 볼 수 있습니다.때로는 Excel 작업표에 있는 한 줄의 데이터가 유효한지 판단하여 문서를 만드는지 여부를 결정해야 하기 때문이다.이 때 QueryCreateDoc 이벤트에 대한 응답 프로그램을 등록하고 진짜로 돌아갈 때 문서를 만들 수 있습니다.
Call importer.AddEventHandler("QueryCreateDoc", {Use"LocalLib":EventResult=CheckRecord()})

좋은 웹페이지 즐겨찾기