質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

1843閲覧

Excel VBA で削除処理 レコードが無い場合の条件分岐

ko_e

総合スコア2

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/09/04 04:49

編集2020/09/04 05:27

前提・実現したいこと

ExcelとOracle DataBaseを繋げて、Excel VBAでDB操作(Delete処理)を行いたいです。

【Delete処理内容】
ユーザーフォーム(DeleteForm)に生徒番号を入力
→入力値と一致する生徒を探す
→レコードがある…削除
→レコードが無い…メッセージボックス表示

発生している問題・エラーメッセージ

レコードがある/ない の分岐がうまくいきません。
存在しない生徒番号を入力しても「レコードがある」方に行ってしまいます。
「レコードが無い場合、EOFがTrueになる」とネットに書いてあったはずですが毎回Falseになります。

実行時エラー '3709' この操作を実行するために接続を使用できません。 このコンテキストで閉じているかあるいは無効です。

該当のソースコード

Excel

1Public Sub DeleteFormButton_Click() 'フォーム入力→削除ボタンの処理 2'tnsnames.ora ファイルのネットサービス名' 3 Const STRDATASOURCE = "__SERVICE__" 4 5 Const USERNAME = "__USERNAME__" '接続するデータベースのユーザー名 6 Const PASSWORD = "__PASSWORD__" 'パスワード 7 8 Dim oraCon As New ADODB.Connection '接続オブジェクト 9 Dim oraRs As New ADODB.Recordset 'レコードセット 10 Dim oraCmd As New ADODB.Command '操作 11 Dim constr As String 12 Dim strSQL1 As String 13 Dim strSQL2 As String 14 15 constr = "Provider=MSDAORA" 16 constr = constr & ";Data Source=" & STRDATASOURCE 17 constr = constr & ";User ID=" & USERNAME 18 constr = constr & ";Password=" & PASSWORD 19 20 oraCon.ConnectionString = constr 21 oraCon.Open 22' DBと接続までは完了しています 23 24 strSQL1 = "SELECT MAX(ID) FROM student WHERE ID = '" & Me.DeleteForm.Text & "'" 25 oraRs.Open strSQL1, oraCon 26 27 If oraRs.EOF Then 28 nullMsg 29 Else 30 With oraCmd 31 strSQL2 = "DELETE FROM student WHERE ID = '" & Me.DeleteForm.Text & "' ; " 32 .CommandText = strSQL2 33'ここからエラー 34 oraCmd.Execute (strSQL2), oraCon 35 Set oraRs = .Execute 36 End With 37 End If 38 39 oraCon.Close 40 41 Unload Me 42End Sub 43--- 44Sub nullMsg() 45 MsgBox "入力された番号と一致する" & vbCrLf & "生徒はいません。", "エラー" 46End Sub 47

試したこと

If文の条件を変更

VBA

1If oraRs.RecordCount = 0 Then

→oraRs.RecordCountの中身はレコードのあるない関わらず常に-1

補足情報(FW/ツールのバージョンなど)

Excel 2010
Oracle DataBase 12c
Oracle Client 12c

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

これでどうでしょう。

VBA

1strSQL1 = "SELECT ID FROM student WHERE ID = '" & Me.DeleteForm.Text & "'"

投稿2020/09/04 05:31

radames1000

総合スコア1923

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ko_e

2020/09/04 06:15

回答ありがとうございます! こちらの方法もレコードが無い方の分岐ができました。 MAXを入れないシンプルなSELECT文にするとEOFがTrueになるのですね… 試行を見落としていました、ありがとうございます!
guest

0

ベストアンサー

下記でどうでしょうか。

vba

1 strSQL1 = "SELECT Count(ID) As Cnt FROM student WHERE ID = '" & Me.DeleteForm.Value & "'" 2 oraRs.Open strSQL1, oraCon 3 4 If oraRs!Cnt = 0 Then 5 oraRs.Close 6 nullMsg 7 Else 8 '以下略 9

投稿2020/09/04 05:27

編集2020/09/04 05:35
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ko_e

2020/09/04 05:43 編集

ありがとうございます! こちらの方法でレコードが無い方に行きました! Cntについて初めて知りました。また勉強します。 ※こちら最初にエラー発生しましたという旨のコメントをつけさせていただきましたが、こちらの記述ミスでした。通知が行っていたら申し訳ありません。
hatena19

2020/09/04 05:50

Cnt 自体に意味はありません。フィールドの名前を設定しただけですので。 Countだとレコードがない場合は0が返るはずなんですけど、Oracle だと違うのかな? Null判定は If oraRs!Cnt = Null Then ではなく If IsNull(oraRs!Cnt) Then です。 If Nz(oraRs!Cnt)=0 Then だと 0 でも Null で真になります。 エラー対処はレコードセットを閉じてから開いてください。 oraRs.Close oraRs.Open strSQL1, oraCon
ko_e

2020/09/04 05:57

Asは命名でしたのでCountですね…申し訳ありません 私が記述ミスでNullが返ってしまった件への補足もありがとうございます…! Nzは0でもNullでもTrueになるのですか! 今まで一覧表示処理だけで初めてExecuteを使ったため、レコードセットを閉じる場所も悩んでいました(T_T) とても勉強になりますありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問