[[20191009150802]] 『Currency型変数からセルへの代入で小数点の桁が丸』(tkit) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『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.