またまたの書き込みですみません(^^;
CRecordsetクラスを使って、AccessのMDBファイルに書き込みをしようとしています。
☆Accessで、新規mdbファイルを作成。
☆テーブルを一つ作成し、フィールド「data1」「data2」「data3」を作成。
☆コントロールパネル→管理ツール→データソース で、dsnを作成(ここでは「test」とします)
☆VC++6を起動、とりあえずMFCサポートのコンソールアプリケーションでプロジェクトを作成。
☆ClassWizerdで、CRecordsetクラス「CRec」を作成
といった手順で作成し、ソース中(関連部分のみ抜粋)では
CRec test; //オブジェクトの作成
test.Open();
printf("ファイルオープン完了!!\n");
if(!test.CanAppend())
{
printf("追加できません\n");
}
test.AddNew();
test.m_data1 = "一つ目";
test.m_data2 = "二つ目";
test.m_data3 = "三つ目";
if(!test.Update())
{
printf("アップデートできませんでした。\n");
}
test.Requery();
rec.Close();
といった流れで作成しています。
コンパイルもビルドもうまくいくのですが、試しに動かしてみると・・・
テーブルとその中にフィールドだけを作成して中身がない状態で書き込まれると、エラーがおきて強制終了されてしまいます。
mdbファイルの中身を見るとしっかり更新されています。
また、1行でも中身がある状態だと、エラーもなく更新できます。
一番最初の時だけ、何か特別なことをしなければならないんでしょうか?
ご存じの方がいらっしゃいましたら、教えていただけませんでしょうか?
ぜんぜん詳しくないのですが、気になった点について
CanUpdateの必要はないのでしょうか?
また、RequeryはCDBException型の例外を送出するようですが、
これをcatchして詳細を見てはいかがでしょうか?
たくさん
最初の投稿のソースの部分で
if(!test.CanAppend())
{
printf("追加できません\n");
}
と、きちんとCanUpdateはしています。
> また、RequeryはCDBException型の例外を送出するようですが、
> これをcatchして詳細を見てはいかがでしょうか?
こちらについては、もしよろしければ方法を教えていただけませんか?
MFC初心者なので、よく分かっていなくて・・・
例外のキャッチは次のような感じですが、
try{
test.Requery();
}
catch(CDBException db_exp)
{
printf("%s\n", db_exp.strError);
}
最後の
rec.Close();
は、
test.Close();
だったりしませんか?
前後のコードがわからないのでなんともいえませんが・・・
たくさん
> 最後の
> rec.Close();
> は、
> test.Close();
> だったりしませんか?
・・・です。
失礼しました(^^;
とりあえず、月曜に会社にいったらやってみますね♪
ありがとうございます(T_T)
いろいろ試してみたところ、
test.Update();
のところでおかしくなっているようです。
たくさんに教えていただいた「try・・・」を試してみたところ、同様にポップアップで「Runtime Error!!」とでて、そこには
This application has requested the Runtime to Terminate it in an usual way.
Plese contact the application's support team for more information.
とでて、OKボタンをクリックすると強制終了されます。
一体どこがいけないのでしょう・・・?
補足で・・・
> たくさんに教えていただいた「try・・・」を試してみたところ、
これは、まず
try{
test.Requery();
}
catch(CDBException db_exp)
{
db_exp.ReportError();
}
で試したところ、そこまで到達できず、次に
try{
test.Update();
}
catch(CDBException db_exp)
{
db_exp.ReportError();
}
で試したところ、やはり同じようになりました。
Updateの部分を消すと、強制終了が起こりません(当然、データは書き込まれませんが・・・)。
どなたか助けてください・・・
すみません、間違ってたようです。
try{
test.Requery();
}
catch(CDBException* db_exp)
{
db_exp->ReportError();
}
これでどうでしょうか?
ちなみに、最初のソースを
test.Close();
と変更しただけのサンプルはこちらで正しく動作しました^^;
試してみたところ、「変更または削除に失敗しました」とポップアップが上がってきます。
長〜区なってしまいますが、こちらがソースの抜粋です(変数も、ここで使うののみ記述しています)。
#define MAX_REC2 1024
//文字列時間(yy/mm/dd)をCTimeに格納する関数(動作確認済みです)
BOOL CtoTime(char *c_ymd, CTime *ymd);
CRec CRec;
int m, n, z;
FILE *LoadData;
char rec;
char rec2[MAX_REC2];
〜fopen、等は省略〜
m = 0;
n = 0;
z = 0;
while(1)
{
rec = fgetc(LoadData);
if(rec == EOF)
{
break;
}
//最初の2行は書き込まない
if(m < 2)
{
if(rec == '\n')
{
m++;
}
}
//3行目から書き込み
else
{
if(rec == ',')
{
z++;
for(; n < MAX_REC2; n++)
{
rec2[n] = '\0';
}
if(z >= 7)
{
printf("データのフォーマットが異常です①。:%s", argv[i]);
getchar();
CRec.Close();
return 1;
}
else if(z == 1)
{
CRec.m_Data1 = rec2;
}
else if(z == 2)
{
CRec.m_ata2 = rec2;
}
else if(z == 3)
{
CRec.m_Data3 = rec2;
}
else if(z == 4)
{
CRec.m_Data4 = rec2;
}
else if(z == 5)
{
CRec.m_Data5 = rec2;
}
else if(z == 6)
{
CRec.m_Data6 = rec2;
}
n = 0;
}
else if(rec == '\n')
{
if(z != 6)
{
printf("データのフォーマットが異常です②→%d。:%s", z, argv[i]);
getchar();
CRec.Close();
return 1;
}
else
{
m++;
for(; n < MAX_REC2; n++)
{
rec2[n] = '\0';
}
CtoTime(rec2, &CRec.m_Timedata);
n = 0;
z = 0;
try
{
CRec.Update();
}
catch(CDBException *db_exp)
{
db_exp->ReportError();
}
CRec.Requery();
}
}
else
{
rec2[n] = rec;
n++;
}
}
}
抜けがあったらごめんなさい(^^;
やろうとしていることは
☆ある決まった形式のcsvファイルを読み込む
☆最初の2行は飛ばして3行目から一文字ずつ見ていく
○普通の文字列なら文字列変数rec2に追記
○「,」になったら、該当するAccessの項目に書き込み
○改行がでたら、その行の最後の項目は日付なので、
AccessのDATEの形式に変換して書き込みをして、
Updare、Requeryをして次の行へ・・・
☆以上をファイルがEOFになるまで繰り返す
といった感じです。
Update()の部分で突っかかっているみたいです・・・。
なぜなんでしょう・・・?
変換関数が動作確認済みで、
日付のフィールドに正しくセットされているということであれば
データベースのほうも確認してみたほうがよいのではないでしょうか?
途中から、全部のデータを保存できなくなってしまっていたのですが・・・
ODBC、プロジェクト(クラスも)すべてを新規作成して、ソースをコピーしたところ、とりあえず、mdbファイルに1行でもデータがあれば問題なく動きました。
ところが、やはりフィールドだけ存在し、1行もデータがない状態のテーブルに書き込みをしようとすると、Windowsお約束の「強制終了(エラーを送信する、とかでてくるやつ)」が現れてうまくいかないです・・・。
最初の1行目にデータを書き込む場合は、何か特別な処理をしなければならないんでしょうか・・・?
ツイート | ![]() |