先日このような記事を公開した
この記事で作成した関数を組んでいる途中に想定外の事態が発生したので備忘録
思わぬ変換
ちなみにFormat関数はどのようなのか。
Format関数
Format(Expression, [Format], [FirstDayOfWeek], [FirstWeekOfYear])
引数 | 内容 |
---|---|
Expression | 必須。表示を変更したい文字列を指定 |
Format | 書式を設定 |
FirstDayOfWeek | 週の最初の曜日を指定する定数 |
FirstWeekOfYear | 年内で最初の曜日を指定する定数 |
引数「Expression」で指定した文字列を、引数「Format」で指定した書式に変換する関数です。
ExcelのText関数と同等の機能です。
例えばこのように使用します。
想定外の変換
ではどのような想定外の変換が発生したのか。
上記画像内で「"10"」「"1A"」「"1B"」という文字列を「00000000」という書式で変換しようとしています。
これは16進数の表記で頭ゼロを補完しようという意図でした。
10は予定通り。
1Bは予定外でしたが、よく考えれば想定の範囲内。
ところが1Aのみ完全に想定外の動きです。
1Bと同じ動きをしないどころか、10とも違い全てが0で表示されています。
なぜこのような動作になったのでしょうか?
原因追求
原因を突き止めるために下記のようなコードを実行しました。
Sub Format_Sample() Dim i As Long Dim ans As String For i = 1 To 100 ans = i & "A" Debug.Print Format(ans, "00000000") Next End Sub
結果はこの様になりました。
24以降は想定内の動きですが、1から23の動きが想定外です。
ちなみに「A」以外にも「P」も同様の想定外の動きをします。
悩んでいたところtwitterで助け舟を頂きました。
よく分かりませんが、
— 踊るエクセル@VBEアドイン作ってVBEハック中・・・ (@ExcelVBAer) 2022年1月9日
MSのサイトを見ると、
日付や時刻に関する説明が
多数ありました💡
A,Pが、AM,PMとして扱われているとか?!?!🤔💦https://t.co/othwAoRNIs pic.twitter.com/SpHBV4ZzHj
なるほど!
AとP、1から23の数値だけ想定外の動きをしていることと一致します。
仮説検証
先程の想定を下記のコードで検証してみます。
Sub Format_Sample() Dim i As Long Dim ans As String For i = 1 To 100 ans = i & "A" Debug.Print ans & vbTab & _ Format(ans, "00000000") & vbTab & _ Format(ans, "0.####") Next End Sub
結果はこの様になりました。
1Aのところをみると0.0417をという値が表示されています。
これは「1 ÷ 24 ≒ 0.0417」で1時間を表しています。
つまり仮説のとおりAないしPをつけることで暗黙的に日付・時刻に変換されていると考えられます。
まとめ
引数「Format」では無く、引数「Expression」の値で型変換が行われるという想定外の事でモヤモヤと悩んでしまいました。
結論として自作の進数変換関数では16進数には頭ゼロをつけないことにしたので、今回の検証結果を活用することはなかったのですが、手探りで遠回りをしたことで勉強になりました。