今回はExcelのステータスバーに電光掲示板のように文字をスクロールさせるマクロを紹介。
もともと作りたかった案件とは違うが、そちらが失敗して副産物として単体で何か使えそうな気がしたので簡単にメモ。
矢印の方向に文字が流れる。
コード
※Mainプロシージャを起動すると無限ループになるので止め方をご存知の方のみ実行してください。
#If VBA7 Then Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr) #Else Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long) #End If Sub Main() Do Application.StatusBar = RotateString("ただいまマクロを実行しています。しばらくお待ちください。", " ") DoEvents Sleep 100 Loop End Sub Private Function RotateString(cap As String, pad As String) Dim paddedString As String paddedString = String(Len(cap), pad) & cap & String(Len(cap), pad) Static i As Long If Len(cap) * 2 > i Then i = i + 1 Else i = 1 End If RotateString = Mid(paddedString, i, Len(cap)) End Function
解説
RotateString関数のStatic変数 i がポイント。
Staticで宣言した変数はプロシージャが終了しても値が保持されるので、このように呼び出すたびに違う値を返す関数を作るのに便利だ。
Staticを使いこなすコツは、「明示的に初期化しない」こと。
たとえば以下の箇所は、宣言された後、値が代入される前にIf文の判定でiを参照している。
Static i As Long If Len(cap) * 2 > i Then i = i + 1 Else i = 1 End If
Long型で宣言したなら初期値は0なので、初回の呼び出し時にiは0である。
2度目の呼び出し時には、iは前回の呼び出しの終了時点の値をキープしている。
もし以下のように0で初期化する処理を挟んでしまうと何度呼び出しても0が入ってしまい、Staticにした意味がなくなる。
Static i As Long i = 0 If Len(cap) * 2 > i Then i = i + 1 Else i = 1 End If
明示的に代入する前に参照させるのがStaticを使いこなすコツだ。
これは慣れるまでなんとなく気持ち悪いかもしれないが、そういうものだと割り切るしかない。
関数のおおまかな処理
(1) まず、引き渡された文字列に、それと同じ長さの詰め物を両サイドに敷き詰める。
詰め物 & "サンプル" & 詰め物
↓こうなる
"□□□□サンプル□□□□"
(2) iが文字列の長さの2倍未満なら、iを増分させる。
初回は0なので、iが1になる。
(3) iの値の位置から元の文字列と同じ長さを切り出す。
"□□□□"となる。
2回目の実行ではiが増えているので、"□□□サ"、3回目は"□□サン"という風に、切り出す位置を変えているだけ。
以上