ファイルメーカーを閉じるとき〔ウインドウの処理とバックアップ〕

ファイルを閉じるときの動作を分岐するスクリプトです。

他のFM(ファイルメーカー)のファイルが開いていたら現在のファイルを閉じるだけにして、他に開いているファイルが無ければアプリケーションを終了させる方法です。

内容解説

デザイン関数にある WindowNames で開いているウインドウの一覧を取得できるので、それを ValueCount に入れてウインドウの数を取得しています。

ウインドウが2個以上あれば他のファイルが開いているので現在のファイルだけを閉じますし、1個であれば他のファイルは開いていないのでアプリケーションを終了します。

もし現在のファイルで複数のウインドウを開いているならそれに合わせて数値は変更してください。

最初の方では閉じるかどうかを尋ねるダイアログを表示しています。

FMのダイアログはデフォルトボタンが「OK」になっていますが、なんとなく Enter を押したら先に進んでしまうこの仕様に慣れないため、デフォルトボタンは「キャンセル」、ボタン2は「OK」にしています。

  なのでスクリプトで分岐するときは Get ( 最終メッセージ選択 ) = 2 の条件が「OK」ボタンのときになっています。

バックアップを取る

閉じるときにバックアップを取りたいこともあるでしょう。しかも自動で。しかも別ドライブに!

FM7のスクリプトではファイルの保存機能がお粗末なので(失礼)、コマンドプロンプトを使います。

2行追加してみました。

まず、名前を付けて保存で最適化したファイルを保存します。

これだと現在のファイルと同じフォルダ内に「バックアップ.fp7」という名前で上書き保存されていきます。

気をつけなければいけないのは完全パス(いわゆる絶対パス)を使って別ドライブを指定したいときです。同じPCでしかも同じ環境で運用するならドライブ文字が決まっていますので、出力ファイルパス一覧に完全パスを書いてしまっても構いません。

ですが、ファイルを人に渡したりする場合、PCの環境によってドライブ文字が変わることは十分に考えられます。これに対応しようとしても出力ファイルパス一覧をフィールド内容や変数で指定することはできません。(そもそもFM7には変数というものが無いですけども)

なので Eventを送信 に下記のように記述してコマンドプロンプトで実行させます。

"cmd /c move \"" & Substitute ( Middle ( Get ( ファイルパス ) ; 7 ; Length ( Get ( ファイルパス ) ) - Length ( Get ( ファイル名 ) ) - 10 ) ; "/" ; "\\" ) & "バックアップ.fp7\" \"" & 保存先ファイルパス & "\""

保存先ファイルパス の部分には「保存先の絶対パスファイル名.拡張子」を入れたフィールドなどを指定してください。フィールドで指定できるのでパスの指定が自由になります。

わかりやすくカスタムダイアログボックスで表示させてみたものがこちら↓。保存先ファイルパスはとりあえず文字列で表示。

今は本体のファイルが E:\Ekafp7 というフォルダに入っているのでこうなりました。これで バックアップ.fp7 が保存先ファイルパスに移動します。

簡単に内容を見ていくと、

cmd でコマンドプロンプトが起動します。
/c は実行後にコマンドプロンプトを終了させるオプション。
move は移動させるコマンドですが、同時にリネームも可能です。

なので保存先ファイル名にタイムスタンプを仕込んで、複数のバックアップを保存しておくこともできます。拡張子も「.fp7」にこだわらず「.bak」にしておくこともできます。元の バックアップ.fp7 を残しておきたければ move の代わりに copy を使います。

ファイルパスがダブルクォーテーションマーク「”」で囲まれているのは、パスの中に空白が含まれていたときに対応するためです。

また、FM7のファイルパスは「/」で区切られますが、コマンドプロンプトでは「\」に変換しておかないと動作しませんので Substitute を使って変換しています。

保存先のフォルダパスが無効だった場合はエラーになり、そのままコマンドプロンプトが閉じてしまいますのでユーザーには知らされません。

保存先フォルダパスが有効かどうかも事前に調べられますが、1度実行してみて保存されたか確かめれば良い話なのでこれはいいでしょう(自分では事前にスクリプトで調べています。解説を面倒がっているわけではないですよ)。

FM8以降は触ったことがないので知りませんが、このあたりはさぞ改善されていることでしょうね。
変数が使えるバージョンからは困らないのかも。よく知りませんが…

おまけ

最後に記録として1つ。Eventを送信の部分で記述すると、バックアップ.fp7 が「本体ファイル名(タイムスタンプ数字14桁).bak」にリネームされて保存先に別名保存されて、保存数だけ残るようにするコマンド。これなら複数のバックアップを残しておける。長いから解説面倒なのでほぼ自分用。

2015.12.22修正

"cmd /c copy \"" & Substitute ( Middle ( Get ( ファイルパス ) ; 7 ; Length ( Get ( ファイルパス ) ) - Length ( Get ( ファイル名 ) ) - 10 ) ; "/" ; "\\" ) & "バックアップ.fp7\" \"" & Substitute ( Substitute ( バックアップフォルダパス ; "/" ; "\\" ) & "\\" ; "\\\\" ; "\\" ) & Get ( ファイル名 ) & "(" & Substitute ( Left ( GetAsText ( Get ( タイムスタンプ ) ) ; 10 ) ; "/" ; "" ) & Case ( Position ( GetAsText ( Get ( タイムスタンプ ) ) ; ":" ; 1 ; 1 ) - Position ( GetAsText ( Get ( タイムスタンプ ) ) ; " " ; 1 ; 1 ) = 3 ; Middle ( GetAsText ( Get ( タイムスタンプ ) ) ; Position ( GetAsText ( Get ( タイムスタンプ ) ) ; " " ; 1 ; 1 ) + 1 ; 2 ) ; "0" & Middle ( GetAsText ( Get ( タイムスタンプ ) ) ; Position ( GetAsText ( Get ( タイムスタンプ ) ) ; " " ; 1 ; 1 ) + 1 ; 1 ) ) & Middle ( GetAsText ( Get ( タイムスタンプ ) ) ; Position ( GetAsText ( Get ( タイムスタンプ ) ) ; ":" ; 1 ; 1 ) + 1 ; 2 ) & Case ( PatternCount ( GetAsText ( Get ( タイムスタンプ ) ) ; ":" ) = 1 ; "00" ; Right ( GetAsText ( Get ( タイムスタンプ ) ) ; 2 ) ) & ").bak\" & cd /d \"" & Substitute ( Substitute ( バックアップフォルダパス ; "/" ; "\\" ) & "\\" ; "\\\\" ; "\\" ) & "\" & for /f \"skip=" & バックアップ保存数 & "\" %B in ('dir /a-d /b /o-n \"" & Get ( ファイル名 ) & "(??????????????).bak\"') do del %B"

バックアップフォルダパス にバックアップ先フォルダ名を入れたフィールドを設定。パスの最後の「\」はあってもなくても自動で調整するようにしています。
バックアップ保存数 に保存して残す数を入れたフィールドを設定。古いものから削除されます。

カスタムダイアログボックスに表示してみるとこんな感じ↓。「テストファイル.fp7」というファイルから2015年12月19日14時40分05秒に実行するとこうなります。

よくわかりませんねw

cmd に渡すコマンドは & で継げば連続して実行されます。何個までいけるかは未検証。

バックアップフォルダにリネームしつつ copy して、cd でバックアップフォルダをカレントディレクトリにしてから、del で保存数だけ残して削除するという流れです。

もしご自身で作成される場合は、コマンド1つごとに分けて記述して後で全部継げたほうが良いと思います。

なんか少し解説してしまいましたがとにかく動けば良し。

ちなみにMacでどうやるのかはわかりません。ターミナルというのがコマンドプロンプトのように使えるみたいですが、うちにMacが無いので検討できません。。

iPad欲しいです。
FMのためじゃなくてG-Bowlっていうアプリを使ってみたい☆
豆腐屋さんの水コップを再現できるらしいですよ(何のことやら)。

Leave a comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

seven + 6 =