`
从此醉
  • 浏览: 1050604 次
  • 性别: Icon_minigender_1
  • 来自: US
社区版块
存档分类
最新评论

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

在循环体中,要记得增加记录行数的变量。一般情况下,某一列的值需要做一些特定的计算,无法将列数也像行数一样循环,而是每写一列的值都必须写一次sheet.Cells(rowNum, 2).Value。这样在整个写值的过程中,都必须清楚和操作当前单元格的位置。这样既累人又易出错,特别是当报表比较复杂,牵涉到工作表的不同区域,或是计算列值比较复杂,要放在单独的方法中时。

SheetWriter正是为了解决这个问题而开发的。我们只要调用它的简单的方法,传入要写的值,而无需时刻操心当前单元格的位置。

这个类的字段和方法名称都简单明了,也附有注释。最普通的情况下,只需要创建一个实例writer,将其移动到报表的初始位置MoveTo(),在循环中写值WriteCell(),换行NextRow(),就可以了。其他一些属性和方法,是为了更复杂和特殊的情况。比如当报表的某个部分是需要纵向循环书写的,就可以设置writer的模式为MODE_COLUMN,这是writer每写一个单元格就会往下移动一格,而不是像在普通的横向书写时向右移动一格;写完一列后要换列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所用到的思路和解决问题的模式,我相信在其他情况下,甚至其他语言中,都可以找到应用的机会。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics