none
【C#】Access上の数値型(倍精度浮動小数点型)、通貨型(小数点2位まで表示)の型変換について

    質問

  • お世話になります。
    C#
    Windowsフォームでの操作でご質問があります。

    DataGridView上のバインドさせたフィールドを使って計算させた
    値(「数量」×「単価」)を、非バインドで追加した列(「金額」)に表示させたい
    と思っておりますが、型変換が上手くいかずエラーとなってしまいます。

    エラーの回避方法をお教えいただきたいと思っております。
    恐れ入りますがよろしくお願い致します。

    【環境】
    ・作成しているもの:VisualC#Windows Forms アプリ
    OSWindows7
    .NET のバージョン: 4.7.02053
    C#のバージョン:visual studio 2017
    ・接続データベース:Access2003 SP3

    Access側の型>
    数量:数値型(倍精度浮動小数点型)DataGridView4列目に表示
    単価:通貨型(小数点2位まで表示)DataGridView5列目に表示
    金額:Access側テーブルにフィールド無し。DataGridView6列目に非バインドで追加し表示のみ

    <数量でのエラー内容>
    System.InvalidCastException: ' 'System.Double' のオブジェクトを型 'System.String' にキャストできません。'

    <単価でのエラー内容>
    System.InvalidCastException: ' 'System.Int32' のオブジェクトを型 'System.String' にキャストできません。'

    <記載したコーディング>

    private void A_DataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)

            {

                if ((A_DataGridView[4, e.RowIndex].Value != null) && (A_DataGridView[5, e.RowIndex].Value != null))

                {

                    double v1 = double.Parse((string) A_DataGridView[4, e.RowIndex].Value);

                    double v2 = double.Parse((string) A_DataGridView[5, e.RowIndex].Value);

                    A_DataGridView[6, e.RowIndex].Value = (v1 * v2).ToString();

                }

            }

    2018年6月13日 2:42

回答

  • Convert.ToDoubleメソッドを使えば、元の型が何であるかをあまり意識することなく無難にdouble型に変換できます。

    double v1 = Convert.ToDouble(A_DataGridView[4, e.RowIndex].Value);
    double v2 = Convert.ToDouble(A_DataGridView[5, e.RowIndex].Value);


    • 編集済み 佐祐理 2018年6月13日 3:06
    • 回答としてマーク sasatomo 2018年6月14日 6:21
    2018年6月13日 2:48
  • キャストではなくて、ToStringメソッドを使ってはいかがでしょうか?

    A_DataGridView[4, e.RowIndex].Value.ToString()


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク sasatomo 2018年6月14日 6:21
    2018年6月13日 2:50
    モデレータ
  • エラーメッセージから推測するに、A_DataGridView[4, e.RowIndex].Value が double 型、A_DataGridView[5, e.RowIndex].Value が int 型にキャストできると思いますがそうであれば、

    double v1 = double.Parse((string) A_DataGridView[4, e.RowIndex].Value);
    double v2 = double.Parse((string) A_DataGridView[5, e.RowIndex].Value);

    を以下のようにすればよいのでは?

    double v1 = (double) A_DataGridView[4, e.RowIndex].Value;
    int v2 = (int) A_DataGridView[5, e.RowIndex].Value;


    そうすれば、少なくとも今出ている例外は出なくなり、(v1 * v2).ToString(); も問題ないはずです。



    • 編集済み SurferOnWww 2018年6月13日 3:10 int ⇔ double 訂正
    • 回答としてマーク sasatomo 2018年6月14日 1:35
    2018年6月13日 3:03
  • 【追伸】

    以下のところ、間違いないですか? よくチェックしてみてください。

    > <Access側の型>
    > 数量:数値型(倍精度浮動小数点型)DataGridViewの4列目に表示
    > 単価:通貨型(小数点2位まで表示)DataGridViewの5列目に表示

    自分の環境にある Northwind 2003.accdb の Products 2003 テーブルの数値型、通貨型は(以下の画像参照)、それから Visual Studio のウィザードで型付 DataSet を作ると、当該列の型はそれぞれ short, decimal となります。

    その型付 DataSet をデータバインドして作られる DrarGridView の当該列の型は同じく short, decimal となります。以下の画像を見てください。

    そこが間違っていると、上記の質問は意味がないです。


    • 編集済み SurferOnWww 2018年6月13日 4:43 訂正
    • 回答としてマーク sasatomo 2018年6月14日 1:35
    2018年6月13日 4:39
  • > .mdb ファイルを修正後、アプリケーションを作り直して検証してみましたが、同じエラーメッセージとなりました。

    やり方の問題だと思います。はっきり言うと、質問者さんのやり方がどこか間違っているとしか思えません。

    そこまで言って、そうでは無かったりすると何なので、.mdb ファイルのサンプルを作り、JET プロバイダを使って検証してみました。

    以下に示すように期待通りの結果になります。

    .mdb ファイル

    JET プロバイダ使用

    問題部分の C# のコード

    結果

    今のままだと丸めの誤差で計算結果が 1 銭単位で違ってくる可能性が大です。なので、このまま対症療法を続けるのではなく問題の原因を調べて、あるべき姿に近づけてはいかがですか。

    質問者さんはそこまでやる気はなさそうな気もしますけど、もしそうであればそう言ってください。これで終わりにしますので。

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月15日 9:16
  • v1およびv2が0なのは、初期値の0であって、まだ何も値がセットされていないからだと思います。
    ブレークポイントはv1の行に設定しませんでしたか? ブレークポイントで止まった行はまだ実行されていません。つまり、ブレークポイントはその止まった行が実行される直前で停止している状態です。

    知りたいのは、上でも書きましたが、A_DataGridView[4, e.RowIndex].Value と A_DataGridView[5, e.RowIndex].Value の値です。ブレークポイントで止まった時、マウスポインタはそれぞれのValueの上に持って行って下さい。それぞれのValueが表示されますが、それがsasatomoさんが思っている値でしょうか?

    イミディエイトウィンドウに、
    A_DataGridView[1, 3].Value
    のように添え字を適当に変えて値を確かめてみて下さい。自分の思った通りの値が表示されますでしょうか?


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月18日 9:00
    モデレータ
  • Access 2003ということはMicrosoft Jet Database Engine 4.0が使われているはずです。Data Type Support (OLE DB)によると通貨型はDBTYPE_CYであり、OLE DB データ型のマッピングによるとDBTYPE_CYはDecimal型として扱われることになっています。

    にもかかわらず、投稿されたようなエラーが発生するということは、質問者さんが説明されている内容と実際の設定内容が異なっているものと思われます。
    ともあれ、接続方法はこれ以外にもあり、ODBCを経由すると通貨型が存在しないため、SQL_DOUBLEからのDouble型と扱われることもあるでしょうし、Access 2007からはACEと呼ばれる新しいプロバイダも導入されていて、どの方式で接続しているのかはわかりづらくもあります。

    そこで、最初に説明したように、Convert.ToDouble(Object)メソッドを使用すれば、Int32であれDoubleであれ数値っぽい型や数値を含むString型などどのような型であっても.NETラインタイム側が適切に処理してDouble型を返してくれます。プログラムの構成上、数値っぽいものが得られることが分かっているのであれば、あまり悩まずConvert.ToDoubleされることをお勧めします。

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月18日 13:50
  • データベースへの接続方法次第で.NET型は変わり得ると思います。その上で、質問文には例外メッセージが提示されているので、それが真として回答すれば十分に思います。
    • 回答としてマーク sasatomo 2018年6月14日 6:21
    2018年6月13日 6:15
  • データベースへの接続方法次第で.NET型は変わり得ると思います。その上で、質問文には例外メッセージが提示されているので、それが真として回答すれば十分に思います。

    質問文を信じて回答したら大ハズレということが過去何回かあったような気がしますが、とりあえず信じて最初の回答をしています。でも、確認は必要。また自分の回答が大ハズレになるかもしれませんので。

    単価 x 数量の数量を「倍精度浮動小数点型」にするのは少なくとも自分的にはあり得ないし、単価を「通貨型」にしたのに型付 DataSet の当該列の型が Int32 になるのは解せないので。


    • 回答としてマーク sasatomo 2018年6月14日 1:35
    2018年6月13日 7:09
  • > 始めに教えていただいた方法でエラーの回避が出来ました。

    「初めに」とはどれですか? 最適解と判断されたのでしょうか? 「初めに」案を採用した理由を教えてください。

    > こちらでも調査し検証致しました。

    調査結果を書いていただけませんか。

    最初の質問に書いてあった「数値型(倍精度浮動小数点型)」が正しければそれが double になるのは納得ですが、「通貨型」が decimal ではなく Int32 になるのが解せません。

    自分の環境と違いがあるとすると、多分質問者さんの方は Access ファイルは .mdb(自分は .accdb)、データベースエンジンは JET(自分は ACE)ぐらいしか思い当たりませんが、そのあたりはいかがですか?

    このフォーラムは技術者同士の情報交換の場として提供されているそうですので、質問者さんにも情報提供に協力していただけると幸いです。

    • 回答としてマーク sasatomo 2018年6月14日 6:33
    2018年6月14日 2:20
  • コメントを読む限り私の回答を採用して「エラーの回避が出来」たのかと思いますが、私の回答が「回答としてマーク」されないのはちょっと納得いきません。
    • 回答としてマーク sasatomo 2018年6月14日 6:33
    2018年6月14日 5:40
  • 対症療法で済ませたという感じがしますが、対症療法ばかりではそのうち破綻するような気がします。

    何でもいからできれば OK という訳でなければ、あるべき姿を考えて設定・コーディングしませんか?

    基本的に、「単価」x「数量」を扱う場合、丸め誤差を最小限に抑えるために「単価」には decimal 型を、「数量」には整数型(short, int, long など)を使うことを考えてください。

    ($ と違って、小数点以下は扱わないということであれば「単価」も整数型でもいいかもしれませんが、それはちょっと置いといて)

    元となる Access で、「単価」は実は「通貨型」になっているとのことなのでそれはそのままとし、「数量」は「数値型(倍精度浮動小数点型)」ではなくてデフォルトの「数値型(長整数型)」に変更しましょう。

    そうすれば、型付 DataSet で「単価」は decimal、「数量」は int になるはずです。それがあるべき姿だと思います。

    そうすれば、DataGridView の 4 列が「数量」、5 列が「単価」であれば、以下のようにできるはずです。

    int v1 = (int) A_DataGridView[4, e.RowIndex].Value;          // 数量
    decimal v2 = (decimal) A_DataGridView[5, e.RowIndex].Value;  // 単価

    また、v1 * v2 の結果は decimal 型になります。丸め誤差は最小限に抑えられるはずです。

    以上のようにすれば、A_DataGridView[4, e.RowIndex].Value や A_DataGridView[4, e.RowIndex].Value を double 型に変換する必要はありません。というより、丸めの誤差が出るという好ましからざる結果を生むかもしれません。


    • 編集済み SurferOnWww 2018年6月14日 7:46 訂正
    • 回答としてマーク sasatomo 14 時間 50 分前
    2018年6月14日 7:41
  • .mdb ファイルを修正後、型付 DataSet + TableAdapter を含め、アプリケーションを作り直しましたか? もしやってなければ、それをやってみてください。
    • 回答としてマーク sasatomo 14 時間 50 分前
    2018年6月15日 4:43
  • int v1 = (int) A_DataGridView[4, e.RowIndex].Value;          // 数量

    decimal v2 = (decimal) A_DataGridView[5, e.RowIndex].Value;  // 単価

    とコーディング致しましたが、

    System.NullReferenceException: 'オブジェクト参照がオブジェクト インスタンスに設定されていません。'
    System.Windows.Forms.DataGridViewCell.Value.get が null を返しました。


    ちなみに ブレークポイントで止めて、A_DataGridView[4, e.RowIndex].Value と A_DataGridView[5, e.RowIndex].Value の値はどうなっていますか?
    これがnullであれば、DataGridViewにうまく値が渡っていないか、4や5などのインデックスが違っている可能性があります。
    いずれにしてもデバッグの問題ですので、適当なところでブレークポイントで止め、自分の思った通りの値が来ているかチェックしてみて下さい。ブレークポイントで止まった時に、イミディエイトウィンドウにA_DataGridView[4, e.RowIndex].Valueなどを打ち込んで確認することもできます。

    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月15日 10:59
    モデレータ
  • 上の私のレスの画像(下に再掲します)のように、型と値を調べるコードを入れてデバッガで見た結果のスクリーンショットを貼ってください。もし、まだこのフォーラムで画像が貼れなければ、言葉でどうなったか書いてください。

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月18日 6:51

すべての返信

  • Convert.ToDoubleメソッドを使えば、元の型が何であるかをあまり意識することなく無難にdouble型に変換できます。

    double v1 = Convert.ToDouble(A_DataGridView[4, e.RowIndex].Value);
    double v2 = Convert.ToDouble(A_DataGridView[5, e.RowIndex].Value);


    • 編集済み 佐祐理 2018年6月13日 3:06
    • 回答としてマーク sasatomo 2018年6月14日 6:21
    2018年6月13日 2:48
  • キャストではなくて、ToStringメソッドを使ってはいかがでしょうか?

    A_DataGridView[4, e.RowIndex].Value.ToString()


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク sasatomo 2018年6月14日 6:21
    2018年6月13日 2:50
    モデレータ
  • エラーメッセージから推測するに、A_DataGridView[4, e.RowIndex].Value が double 型、A_DataGridView[5, e.RowIndex].Value が int 型にキャストできると思いますがそうであれば、

    double v1 = double.Parse((string) A_DataGridView[4, e.RowIndex].Value);
    double v2 = double.Parse((string) A_DataGridView[5, e.RowIndex].Value);

    を以下のようにすればよいのでは?

    double v1 = (double) A_DataGridView[4, e.RowIndex].Value;
    int v2 = (int) A_DataGridView[5, e.RowIndex].Value;


    そうすれば、少なくとも今出ている例外は出なくなり、(v1 * v2).ToString(); も問題ないはずです。



    • 編集済み SurferOnWww 2018年6月13日 3:10 int ⇔ double 訂正
    • 回答としてマーク sasatomo 2018年6月14日 1:35
    2018年6月13日 3:03
  • 【追伸】

    以下のところ、間違いないですか? よくチェックしてみてください。

    > <Access側の型>
    > 数量:数値型(倍精度浮動小数点型)DataGridViewの4列目に表示
    > 単価:通貨型(小数点2位まで表示)DataGridViewの5列目に表示

    自分の環境にある Northwind 2003.accdb の Products 2003 テーブルの数値型、通貨型は(以下の画像参照)、それから Visual Studio のウィザードで型付 DataSet を作ると、当該列の型はそれぞれ short, decimal となります。

    その型付 DataSet をデータバインドして作られる DrarGridView の当該列の型は同じく short, decimal となります。以下の画像を見てください。

    そこが間違っていると、上記の質問は意味がないです。


    • 編集済み SurferOnWww 2018年6月13日 4:43 訂正
    • 回答としてマーク sasatomo 2018年6月14日 1:35
    2018年6月13日 4:39
  • データベースへの接続方法次第で.NET型は変わり得ると思います。その上で、質問文には例外メッセージが提示されているので、それが真として回答すれば十分に思います。
    • 回答としてマーク sasatomo 2018年6月14日 6:21
    2018年6月13日 6:15
  • データベースへの接続方法次第で.NET型は変わり得ると思います。その上で、質問文には例外メッセージが提示されているので、それが真として回答すれば十分に思います。

    質問文を信じて回答したら大ハズレということが過去何回かあったような気がしますが、とりあえず信じて最初の回答をしています。でも、確認は必要。また自分の回答が大ハズレになるかもしれませんので。

    単価 x 数量の数量を「倍精度浮動小数点型」にするのは少なくとも自分的にはあり得ないし、単価を「通貨型」にしたのに型付 DataSet の当該列の型が Int32 になるのは解せないので。


    • 回答としてマーク sasatomo 2018年6月14日 1:35
    2018年6月13日 7:09
  • 佐祐理様

    ありがとうございました。
    教えていただいた方法でエラーの回避が出来ました。
    感謝申し上げます。

    2018年6月14日 1:33
  • Trapemiya

    いつもありがとうございます。
    キャストを使わない方法も試してみようと思います。
    ありがとうございます。

    2018年6月14日 1:33
  • SurferOnWww

    いつもありがとうございます。
    始めに教えていただいた方法でエラーの回避が出来ました。
    ありがとうございました。

    また、Access側の詳細まで詳しく調査して下さり、
    お手数をおかけしました。こちらでも調査し検証致しました。
    SurferOnWww様のおっしゃる通り数量を「倍精度浮動小数点型」にする
    必要は無いように思いましたので、Accessmdb作成者にその意図を確認し、
    整備していきたいと感じました。

    本当にありがとうございました、 感謝申し上げます。

    2018年6月14日 1:35
  • > 始めに教えていただいた方法でエラーの回避が出来ました。

    「初めに」とはどれですか? 最適解と判断されたのでしょうか? 「初めに」案を採用した理由を教えてください。

    > こちらでも調査し検証致しました。

    調査結果を書いていただけませんか。

    最初の質問に書いてあった「数値型(倍精度浮動小数点型)」が正しければそれが double になるのは納得ですが、「通貨型」が decimal ではなく Int32 になるのが解せません。

    自分の環境と違いがあるとすると、多分質問者さんの方は Access ファイルは .mdb(自分は .accdb)、データベースエンジンは JET(自分は ACE)ぐらいしか思い当たりませんが、そのあたりはいかがですか?

    このフォーラムは技術者同士の情報交換の場として提供されているそうですので、質問者さんにも情報提供に協力していただけると幸いです。

    • 回答としてマーク sasatomo 2018年6月14日 6:33
    2018年6月14日 2:20
  • コメントを読む限り私の回答を採用して「エラーの回避が出来」たのかと思いますが、私の回答が「回答としてマーク」されないのはちょっと納得いきません。
    • 回答としてマーク sasatomo 2018年6月14日 6:33
    2018年6月14日 5:40
  • SurferOnWww様

    結果報告が足りず申し訳ありませんでした。
    「数値型(倍精度浮動小数点型)」がdouble、「通貨型」が decimalとなりました。
    単価が2種類あり、最初検証していた単価は良く見ると数値型となっていたため、
    Int32のエラーとなっていたようでした。
    調査ミス、また、言葉足らずで申し訳ありません。

    SurferOnWww様の初めの回答、

    double v1 = (double) A_DataGridView[4, e.RowIndex].Value;
    int v2 = (int) A_DataGridView[5, e.RowIndex].Value;

    は、数値型の単価ではエラー回避されましたが、
    通貨型の単価ではエラーとなりました。(ご連絡せず申し訳ありません)

    佐祐理様にお教えいただいた回答で
    運用してみようと思っております。
    ご報告が足りず申し訳ありませんでした。
    慣れないことで、ご迷惑をおかけし申し訳ありませんでした。
    ありがとうございます。

    2018年6月14日 6:32
  • 佐祐理様

    大変失礼いたしました。
    「回答としてマーク」したつもりでしたが漏れてしまっておりました。
    大変申し訳ありませんでした。
    先ほど「回答としてマーク」を致しました。
    ありがとうございました。

    2018年6月14日 6:33
  • 対症療法で済ませたという感じがしますが、対症療法ばかりではそのうち破綻するような気がします。

    何でもいからできれば OK という訳でなければ、あるべき姿を考えて設定・コーディングしませんか?

    基本的に、「単価」x「数量」を扱う場合、丸め誤差を最小限に抑えるために「単価」には decimal 型を、「数量」には整数型(short, int, long など)を使うことを考えてください。

    ($ と違って、小数点以下は扱わないということであれば「単価」も整数型でもいいかもしれませんが、それはちょっと置いといて)

    元となる Access で、「単価」は実は「通貨型」になっているとのことなのでそれはそのままとし、「数量」は「数値型(倍精度浮動小数点型)」ではなくてデフォルトの「数値型(長整数型)」に変更しましょう。

    そうすれば、型付 DataSet で「単価」は decimal、「数量」は int になるはずです。それがあるべき姿だと思います。

    そうすれば、DataGridView の 4 列が「数量」、5 列が「単価」であれば、以下のようにできるはずです。

    int v1 = (int) A_DataGridView[4, e.RowIndex].Value;          // 数量
    decimal v2 = (decimal) A_DataGridView[5, e.RowIndex].Value;  // 単価

    また、v1 * v2 の結果は decimal 型になります。丸め誤差は最小限に抑えられるはずです。

    以上のようにすれば、A_DataGridView[4, e.RowIndex].Value や A_DataGridView[4, e.RowIndex].Value を double 型に変換する必要はありません。というより、丸めの誤差が出るという好ましからざる結果を生むかもしれません。


    • 編集済み SurferOnWww 2018年6月14日 7:46 訂正
    • 回答としてマーク sasatomo 14 時間 50 分前
    2018年6月14日 7:41
  • SurferOnWww様

    アドバイスをありがとうございます。
    「数量」は作成者にも確認した上で「数値型(長整数型)」に変更致しました。
    「単価」は、「紙一枚@1.64円」と言うデータがありましたので整数型にはせずに
    そのまま通貨型、decimal 型に致しました。その上で

    int v1 = (int) A_DataGridView[4, e.RowIndex].Value;          // 数量
    decimal v2 = (decimal) A_DataGridView[5, e.RowIndex].Value;  // 単価

    とコーディング致しましたが、

    System.NullReferenceException: 'オブジェクト参照がオブジェクト インスタンスに設定されていません。'
    System.Windows.Forms.DataGridViewCell.Value.get が null を返しました。

    とのエラーになり、Access側の型を整備をしながら修正したからなのか、
    それともデータベースエンジン(JETとACE)の違いなのか、
    判断がつかなくなってしまい、大変申し訳ありません。

    お気づきの点がありましたらご教示いただければと思っております。
    いつもアドバイスをありがとうございます。

    2018年6月15日 4:13
  • .mdb ファイルを修正後、型付 DataSet + TableAdapter を含め、アプリケーションを作り直しましたか? もしやってなければ、それをやってみてください。
    • 回答としてマーク sasatomo 14 時間 50 分前
    2018年6月15日 4:43
  • SurferOnWww

    お忙しいところありがとうございます。
    .mdb ファイルを修正後、アプリケーションを作り直して検証してみましたが、
    同じエラーメッセージとなりました。
    お手数をおかけしており大変申し訳ありませんでした。
    いつもアドバイスをありがとうございます。


    • 編集済み sasatomo 2018年6月15日 8:20
    2018年6月15日 8:20
  • > .mdb ファイルを修正後、アプリケーションを作り直して検証してみましたが、同じエラーメッセージとなりました。

    やり方の問題だと思います。はっきり言うと、質問者さんのやり方がどこか間違っているとしか思えません。

    そこまで言って、そうでは無かったりすると何なので、.mdb ファイルのサンプルを作り、JET プロバイダを使って検証してみました。

    以下に示すように期待通りの結果になります。

    .mdb ファイル

    JET プロバイダ使用

    問題部分の C# のコード

    結果

    今のままだと丸めの誤差で計算結果が 1 銭単位で違ってくる可能性が大です。なので、このまま対症療法を続けるのではなく問題の原因を調べて、あるべき姿に近づけてはいかがですか。

    質問者さんはそこまでやる気はなさそうな気もしますけど、もしそうであればそう言ってください。これで終わりにしますので。

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月15日 9:16
  • int v1 = (int) A_DataGridView[4, e.RowIndex].Value;          // 数量

    decimal v2 = (decimal) A_DataGridView[5, e.RowIndex].Value;  // 単価

    とコーディング致しましたが、

    System.NullReferenceException: 'オブジェクト参照がオブジェクト インスタンスに設定されていません。'
    System.Windows.Forms.DataGridViewCell.Value.get が null を返しました。


    ちなみに ブレークポイントで止めて、A_DataGridView[4, e.RowIndex].Value と A_DataGridView[5, e.RowIndex].Value の値はどうなっていますか?
    これがnullであれば、DataGridViewにうまく値が渡っていないか、4や5などのインデックスが違っている可能性があります。
    いずれにしてもデバッグの問題ですので、適当なところでブレークポイントで止め、自分の思った通りの値が来ているかチェックしてみて下さい。ブレークポイントで止まった時に、イミディエイトウィンドウにA_DataGridView[4, e.RowIndex].Valueなどを打ち込んで確認することもできます。

    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月15日 10:59
    モデレータ
  • SurferOnWww様

    お忙しいところ、.mdbのサンプルまで作成して
    検証して下さりありがとうございます。
    お手数をおかけしてしまい大変申し訳ありません。

    何度かプロジェクトを一から作成してみたのですが、
    同じエラーとなりました。
    おっしゃる通り私のやり方がどこか間違っているのだと思うのですが、
    気づくことが出来ておらず申し訳ありません。

    Trapemiya様のアドバイスでブレークポイントで止めてみますと、
    値がv1,v2共に0となっておりました。
    また、イミディエイトウィンドウに値を入れてみますと、
    v1は入りましたが、v2は
    「error CS0664: 型 double のリテラルを暗黙的に
    型 'decimal' に変換することはできません。
    'M' サフィックスを使用して、この型のリテラルを
    作成してください。」となりました。
    大変申し訳ないのですが、もしお気づきの点などがありましたら
    ご教示いただければと思っております。
    いつもありがとうございます。

    2018年6月18日 6:20
  • Trapemiya様

    お忙しいところアドバイスをありがとうございます。
    ブレークポイントで止めてみますと、
    値がv1,v2共に0となっておりました。
    インデックスは合っております。
    値がうまく渡っていないのでしょうか?
    また、イミディエイトウィンドウに値を入れてみますと、
    v1は入りましたが、v2は
    「error CS0664: 型 double のリテラルを暗黙的に
    型 'decimal' に変換することはできません。
    'M' サフィックスを使用して、この型のリテラルを
    作成してください。」となりました。
    もしお気づきの点などがありましたら
    ご教示いただければと思っております。
    いつもありがとうございます。

    2018年6月18日 6:21
  • 上の私のレスの画像(下に再掲します)のように、型と値を調べるコードを入れてデバッガで見た結果のスクリーンショットを貼ってください。もし、まだこのフォーラムで画像が貼れなければ、言葉でどうなったか書いてください。

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月18日 6:51
  • v1およびv2が0なのは、初期値の0であって、まだ何も値がセットされていないからだと思います。
    ブレークポイントはv1の行に設定しませんでしたか? ブレークポイントで止まった行はまだ実行されていません。つまり、ブレークポイントはその止まった行が実行される直前で停止している状態です。

    知りたいのは、上でも書きましたが、A_DataGridView[4, e.RowIndex].Value と A_DataGridView[5, e.RowIndex].Value の値です。ブレークポイントで止まった時、マウスポインタはそれぞれのValueの上に持って行って下さい。それぞれのValueが表示されますが、それがsasatomoさんが思っている値でしょうか?

    イミディエイトウィンドウに、
    A_DataGridView[1, 3].Value
    のように添え字を適当に変えて値を確かめてみて下さい。自分の思った通りの値が表示されますでしょうか?


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月18日 9:00
    モデレータ
  • Access 2003ということはMicrosoft Jet Database Engine 4.0が使われているはずです。Data Type Support (OLE DB)によると通貨型はDBTYPE_CYであり、OLE DB データ型のマッピングによるとDBTYPE_CYはDecimal型として扱われることになっています。

    にもかかわらず、投稿されたようなエラーが発生するということは、質問者さんが説明されている内容と実際の設定内容が異なっているものと思われます。
    ともあれ、接続方法はこれ以外にもあり、ODBCを経由すると通貨型が存在しないため、SQL_DOUBLEからのDouble型と扱われることもあるでしょうし、Access 2007からはACEと呼ばれる新しいプロバイダも導入されていて、どの方式で接続しているのかはわかりづらくもあります。

    そこで、最初に説明したように、Convert.ToDouble(Object)メソッドを使用すれば、Int32であれDoubleであれ数値っぽい型や数値を含むString型などどのような型であっても.NETラインタイム側が適切に処理してDouble型を返してくれます。プログラムの構成上、数値っぽいものが得られることが分かっているのであれば、あまり悩まずConvert.ToDoubleされることをお勧めします。

    • 回答としてマーク sasatomo 14 時間 51 分前
    2018年6月18日 13:50
  • SurferOnWww様

    お手数をおかけしており申し訳ありません。
    画像を添付することが出来ませんでしたので、
    言葉で申し上げます。

    unitPrice,unitsInStock,valueの値がNullになっておりました。

    皆様がおっしゃるように、恐らく私のやり方がどこか間違っているのだと思い、
    それに気がつくことが出来ずにいるのだと思います。
    大変申し訳ありません。
    私自身も原因を分かりたいのですが、皆様にもお手数をおかけしてしまいます為、
    今回は佐祐理様にお教えいただいた方法で運用してみたいと思います。
    いつもありがとうございます。

    14 時間 54 分前
  • Trapemiya様

    いつもありがとうございます。
    申し訳ありません、ブレークポイントをv1に設定しておりましたので、
    計算させている位置に設定したところ、
    値が入っており、この値は合っておりましたが、
    ブレークポイントをどこにも設定せずにデバックを開始すると
    int v1 =の位置で

    System.NullReferenceException: 'オブジェクト参照がオブジェクト インスタンスに設定されていません。'
    System.Windows.Forms.DataGridViewCell.Value.get が null を返しました。

    のエラーとなります。

    皆様がおっしゃるように、恐らく私のやり方がどこか間違っているのだと思い、
    それに気がつくことが出来ずにいるのだと思います。
    大変申し訳ありません。
    私自身も原因を分かりたいのですが、皆様にもお手数をおかけしてしまいます為、
    今回は佐祐理様にお教えいただいた方法で運用してみたいと思います。
    いつもありがとうございます。

    14 時間 53 分前
  • 佐祐理様

    お手数をおかけしており申し訳ありません。
    またご説明をありがとうございます。
    20年ほど前に作成された古いmdbをずっと使い続けてきたそうで、
    新しいパソコンで動かすとエラーが出るようになってきたとのことで、
    差し当たり私の学習も兼ねて今回C#で作成し直しを行っております。
    説明の仕方が悪くご迷惑をおかけしており申し訳ありません。
    今後も作成が続きますが、説明の仕方に気を付けて参りたいと
    思っております。
    いつもありがとうございます。

    14 時間 51 分前
  • > unitPrice,unitsInStock,valueの値がNullになっておりました。

    それはブレークポイントの設定の問題でしょう。以下のように各メソッドが実行される前の時点で止めたら null になります。

    以下のように、各メソッドが実行された後に設定して止めれば別の結果になったと思うのですが?

    何にしても、掲示板のやり取りで解決するのは難しいようですし、質問者さんもこれ以上やる気はなさそうですね。諦めました。

    14 時間 5 分前