データベースのデータ表示

[戻る]
サマー [E-Mail] [HomePage] 2006/06/30(金) 17:57:42
サマーといいます。
通信機器(組み込み,C言語)の開発5年ほど経験があります。Windows環境での開発は
ほんの一ヶ月まえから取り組んでいます。よろしくお願いします。

Windows XP,Visual C++ 2005 .Net Frameworkをつかっています。

以下のコードでコンパイルは通りますが、期待している機能(help.mdfデータベースに
設定してあるデータをlistViewコントロールに表示する)はできていません。
キャストしているところが一番あやしそうですが、どなたが原因わかるでしょうか。


// データベース接続
             SqlConnection ^ objConn;
             String ^ sConnectionString;
             sConnectionString = "Data 
Source=.\\SQLEXPRESS;AttachDbFilename=C:\\help.mdf;Integrated 
Security=True;Connect Timeout=30;User Instance=True";
             
             // コネクションのインスタンス生成
             objConn = gcnew SqlConnection(sConnectionString);
             objConn->Open();

             // データアダプターのインスタンス生成
             SqlDataAdapter^ daAuthors = gcnew SqlDataAdapter
("Select * From Main_Table", objConn);

             // データセット型のインスタンス生成
             DataSet^ dsPubs = gcnew DataSet("Pubs");

             // データ読み込み
             daAuthors->Fill(dsPubs, "Main_Table");

             for each ( DataTable^ tblAuthors in dsPubs-
>Tables )
             {
                 for each (DataRow^ row in tblAuthors-
>Rows )
                 {
                     // リストビューにデータ表示
                     array< String^ >^  item1 = 
dynamic_cast<array< String^ >^>(row->ItemArray);
                     listView2->Items->Add(gcnew 
ListViewItem(item1));
                 }
             }

サマー [E-Mail] [HomePage] 2006/06/30(金) 20:41:20
デバッガで確認したところrow->ItemArrayにはデータはセットされているようです。

επιστημη 2006/06/30(金) 21:09:45
ItemArrayはObject[]すなわち array<Object^>^ ですよね。
それを無理やり array<String^>^ にdynamic_cast して変換できるわけないと思う。

Array::ConvertAll か何かで変換すんじゃないでしょか。

επιστημη 2006/06/30(金) 23:36:46
…なんでこんなややこしいコードになるんだろ。
↓こんだけでいいんじゃねぇ?

  static String^ obj2str(Object^ x) { return x->ToString(); }

  Void button1_Click(Object^  sender, EventArgs^  e) {
    SqlConnection^ conn = gcnew SqlConnection("接続文字列");
    conn->Open(); 

    SqlCommand^ cmd = conn->CreateCommand(); 
    cmd->CommandText = "SELECT 名前,電話番号 FROM 電話帳;";
    SqlDataReader^ reader = cmd->ExecuteReader();

    while ( reader->Read() ) {
      array<Object^>^ item = gcnew array<Object^>(reader->FieldCount);
      reader->GetValues(item);
      listView1->Items->Add( gcnew ListViewItem(
           Array::ConvertAll(item, 
                  gcnew Converter<Object^,String^>(obj2str))) );
    }
    conn->Close();
  }

サマー [E-Mail] [HomePage] 2006/07/01(土) 13:14:39
Converter<Object^,String^>(obj2str))) );
↑ここのobj2strの意味がわかりません。obj2strは関数でしょか?

Blue 2006/07/01(土) 14:06:33
Converter ジェネリック デリゲート  
http://msdn2.microsoft.com/ja-jp/library/kt456a2y.aspx

C++サンプルがのっています。

> すぐに質問し返してこないで、MSDNを調べてみてください。(基本)

サマー [E-Mail] [HomePage] 2006/07/01(土) 14:53:05
(654): String^ obj2str(Object^ x) 
             { 
                 return x->ToString(); 
             }

             for each ( DataTable^ tblAuthors in dsPubs-
>Tables )
             {
                 for each (DataRow^ row in tblAuthors-
>Rows )
                 {
                     // リストビューにデータ表示
                     array<String^>^ item1 = Array::ConvertAll(row-
>ItemArray,gcnew Converter<Object^,String^>(obj2str));
                     listView2->Items->Add(gcnew 
ListViewItem(item1));
                 }
             }


obj2strの意味がよくわからないです。上のようなコードを書きましたが、

(654) : error C2601: 'obj2str' : ローカル関数の定義が正しくありません。

とエラーがでてしまいます。

Blue 2006/07/01(土) 15:09:00
obj2strにstaticつけていないからです。
なぜstaticが必要なのかは、C++の基本ですのできちんと調べておいてください。


ちなみに、System::Convert::ToStringでも同等のことはできます。

using namespace System;
using namespace System::Collections::Generic;

int main()
{
    List< Object^ >^ lst = gcnew List< Object^ >();
    lst->Add( 10 );
    lst->Add( 2.5f );
    lst->Add( DateTime::Now );
    lst->Add( "Test" );

    // ※
    Converter< Object^, String^ >^ conv;
    conv = gcnew Converter< Object^, String^ >( System::Convert::ToString );

    List< String^ > slst = lst->ConvertAll( conv );
    for each ( String^ s in slst )
    {
        Console::WriteLine( s );
    }
}

サマー [E-Mail] [HomePage] 2006/07/01(土) 15:30:24
             // データベース接続
             SqlConnection ^ objConn;
             String ^ sConnectionString;
             sConnectionString = "Data 
Source=.\\SQLEXPRESS;AttachDbFilename=C:\\kakeibo.mdf;Integrated 
Security=True;Connect Timeout=30;User Instance=True";
             
             // コネクションのインスタンス生成
             objConn = gcnew SqlConnection(sConnectionString);
             objConn->Open();

             // データアダプターのインスタンス生成
             SqlDataAdapter^ daAuthors = gcnew SqlDataAdapter
("Select * From Main_Table", objConn);

             // データセット型のインスタンス生成
             DataSet^ dsPubs = gcnew DataSet("Pubs");

             // データ読み込み
             daAuthors->Fill(dsPubs, "Main_Table");

             for each ( DataTable^ tblAuthors in dsPubs-
>Tables )
             {
                 for each (DataRow^ row in tblAuthors-
>Rows )
                 {
                     // リストビューにデータ表示
                     Converter<Object^, String^>^ 
conv;
                     conv = gcnew Converter< Object^, 
String^ >( System::Convert::ToString );

                     array<String^>^ item1 = Array::ConvertAll(row->ItemArray, 
conv);
                     listView2->Items->Add(gcnew 
ListViewItem(item1));
                 }
             }

以上のコードでデータベース接続からデータのリストビューへの表示が可能になり
ました。ご協力ありがとうございました。

サマー [E-Mail] [HomePage] 2006/07/01(土) 15:31:04
[[解決]]
以上でこの質問を閉じさせていただきます。

Blue 2006/07/01(土) 16:30:52
ListViewItemオブジェクトを array< String^ >^  を無理して使わなくても、
ひとつずつ設定していくことも可能です。

String^ connstr = 
    L"Data Source=.\\SQLEXPRESS;"
    L"AttachDbFilename=C:\\kakeibo.mdf;"
    L"Integrated Security=True;"
    L"Connect Timeout=30;"
    L"User Instance=True";
SqlConnection^ conn = gcnew SqlConnection( connstr );
conn->Open();

SqlDataAdapter^ da = gcnew SqlDataAdapter( L"SELECT * FROM Main_Table", conn );
DataSet^ ds = gcnew DataSet();
da->Fill( ds );

DataTable^ dt = ds->Tables[ 0 ];
for each ( DataRow^ dr in dt->Rows )
{
    ListViewItem^ item = gcnew ListViewItem();
    for ( int i = 0; i < dr->ItemArray->Length; i++ )
    {
        if ( i == 0 ) item->Text = dr->ItemArray[ i ]->ToString();
        else          item->SubItems->Add( dr->ItemArray[ i ]->ToString() );
    }
    this->listView1->Items->Add( item );
}

conn->Close()

επιστημη 2006/07/01(土) 17:22:20
解決したのはいいんだけど、ConvertAllを通す意味わかってくれたんかな?

「言われたとおりにやったらできたからOK」
の連続だと何度も同じこと繰り返しますよ。

古いスレッドには追加発言できません。