- ベストアンサー
VBAのデバックについて教えてください
- VBAのデバック方法について教えていただきたいです。急いでいるため、どなたかお手伝いいただけると助かります。
- Do Until rs.EOFまでの部分の意味がわかりません。この部分について教えていただけると助かります。
- VBAのデバックで使用する変数と関数について教えていただけますか?情報が不足しているため、具体的な内容を教えてください。
- みんなの回答 (19)
- 専門家の回答
質問者が選んだベストアンサー
もう一つ追加。 >strcriteria = "CAT = '" & rs!CAT & "'" において、 等号「=」の右側について、 >"CAT = '" & rs!CAT & "'" は一つの文字列になっていますが、 rs!CATは一旦、「"」の囲みから外に 出ています。ここがわかりにくいところですが、 規則として変数は囲みの外に出して連結しなければ いけないことになっています。そこで「&」を使って 連結しています。 したがって、 >strcriteria = "CAT = '" & rs!CAT & "'" を、 >strcriteria = "CAT = 'rs!CAT'" のようにするとAccessは「rs!CAT」という文字列を 探すことになってしまい、レコードセットrsのCATという フィールドを検索することにはならなくなってしまいます。
その他の回答 (18)
- layy
- ベストアンサー率23% (292/1222)
>たとえば、MCD3472のCATAB-1234は更新がうまくいきます。しかしMCD3162のCAT002682は更新がうまくいきません MCD3472のCATAB-1234のあとMCD3162のCAT002682はNG、 では MCD3162のCAT002682のあとMCD3472のCATAB-1234はNGなのでしょうか? 特定原因がわかるまでは、こういう実施結果が証拠というか、 判明した事実になってきます。 いろんな方面から事実をかき集めるという手段です。 回答としてはこれらをあてにするしかないです。 原因が見てきたら、 こういう結果になって当然だった、なるほど、となるわけですが・・・。 文法エラーなどは、資料がいつか見つかって解決することありますが、 デバッグ作業は特に決まったやり方はなくて個々の経験の積み上げなところあります。 大変でしょうが、今が大事な作業です。
お礼
ありがとうございます。>MCD3162のCAT002682のあとMCD3472のCATAB-1234はNGなのでしょうか? →それが、そのとおりなんです。だからなおさら意味がわかりませんし、MCDによって何か違うのか?と疑問になってきた理由です。 もちろん、数字4桁に何か違いがあるとは思えませんが、もともと作成したのが自分ではないので、他のところにリンクしていたりして(想像ですが)、そういったことが関連していて更新できないのかな、、?と。 こんなことを言っては元も子もないですが、いちどこれとは別件で、(エラーがあって)システム屋の人に見てもらったことがあったのですが、そのとき、これはもともとアクセスの古いバージョンから以降してきているからそのせいでシステムがうまく作動しなくなっているところがある、と言われたことがありました。そういうことも関係しているのかもしれません。ですので、私としては、結局、仕入れ価格の更新さえできればどんな方法でもかまわないので、(最悪は、テーブルから直接削除、そして新しいものを貼り付け、ですが)別の方法でやってみたいと思っております。
- layy
- ベストアンサー率23% (292/1222)
メッセージがたくさん出るなら、何か変数を用意してカウントします。結果0なら全く通過していない、10なら通過10件は存在したという確認までとれます。最後に処理したときのSTRCRITERIAが何か、こんなのも情報の1つ。 FINDは使わないで RS2のテーブルを1レコード目から最終レコード目まで1レコードごとに判断しても同じ結果か。 FIND検索のとき、いざ検索を始めるカレントレコード位置はどうなっているか。2回目も先頭か?。 記述もデータも変えてないなら1回目実行したことで期待している状態になってないまま2回目実行かと思われます。 ACCESSCLUBのサイト、ADO入門講座の、「レコードを検索する FINDメソッド」、留意点等を見て下さい。参考になりそうです。
- layy
- ベストアンサー率23% (292/1222)
今言ってもピンと来ないとは思いますが、 基本的に稼働実績のあるプログラムって記載したとおりに実行します。 それでもおかしいときは、データに依存していることが多いです。 そこの見極めで苦労されていると感じます。 プログラムで間違った動きをしていないか。 1回目と2回目で(記述もデータも同じで)同じ動きをする仕組みか。 1回目と2回目で状態が変わったりしていないか。 例えば、 1回目はフラグが0→1になるが2回目は(1回目の終了時の)1のまま処理されてたからおかしかった、 というものは、0にする行為が抜けている不具合が潜んでいる、等。 1回目未更新データを抽出して更新、同じ検索条件で2回目に行うと(更新済で)データが見つからない、等。 おかしいと思うときは、 変わるはずがないという見方でなく、 どこかが変わっている、変わりそうなのはどこか、 という視点で見るとけっこう見つけやすいです。 >自分で作ったシステムではないため、 >その規則性が私にはいまだわからなくてじっと眺めているのですが、 稼働させている以上、少しずつでも自分のものにしていかないと 眺めても解決には至りません。 何もわからないで手つかずのときは、 自分の知りたいようにプログラムに手を加えます。 Do Until rs.EOF '該当レコードあり If rs!MCD = "3162" Then を Do Until rs.EOF MSGBOX("該当レコードあり") If rs!MCD = "3162" Then というようにしたり。 If rs!MCD = Me!tx検索 Then MSGBOX("rs!MCD = " & rs!MCD & " " & "Me!tx検索 = " & Me!tx検索) ELSE MSGBOX("rs!MCD = " & rs!MCD & " " & "Me!tx検索 = " & Me!tx検索) にしたり。 目に見えてない情報を引きだすことで解決への糸口を見つけます。 特別処理結果に左右されなければ、メッセージボックスを出して 通過したことをわからせることもします。 目で追いかけることと結果が表示されて確認することと 違うときあります。 値が同じと思っていたが実際違っていた、とかいうものです。 >私には何の区別があって更新ができたりできなかったりするのかわからない 前述のように、 1回目と2回目でどの順番でどの行がどう処理されているか、を検証すること。 この作業を身につけるのが解決早いように思います。 今抱えている疑問の答えズバリでないのでスルーしたかもしれませんが、 時間かかりますが、答えを出すための確実な手段です。 修正できない状況であれば、それはそれで別のデバッグ手段を考えます。
補足
ありがとうございます。いろいろとやってみましたが、、メッセージ表示もためしてみましたが、該当レコードあり、と出てきました。(それも、更新するデータが大量なので連続でずっと。。)なので、問題解決には至りませんでした。 ほかにもいろんなMCDで試してみましたが、これはOK、これはNG、というふうに、分かれてきました。いずれも、理由はよくわかりませんでした。 おなじCATでも、MCDを変えると、OKになったりNG(NGというのは価格更新されない、という意味を表します)になったりしました。 何かほかのところにリンクしているのでしょうか?システムをたちあげた人がいなくなったので、全くわからないのですが。。 いずれにせよ、とにかくIF MCDでひっかけるのはなしにして、もっとも単純だと思われる、このテーブル(商品2_T25discountてすと)に入っているCATをかたっぱしから商品2テーブルから検索するには (つまり、IFをとるには)どうしたらいいでしょうか。もしかしたらデータが多すぎて、大変になるかもしれませんが、MCDでうまくいかないのなら、なにか他の方法を、、と思いました。
- piroin654
- ベストアンサー率75% (692/917)
>先述の、「コマンドボタンをもうひとつ用意して、 >下記コードのコマンド25を26と変更。MCDを変更。 >あとはそっくりコピーしてそのまま貼り付けたと >きのエラー」と一緒です。 何かエラー表示が出たのか、あるいはエラー表示が 出なかったが更新が出来なかった、のどちらかは わかりませんが、提示されたコードの中で、End If の位置が変なところにあるので変更してみてください。 以下です。 Do Until rs.EOF 'asico該当レコードあり If rs!MCD = Me!tx検索 Then '--------------------------------------------- strcriteria = "CAT = '" & rs!CAT & "'" ' --- A rs2.Find strcriteria, 0, adSearchForward If rs2.EOF Then ' Else rs!仕入単価世代1 = rs!仕入単価 rs!仕入単価 = rs2!discount End If '--------------------------------------------- rs!更新日 = Now() rs.Update End If rs.MoveNext Loop を、 If rs!MCD = Me!tx検索 Then '--------------------------------------------- strcriteria = "CAT = '" & rs!CAT & "'" ' --- A rs2.Find strcriteria, 0, adSearchForward If rs2.EOF Then ' Else rs!仕入単価世代1 = rs!仕入単価 rs!仕入単価 = rs2!discount '--------------------------------------------- rs!更新日 = Now() rs.Update End If End If rs.MoveNext Loop にしてください。End If の位置を変更しています。 もし、MCDが数値型ならば、 >If rs!MCD = Me!tx検索 Then を If rs!MCD = CLng(Me!tx検索) Then としてください。MCDがテキスト型ならば そのままでいいです。反応があるということは MCDはテキスト型ですかね。
補足
ずっとおつきあいいただき申し訳ありません。エラーメッセージなどはないのですが、この更新ボタンをクリックすると、(テーブルのデータに更新日時が入るようになっているようなのですが)そこには反応した痕跡がありますが、仕入れ価格自体は更新されていないことをエラーと私が呼びました。 MCDは、調べたところテキスト型でした。ですので、>If rs!MCD = Me!tx検索 Then で、問題なく反応し、価格更新できました。ただ、先にも書きましたとおり、MCDによって、更新がうまくいくものといかないものが出てきました。 その規則性が私にはいまだわからなくてじっと眺めているのですが、MCDによってCATも異なるので、CATのせいか、とも考えました。 しかし、たとえば、MCD3472のCATAB-1234は更新がうまくいきます。しかしMCD3162のCAT002682は更新がうまくいきません(仕入れ価格に変更がされません)。 002682というCATに問題があるのでは、と思い、(数値とかテキストとかそういったことが問題なのかと思い)MCD3472のCAT002682を設定してみて更新ボタンを押してみると、更新がうまくいきました。私の目には、MCDによって、 更新できるものとできないものがあるかのように見えます。(3472はOKで3162は不可・・・??)しかしMCDは単なるテキスト型で(テーブルではテキスト型となっていますが、実際には数値4つの並びです)、私には何の区別があって更新ができたりできなかったりするのかわからないです。
- layy
- ベストアンサー率23% (292/1222)
1つめ実行と2つめ実行とMCD以外何が違うか、どの行を処理したか、追いかける。メッセージを付与しても良い。 現状では、検索でいきなりRS2.EOFになるときとか仕入単価を更新しないが更新日だけ更新する仕組みになってませんか?。更新したレコードにのみ当日日付更新が正しいのでは?。 善くも悪くも「完了しました」メッセージなので、何か変化をつけておくとよさそう。
補足
はい。全くその通りです。ですが、自分で作ったシステムではないため、今はこれは何を作成したのだろう、と理解するだけで精一杯なのです・・・・ やりたいことは仕入れ価格の更新です。 このシステム自体は問題なく動いていますが、別のMCDに変えるとなぜうまくいかなくなるのか、確かめているところです。
- piroin654
- ベストアンサー率75% (692/917)
以下のようなことが考えられます。 (1) フォームの基となるクエリが更新不可能になっている フォームの左下に「このレコードセットは更新できません」 という表示が出ていないか確認 (2) フォームのプロパティの「更新の許可」の確認 (3) フォームを開くときにマクロが設定されていて、 そのマクロの「データモード欄」 に 読み取り専用 がせっていされていないか確認。確認は以下の一番下の方法。 http://www.accessclub.jp/beginer/years/years_07.htm などですが。一応これらを確認してみてください。
補足
早急な回答をまことにありがとうございます。原因は2でした。ただ、別の問題で、うまくいきませんでした。実際にお見せできないまま、言葉で書いてもずいぶんわかりにくくなっていると思うのですが。申し訳ないです。先述の、「コマンドボタンをもうひとつ用意して、下記コードのコマンド25を26と変更。MCDを変更。あとはそっくりコピーしてそのまま貼り付けたときのエラー」と一緒です。それはこのもとのコードのMCDだとうまくいくのですが、MCDを入れ替えると、仕入れ価格が更新されません。しかし、その入れ替え後のMCDのデータをテーブルで見ると、更新日時がコマンド26をクリックした日時になっています。ですので、何か反応、応答はしているようなのです。このMCDでしか仕入れ価格の更新が行われない、そんなコードになっているのでしょうか。。。??? Private Sub コマンド25_Click() 'On Error GoTo Err_コマンド25_Click Dim cn As ADODB.Connection Dim cn2 As ADODB.Connection Dim rs As ADODB.Recordset Dim rs2 As ADODB.Recordset Dim strmsg As String Dim lngRet As Long Dim strcriteria As String Set cn = CurrentProject.Connection Set rs = New ADODB.Recordset Set cn2 = CurrentProject.Connection Set rs2 = New ADODB.Recordset rs.Open "商品2_T", cn, adOpenKeyset, adLockOptimistic rs2.Open "商品2_T25discountてすと", cn2, adOpenKeyset, adLockOptimistic MsgBox "更新を開始します ", 64, 更新 Do Until rs.EOF 'asico該当レコードあり If rs!MCD = Me!tx検索 Then '--------------------------------------------- strcriteria = "CAT = '" & rs!CAT & "'" ' --- A rs2.Find strcriteria, 0, adSearchForward If rs2.EOF Then ' Else rs!仕入単価世代1 = rs!仕入単価 rs!仕入単価 = rs2!discount End If '--------------------------------------------- rs!更新日 = Now() rs.Update End If rs.MoveNext Loop MsgBox "更新が完了しました ", 64, 更新 rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing rs2.Close: Set rs2 = Nothing cn2.Close: Set cn2 = Nothin Exit_コマンド25_Click: Exit Sub Err_コマンド25_Click: MsgBox Err.Description Resume Exit_コマンド25_Click End Sub
- layy
- ベストアンサー率23% (292/1222)
エクセルてお仕事 のサイトのVBA基本のコーナーにて 初心者のよくある疑問・間違いや誤解 ということでまとめたページがあります。VBAですがデバッグ概念はほかプログラムでも同じです。 文字列連結は、「’」「”」がない状態で記載し、それから文字なのか変数なのか見極め、文法エラーにならないようペアで囲みながら記載する、そういうやり方もあります。工夫する。 参考で。
お礼
回答ありがとうございます。 自分で作成できるようになったらぜひ参考にさせていただきます。
- layy
- ベストアンサー率23% (292/1222)
「あいまい検索(=FIND)」と記載してしまっていた件、 申し訳ありません。 >もちろん自分でも調べてはいるのですが、 質問に至ったのは、おかしい行の特定ができてなかったから、 かと思われます。 実際、最初からどの行まで処理が正しく動いていたのか、 ステップ実行、DEBUG.PRINTの活用、メッセージボックス記述、などのデバッグをして、 そのあたりの検証はどうなのか、気になるところです。 また、 文法エラーにはならないがデータ検索したら結果が伴なってない、 こういうときは検索条件が怪しい、という観点から見直しするのも手です。 検索条件の値がおかしいと、それなりに検索処理をしますから、 対象レコードが結果0件だったりすることあります。 結果うまくいったけど、結局何がどうおかしかったのか 理解できていない、こんなことにならないようにしてください。
補足
そうですね。初心者なのでとにかく今のトラブルを解決できれば、、と焦ってしまうのですが、皆さんが大変丁寧に教えてくださるので、わかるようにしたいと思っています。どうやら今回は、このVBAのコード自体が悪いのではなく、、というのも、途中で書いたのですが、異なるMCDでも検索をしたかったので、コマンドボタンを作成して、まったくこのコードをそのままコピーして、MCDのところだけ書き換え、やってみたところ、もとのコードを設定したコマンドボタンはうまく作動していたのですが、そのコピーしたほうは、仕入れ価格の更新ができませんでした。 それで、何が悪いのかと思ってこのコードの中身をお尋ねしていた次第です。
- piroin654
- ベストアンサー率75% (692/917)
たとえば、フォーム上にテキストボックスを追加して 名前をtx検索とします。 そこで、 If rs!MCD = "3162" Then を If rs!MCD = Me!tx検索 Then に置き換えます。 tx検索に他のMCDを入れれば他のMCDについても 一つのコマンドボタンのクリックで情報が 得られます。 なお、他の方が >あいまい検索(=FIND) というような回答をされていますがこれは間違いです。 Findはあいまい検索をしません。あいまい検索を するときはLike演算子を使います。
補足
すっごく簡単な処理方法を教えてくださりありがとうございます。それが、まさかのところでひっかかりました。テキストボックスを作ったのですが、全く入力を受付ないのです。編集ロックもかかっていませんし、使用可能-はい なのですが、、 いろいろ調べたらネットではマクロに原因が、とかいろいろあったのですが、自分ではわからないです。ここのフォームに関係するコードに原因があったりするものなのでしょうか?
- piroin654
- ベストアンサー率75% (692/917)
抽出の時の規則的なことを書いておきます。 (1) rs!CATがテキスト型のとき、 strcriteria = "CAT = '" & rs!CAT & "'" あるいは、具体例として strcriteria = "CAT = 'もち米'" (2) rs!CATが数値型のとき strcriteria = "CAT = " & rs!CAT & "" あるいは、具体例として strcriteria = "CAT = 50" (3) rs!CATが日付/時刻型のとき strcriteria = "CAT = #" & rs!CAT & "#" あるいは、具体例として strcriteria = "CAT = #2010/01/01#" このようにします。このとき条件に変数がある場合は、 「&」を使って文字列を連結し、一つの条件文に します。そして、strcriteriaには、「"」で囲んだ 文字列が代入されます。
- 1
- 2
お礼
そうなんです。>strcriteria = "CAT = 'rs!CAT'" だと見やすくてわかるのですが、>strcriteria = "CAT = '" & rs!CAT & "'" だとやたら記号が多いように見えて、真相がわからなくなってしまったのです。 具体例を出して説明していただきありがとうございました。またもうひとつの質問についてもありがとうございました。会社のシステムのため、触って試してみるのにもう少し時間がかかりそうですが、教えていただいたように(MCDの変更)またやってみて、報告させていただきます。
補足
なるほど、です。素人でもわかりました。確かにそれだと文字列を探すことになってしまいますね。だからといって & というのは、素人には難しい規則ですが、なぜ&がついていて、コーテーションがやたら多く見えるのかが、よくわかりました。