[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Currency型変数からセルへの代入で小数点の桁が丸められる』(tkit)
小数点ありの計算で誤差がでないようにCurrency型変数を使っています。
セルの表示形式をユーザー定義0.000で、当該セルにCurrency型変数の値を代入すると、
小数点が3桁目で四捨五入され、0.140と表示し、数式バー上も0.14となります。
変数の値は、常に0.135です。
表示形式を通貨小数点3桁にしても、0.140のままでした。
Value2とするか変数の型をSingleまたはDoubleにすれば、正規の値となるため、
セル側でCurrency型の場合、変換していることが分かりましたが、
何か理由があるのでしょうか。
経理系はさっぱりなため、ご教示いただけると助かります。
Sub test()
Dim n As Currency
n = 0.135
Range("A1").Value = n
Range("A1").Value2 = n
Dim s As Single
s = n
Range("A1").Value = s
Dim d As Double
d = n
Range("A1").Value = d
End Sub
< 使用 Excel:Excel2016、使用 OS:Windows10 >
>セル側でCurrency型の場合、変換していることが分かりましたが、 >何か理由があるのでしょうか。
余り深く考えたことは無いですが・・
その型は、我々は小数の計算精度を高めると言うだけの意識で使いますが、 エクセルを作った米国の人達は、「通貨としての単位」を意識しており、 セントまでが有効単位であるとして「.Valueプロパティ」の処理は、 下2桁までをセルに出力する様に作り込んでいるんじゃないですかね。
(半平太) 2019/10/09(水) 16:41
回答ではないが。 Singleでセルに入れた場合は表示形式が小数点以下2桁のために0.135に見えているが数式バーでは 0.135000005364418 になっている。 (ねむねむ) 2019/10/09(水) 16:54
すまない。
>表示形式が小数点以下2桁
↓
表示形式が小数点以下3桁
(ねむねむ) 2019/10/09(水) 16:55
こんなことがあるとは知りませんでした。
セルの書式を通貨にしておくと
Range("A1").Value = Range("A1").Value
で桁落ちするという... 困った仕様ですね。 (´・ω・`) 2019/10/09(水) 17:24
元々、Single型の計算結果が、ねむねむさんのレスであるように
正規の値とならず、Double型でも上手くいかず、ネットで調べ、
Currency型に変更したという経緯でした。
仕様なんでしょうね。
代入の際、Cstr関数で文字列にして、計算の必要なセルには*1にしようと
考えています。
Sub test()
Dim n As Currency
n = 0.135
Range("A1").Value = Cstr(n)
Range("A1").Value = Range("A1").Value * 1
End Sub
(tkit) 2019/10/10(木) 08:45
>代入の際、Cstr関数で文字列にして、計算の必要なセルには*1にしようと
>考えています。
> : :
>Range("A1").Value = Range("A1").Value * 1
意図・問題点が、いまひとつ呑み込めないです。
その簡略化したコードですと、(´・ω・`)さんの実験と同じく、桁落ちしますよね?
(半平太) 2019/10/10(木) 10:08
(´・ω・`)さんの実験は前提条件として、セルの表示形式が通貨の場合なので >セルの表示形式をユーザー定義0.000 の場合(標準でも)桁落ちにはならないようだ。
(ねむねむ) 2019/10/10(木) 10:15
> その簡略化したコードですと、(´・ω・`)さんの実験と同じく、桁落ちしますよね?
桁落ちするのは、セル書式の表示形式が 通貨型 の場合なので、数値型にしておけば大丈夫です。
Value2プロパティを使ったり、
Range("A1").Value = Range("A1").Value * 1#
とするなど、浮動小数点型に明示的に変換する方が安全ですね (´・ω・`) 2019/10/10(木) 10:16
何か理解しにくいのですが、A1セルの書式は通貨じゃないんですか?
だったら、単なる小数演算誤差の話じゃないですか?
提示された(簡略化した)コードじゃ、たたき台にならないです。 (Currency型を使う意味がどこにもない)
もっと議論するにふさわしいコードをアップしてください。
(半平太) 2019/10/10(木) 10:22
Sub test()
Dim n As Variant
With Range("A1")
'▼ユーザー定義0.000
.NumberFormatLocal = "0.000"
'▼Single型代入 セルA1の表示"0.135" シリアル値"0.135000005364418"←だからCurrency型に変更
n = 0.14! - 0.005!
.Value = n
'▼Currency型代入 セルA1の表示"0.140" シリアル値"0.14"←ここが問題(0.135ではない)
n = 0.14@ - 0.005@
.Value = n
'▼対策として、String型にする。
.Value = CStr(n)
'▼表示で、文字列に数字が〜 の対策でした。
.Value = .Value * 1#
End With
End Sub
(tkit) 2019/10/10(木) 12:12
> '▼Currency型代入 セルA1の表示"0.140" シリアル値"0.14"←ここが問題(0.135ではない) > n = 0.14@ - 0.005@ > .Value = n > '▼対策として、String型にする。 > .Value = CStr(n) > '▼表示で、文字列に数字が〜 の対策でした。 > .Value = .Value * 1#
そこの部分が、回りくどくて理解に苦しむなぁ・・
'▼Currency型代入 セルA1の表示"0.140" シリアル値"0.14"←ここが問題(0.135ではない)
n = 0.14@ - 0.005@
.Value = CDbl(n)
でいいんじゃないですか?
(半平太) 2019/10/10(木) 15:01
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.