ロックマンです。
今回は最近触ってるEXCELツール(VBAマクロ)の作成時の気付きについて忘備録として記事を挙げさせていただきます。(その2)
最初に
VBA嫌いじゃ~~~~~~~~~~~~~~~~~~~~!!!!!!!!
:
:
こほん。
やりたいこと
実数(小数点付き)のデータを整数化をする。
今回の要件では切り捨てをおこなう事になった。
初めにどう考えたか?
Roundがあることは知っていた。ので
Floor,ceil的な物があるだろうと思った。
ないんだな、それが(画像略)
後はだいたいCastすればだいたい解決できると思った。
そうはならなかった。ならなかったんだよ、ロック(画像略)
実験対象
以下の処理を行う。
- Int(数値)
- FIX(数値)
- CInt(数値)
- Application.WorksheetFunction.RoundDown(数値,桁数)
実証
IntとFix
結論としては、この2つで切り捨てはできました。
プラス値では挙動は同じですが、マイナス値のときに挙動が変わります。
Int と Fix はどちらも、number の小数部分を除去して、結果の整数値を返します。 Int と Fix の違いは、number が負の場合、Int は number 以下で最初の負の整数を返すのに対し、Fix は number 以上で最初の負の整数を返します。
コード
Dim p1 As Double, p2 As Double, p3 As Double
Dim m1 As Double, m2 As Double, m3 As Double
p1 = 0.5: p2 = 1: p3 = 1.5
m1 = -0.5: m2 = -1: m3 = -1.5
Debug.Print (Int(p1) & " " & Int(p2) & " " & Int(p3))
>>> 0 1 1
Debug.Print (Int(m1) & " " & Int(m2) & " " & Int(m3))
>>> -1 -1 -2
Debug.Print (Fix(p1) & " " & Fix(p2) & " " & Fix(p3))
>>> 0 1 1
Debug.Print (Fix(m1) & " " & Fix(m2) & " " & Fix(m3))
>>> 0 -1 -1
RoundDownとCast(Cint)
RoundDownはマークシート関数ですが、結果としてはFIXと同じ挙動になります。が私としてはワークシート関数は可読性が悪いので極力使わないに越したことがないので、FIXでええやんとなります。
問題はCAST(CInt)、コードをみてもらうと分かりますが。
0.5が 0、1.5が 2 になります。...四捨五入じゃない!?
これはCastの記事に書いてありました
小数点以下が 0.5 の場合、CInt および CLng は、常に一番近い偶数に数値を丸めます。 たとえば、0.5 は 0 に、1.5 は 2 に丸められます。
なんでそうなんねん!!!!!!!!
コード
Dim p1 As Double, p2 As Double, p3 As Double
Dim m1 As Double, m2 As Double, m3 As Double
p1 = 0.5: p2 = 1: p3 = 1.5
m1 = -0.5: m2 = -1: m3 = -1.5
Debug.Print (Application.WorksheetFunction.RoundDown(p1, 0) & " " & Application.WorksheetFunction.RoundDown(p2, 0) & " " & Application.WorksheetFunction.RoundDown(p3, 0))
>>> 0 1 1
Debug.Print (Application.WorksheetFunction.RoundDown(m1, 0) & " " & Application.WorksheetFunction.RoundDown(m2, 0) & " " & Application.WorksheetFunction.RoundDown(m3, 0))
>>> 0 -1 -1
Debug.Print (CInt(p1) & " " & CInt(p2) & " " & CInt(p3))
>>> 0 1 2
Debug.Print (CInt(m1) & " " & CInt(m2) & " " & CInt(m3))
>>> 0 -1 -2
結論
なんでそうなんねん!CAST