40.オブジェクト向けLotusScript(十二)のSheetWriter


ここでは、Excelワークシートのセル値を書き込むときに使用するツールクラス:SheetWriterについて説明します.Excelワークシートのオブジェクトハンドルを取得した後、その中のセルを書くのはもともと平凡なことです.
sheet.Cells(2, 3).Value=”Book”
しかし、プログラムでは、連続したセルを大量に書くと、少し煩雑になります.以前のレポート・サンプルでは、上記のように直接書くと、このようなコードに似ています.
…
While Not doc Is Nothing
	rowNum = rowNum + 1
	‘Write each column in the current row
	‘Column book
	sheet.Cells(rowNum, 1).Value=doc.Book(0)
	‘Column price
	sheet.Cells(rowNum, 2).Value=doc.Price(0)
	‘Column book number
	sheet.Cells(rowNum, 3).Value=doc.BookNumber(0)
	…
	set doc = dc.GetNextDocument(doc)
Wend

循環体では、記録行数の変数を増やすことを覚えておいてください.一般的に、ある列の値は特定の計算を行う必要があり、列数も行数のように循環することはできず、1列を書くたびにsheetを書かなければならない.Cells(rowNum, 2).Value.これにより、値の書き込み中に現在のセルの位置を明確に操作する必要があります.これにより、特にレポートが複雑で、ワークシートの異なる領域に関連している場合や、カラム値の計算が複雑で、個別のメソッドに配置されている場合に発生しやすくなります.
SheetWriterはこの問題を解決するために開発されたのです.現在のセルの位置を常に心配することなく、簡単な方法を呼び出して、書く値を入力します.
このクラスのフィールドもメソッド名も簡単明瞭で、コメントも付いています.最も一般的な場合は、インスタンスwriterを作成してレポートの初期位置MoveTo()に移動し、ループに値WriteCell()を書き込み、NextRow()を改行すればよいだけです.他のいくつかの属性と方法は、より複雑で特殊な状況のためです.たとえば、レポートの一部が縦にループして書く必要がある場合、writerのモードをMODE_に設定できます.COLUMN、これはwriterが1つのセルを書くたびに1つ下に移動するので、普通の横書きのように右に1つ移動するのではありません.1列書き終わったらNextColumn()と入れ替え、この時点でジャンプするセルがある行数、つまり書き込まれている四角形領域の上界TopBoundを設定することもできます.これらのアプリケーションは39.オブジェクト向けLotusScript(十一)の書き出しExcel(三)に見えます.
%REM
	Class SheetWriter
	Description: Comments for Class
%END REM
Public Class SheetWriter
	Private sheet As Variant 'xls sheet
	Public row As Integer
	Private col As Integer
	Public LeftBound As Integer 'The most left column of the current region
	Public TopBound As Integer 'The most top column of the current region   
	Public MODE_ROW As Integer 'Write horizontally
	Public MODE_COLUMN As Integer 'Write vertically
	Public Mode As Integer 
	%REM
		Sub New
		Description: Comments for Sub
	%END REM
	Sub New(xlsSheet As Variant)
		Set me.sheet=xlsSheet
		me.LeftBound=1
		me.TopBound=1
		me.row=1
		me.col=1
		me.MODE_COLUMN=1
		me.MODE_ROW=0
		me.Mode=me.MODE_ROW
	End Sub
	
	%REM
		Function WriteCell
		Description: Write the current cell and move the cursor to
		the right neighbour cell
	%END REM
	Public Function WriteCell(value As Variant)
		sheet.Cells(row, col).Value=value
		If me.Mode=me.MODE_ROW then
			col=col+1
		Else
			me.row=me.row+1
		End if
	End Function
	
	%REM
		Function CurrentValue
		Description: Comments for Function
	%END REM
	Public Function CurrentValue()
		me.CurrentValue()=sheet.Cells(row, col)
	End Function
	
	%REM
		Function NextRow
		Description: Move the cursor to the next row.
	%END REM
	Public Function NextRow
		row=row+1
		col=me.LeftBound
	End Function
	
	%REM
		Function NextColumn
		Description: Move the cursor to the next column
	%END REM
	Public Function NextColumn
		col=col+1
		row=me.TopBound
	End Function
	
	%REM
		Function MoveTo
		Description: Move the cursor to the given position.
	%END REM
	Public Function MoveTo(row As Integer, column As Integer)
		me.row=row
		me.col=column
	End Function
	
	%REM
		Function MoveBy
		Description: Move the cursor the given number of cells
	%END REM
	Public Function MoveBy(rows As Integer, columns As Integer)
		me.row=me.row+rows
		me.col=me.col+columns
	End Function
	
	%REM
		Function UpdateLeftBound
		Description: Update LeftBound with the current column number
	%END REM
	Public Function UpdateLeftBound()
		me.LeftBound=me.col	
	End Function
	
	%REM
		Function UpdateTopBound
		Description: Update TopBound with the current row number
	%END REM
	Public Function UpdateTopBound()
		me.TopBound=me.row
	End Function
End Class

SheetWriterクラスがあれば、私たちが始めた例はこうなります.
…
While Not doc Is Nothing
	‘Write each column in the current row
	‘Column book
	writer.WriteCell(doc.Book(0))
	‘Column price
	writer.WriteCell(doc.Price(0))
	‘Column book number
	writer.WriteCell(doc.BookNumber(0))
	…
	call writer.NextRow()
	set doc = dc.GetNextDocument(doc)
Wend

SheetWriterが使っている考え方と問題を解決するモデルは、他の場合、他の言語でも応用の機会を見つけることができると信じています.