dポイントプレゼントキャンペーン実施中!

 こんにちは。いつもお世話になっております。
 プログラミングの初心者で、現在VC++でプログラムを作成しています。環境は、OSがWindowsXP、統合環境はVisualStudio2008 Professionalを使用しています.
 ADO.NETでデータベースを作成しているのですが、DataSetを介して、任意のフィールドを変更・更新がうまくいきません。プログラムの内容は、保存されているAccessデータから表を読み込み、その表に対して挿入、変更、削除を行い、最後にupdateをしてAccessのデータを更新するというものです。以下、プログラムの一部を抜粋します。拙い説明で申し訳ありません。原因が分かる方、よろしくご教授ください。
m(_)m


private: bool LoadAccessFile(String^ path)
{
// コネクションを作成
OleDbConnection^ cn = gcnew OleDbConnection();
cn->ConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;"
"Data Source=" + path;
// すべてのデータを読み込む
OleDbDataAdapter^ da = gcnew OleDbDataAdapter("select * from 実績テーブル", cn);
OleDbDataAdapter^ da2 = gcnew OleDbDataAdapter("select * from クエリ1", cn);
OleDbCommandBuilder^ builder = gcnew OleDbCommandBuilder(da);

//test
OleDbCommand^ selectCommand = cn->CreateCommand();
OleDbCommand^ selectCommand2 = cn->CreateCommand();
OleDbCommand^ insertCommand = cn->CreateCommand();
OleDbCommand^ updateCommand = cn->CreateCommand();
OleDbCommand^ deleteCommand = cn->CreateCommand();


selectCommand->CommandText = "select 通し番号, 日付, 内容, 金額, カテゴリー番号, 銀行口座通し番号 from 実績テーブル
where 通し番号=2";
selectCommand2->CommandText = "select 通し番号, 日付, 内容, 金額, カテゴリー名称, 銀行口座口座名称 from クエリ1";
insertCommand->CommandText = "insert into 実績テーブル (通し番号, 日付, 内容, 金額, カテゴリー番号, 銀行口座通し番号)
values (@通し番号, @日付, @内容, @金額, @カテゴリー番号, @銀行口座通し番号)";

     (中略)

// OleDbDataAdapterのスキーマと、SelectCommandで抽出したデータを格納
da->FillSchema(ds, System::Data::SchemaType::Mapped);
da->Fill(ds->Tables["Table"]);

// "Table"表の2行3列目のデータを変更
ds->Tables->Add("クエリ1");
//test(090223)
DataRow^ row = ds->Tables["Table"]->Rows[1];
//Rows[0]の添え字を0以外にするとエラー。「位置1に行がありません」
DataColumn^ column = ds->Tables["Table"]->Columns[2];
row[column] = "本";

// "Table"表の0行目を削除
ds->Tables["Table"]->Rows[0]->Delete();
//Rows[0]の添え字を0以外にするとエラー。「位置1に行がありません」

A 回答 (4件)

dsに取得するデータが where句で選別されているので


これにより 1行しか返さないのではないかと思います

『通し番号』とあるので テーブルの中で一意の値なのでしょう

OleDbCommanBuilderの使い方をリファレンスで確認しましょう

//test
部分の selectCommand等を daやda2の各コマンドに再設定しているのであれば間違った使い方の可能性が高いです

daの生成時に選択クエリーを与えたのであればSelectCommandプロパティが生成されています
このdaを与えてCommnadBuilderを生成する時点で
daのSelectCommand,InsertCommand,UpdateCommand,DeleteCommandが更新されるはずです

この回答への補足

 redfox63さん、回答ありがとうございます。m(_)m

 ds->Tables["Table"]->Rows[1]->Delete();
のRowsの添え字を0以外に設定するとエラーになる件は、redfox63さんご指摘の通り、selectCommand->CommandTextでwhere句を使い1行のみを抽出していたためでした。where句を削除することによって意図したデータの変更ができました。ありがとうございました。m(_)m

 また、質問を重ねてしまい申し訳ないのですが、CommnadBuilderについて一つ質問させてください。
OleDbCommandBuilder^ builder = gcnew OleDbCommandBuilder(da);
のようにOleDbCommandBuilderをインスタンス化して、SelectCommandを手動で用意すると、InsertCommand,UpdateCommand,DeleteCommandが自動的に生成されると、リファレンスに書かれていたのですが、InsertCommand,UpdateCommand,DeleteCommandは、SelectCommand設定後に使用できるようになるということでしょうか? また、InsertCommand,UpdateCommand,DeleteCommandは、生成後はパラメーターやスキーマの情報は、SelectCommandに設定された情報を取得して使用するのでしょうか? 以上、お手数ですがご回答いただければ幸いです。m(_)m


 

補足日時:2009/03/02 11:23
    • good
    • 0

確認のため簡単なプロジェクトを組んでやってみましたが


どうも Adpter/CommandBulider経由でやると Updateなどが上手く機能しないような状況になってしまいます

そこで
プロジェクト > 追加 > 新しいの項目 > データセット
を追加し
このxsdファイルに TableAdapterを追加
ウィザードで SQLなどを指定

フォームへのデータ表示更新のために 『データ ソース』から追加
といった手順で BindingSource経由にしてみたところ Updateも問題なくいくようです

既存のAdapterクラスのUpdateメソッドに対しての設定が足りないのだろうと思いますが調べきれておりません m(__)m
    • good
    • 0
この回答へのお礼

 redfox63さん、回答ありがとうございます。m(_)m

 お手数をお掛けしてしまい申し訳ありませんでした。私も色々やってみたのですが、CommandBulider経由でのUpdateは、うまくいきませんでした。もう少しUpdateメソッドについて調べてみようと思います。ありがとうございました。m(_)m

お礼日時:2009/03/06 09:10

ごめんなさい m(__)m


少々勘違いがあったようです
CommandBuilderを生成した時点でDataAtdpterのCommand群は更新されません

builder = gcnew OleDbCommandBuilder(da);
を行って
da->InsertCommand = builder->GetInsertCommand();
da->DeleteCommand = builder->GetDeleteCommand();
da->UpdateCommand = builder->GetUpdateCommand();
といった具合に自動生成されたコマンド群を設定してください

この回答への補足

 redfox63さん、回答ありがとうございます。m(_)m

 リファレンスではSelectCommandの設定後、InsertCommand、DeleteCommand、UpdateCommandが自動生成されるとあるのですが、その場合でもInsertCommand、DeleteCommand、UpdateCommandは、 builder->GetInsertCommand(); のように設定が必要ということでしょうか?
 また、生成されたInsertCommand、DeleteCommand、UpdateCommandの初期値はどのような中身が設定されるのでしょうか?質問を重ねてしまい申し訳ないのですが、よろしくお願いいたします。m(_)m

 

補足日時:2009/03/04 09:12
    • good
    • 0

アクセスのデータを クエリから取得しているのでしょうか?



クエリからでは Update等の更新は出来そうに無いと思います
クエリーのSQLを使って DataSetを取得しましょう

2行目などの取得が出来ないとのことですが
ds->Tables["Table"]->Rows.Count
の値はいくつになっているのでしょう

この回答への補足

redfox63さん、早速の回答ありがとうございます。m(_)m

Accessのデータは、テーブルからds(DataSet)にデータを取得しています。dsの変更後、dsに対してupdateを実行して、外部キーを持っているクエリ1をVC++のDataGridViewに表示させています。(データベースに不慣れなので間違っていればご指摘くださいm(_)m)

もう一つ、ご指摘のあったテーブルのカレントの行を以下の方法で調べて見たのですが、「1」となっていました。
int i = ds->Tables["Table"]->Rows->Count;

補足日時:2009/02/27 08:39
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!