3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(OpenOffice Basic)Calcでセルアクセスの高速化

OpenOffice3.2です。

ThisComponent.Sheets(0).getCellByPosition( col , row ).setString("")

などで多数のセルにアクセスすると非常に遅くなります。(特にセルのカラー等スタイルを変更する場合)

例えば選択した約12000個のセルに一斉に書き込みを行い、セルのフォントカラー変更するのに、941秒もかかってしまいました。

ということで、高速化です。

参考にしたのは[OpenOffice.org Basic] シートへの高速なアクセスです。

まず、画面更新の抑制をすることでかなり速くなるようです。

VBAでも Application.ScreenUpdating プロパティに bool 値をいれて画面更新の停止・再開をすることである程度高速化できました。

OpenOffice Basicだと、下記のコードで画面更新が制御できるようです。

ThisComponent.addActionLock()   ' 画面更新抑制

ThisComponent.removeActionLock() ' 画面更新抑制解除

これにより、先ほどの12000個のセルに対する処理は、25秒と大幅に短縮されました。

さて、さらに高速化する方法があるようです。

それは配列にためたデータで読み込み書き込みを行う方法です。

この方法を使うと1秒でセルの読み取り・書き込みが完了しました。

圧倒的な速度です。

例えばセルの現在の値(時刻フォーマット)を読み込んで1:00加算するのは下記のようなコードとなります。

Dim str As String

str = "01:00"

'まずセル内容読取る

Dim aryData() As Variant

aryData = ThisComponent.Sheets(0).getCellRangeByPosition( 0 , 0 , 100 , 100 ).getDataArray()

 

Dim iRow As Integer , iClm As Integer

For iRow = 0 To Ubound( aryData )

For iClm = 0 To Ubound( aryData(iRow) )

Dim dNowTime As Double

Dim dTime As Double

dNowTime = aryData(iRow)(iClm)

dTime = CDbl( TimeSerial( Mid( str,1,2 ) , Right(str,2) , 0 ) )

'時間を加算

aryData(iRow)(iClm) = dNowTime + dTime

Next iClm

Next iRow

 

'配列をシートにセット

ThisComponent.Sheets(0).getCellRangeByPosition( 0 , 0 , 100 , 100 ).setDataArray( aryData )