- ベストアンサー
ACCESS 2003の条件分岐について教えて頂けないでしょうか?
access2003を勉強中です。 先週1週間かけても解決できないことがありまして、どなたか教えて頂けないでしょうか。 内容は 会社で使用する勤務表に関してです。 ユーザー名(コンボボックス)、日付(カレンダーコントロール)、 出社時間(テキストボックス)、退社時間(テキストボックス 、作業内容(テキストボックス)をユーザーが入力し「登録」 コマンドボタンのイベントで入力した内容を、勤務表テーブルに 反映させたいのです。 その時に同じユーザーの同じ日付を2件入力させないようにしたいので フォームに入力された内容からユーザー名と日付によって、 同じ内容が勤務表テーブルに無ければinsert、有ればupdateと 条件分岐をしたいのです。 しかし、 Public Sub kinmu() Dim mmrs As ADODB.Recordset Dim mmcn As ADODB.Connection Set mmrs = New ADODB.Recordset Set mmcn = Application.CurrentProject.Connection mmrs.Open "勤務表", mmcn, adOpenKeyset, adLockOptimistic mmrs.MoveFirst If DCount("[ユーザー名] & [日]", "[勤務表]", "[ユーザー名]=[Forms]![フォーム1]![コンボ56]" & _ "and[日]=[Forms]![フォーム1]![テキスト88]") = 0 Then mmcn.Execute "INSERT INTO 勤務表 ([ユーザー名],[日],[出社],[退社],[作業内容]) VALUES ([Forms]![フォーム1]![コンボ56],[Forms]![フォーム1]![テキスト88],[Forms]![フォーム1]![テキスト8],[Forms]![フォーム1]![テキスト17],[Forms]![フォーム1]![テキスト28]);" Else mmcn.Execute "UPDATE 勤務表 SET (ユーザー名=[Forms]![フォーム1]![コンボ56],日=[Forms]![フォーム1]![テキスト88],出社=[Forms]![フォーム1]![テキスト8],退社=[Forms]![フォーム1]![テキスト17],作業内容=[Forms]![フォーム1]![テキスト28] where [ユーザー名]=[Forms]![フォーム1]![コンボ56] and [日]=[Forms]![フォーム1]![テキスト88]);" End If として、「登録」コマンドボタンのイベントとしてCallキーワードによって呼び出そうとしているのですが、うまくいきません。 最初はDCount関数で件数を求め、それを変数に入れる。 IIF関数による分岐。などいろいろ試してはいたのですが、、、。 どなたか教えて下さい。よろしくお願いします。
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
1)レコードセットは何のために開いているのですか? 2)分岐うんぬんの前に、 mmcn.Execute "INSERT INTO 勤務表 ([ユーザー名],[日],[出社],[退社],[作業内容]) VALUES ([Forms]![フォーム1]![コンボ56],[Forms]![フォーム1]![テキスト88],[Forms]![フォーム1]![テキスト8],[Forms]![フォーム1]![テキスト17],[Forms]![フォーム1]![テキスト28]);" これは正しく動作していますか?
その他の回答 (9)
- Dxak
- ベストアンサー率34% (510/1465)
#1です まずは、UPDATE文の見直しだけしてみると・・・ Dim mySQL as String mySQL = "UPDATE 勤務表 SET ( " & _ "ユーザー名 = '" & [Forms]![フォーム1]![コンボ56] & "', " & _ "日 = #" & Format([Forms]![フォーム1]![テキスト88], "yyyy/mm/dd") & "#, " & _ "出社 = #" & Format([Forms]! [フォーム1]![テキスト8],"hh:nn") & "#, " & _ "退社 = #" & Format([Forms]![フォーム1]![テキスト17],"hh:nn") & "#, " & _ "作業内容 = '" & [Forms]![フォーム1]![テキスト 28] "' " & _ "Where [ユーザー名] = '" & [Forms]![フォーム1]![コンボ56] & "' " &_ "And [日] = #" & Format([Forms]![フォーム1]![テキスト88], "yyyy/mm/dd") & "# ;" Debug.Print mySQL mmcn.Execute mySQL と、いう感じかな? > 作業時間 日付/時刻型 の辺りは、基本的にクエリー上に生成するフィールドであって、テーブル上ではないと思うんだけど・・・「休憩時間」がないのが、引っかかってるのかな? 後、日付も・・・基本的に、出社時刻、退社時刻に、含められるから、クエリー上に作成、テーブル上に設定するフィールドじゃ、無いような・・・ > シングルクオートやダブルクオート等使い方が複雑で理解できていません。 これは、VBA上では、ダブルクオートのみが文字列として区分 SQL上では、シングルクオート、ダブルクオート同義、VBA上では、VBAの文字列と混同しないように、SQL用にシングルクオートを使用してると・・・特に好み次第で、使い方が違うという話^^;;;
補足
返信いただきありがとうございました。 実は、いろいろと調べていくうちにやりたい事は下記のコードで できることがわかりました。せっかく高度なやり方を教えて頂いた のに。。。早く教えて頂いた内容で使いこなせるよう勉強したいと 思います。今回は本当にありがとうございました。 'DCount関数で勤務表の中からユーザー名がコンボ56と同じ且つ日がテキスト88と同じものをカウントする If DCount("*", "勤務表", "勤務表.ユーザー名 = " & _ "[Forms]![フォーム1].[コンボ56] AND 勤務表.日 = [Forms]![フォーム1].[テキスト88]") = 0 Then 'DCount関数の結果が0だったら挿入処理 DoCmd.RunSQL "INSERT INTO 勤務表 " & _ "(ユーザー名,月,日,出社,出社属性,退社,退社属性,作業時間,作業内容) " & _ "VALUES ([Forms]![フォーム1]![コンボ56], " & _ "[Forms]![フォーム1]![テキスト77], " & _ "[Forms]![フォーム1]![テキスト88], " & _ "[Forms]![フォーム1]![テキスト8], " & _ "[Forms]![フォーム1]![コンボ58], " & _ "[Forms]![フォーム1]![テキスト17], " & _ "[Forms]![フォーム1]![コンボ60], " & _ "[Forms]![フォーム1]![テキスト66], " & _ "[Forms]![フォーム1]![テキスト28]);" Else 'DCount関数の結果が0ではなかったら更新処理 DoCmd.RunSQL "UPDATE 勤務表 SET " & _ "ユーザー名 = [Forms]![フォーム1].[コンボ56] , " & _ "月 = [Forms]![フォーム1]![テキスト77] , " & _ "日 = [Forms]![フォーム1]![テキスト88] , " & _ "出社 = [Forms]![フォーム1]![テキスト8] , " & _ "出社属性 = [Forms]![フォーム1]![コンボ58] , " & _ "退社 = [Forms]![フォーム1]![テキスト17] , " & _ "退社属性 = [Forms]![フォーム1]![コンボ60] , " & _ "作業時間 = [Forms]![フォーム1]![テキスト66] , " & _ "作業内容 = [Forms]![フォーム1]![テキスト28] " & _ "where ユーザー名 = [Forms]![フォーム1].[コンボ56] And 日 = [Forms]![フォーム1]![テキスト88];" End If
- Pakkun10
- ベストアンサー率44% (22/50)
本題とそれてきましたのでこのあたりで最後にします。 http://office.microsoft.com/ja-jp/access/HA011170771041.aspx ここが参考になると思うので読んでみてください。 また、検索サイトで「access SQL フォームの値」などのキーワードで検索してみるといいかもしれません。 いくつものことを一度にやろうとすると、うまくいかなかったときにどこが悪いのかわかりません。 MsgBoxなどを利用して自分の思い通りの値が取得できているかどうかを確認しながらプログラミングしたらいいと思います。
補足
今回は何度も教えて頂きまして本当にありがとうございました。 なんとかやろうとしている事はできました。 ただご指摘の通り一度に多くを求めるのはよくないと感じました。 また、なにかありましたらよろしくお願いします。
- Pakkun10
- ベストアンサー率44% (22/50)
No7です。 × MsgBox DLookup("*","勤務表","ユーザー名='xxxxx'") ○ MsgBox DCount("*","勤務表","ユーザー名='xxxxx'") でした。
- Pakkun10
- ベストアンサー率44% (22/50)
順番に・・・ということで、まずは If DCount("*", "勤務表", "勤務表.ユーザー名 = [Forms]![フォーム1].[コンボ56] AND 勤務表.日 = [Forms]![フォーム1].[テキスト88]") = 0 Then この部分をどうにかしてみたらいかがでしょうか? フォームにボタンを設置して 'xxxxxはテーブルに存在する名前 MsgBox DLookup("*","勤務表","ユーザー名='xxxxx'") のようなコードを書いてみてください。 テーブルにxxxxxさんが登録されている数がメッセージボックスで示されると思います。 次に、xxxxxを固定ではなくフォーム上のテキストボックスの入力した文字列が指定出来るようにするにはどうしたらいいか考えます。 というような感じで順番にプログラムを作っていくと良いかと思います。 ちなみに、これ以上詳しい説明を求めるのであればプログラムを組む以前にまず本を読んだ方がいいと思います。 初心者用の本でいいので1冊買ってみるのをおすすめします。
補足
度々のご返信感謝いたします。 ご指摘頂いた内容にてやってみたいと思います。 それとなんですが、、、 実は昨日のコードで勤務表テーブルに"ユーザー名"と"日"の組み合わせが1件も無い場合は入力フォームの値が勤務表にinsertされることは確認できたのですが、1件ある場合は 実行時エラー'3464' 抽出条件でデータ型が一致しません。 というエラーになってしまいます。どうやらupdateの構文が違うみたいです。 実は初心者用の本ほ3冊購入しており、会社にある2冊の計5冊をみながらやっているのですが、、、、情けないです。 ただ、どの本にもinsert,updateで (1)フォームの値を指定する時の方法 (2)updateのWHERE句で2つの条件を指定する方法 が無く、悩んでおります。 (いづれの本もSQLに関してはクエリで条件を指定しテーブルにinsert,updateする等のやり方で、今回は参考にならなそうです。) 他、Meキーワードの使い方も何がおかしいのかわからない状態です。 お忙しいとは思いますが、アドバイス頂ければと思います。よろしくお願いします。
- Dxak
- ベストアンサー率34% (510/1465)
#1です > Format関数を使用してyyyy/mm/ddか、mm/dd/yyyyを指定してあげてください ぁぁ、すみません 英語版Windowsだと、dd/mm/yyyyへ自動的に変換する場合があるので・・・yyyy/mm/ddの方が良いです
- Dxak
- ベストアンサー率34% (510/1465)
#1です > UPDATE文の更新条件の内容を > (1)勤務表テーブルの"ユーザー名"がコンボ56と同じ > (2)勤務表テーブルの"日"の値がテキスト88と同じ のエラーがどう言うSQL文を出しているか判りませんが・・・ テーブルのデータの型によって文自体も変わります ユーザ名はテキスト?数値? テキストは「'」で前後を囲む、数値は不要 日は、テキスト?日付時刻型? テキストは「'」で前後を囲む、日付型は「#」で囲む で、日付時刻型のデフォルトは、PCの設定よって変換が変わりますので、Format関数を使用してyyyy/mm/ddか、mm/dd/yyyyを指定してあげてください たまに自動だと、yyの2桁になる場合が、稀にあります まずは、テーブルの型を提示しないと、明確な回答は出ないよ^^;
補足
ご返信ありがとうございます。 そして、当方の返信が遅くなり大変申し訳ありません。 さっそくなんですが、 UPDATE文を実行時のエラーは 実行時エラー '3464' 抽出条件でデータ形が一致しません。 というものです。 ユーザー名 は テキスト型、 日 は 日付/時刻型 他にも 月 数値型 出社 日付/時刻型 出社属性 テキスト型 退社 日付/時刻型 退社属性 テキスト型 作業時間 日付/時刻型 作業内容 テキスト型 というフィールドがあります。 素人の質問で大変申し訳ないのですが、 ユーザー名=[Forms]![フォーム1]![コンボ56] の場合どこに ' を使用すればいいのでしょうか? いろいろ自分なりにも調べてはいるのですが、シングルクオートやダブルクオート等使い方が複雑で理解できていません。 アドバイス頂けますでしょうか?よろしくお願いします。
- Pakkun10
- ベストアンサー率44% (22/50)
まずは動作するInsert文とupdate文を書くところから始めましょう。 ADOでもいいですが、ローカルテーブルが対象であれば Docmd.RUNSQL "Insert into ~" Docmd.RUNSQL "update ~ Set ~" で事足ります。 また、 "ユーザー名=[Forms]![フォーム1]![コンボ56],・・・" ではなく、 "ユーザー名='" & [Forms]![フォーム1]![コンボ56] & "',・・・" のように書きます。 自分自身のフォームが対象であればMeキーワードを使った方がすっきりかけます。 いきなり長いコードを書くのではなく、一つずつ確認しながら書いていくことをおすすめします。
補足
度々のご返信ありがとうございます。 ご指摘頂いた内容でできるようにいろいろ試してはいるのですが、 どうやら DCount , Insert , updateともシングルクオートもしくはダブルクオートの使い方がおかしいのかうまくいきません。 If DCount("*", "勤務表", "勤務表.ユーザー名 = [Forms]![フォーム1].[コンボ56] AND 勤務表.日 = [Forms]![フォーム1].[テキスト88]") = 0 Then DoCmd.RunSQL "INSERT INTO 勤務表 (ユーザー名,月,日,出社, 出社属性,退社,退社属性,作業時間,作業内容) VALUES ( [Forms]![フォーム1]![ユーザー名], [Forms]![フォーム1]![月], [Forms]![フォーム1]![日], [Forms]![フォーム1]![出社], [Forms]![フォーム1]![出社属性], [Forms]![フォーム1]![退社], [Forms]![フォーム1]![退社属性], [Forms]![フォーム1]![作業時間], [Forms]![フォーム1]![作業内容]);" Else DoCmd.RunSQL "UPDATE 勤務表 SET 勤務表.ユーザー名 = '" & [Forms]![フォーム1]![コンボ56] & "' , 勤務表.月 = '" & [Forms]![フォーム1]![テキスト77] & "' , 勤務表.日 = '" & [Forms]![フォーム1]![テキスト88] & "' , 勤務表.出社 = '" & [Forms]![フォーム1]![テキスト8] & "' , 勤務表.出社属性 = '" & [Forms]![フォーム1]![コンボ58] & "' , 勤務表.退社 = '" & [Forms]![フォーム1]![テキスト17] & "' , 勤務表.退社属性 = '" & [Forms]![フォーム1]![コンボ60] & "' , 勤務表.作業時間 = '" & [Forms]![フォーム1]![テキスト66] & "' , 勤務表.作業内容 = '" & [Forms]![フォーム1]![テキスト28] & "' where 勤務表.ユーザー名 = '" & [Forms]![フォーム1]![コンボ56] & "' and 勤務表.日 = '" & [Forms]![フォーム1]![テキスト77] & "';" End If 他、Meキーワードは使用時エラーになってしまいます。 何度も申し訳ありませんが、よろしくお願いします。
- Masa2072
- ベストアンサー率51% (94/182)
どうせDCOUNTで件数を求めるのにADOレコードセットを開くのなら mmrs.Open "SELECT * FROM 勤務表 WHERE [ユーザー名] = '" & Me.コンボ56 & "' AND [日] = #" & Me.テキスト88 & "#" でレコードセットを開き mmrs.RecordCountが1ならフィールドに各コントロールの値を代入してmmrs.Update mmrs.RecordCountが0ならmmrs.AddNewしてコントロール値を代入後Update とかの方がソース的にはすっきりすると思うのですが
補足
ご返信ありがとうございます。 そして当方からの返信が遅くなり大変申し訳ありません。 ご指摘頂いた内容是非参考にさせて頂きます。 いろいろ試しておりまして、まだ、実際にできておりませんが、結果は 返信させて頂きたいと思います。 よろしくお願いします。
- Dxak
- ベストアンサー率34% (510/1465)
ADOは、よく判りませんが・・・とりあえず気が付いた点で > If DCount("[ユーザー名] & [日]", "[勤務表]", _ > "[ユーザー名]=[Forms]![フォーム1]![コンボ56]" & _ > "and[日]=[Forms]![フォーム1]![テキスト88]") = 0 Then 「"[ユーザー名] & [日]"」の、フィールド名が適切ではない ("*"で十分だと思うよ) また、「and」の前後にブランクが無いため、演算子として、機能していない 環境によっては、誤動作の元になるので、「[Forms]![フォーム1]![~]」は、「"」の中ではなく、VBAにて値に変更して置く うまく行けば動くが、うまく行かないと、動作しない可能性が残る
補足
ご返信頂きありがとうございました。 また、当方からの返信遅くなり大変申し訳ありません。 Formの値を変更する件は、一度やりたい内容ができてから修正 したいと考えています。その他はご指摘通り変更させて頂きました。 ただ、いろいろ試しておりますが、なかなかうまくいきません。 (今はUPDATE文の構文エラーという内容で進めなくなっています。) UPDATE文の更新条件の内容を (1)勤務表テーブルの"ユーザー名"がコンボ56と同じ (2)勤務表テーブルの"日"の値がテキスト88と同じ 場合に更新するというふうに2つ設定する場合どのようにすればよいのでしょうか?アドバイス頂けると大変助かります。よろしくお願いします。
補足
早速のお返事ありがとうございます。 レコードセットは何のために開いているというか、開かないとできないものかと思っていました。 他、動作に関してなんですが、正直動作していません。 いろいろ試したのですが、クエリにてSQLを実行すると動いているのがわかるのですが、条件分岐にに組み込もうとすると動きません。動かせません、、、。