エクセルVBAでツールを作る時に、エクセルマクロブックを閉じても、どこかに何かの設定を保存しておきたい時がありませんか?「本日〇回目のプログラムの実行します」の〇のところを変えたい、というイメージです。
エクセルシートに書き込んでしまうのではなく、レジストリというPC内の場所にデータを保存して操作する方法について解説します。
目次
レジストリを利用して、エクセルブック外に値を保存する
レジストリとは普段は見えないフォルダのような場所です。アプリケーションなどを動かす設定値などPCを動かす大事な値が入っています。間違って消すといけないので、ムリして開こうとしないほうがよいです。とはいえ、中が気になる人もいると思うので、ココで見た目だけ紹介しておきます。
今回はVBAを使ってレジストリの中に値を書き込んだりするのですが、そこはVBAさんの優しさで、絶対に大丈夫なところにしか値を書いたり消したりできません。
VBAから使う分には安全なので、安心して利用しましょう。
今回やりたいこと
今回やりたいことは、そのマクロが本日何度目に実行されたのかを記録することです。エクセルマクロブックを閉じても、きょう実行した回数を覚えおいて欲しいと言うわけです。ついでに、最後に実行した日付も記録しておきましょう。
実務では、エクセルを開いたときに、前回実行した日次をメッセージボックスで表示して、前日処理漏れがなかったかチェックできるようにする、といった事が考えられます。
なぜエクセルシートに書き込まないほうが良いのか
まあ、ぶっちゃけどこかのシートのA1セルに書き込んでもいいです。でも、何か、ちょっと気が進まない感じです。(解説になっていない。。。)
レジストリにデータを保存して、取り出して使う
それでは、具体的にコードを記述していきましょう。
SaveSettingメソッド
レジストリに値を書き込むにはSaveSettingメソッドというのを使います。表示⇒オブジェクトブラウザで検索窓にsavesettingと打ち込んで調べたところ、下記の表示が出てきました。
4つ引数を取ります。見慣れない単語が多いですが、言い方が慣れないだけで、簡単です。何で見慣れない単語になっているかというとレジストリというのが、設定値を保存しておく場所なので、それにならっていると言うことです。順に解説します。
- AppName
フォルダのことです。レジストリの中の何というフォルダに入れておくか。レジストリ内では他の設定は、アプリごとにフォルダにまとめられているので、「アプリの名前」という変な引数の名前になっています。
この名前は何でもいいです。レジストリを操作するエクセルマクロブックの名前やモジュールの名前にでもしておけば分かりやすくていいと思います。例えば、売上処理ブック、とかですね。
- Section
フォルダの中のフォルダのことです。AppNameのフォルダの中にさらに細かくフォルダを作ってその中にファイルを置くイメージです。アプリごと(売上処理ブックのようなAppNameのフォルダごと)に、機能ごとのフォルダを用意する。その中にデータを書き込むファイルを置く作戦です。
- Key
ファイル名のことです。この中にデータを書き込みます。
- Setting
Key(=ファイル)に書き込むデータのことです。前述のように、アプリごとの設定を保存しておくのが前提なので、このような引数名になっています。単なるデータのことです。
念のためイメージを図示しておきます。こんな感じです。
SaveSettingメソッドでレジストリ内にデータを作る
データを実際に書き込んでみます。データを書き込むと言うより、データを格納してあるファイルとフォルダとその上のフォルダを同時に作ります。
Sub 本日の処理回数と最終処理日を記録する() SaveSetting "本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "処理回数", "1" SaveSetting "本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "最終処理日", Date End Sub
これで、レジストリの中にデータを格納することができました。注意すべきはSetting(=データ)の型はString型だと言うことです。
処理回数のKeyに格納する値が"1"になっています。文字列なので””をつけています*1。また、これは暫定処置で、後ほどデータを取得する方法を確認してから、本日の処理回数を格納するように書き換えます。
GetSettingメソッド
GetSettingメソッドでデータを取り出します。オブジェクトブラウザで調べると、このように表示されました。
SaveSettingメソッドの時にはなかった、「Default」という引数が書かれています。[]と書いてあるので省略可能です。これはKey(=ファイル)が見つからなかったときに返す値を表しています。
GetSettingメソッドでレジストリ内のデータを取得する
それでは、早速使っていきましょう。先ほどのSaveSettingの上に変数の宣言、下にGetSettingを追記します。
Sub 本日の処理回数と最終処理日を記録する() Dim 処理回数_str As String Dim 最終処理日_str As String SaveSetting "本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "処理回数", "1" SaveSetting "本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "最終処理日", Date 処理回数_str = GetSetting("本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "処理回数", "0") 最終処理日_str = GetSetting("本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "最終処理日", "そんな日付ありません") End Sub
これで書き込んだり取得したりすることができました。
本日の処理回数を実装して、実用的にする
あとは、レジストリの値を冒頭で1足してあげれば完成です。Val関数で数値に変換してから足しています*2。
Sub 本日の処理回数と最終処理日を記録する() Dim 処理回数_long As Long Dim 処理回数_str As String Dim 最終処理日_str As String 処理回数_long = Val(GetSetting("本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "処理回数", "0")) 処理回数_long = 処理回数_long + 1 SaveSetting "本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "処理回数", 処理回数_long SaveSetting "本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "最終処理日", Date 処理回数_str = GetSetting("本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "処理回数", "0") 最終処理日_str = GetSetting("本日の処理回数と最終処理日を記録するアプリ", "実行記録セクション", "最終処理日", "そんな日付ありません") MsgBox "本日の処理回数:" & 処理回数_str & "回" & vbCrLf & _ "最終処理日:" & 最終処理日_str End Sub
できました。
レジストリに書き込んでいる為、エクセルブックを閉じてもちゃんとカウントアップされます。エラーで処理ができなかったときやブックが存在しないときに、レジストリに書き込まないようにすれば、処理済みか処理済みでないかを判定する、最終処理日が変更されなければメールで通知するなど、工夫次第でいろんな事ができます。
いろいろと試してみましょう!