none
コンボボックスの初期設定について

    質問

  • こんにちは。

    VB2005+SQLServerExpressで開発を行っています。

    コンボボックスについてですが、DBからデータを取得してデータを表示する方法まではわかったのですが、
    現在の方法だと1番目のデータがコンボボックスに表示されてしまいます。

    使用をするまではコンボボックスにデータを表示したくないのですが、現在考えているのは

    1.コンボボックスを使用する(フォーカスが当たる)まで、データをセットしない
    2.最初に表示されるデータを空白にしておく

    という2つの方法を思いつきました。

    ただ、2番目の方法についてはコンボボックスに表示するデータの使用回数が多い順に並び替えをしたいと
    言うこともあり、よい方法が思いつきません。

    以上の点から、1の方法をとるしかないのかなと思っているのですが、たいしたことではないのですが、
    表示されるまでに気になるほどの間ができてもいやだなとも思います。

    皆様はコンボボックスへのデータの表示はどのように行っているのでしょうか。

    参考までにご意見をいただければ幸いです。
    よろしくお願いいたします。
    2009年5月16日 6:53

回答

  • ただ、こちらでも1点わからないことがあるのですが、データテーブルに新規データを追加した場合、
    データテーブルを並び替えたりはしていないのですが、追加したデータがコンボボックスに表示されていました。
    新しいデータはデータテーブルの最後に追加されるということをどこかで目にしたので、不思議に感じているのですが
    こういった使用なのでしょうか。
    コンボボックスに限らず、バインドするのはデータテーブルではなく、そのビューになります。ビューを明に作成していなければ、データテーブルのDefaultViewがバインドしています。データテーブル内のデータの順序と必ずしも一致しません。
    また、最後に追加されているかどうかはDataRowのインデックスを調べられると良いと思います。

    また、参考までにUNIONを使用する方法を教えていただけるとありがたいのですが、お願いできますでしょうか。
    (現時点まで、一時テーブルを作成し、それと既存のテーブルをUNIONすればできそうだというところまでで
    まだ、試すことまではできていません。一時テーブルの作り方から調べなければならないのでまだ時間が
    かかりそうですが)
    handcraftさんが書かれている通りです。

    一時テーブルを作成する必要はありません。(handcraftさんが書かれている一時テーブルとは別な意味の一時テーブルですから混同しないようにして下さい)

    もし、コンボボックスのデータを

    select hogecode, hogename from fuga order by hogecode

    と抽出しているのであれば、例えば以下のようにします。

    select hogecode, hogename from fuga
    union
    select 0 as hogecode, '' as hogename
    order by hogecode

    #上記のasは省略できます。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月16日 15:11

すべての返信

  • 2番目の方法が一般的でしょう。ただし、空白のデータをデータベースへ保存しておくのではありません。データベースから抽出する際にunion句を使用して空白データを付加したり、データベースからデータテーブルへ抽出した際に、データテーブルに空白データを付加する方法が考えられます。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月16日 8:11
  • ご回答ありがとうございます。

    ご提示いただいた方法を調べていたのですが、UNIONを使う方法がどうにもわからず、データテーブルに空白行を
    追加する方法で実現できました。

    ただ、こちらでも1点わからないことがあるのですが、データテーブルに新規データを追加した場合、
    データテーブルを並び替えたりはしていないのですが、追加したデータがコンボボックスに表示されていました。
    新しいデータはデータテーブルの最後に追加されるということをどこかで目にしたので、不思議に感じているのですが
    こういった使用なのでしょうか。

    また、参考までにUNIONを使用する方法を教えていただけるとありがたいのですが、お願いできますでしょうか。
    (現時点まで、一時テーブルを作成し、それと既存のテーブルをUNIONすればできそうだというところまでで
    まだ、試すことまではできていません。一時テーブルの作り方から調べなければならないのでまだ時間が
    かかりそうですが)

    実際に動いてはいるものの、非常に不安で一杯です。
    2009年5月16日 12:03
  • こんにちは

    UNION の方法についてです。下記のようの空文字の行と表示したいテーブルに対してSELECT をした結果をUNIONするということだと思います。

    -- テスト用に一時テーブル作成
    
    CREATE TABLE #Test(
    
      data nvarchar(100),
    
      sortkey int 
    
    )
    
    INSERT INTO #Test(data, sortkey)
    
    VALUES (N'test1', 1)
    
    INSERT INTO #Test(data, sortkey)
    
    VALUES (N'test2', 2)
    
    INSERT INTO #Test(data, sortkey)
    
    VALUES (N'test3', 3)
    
    -- 空文字が先頭にくるようにUNION
    
       SELECT '' data, 0 sortkey
    
    UNION 
    
       SELECT data, sortkey 
    
         FROM #Test
    
      ORDER BY sortkey
    DataTable の件は、最後に追加したデータテーブルの行がコンボボックスに選択されているということですか?
    2009年5月16日 12:33
  • ただ、こちらでも1点わからないことがあるのですが、データテーブルに新規データを追加した場合、
    データテーブルを並び替えたりはしていないのですが、追加したデータがコンボボックスに表示されていました。
    新しいデータはデータテーブルの最後に追加されるということをどこかで目にしたので、不思議に感じているのですが
    こういった使用なのでしょうか。
    コンボボックスに限らず、バインドするのはデータテーブルではなく、そのビューになります。ビューを明に作成していなければ、データテーブルのDefaultViewがバインドしています。データテーブル内のデータの順序と必ずしも一致しません。
    また、最後に追加されているかどうかはDataRowのインデックスを調べられると良いと思います。

    また、参考までにUNIONを使用する方法を教えていただけるとありがたいのですが、お願いできますでしょうか。
    (現時点まで、一時テーブルを作成し、それと既存のテーブルをUNIONすればできそうだというところまでで
    まだ、試すことまではできていません。一時テーブルの作り方から調べなければならないのでまだ時間が
    かかりそうですが)
    handcraftさんが書かれている通りです。

    一時テーブルを作成する必要はありません。(handcraftさんが書かれている一時テーブルとは別な意味の一時テーブルですから混同しないようにして下さい)

    もし、コンボボックスのデータを

    select hogecode, hogename from fuga order by hogecode

    と抽出しているのであれば、例えば以下のようにします。

    select hogecode, hogename from fuga
    union
    select 0 as hogecode, '' as hogename
    order by hogecode

    #上記のasは省略できます。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月16日 15:11
  • ご回答ありがとうございます。

    handcraft様

    データテーブルの追加した行がコンボボックスに表示されていると申し上げましたが、私の勘違いでした。

    また、UNIONの使用方法の説明ありがとうございます。
    非常に勉強になりました。

    trapemiya様
    いつも、ご丁寧にありがとうございます。

    最後に記述してくださいましたSQLを初めは挑戦しようとしていたのですが、なかなかできず、質問をした次第でございまして、
    UNION 以下のSQL文に列名をつけたら、ストアドプロシージャでも可能でした。

    また、ひとつのDataTable もしくは DataViewをフォーム内の複数のコンボボックス(同じ内容を使うものが3個あります)に
    セットしたところ、ひとつを変更するとすべてが変更されてしまい、コンボボックスの数だけDataViewを作成し、それぞれに
    セットすることで回避できました。

    Accessを使用しているときは意識していなかったのですが、おそらく内部で今回自分が手作業で行ったようなことが行われて
    いると思うと、すごいと感心するばかりです。

    私の解釈で間違っている点がありましたら、ご指摘いただけると幸いです。

    ありがとうございました。
    2009年5月16日 20:07
  • Accessを使用しているときは意識していなかったのですが、おそらく内部で今回自分が手作業で行ったようなことが行われて
    いると思うと、すごいと感心するばかりです。
    Accessでは最近プログラミングしていませんので忘れていますが、たぶんコントロール間で表示する値を同期する仕組みは無かったんじゃないかと思います。Windowsフォームの場合は、この同期する仕組みが標準で組み込まれています。したがって、同じデータソースを表示しているDataGridViewや複数のComboBoxがあった場合、どれから一つで表示する値を変えると(DataGridViewの場合は行の選択を変えると)、他の全てのコントロールも同期して表示する値が変わります。
    これはCurrecyManagerクラスによって実現されています。バインドが作成されるとそのデータソースに対して一つのCurrecyManagerが作成されます。データソースとCurrecyManagerは一対です。この対に複数のコントロールがバインドすることにより同期が実現されています。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月17日 1:49