ダイアログボックスからの入力をデータベースに反映できない

[戻る]
のりのり [E-Mail] 2002/06/28(金) 09:44:15
おはようございます。のりのりです。
今回も宜しくお願いします。

環境
Windows Me
VC++ 6.0
SQL SERVER
を利用(以前と変らず)。

以前の回答でレコードの追加が出来るようになりましたが、Accessでデータを開いてみると
日付/時刻型のフィールド(CMyRecordsetクラスのm_column4)がどうも上手く追加(表示?)で
きないのです。

データベースの問題の項目は日付/時刻型で、ソース上ではCTime型のm_column4になっていま
す。
ダイアログボックスのメンバ変数ではCString型のm_dayとしています。

データベースの内容をダイアログボックスに表示させる時には

CTime t(m_Recordset.m_column4);
// CTimeクラスのFormat関数にて文字列型に変換し、
// CString型のメンバ変数に格納する         
m_day = t.Format(%Y, %m, %d);
// メンバ変数をダイアログに表示させる
UpdateData(FALSE);        

で出来たのですが、追加処理によりダイアログに入力した日付(2002/06/29という形式)を
データベースの方に反映することが出来ないのです。
色々試してみましたが、上手く行きません。NULLになっているか、入力した日付とは
かけ離れた日付が入ってしまうのです。

現状のソースは以下の通りです。
CTime t(atoi(m_day.Mid(0,4),atoi(m_day.Mid(4,2),atoi(m_day.Mid(6,2)));
m_Recordset.m_column4 = t;

2002/06/29と入力して[追加]ボタンを押してもデータベースでは
1984/02/18 0:00:12となってしまいます。

どうか宜しくお願い致します。

dairygoods 2002/06/28(金) 09:57:17
> CTime t(atoi(m_day.Mid(0,4),atoi(m_day.Mid(4,2),atoi(m_day.Mid(6,2)));

まず、この m_day や t の内容を表示して、
期待通りの値が入っているか確認すべきでしょう。

不良PG [E-Mail] 2002/06/28(金) 10:17:31
CTimeのコンストラクタのヘルプを見ることをお勧めします

CTime::CTime


データベースでMS-DOS の日付と時刻を扱いたいというなら間違っていませんが・・

のりのり [E-Mail] 2002/06/28(金) 13:11:18
CTimeのヘルプを見てみましたが、あまり良く分かりませんでした。
VC(C++)を始めたばかりなので…。入門書程度しか読んでいないのです。

今のソースのままではMS-DOSの日付で初期化されてしまうのでしょうか…。
だとするとやはりダイアログからの入力情報をデータベースに追加できないのですね。

もし参考になるソースなどがありましたら、教えていただけませんでしょうか。
すみません。宜しくお願いします。

不良PG [E-Mail] 2002/06/28(金) 13:47:10
ちょっと確認
>CTime t(atoi(m_day.Mid(0,4),atoi(m_day.Mid(4,2),atoi(m_day.Mid(6,2)));
これって
CTime t(atoi(m_day.Mid(0,4)),atoi(m_day.Mid(4,2)),atoi(m_day.Mid(6,2))));
これの間違いだよね?



>今のソースのままではMS-DOSの日付で初期化されてしまうのでしょうか…。
いや、ちょっと意味が違いますが・

>だとするとやはりダイアログからの入力情報をデータベースに追加できないのですね。
ちょっと直せばOKでしょう・・

>CTime t(atoi(m_day.Mid(0,4),atoi(m_day.Mid(4,2),atoi(m_day.Mid(6,2)));

この場合
CTime( WORD wDosDate, WORD wDosTime, int nDST = -1 );
このコンストラクタが使われるので
atoi(m_day.Mid(0,4)) ・・・DOS日付
atoi(m_day.Mid(4,2)) ・・・DOS時刻
atoi(m_day.Mid(6,2)) ・・・夏時間?
の意味になります。

のりのりさんはきっと
atoi(m_day.Mid(0,4)) ・・・年
atoi(m_day.Mid(4,2)) ・・・月
atoi(m_day.Mid(6,2)) ・・・日
を意識していると思いますので
CTime( int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, int nDST 
= -1 );
このコンストラクタを使って

CTime t(atoi(m_day.Mid(0,4)),atoi(m_day.Mid(4,2)),atoi(m_day.Mid(6,2)),0,0,0);
こうすればよいのでは?

のりのり [E-Mail] 2002/06/28(金) 14:18:36
不良PGさん、回答ありがとうございます!

>のりのりさんはきっと
>atoi(m_day.Mid(0,4)) ・・・年
>atoi(m_day.Mid(4,2)) ・・・月
>atoi(m_day.Mid(6,2)) ・・・日
>を意識していると思いますので
>CTime( int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, 
>int nDST = -1 );
>このコンストラクタを使って

>CTime t(atoi(m_day.Mid(0,4)),atoi(m_day.Mid(4,2)),atoi(m_day.Mid(6,2)),0,0,0);
>こうすればよいのでは?

さっそく試してみました。
こうしてCTime型に変換された年月日tを
m_Recordset.m_column4 = t;
として格納するということですよね。
実行してみたのですが、
「Microsoft Visual C++ Debug Library」というタイトルのダイアログボックスが出てきて
しまい、プログラムが落ちてしまいました…。
メッセージ内容:
For information on how your program can cause an assertion 
failure, see the Visual C++ documentation on asserts.

どのように対処したら良いでしょうか。お時間があれば宜しくお願いします。

のりのり [E-Mail] 2002/06/28(金) 14:32:48
[[解決]]
すみません!解決しました。理由がわかりました。

CTime t(atoi(m_day.Mid(0,4)),atoi(m_day.Mid(4,2)),atoi(m_day.Mid(6,2)),0,0,0);

で正しく引数を渡して初期化(?)していたつもりでしたが、入力形式は2002/06/29
のように年4桁+/+月2桁+/+日2桁のため、Mid関数で指定するときにずれてしまっていたの
が原因だったのだと思います。それで、

CTime t(atoi(m_day.Mid(0,4)),atoi(m_day.Mid(5,2)),atoi(m_day.Mid(8,2)),0,0,0);

と指定してみたところ、上手く表示かつ追加できるようになりました。

何回もアドバイスを下さってありがとうございました。

分からないまま進めてきたので、基礎の部分を見直そうかと思います。
何か有益な情報などありましたら是非教えてください。

失礼します(^^)

dairygoods 2002/06/28(金) 15:07:52
私ならこうします。

int year, month, day;
int n = sscanf(m_day, "%d/%d/%d", &year, &month, &day);
if (n!=3) 
  return;//format error

CTime t(year,month,day,0,0,0);
...

こうなってれば、プログラムを見ただけでm_dayが"年/月/日"だと分かるし、
何文字目とか気にしなくていいですから。

のりのり 2002/07/01(月) 09:15:46
おはようございます。
dairygoodsさん 回答ありがとうございます!

そうですよね。自分でも変数がわかりにくい名前になっていると思います。
こういう点にも気をつけて組んでいこうと思います。

参考になる意見をありがとうございました。

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