Top小ネタ色々Excelで有効数字

Excelで有効数字

2010年1月23日


13.そして、3桁へ・・・

さて、2桁ができたので、同じように考えて3桁にも挑戦。
同じように考えていたのだが、こちらは分岐が多そうなので、ちょっと違うプログラムにしてみた。

まず、何が違うかというと、後ろに追加する可能性のある文字列がやや多い。
2つのゼロを追加しないといけない「00」「.00」の他、1つのゼロで事足りる「0」「.0」という可能性もある。

では、どんな場合に起こるのか、という事なのだが、これもじ〜っと数字を見ながら考えていた。
そして、分かったのが、とりあえず、2桁と同じように末尾がゼロになるかどうかを評価した後で、
もう1つ上の位まで調べて、そこもゼロになるかどうか評価すれば楽そうだという事。

人間の頭で考えている時は一瞬なのに、何故こんなにも難しくなるんだ?

方針が決まったら場合分け。末尾が0になるのは、2桁の時と同じで、
四捨五入する位ともう1つ上の位が00〜04、95〜99の時。
さらに、末尾が00となるのは、000〜004、995〜999の時。
どうやら、この2段構えでいけばいいらしいのだ。

つまり、2桁を調べて末尾がゼロになるかを調べ、
その上で、さらに3桁を調べてゼロが2つ付くかを調べれば漏れが無さそう。

それにしたって、これらを一気に全部If文で入れ子にすると大変なことになりそうなので、
Booleanの変数を導入することに。その名もaddZeroaddZeroZero
我ながらセンスの無さに惚れ惚れしてしまう。

そして、3桁を調べないといけないので、3桁を取り出した時の受け皿としてlastThreeDigitも宣言しておく。
勿論、2桁も調べるのでlastTwoDigitも健在。
これら2つの変数への代入は2桁のところと同じ発想で移植してくる。つまり、

lastTwoDigit = Right(Int(Abs(myCellValue) * 10 ^ (3 - Int(Log(Abs(myCellValue)) / Log(10)))), 2)
lastThreeDigit = Right(Int(Abs(myCellValue) * 10 ^ (3 - Int(Log(Abs(myCellValue)) / Log(10)))), 3)

となる。

四捨五入する位置が4桁目なので、Intの前の数字が2から3になっているのと、
2桁と3桁を抜き出すのでRightの最後に出てくる抜き出す文字数が2と3になっているくらいの違い。

あとはこれらを上手く組み合わせて、組み込んでいけばいい。
あとはパターンをどう分けるか・・・だけである。

このパターンについては言葉で書くよりも、表に書いた方が早い。
今回はaddZeroがTrueかFalseかで最初の分岐を行っているが、
丸めた後の絶対値で最初の分岐を行ってもいいかもしれない。
また、絶対値の後にaddZeroZeroを評価しているが、これもよく分からない。
何となくプログラムを書いていて、この順番が頭の整理をしながら書き易かったというだけです。
処理としてどの順番が一番早いのかは・・・よく分からない。

addZero 丸めた後の絶対値 丸める前の絶対値 addZeroZero 付け加える文字列
True 100以上 99.5以上 True/False なし
10以上100未満 9.95以上99.5未満 True/False 0
1以上10未満 0.995以上9.95未満 True .00
False 0
1未満 0.995未満 True 00
False 0
False なし

ここまで分かれば、後はこれを実際のIf文などに書き起こしていくだけである。
今回はElseIfNotという演算子も使っているが、大したものではないので、ヘルプの検索でもして頂きたい。

さぁ、これで3桁も出来上がったので、長くなるが3桁のスクリプトを全部載せておく。
ここまで書いてきた事を見れば、きっと理解できる筈・・・(希望)。

Sub significantFigure3()

Call significantCancel '重複防止の為、一度呼び出す

'変数の定義
Dim myRange As Range
Dim myCellFormula As String '式として変換する為の変数
Dim myCellValue As Variant 'variantで数字と文字列の判定
Dim startFrom As Variant 'variantで1文字目を取得
Dim lastTwoDigit As Integer '残る桁とその1つ下の桁の判定
Dim lastThreeDigit As Integer '残る桁2つとその下の桁の判定
Dim isMinus As Boolean '負の数の判別用
Dim isNotZero As Boolean '0でないことの確認
Dim stringAddition As Boolean '文字列を追加する必要性の有無
Dim addZero As Boolean '丸めた後の数の末尾が0
Dim addZeroZero As Boolean '丸めた後の数の末尾が00

Set myRange = Application.Selection


For Each c In myRange.Cells '個々のセルを抽出
myCellFormula = c.Formula
myCellValue = c.Value

isNotZero = True
addZero = False
addZeroZero = False

If Len(myCellFormula) > 0 Then '空白セルをエスケープ
	If IsNumeric(myCellValue) Then '文字列セルをエスケープ


	'値が正か負か0かを判定。
	'isMinusのBooleanに値を代入
	Select Case myCellValue
	Case Is < 0
		isMinus = True
	Case Is > 0
		isMinus = False
	Case Is = 0
		isNotZero = False
	End Select

	If isNotZero Then

		'セルの先頭文字を取得して式か数かを判定。
		'式なら=を除去
		startFrom = Left(myCellFormula, 1)
		If startFrom = "=" Then
			myCellFormula = Mid(myCellFormula, 2)
		End If
        
		'ここで丸めを実行
		c.Formula = "=ROUND(ABS(" & myCellFormula & "),2-INT(LOG10(ABS(" & myCellFormula & "))))"
    
		'負の数の場合、マイナスを復活させる。
		If isMinus Then
			c.Formula = c.Formula & "*(-1)"
		End If


		'末尾の0、.0、.00の処理
		lastTwoDigit = Right(Int(Abs(myCellValue) * 10 ^ (3 - Int(Log(Abs(myCellValue)) / Log(10)))), 2) '2桁の取り出し
		lastThreeDigit = Right(Int(Abs(myCellValue) * 10 ^ (3 - Int(Log(Abs(myCellValue)) / Log(10)))), 3) '3桁の取り出し

		If lastTwoDigit >= 95 Or lastTwoDigit <= 4 Then
			If lastThreeDigit >= 995 Or lastThreeDigit <= 4 Then
				addZeroZero = True
			End If
			addZero = True
		End If

		If addZero Then 'そもそもの必要性の判断
			If Abs(myCellValue) < 99.5 And Abs(myCellValue) >= 9.95 Then '10の位までの数。「.0」を追加
				c.Formula = c.Formula & "&"".0"""
				c.HorizontalAlignment = xlRight
			ElseIf Abs(myCellValue) < 9.95 And Abs(myCellValue) >= 0.995 Then '1の位までの数。
				If Not addZeroZero Then
					c.Formula = c.Formula & "&""0"""
					c.HorizontalAlignment = xlRight
				Else
					c.Formula = c.Formula & "&"".00"""
					c.HorizontalAlignment = xlRight
				End If
			ElseIf myCellValue < 0.995 Then '1より小
				If Not addZeroZero Then
					c.Formula = c.Formula & "&""0"""
					c.HorizontalAlignment = xlRight
				Else
					c.Formula = c.Formula & "&""00"""
					c.HorizontalAlignment = xlRight
				End If
			End If
		End If
	End If
	End If
End If

Next

End Sub

これで有効数字を3桁のプログラムも完成した事になる。


[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14]

<<Prev. | 小ネタTOP | NEXT>>