よろずやネット

最近はLibreofficeにハマっています。

LibreOffice Calc、各セルへの値の書き込みの高速化(配列を使用)

配列を使うと各セルへの値の書き込みが劇的に高速化します。
配列を使用した下記コードでは、所要時間1秒以下で10万個のセルへの書き込みが完了します。
LibreOffice Calcのマクロの欠点である「遅さ」を解決します。

【フロー】
1.データを配列に格納します。
2.データが入った配列をsetDataArrayメソッドで特定セルレンジに適用します。

Option Explicit
REM  *****  BASIC  *****
Global oDoc As Object
Global oController As Object
Global oSheets As Object
Global ArraySheets() As Variant
Global ArrayData(0,0) As Variant
' ########################################

Sub SetGlobalVar
	oDoc = ThisComponent 
	oController = oDoc.getCurrentController() 
	oSheets = oDoc.getSheets()
End Sub

Sub SetDataWithArray

	If (isnull(oDoc)) Then
		Call SetGlobalVar
	End If

	Erase ArrayData()

	Dim StartTime As Double
	Dim SecondsElapsed As Double
	StartTime = Timer
	
	Dim iRowCount As Long
	Dim iColCount As Long
	iRowCount = 1000	'行数
	iColCount = 100	'列数
	
	Redim ArrayData(iRowCount -1, iColCount -1)

'Call ScreenSetFreeze ' 前回の投稿記事を参照下さい。

	Dim i As Long
	Dim j As Long
	
	For i=0 to iRowCount-1
		For j=0 to iColCount-1
			ArrayData(i,j) = "test" & Cstr((i+1)*(j+1))
		Next
	Next

	Dim ActiveSheetName As String
	Dim oSheetName As String
	Dim oSheet As Object
	ActiveSheetName = oDoc.getCurrentController().getActiveSheet().Name
	oSheetName = ActiveSheetName
	oSheet = oSheets.getByName(oSheetName)
	
	Dim iRowTarge As Long
	Dim iColTarge As Long
	
	iRowTarge = 0
	iColTarge = 0
	
	Dim oCellRange As Object
	oCellRange = oSheet.getCellRangeByPosition(iColTarge, iRowTarge, iColTarge+iColCount-1, iRowTarge+ iRowCount-1)
	oCellRange.setDataArray(ArrayData)	

'Call ScreenUnsetFreeze ' 前回の投稿記事を参照下さい。

	SecondsElapsed = Timer - StartTime ' 経過時間(秒)を計測
	Msgbox("処理時間: " & SecondsElapsed & "秒")
	' ScreenSetFreezeなし, 1000 x 100  = 1秒
	' ScreenSetFreezeあり, 1000 x 100  = 1秒
	
End Sub 'SetDataWithArray