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

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

(OpenOffice Basic)自身のファイルの最終更新日時を知りたい

セルの中に自身のファイルの最終更新日時を入れたいという話です。

自身のファイルパスは、(OpenOffice Basic)自身のファイルパスを表示するの方法で取得できます。
ファイルの更新日時は、FileDateTime 関数で取得できるようです。

とういことで、下記のようなコードになります。

Sub GetLastFileDate1()

       Dim oCell As Object
       '結果を保存するセル設定
       oCell = ThisComponent.Sheets("Sheet1").getCellRangeByName("A2")

       Dim oUrl As String
       '自身のファイルのパス取得
       oUrl = ThisComponent.getLocation() 
       
       Dim strDateTime As Date 
       'ファイルの更新日時を取得
       strDateTime = FileDateTime(  ConvertFromUrl(oUrl)  )

       'セルに書き出し
       oCell.setValue( strDateTime )
       
End Sub

'ユーザ定義関数関数として定義
Function GetLastFileDate2() as Date

       Dim oUrl As String
       '自身のファイルのパス取得
       oUrl = ThisComponent.getLocation() 
       
       Dim strDateTime As Date 
       'ファイルの更新日時を取得
       strDateTime = FileDateTime(  ConvertFromUrl(oUrl)  )
       
       '戻り値設定
       GetLastFileDate2=strDateTime
End Function

GetLastFileDate1が、マクロの内でどのセルに結果を書きだすか指定しています。ボタン等をこのプロシージャに関連付ける方法になるかと思います。
GetLastFileDate2はユーザ定義関数での利用を想定しています。

セルに =GetLastFileDate2() とすれば、そのファイルの最終更新日時が表示されます。
ただ、このユーザー定義関数は問題があり、一旦セルに設定してしまうと、このシートを次に開く時まで値が更新されません。(つまり、途中で上書保存しても値が変わらないのです)
一旦式が入ったセルをコピペすれば反映できます。なので、あまり汎用的には使えないかもしれません。

Excelでも同様の問題があるようで、VBAでは、Application.Volatile を設定すれば、他のセル更新時にユーザ定義関数も自動的に更新してくれるようです。
ちなみに、Excelで最終更新日時を取る場合は、以下のようなユーザ定義関数を作ればいいようです。

Function LastSaveTime()
     Application.Volatile
     LastSaveTime = ThisWorkbook.BuiltinDocumentProperties("Last save time").Value
End Function

OpenOfficeのマクロでは、Application.Volatileに相当するものが無いので、他のセルへの更新イベントをキーにすることは難しそうです。
一応、AddinBox/VBAユーザーの為のOpenOffice.org 備忘録:セル範囲オブジェクトを引数で受け取るで、以下のような Range4SheetFunc 関数を定義し、ユーザ定義関数の引数に以下を指定すれば、引数で指定した範囲のセルを触った時に、ユーザ定義関数の値を更新することはできそうです。
(しかし、この範囲にユーザ定義関数の埋めこむセルがあるとNGなので、結構シビヤかもしれません)

=GetLastFileDate2(RANGE4SHEETFUNC ( $A1:$Z11 ; ROW(A1) ; COLUMN(A1) ; SHEET(A1) ) )

'==========[ Range4SheetFunc ]==============
Global Function Range4SheetFunc(ByVal argTargetRange As Variant, _
                         ByVal argTargetTopRow As Long, _
                         ByVal argTargetTopColumn As Long, _
                         ByVal argTargetSheet As Integer) As Variant
                         
' e.g. argTargetRange     : F3:H5
'      argTargetTopRow    : ROW(F3)
'      argTargetTopColumn : COLUMN(F3)
'      argtargetSheet     : SHEET(F3)
'      Return             : "Sheet1.F3:H5" or Null by the error
'
'  The range object is generated with the following code by the string 
'  of the cell address.
'    If IsNull(argRange) Then
'      'Error
'      UserFunc = xxxx
'      Exit Function
'    Else
'      vntSheetRange = Split(argRange, ".")    ' e.g. argRange = "Sheet1.F3:H5"
'      oSheet = ThisComponent.Sheets.getByName(vntSheetRange(0))
'      oRange = oSheet.getCellRangeByName(vntSheetRange(1))
'    End If

Dim oSheet As Object
Dim oRange As Object
Dim lngTop As Long
Dim lngBottom As Long
Dim lngLeft As Long
Dim lngRight As Long

  On Error Goto ErrorHandler
  oSheet = ThisComponent.Sheets(argTargetSheet - 1)  'WorsheetFunction's [SHEET] is 1 origin.
 
  If IsArray(argTargetRange) Then
    lngTop = argTargetTopRow - 1
    lngLeft = argTargetTopColumn - 1
    lngBottom = lngTop + (UBound(argTargetRange,1) - 1)
    lngRight = lngLeft + (UBound(argTargetRange,2) - 1)
    oRange = oSheet.getCellRangeByPosition(lngLeft, lngTop, lngRight, lngBottom)
  Else
    oRange = oSheet.getCellByPosition(argTargetTopColumn -1, argTargetTopRow - 1)
  End If
 
  Range4SheetFunc = Join(Split(oRange.AbsoluteName, "$"),"")  'remove "$"
  Exit Function
ErrorHandler:
  Range4SheetFunc = Null
End Function

やっぱOpenOfficeは痒いところに手が届かないんですよねー。

参考:
LibreOffice Calc Basic fun!!!: ファイルサイズの最終更新日を取得
OpenOffice.org Basic
ファイルの最終更新日時を取得したい:Excel エクセルの使い方-ユーザー定義関数/VBA