none
DataTableのAutoIncrementSeedが更新されない RRS feed

  • 質問

  • 初めて投稿いたします。

    DataTableのAutoIncrement機能で悩んでおります。

    現在、以下の様なデータベースを利用して、

    データベース:Access2007
    テーブル名:テーブル
    フィールド:フィールド1=長整数型(主キー)
          フィールド2=テキスト型
          フィールド3=テキスト型

    以下の開発環境で、

    Visual C++ 2008 Express Edition
    .NET Framework 2.0

    以下のような処理を行っています。

    1. DataAdapterを介してデータベースのテーブルをDataTableに展開
       (Select フィールド1,フィールド2 From テーブル Where フィールド3 = *;)
    2. DataTableはDataGridViewのDataSourceに連結
    3. DataGridViewをTabPageのControl Collectionに追加
    4. 各TabPageをTabControlのControlCollectionに追加

    上記1~4をテーブルのフィールド3のデータ毎に、Form_Loadイベント時に行っています。

    各DataTableの1列目は
    AutoIncrement=true
    AutoIncrementSeed=(テーブルのフィールド1の最大値、または全DataGridView1列目の最大値)+1
    AutoIncrementStep=1
    に設定し、自動的にIDを割り振っています。

    AutoIncrementSeedは、
    A.まず、Form_Load時に、各DataTableに対して設定。
    B.TabControlのSelectedIndexChangedイベントが発生する度に更新。
    しています。

    これらの環境で、現在以下の様な現象が発生し、困っております。

    ①あるDataGridViewのCellのデータを入力。
    ②Cellを入力中のまま(行のヘッダに鉛筆のグリフが表示されている)の状態で、
     レコード数が0(DataTableの1行目がIsNewRow=true)のDataTableのTabに切り替える。
    ③TabControlのSelectedIndexChangedイベントが発生し、そのイベント内で
     その時点でのフィールド1の最大値をAutoIncrementSeedに設定。
    ④ところが、DataGridViewに表示されるフィールド1の値が③で設定した
     AutoIncrementSeedの値で更新されていない。
     (つまり、Form_Loadイベントで設定した値のまま)
    ⑤その結果、フィールド1の値が主キーにも関わらず、重複してしまう。

    上記②にて、1レコードでも登録されているDataTableに切り替えた場合は発生しません。
    同じく②でEnterを押下して入力を確定させた後にTabを切り替えた場合も発生しません。

    また、参考になるか分かりませんが、
    ・入力中のままTabを切り替えた場合、SelectedIndexChangedイベント発生時のActiveControlは、DataGridView。
    ・入力確定後Tabを切り替えた場合、SelectedIndexChangedイベント発生時のActiveControlは、TabControl。
    の違いが有ります。

    長文になり、申し訳ありません。
    何方か、何故上記の様な現象となるのか、ご教示頂けないでしょうか?
    宜しくお願い致します。

    --- Form_Load時の処理 -----------------------------------
        _DataTable[ tab ]->Columns[ "フィールド1" ]->AutoIncrement = true;
        _DataTable[ tab ]->Columns[ "フィールド1" ]->AutoIncrementSeed = getMaxIDInTabControl( "テーブル", "フィールド1" ); // 最大値を取得するメソッド
        _DataGridView[ tab ]->DataSource = _DataTable[ tab ];
    ---------------------------------------------------------

    --- SelectedIndexChangedイベント時の処理 ----------------
        private: System::Void tc_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
        {
            TabControl^ t = ( TabControl^ )sender;

            if ( t->SelectedIndex != -1 ) {
                if ( _DataGridView != nullptr ) {
                   _DataTable[ t->SelectedIndex ]->Columns[ "フィールド1" ]->AutoIncrementSeed =        getMaxIDInTabControl( "テーブル", "フィールド1" ); // 最大値を取得するメソッド
                    this->ActiveControl = _DataGridView[ t->SelectedIndex ];
                }
             }
         }
    ---------------------------------------------------------

    • 編集済み Nobupy 2012年3月26日 2:37
    2012年3月26日 2:33

回答

  • 返信がついてないようなので少しだけ。


    内容的に .NET Framework 動作についてなのでここでは返信はつき難いと思います。

    .NET Framework か、コードを書き直せるなら C# か VB で質問する方が良いでしょう。


    本題については DataTable に Add するタイミングで自動値を生成して欲しいのでしょうけど、IsNewRow=true の行データは DataGridView が管理してるので編集開始時に生成すると考えるのが妥当と思うので、そういう動作になるのではないですかね?

    • 回答としてマーク Nobupy 2012年4月3日 2:35
    2012年4月2日 7:41

すべての返信

  • 返信がついてないようなので少しだけ。


    内容的に .NET Framework 動作についてなのでここでは返信はつき難いと思います。

    .NET Framework か、コードを書き直せるなら C# か VB で質問する方が良いでしょう。


    本題については DataTable に Add するタイミングで自動値を生成して欲しいのでしょうけど、IsNewRow=true の行データは DataGridView が管理してるので編集開始時に生成すると考えるのが妥当と思うので、そういう動作になるのではないですかね?

    • 回答としてマーク Nobupy 2012年4月3日 2:35
    2012年4月2日 7:41
  • kyano30様

    返信、及びアドバイスを頂きまして、有難うございました。

    別のカテゴリーで質問してみます。

    > 本題については DataTable に Add するタイミングで自動値を生成して欲しいのでしょうけど、IsNewRow=true の行データは

    > DataGridView が管理してるので編集開始時に生成すると考えるのが妥当と思うので、そういう動作になるのではないですかね?

       回答、ありがとうございました。 そうかもしれないですね。

       入力中にTabが切り替えられた時、TabControlのSelectedIndexChangedイベント内で、

       一旦、ActiveControlをTabControlへ逃がしてやると、回避出来そうなので、

       今回はこの方法で進めようかと思っています。

       色々とご意見いただき、ありがとうございました。

      

    2012年4月3日 2:59