[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『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.