FileMakerのスクリプトでバックアップを取る方法です。
ファイル名には日付と時刻を付加して保存します。さらに、あらかじめ指定した保存数を残して、古いものは削除します。
目次
1. 実際のスクリプト
「$保存数」には、残しておきたいバックアップファイルの数を入れます。
最新のバックアップファイルが保存された後、この数値を超えた分は、古いものから削除されます。
「$保存パス」は、開いているファイルの階層に「Backup」フォルダが存在する前提で書いてあります。
その「Backup」フォルダ内に日付と時刻付きでバックアップファイルを保存します。
「$保存パス」の計算式は次の通りです。後で解説します。
"file:Backup/"
& Get ( ファイル名 )
& "("
& Substitute ( Get ( 日付 ) ; "/" ; "" )
& Right ( "0" & Hour ( Get ( 時刻 ) ) ; 2 )
& Right ( "0" & Minute ( Get ( 時刻 ) ) ; 2 )
& Right ( "0" & Seconds ( Get ( 時刻 ) ) ; 2 )
& ").bak"
バックアップファイルの作成には「名前を付けて保存」ステップを使います。
「出力ファイルの指定」ダイアログに「$保存パス」を指定します。
「Eventを送信」ステップでは、コマンドプロンプトを使って古いバックアップファイルを削除しています。
計算式は次の通りです。これも後で解説します。
"cmd /c cd /d ""
& Substitute ( Get (ファイルパス) ; [ "file:/" ; "" ] ; [ Get (ファイル名) & ".fmp12" ; "" ] ; [ "/" ; "\\" ] )
& "Backup" & for /f "skip=" & $保存数 & "" %i in ('dir /a-d /b /o-n ""
& Get ( ファイル名 )
& "(??????????????).bak"') do del %i"
2. 日付と時刻を数字のみで取得する
「$保存パス」では、以下の式を使って日付と時刻を数字のみで取得しています。
Substitute ( Get ( 日付 ) ; "/" ; "" )
& Right ( "0" & Hour ( Get ( 時刻 ) ) ; 2 )
& Right ( "0" & Minute ( Get ( 時刻 ) ) ; 2 )
& Right ( "0" & Seconds ( Get ( 時刻 ) ) ; 2 )
日付は、「Get ( 日付 )」から区切り文字「/」を除去するだけです。
時刻はそう簡単にいかず、少し工夫が必要です。
別々に取得した「時、分、秒」の前に「0」を付けたうえで、Right 関数で右から2文字を取得しています。こうすることで、それぞれが2桁ずつの数字になります。
なぜこうするかというと、Hour/Minute/Seconds 関数では、数値が1桁で返ってくることがあるからです。
単に「 Hour ( Get ( 時刻 ) ) & Minute ( Get ( 時刻 ) ) & Seconds ( Get ( 時刻 ) )」としてしまうと、次の2つは同じになってしまいます。
- 12時03分45秒 →「12」「3」「45」→「12345」
- 12時34分05秒 →「12」「34」「5」→「12345」
桁数も少なくなってしまいますので、これでは何かと不都合です。
また、タイムスタンプを使った次の方法でも、桁数が少なくなる時刻があります。
Filter ( Get ( タイムスタンプ ) ; "0123456789" )
この場合、01~09時は0が省かれて1桁少なくなりますし、00秒の時にはその部分が省かれて2桁少なくなってしまいます。
3. 古いバックアップファイルを削除する
バックアップファイルが溜まり続けてしまわないように、古いものから削除しているのが「Eventを送信」の部分です。
計算式をもう一度見てみましょう。
"cmd /c cd /d ""
& Substitute ( Get (ファイルパス) ; [ "file:/" ; "" ] ; [ Get (ファイル名) & ".fmp12" ; "" ] ; [ "/" ; "\\" ] )
& "Backup" & for /f "skip=" & $保存数 & "" %i in ('dir /a-d /b /o-n ""
& Get ( ファイル名 )
& "(??????????????).bak"') do del %i"
「cmd /c」によって起動したコマンドプロンプトへ実際に渡されるコマンドは、以下のようなものになります。
cd /d "フォルダパス\Backup"
& for /f "skip=$保存数" %i in ('dir /a-d /b /o-n "ファイル名(??????????????).bak"') do del %i
まず「cd」コマンドでカレントディレクトリをバックアップフォルダに移動します。
そして、「for」コマンドを利用して「ファイル名(数字14桁).bak」というファイル名を降順に取得し、「del」コマンドで削除しています。
「skip=」の部分で「$保存数」だけ削除をスキップしますので、新しいものが「$保存数」だけ残り、古いものは削除されることになります。
削除するファイル名の部分では、「?」を並べることで14個の文字を表しています。「?」1つが任意の一文字を表します。
実際の運用中には、特定のバックアップファイルを残すために、カッコ内を別の文字列に変えておくようなことがあるかもしれません。
そのため、この部分に「*」を使わないようにしています。「*」は1つで任意の文字列を表しますので、これを使うとカッコ内の文字列の長さに関係なく削除対象になってしまいます。
コマンドプロンプトの代わりに、PowerShell を使っても同じことができますので、参考までに計算式を書いておきます。
"PowerShell /c Set-Location '"
& Substitute ( Get (ファイルパス) ; [ "file:/" ; "" ] ; [ Get (ファイル名) & ".fmp12" ; "" ] )
& "Backup/' ; Get-ChildItem -Include '"
& Get ( ファイル名 )
& "(??????????????).bak' -Name | Sort-Object -Descending | Select-Object -Skip "
& $保存数
& " | Remove-Item"
「Eventを送信」ステップではコマンドプロンプトを良く使っていますが、PowerShell の方ができることの幅が広そうなので、少しずつ勉強中です。
コマンド以外で、書き方がコマンドプロンプトのときと大きく異なるのは次の2点です。
- ファイルパスを囲う文字に「”」ではなく「’」を使う。
- コマンドを並べるのに「&」ではなく「;」を使う。
動作環境: Windows10, FileMaker Pro 16