みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Microsoft Visual C++ 2008 Express E

Microsoft Visual C++ 2008 Express EditionとMicrosoft SQL Server 2008
を使用してWindowsフォームアプリケーションでプログラミングを行っています。

今完成させたい機能は、データベースの値をDataGridViewに表示する。
その表示画面のDataGridViewに値を書き込み更新ボタンをクリックしたらそれがデータベースに
反映される。
DataGridViewのレコードを削除でき、それもデータベースに反映させることができる。
以上の三つです。

DataSetにデータを読み込ませて、DataGridViewに入れるとか、BindingSourceを使用する必要が
あるなどは、どこのサンプルコードにも登場してくるのでなんとなく分かるのですが、完成には至って
いません。
Visual C++のサンプルコードがあれば助かるのですが、今はVC#などのサンプルコードを見ながら
プログラムを作成しています。

知識があまりないものなので、もしよろしければやさしい解説を宜しくお願い致します。

投稿日時 - 2010-05-25 15:23:26

QNo.5920848

すぐに回答ほしいです

質問者が選んだベストアンサー

以下、動作確認済みです。SQL Server2005 初めて使いました(笑)


DataSet^ DS = gcnew DataSet();

String^ str;
SqlConnection^ sqlConn = gcnew SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=D:\\dai_work\\C#\\WebApplication2\\WebApplication2\\App_Data\\Database1.mdf;Integrated Security=True;User Instance=True");
sqlConn->CreateCommand();
sqlConn->Open();


str = "select * from 不具合発生";
SqlCommand^ sqlCmd = gcnew SqlCommand(str, sqlConn);
// 確かに要らないですね、これ。
// SqlDataReader^ exeReader = sqlCmd->ExecuteReader();
// SqlDataReader^ objRd=exeReader;

SqlDataAdapter^ SDA = gcnew SqlDataAdapter();
SDA->SelectCommand = sqlCmd;
SDA->Fill( DS, "不具合発生");

String^ strQuery = "";
String^ strSortedColumnName = "";
DataView^ dataView2 = gcnew DataView(DS->Tables["不具合発生"], strQuery, strSortedColumnName, DataViewRowState::CurrentRows);

dataGridView1->DataSource = dataView2;

sqlConn->Close();



動くまで付き合いましょう(笑)

投稿日時 - 2010-05-28 12:04:35

補足

動作するようになりました。

下記のコードでbuttonの支配下だと動かなかったのですが、Loadの支配下にコードを置くと
動きました。
この動作でも特に問題ないです。
本当にありがとうございます。

投稿日時 - 2010-05-28 13:32:43

お礼

本当に申し訳ありません。

下記のコードだと私は

'発生不具合' 演算子の後にオペランドがありません。

というエラーがアプリケーション実行後に、例外?みたいな感じで発生してしまいます。

投稿日時 - 2010-05-28 13:21:52

このQ&Aは役に立ちましたか?

9人が「このQ&Aが役に立った」と投票しています

回答(9)

str = "select * from 不具合発生";

ココが気になりますね。不具合発生?発生不具合?
データベースのテーブル名は間違いありませんか?このクエリはもちろん普通に通りますよね?
ココ意外はエラーというエラーには結びつきません。

#テーブル名に日本語を使われるのも違和感ありですが、まぁこれは好みでしょう。


SDA->Fill( DS, "不具合発生");

ここでは任意のテーブル名を割り当てれます。もちろん整合性を整える上で、実際のデータベースと同じテーブル名("不具合発生")を使う事は適切です。

gcnew DataView(DS->Tables["不具合発生"],

ここではSDA->Fill() でDS に割り当てたテーブル名("不具合発生")を利用してます。


SDA-Fill() の後、テーブルが1つよみこまれかどうか確認を。
int nCount = DS->Tables->Count;
nCount == 1 になりますか?


ちなみに当方の環境はVisualStudio2008 C++, SQL Express 2005,
using namespace System::Data::SqlClient;
です。

文字列はダブルクォーテーション(")でくくりますよ?

投稿日時 - 2010-05-28 13:47:47

お礼

解説ありがとうございます。

テーブル名は発生不具合です。
やはりテーブル名は英語でつけるものなのですか?

しっかり""でくくっていましたし、テーブルも読み込まれていました。
まーLordには置きましたが表示機能が無事完成してよかったです。

ありがとうございます。

投稿日時 - 2010-05-28 14:03:04

DataSet^ DS = gcnew DataSet();

String^ str;
SqlConnection^ sqlConn = gcnew SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Documents and Settings\\Administrator\\My Documents\\バグ管理.mdf;Integrated Security=True;User Instance=True");
sqlConn->CreateCommand();
sqlConn->Open();


str = "select * from articles";
SqlCommand^ sqlCmd = gcnew SqlCommand(str, sqlConn);
SqlDataReader^ exeReader = sqlCmd->ExecuteReader();
SqlDataReader^ objRd=exeReader;

SqlDataAdapter^ SDA = gcnew SqlDataAdapter();
SDA->SelectCommand = sqlCmd;
SDA->Fill( DS,"articles");


String^ strQuery = "";
String^ strSortedColumnName = "";
DataView^ dataView = gcnew DataView(DS->Tables["articles"], strQuery, strSortedColumnName, DataViewRowState::CurrentRows);

dataGridView1->DataSource = dataView;

sqlConn->Close();


全部やってもうたw

投稿日時 - 2010-05-27 15:07:33

お礼

わざわざソースを載せて頂きありがとうございます。

ソースを参考に作成しました。

articlesは使用するとオブジェクトが無効?とかそのような感じのエラーがでたので実在する
発生不具合というテーブルに書き換えました。

SqlDataReader^ exeReader = sqlCmd->ExecuteReader();
SqlDataReader^ objRd=exeReader;
を使用すると
DataReaderはすでに開かれています。
というエラーがでたのでコメントアウトしました。

今現在は
構文エラー : '発生不具合' 演算子の後にオペランドがありません。
というエラーが出たので修正しているのですが、手詰まり状態です。
よろしければ回答お願い致します。

2bypi8921cfrさんは上記のコードでプログラムは動いている状況なのでしょうか?

投稿日時 - 2010-05-28 10:31:22

VC++ で作ってみました。

MySql::Data::MySqlClient::MySqlConnection^ mySqlConnection = gcnew
MySql::Data::MySqlClient::MySqlConnection("Server=MySQLServer.loog;User Id=user;Password=password;Persist Security Info=True;Database=test_db");
mySqlConnection->Open();

DataSet^ DS = gcnew DataSet();

MySql::Data::MySqlClient::MySqlDataAdapter^ mySqlDataAdapter = gcnew MySql::Data::MySqlClient::MySqlDataAdapter("select * from articles", mySqlConnection);

mySqlDataAdapter->Fill(DS, "articles");

String^ strQuery = "";
String^ strSortedColumnName = "";
DataView^ dataView = gcnew DataView(DS->Tables["articles"], strQuery, strSortedColumnName, DataViewRowState::CurrentRows);

dataGridView1->DataSource = dataView;

mySqlConnection->Close();


MySQL Connector でつないでいますが、その辺は気にしないでください。

どうでしょうか?

投稿日時 - 2010-05-27 12:16:06

お礼

わざわざコードまで載せていただいてありがとうございます。

申し訳ありません。
下記のエラーが出ました。

c:\documents and settings\administrator\デスクトップ\kannri1\syutoku1.h(272) : error C2664: 'System::Data::SqlClient::SqlDataAdapter::SqlDataAdapter(System::Data::SqlClient::SqlCommand ^)' : 1 番目の引数を 'const char [25]' から 'System::Data::SqlClient::SqlCommand ^' に変換できません。(新しい機能 ; ヘルプを参照)
理由: 'const char *' から 'System::Data::SqlClient::SqlCommand ^' へは変換できません。
使用可能なユーザー定義された変換演算子がない、または
アンマネージ型をマネージ型に変換できません。


エラーが出た場所は

String^ str;
SqlConnection^ sqlConn = gcnew SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Documents and Settings\\Administrator\\My Documents\\バグ管理.mdf;Integrated Security=True;User Instance=True");
sqlConn->Open();
DataSet^ DS = gcnew DataSet();


SqlDataAdapter^ SDA = gcnew SqlDataAdapter("select * from articles"); <-ここです。
SqlCommand^ sqlCmd = gcnew SqlCommand(str,sqlConn);

SDA->Fill(DS, "articles");

String^ strQuery = "";
String^ strSortedColumnName = "kennmei";


//dataGridView1->DataSource = DS;
DataView^ dataView = gcnew DataView(DS->Tables["articles"], strQuery, strSortedColumnName, DataViewRowState::CurrentRows);

dataGridView1->DataSource = dataView;


sqlConn->Close();
return;
}

何度も何度も本当に申し訳ありません。

投稿日時 - 2010-05-27 13:50:38

ANo.1 です。

> DataTable DT = DS->Tables["発生不具合"]; 

DataTable^ DT = DS->Tables["発生不具合"]; 

.Net 由来のインスタンスは^ 付きで参照受けできる仕様なんでしょうか?
(ヤバイ、C#ばっかりで知らない事に・・・)


DataView は、DataSet 内の特定のテーブル中の特定のレコード群を保持するオブジェクトです。
ここではテーブル"発生不具合"内のレコード一覧として使っています。

投稿日時 - 2010-05-26 19:35:47

お礼

分かりやすい解説ありがとうございます。

プログラムを一晩寝かせていたらエラー内容が変わってしまいました。

1 引数を取り込む関数には評価されません。

というものになっていました。
エラーが発生している場所は同じです。

試しに^を取ったりはずしたりしてみましたがだめでした。(笑)

VC++はインスタンス化には^を使用します。

投稿日時 - 2010-05-27 10:30:07

ANo.1 です。

ごめんなさい。SDA じゃなくてDS (DataSet) でした。

誤) new DataView(SDA.Tables["articles"],

正) new DataView(DS.Tables["articles"],



でもエラーはCast 周り。違う場所でしょうか・・・?

投稿日時 - 2010-05-26 17:29:39

お礼

そこの部分は気づけたので問題ないです。

this.m_dataView = new DataView(SDA.Tables["articles"], strQuery, strSortedColumnName, DataViewRowState.CurrentRows);

ここの2行で何をやっているのか知りたいです。m_dataViewとはなんでしょうか?

エラーの部分は
DataSet^ DS = gcnew DataSet();
SDA->SelectCommand = sqlCmd;
SDA->Fill( DS,"発生不具合");
DataTable DT = DS->Tables["発生不具合"]; <-ここの行です。

投稿日時 - 2010-05-26 17:57:37

ANo.1 です。

読み込みできているなら、グリッドビューへの関連付けですね。グリッドビューのカラムのDataPropertyName はテーブルのカラム名に)は最初に設定してないといけませんよ?


String strQuery = "";
String strSortedColumnName = "";
this.m_dataView = new DataView(SDA.Tables["articles"], strQuery, strSortedColumnName, DataViewRowState.CurrentRows);

this.m_dataGridView1.DataSource = this.m_dataView;

strQuery でさらなる絞り込み。where 文以降、例えばid in ("001", "002") and visible=1 みたいな。
strSortedColumnName にはソートしたいカラム名で。

DataView はDataSouce に当てた後も保持していないと行けなかったかなぁ・・・?

投稿日時 - 2010-05-26 15:05:19

お礼

回答ありがとうございます。

そのままでは使えなかったので、一部変更して利用させていただきました。

すると次に下記のようなエラーがでました。

c:\documents and settings\administrator\デスクトップ\kannri1\syutoku1.h(260) : error C2664: 'System::Data::DataTable::DataTable(System::String ^)' : 1 番目の引数を 'System::Data::DataTable ^' から 'System::String ^' に変換できません。(新しい機能 ; ヘルプを参照)
使用可能なユーザー定義された変換演算子がない、または
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。

これは普通に型変換というものを行えば解決する問題なのでしょうか?
なんども質問してしまい申し訳ありません。

投稿日時 - 2010-05-26 16:17:39

ANo.1 です。

>> 'Fill' を呼び出す前に、SelectCommand プロパティが初期化されませんでした。

とありますので、

SDA.SelectCommand = sqlCmd;
としてからFill を呼んではいかがでしょう?


ところでサーバーエクスプローラーを使って自分用にカスタマイズされたDataSet 派生型をビジュアルに作れます。テーブルのカラムがMyDataSet のプロパティとして準備されるんですよね。
それを使うと実装の手間が随分減ると思います。(Select 文とか要らなくなる)

MySQL ですが下記も参考になります。
http://ast.qt-space.com/c-sharp/database.html

参考URL:http://www.atmarkit.co.jp/fdotnet/basics/adonet05/adonet05_02.html

投稿日時 - 2010-05-26 10:05:09

お礼

SDA.SelectCommand = sqlCmd;を使用したところエラーが消えました。
しかし新たなエラー

このコマンドに関連付けられている DataReader が既に開かれています。このコマンドを最初に閉じる必要があります。

が表示されたので
SqlDataReader ^ exeReader = sqlCmd->ExecuteReader();
SqlDataReader ^ objRd=exeReader;
の2行をコメントアウトしました。

エラーなくプログラムは実行するのですが、ボタンをクリックしても値は表示されませんでした。
しかしボタンをクリックしたところdataGridViewのテキストにカーソルが向いたので、
反応はしていることは確かです。

今更ながらなのですが、ネットの情報だと自分が使用しているdataGridViewを指定しているだけで
データの表示に成功しているのですが、列単位での指定などは不要なのでしょうか?
もしよろしければ回答宜しくお願い致します。

投稿日時 - 2010-05-26 11:18:30

まさに同じような品をC#で作りました。

今は具体的にどこで躓いているのですか?

投稿日時 - 2010-05-26 01:11:34

お礼

質問をチェックしていただきありがとうございます。

今は、データベースの値を表示させようと
private:
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {

String^ str;
SqlConnection^ sqlConn = gcnew SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Documents and Settings\\Administrator\\My Documents\\バグ管理.mdf;Integrated Security=True;User Instance=True");
sqlConn->Open();


SqlDataAdapter^ SDA = gcnew SqlDataAdapter;

str = "select 件名 from 発生不具合";
SqlCommand^ sqlCmd = gcnew SqlCommand(str,sqlConn);
SqlDataReader ^ exeReader = sqlCmd->ExecuteReader();
SqlDataReader ^ objRd=exeReader;


DataSet^ DS = gcnew DataSet();
SDA->Fill( DS,"発生不具合");


dataGridView1->DataSource = DS;

sqlConn->Close();
return;
}

上記のプログラムを作成しました。
コードの細かい内容などは理解してできていないのですが、DataSetにセットしたデータベースの値を
dataGridView1に入れて表示させようとしているつもりです。
特にコンパイル時のエラーはないのですが、プログラムを実行してbutton1をクリックすると、

追加情報: 'Fill' を呼び出す前に、SelectCommand プロパティが初期化されませんでした。

上記のようなエラーが出ます。
分かるようでしたら解決策を教えていただけないでしょうか?

投稿日時 - 2010-05-26 09:32:36