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

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

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

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

Q&A

解決済

1回答

1253閲覧

VBA setステートメント使用時の処理待ち方法

mo-mo-mo

総合スコア1

VBA

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

0グッド

1クリップ

投稿2022/01/02 11:51

はじめまして。失礼な点が有りましたら申し訳有りません。

前提・実現したいこと

VBAでIEを起動し、google翻訳の結果を取得しセルに出力する。
上記は実現できたが、エラー回避の方法について改善できないか相談したい。

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

Class要素から翻訳結果のテキストを取り出す際に、実行時エラー91が発生することがあります。
しかし、「デバッグ」→「継続」で処理を進めるとそのまま処理ができること、
また、Sleep関数で遅延させても回避できることから、Setステートメントの処理が完了していないと想像しています。
On Error Resume nextで処理を繰り返すことで回避したのですが、出来ればエラーを発生させたくないです。
Setステートメントが終了していることを確認して進めるような方法や、
その他エラーを回避できる方法が有りましたら教えていただけないでしょうか。
該当箇所は★で目印をつけております。

実行時エラー'91' オブジェクト変数またはWithブロック変数が定義されていません。

該当のソースコード

VBA

1 2Sub test() 3Dim objIE As New InternetExplorer 4Dim sl, tl, tgText, tgURL, URL As String '翻訳先URLを作成するための文字列 5Dim Class1 As Object '翻訳結果が記述されるClass 6Dim ResultText1, ResultText2 As String ' 翻訳された文字列 7 8sl = "ja" '翻訳元の言語 9tl = "en" '翻訳先の言語 10 11'IE(InternetExplorer)のオブジェクトを作成する 12Set objIE = CreateObject("InternetExplorer.Application") 13 14For i = 1 To 10 15tgText = Cells(i, 1).Value '翻訳対象 16tgURL = Excel.Application.WorksheetFunction.EncodeURL(tgText) '翻訳対象をURLエンコード 17URL = "https://translate.google.co.jp/?sl=" & sl & "&tl=" & tl & "&text=" & tgURL ' & "op=translate" 18 19Call ieView(objIE, URL) 'IEでGoogle翻訳にアクセスする処理 20 21Set Class1 = objIE.document.getElementsByClassName("NqnNQd") 22タグ1: 23On Error Resume Next'★ここを置き換えたい 24ResultText1 = Class1(0).innerText'★エラーが発生する箇所 25If Err.Number <> 0 Then 26 Err.Clear 27 GoTo タグ1 28End If 29 30Cells(i, 2).Value = ResultText1 31Next i 32 33objIE.Quit 34Set objIE = Nothing 35 36End Sub 37 38Sub ieView(objIE As InternetExplorer, _ 39 URL As String, _ 40 Optional viewFlg As Boolean = False) 41 42 'IE(InternetExplorer)を表示・非表示 43 objIE.Visible = viewFlg 44 45 '指定したURLのページを表示する 46 objIE.navigate URL 47 48 'IE(InternetExplorer)が完全表示されるまで待機 49 Call ieCheck(objIE) 50 51End Sub 52 53Sub ieCheck(objIE As InternetExplorer) 54 55 Dim timeOut As Date 56 57'完全にページが表示されるまで待機する 58 timeOut = Now + TimeSerial(0, 0, 20) 'タイムアウト時間の設定 59 60 Do While objIE.Busy = True Or objIE.readyState <> 4 61 DoEvents 62 Sleep 1 63 If Now > timeOut Then 'タイムアウト処理 64 objIE.Refresh 65 timeOut = Now + TimeSerial(0, 0, 20) 66 End If 67 Loop 68 69 timeOut = Now + TimeSerial(0, 0, 20) 70 71 Do While objIE.document.readyState <> "complete" 72 DoEvents 73 Sleep 1 74 If Now > timeOut Then 'タイムアウト処理 75 objIE.Refresh 76 timeOut = Now + TimeSerial(0, 0, 20) 77 End If 78 Loop 79 80End Sub

試したこと

If then でclass1に情報があるか判別する回路に置換してみたのですが、エラー回避ができませんでした。
If class1 is nothing then
Goto タグ1
end if
ResultText1 = Class1(0).innerText
※この場合はfor文の先頭でClass1 の初期化処理も追加しています。

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

Excel 2016

ここにより詳細な情報を記載してください。

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

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

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

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

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

mo-mo-mo

2022/01/14 02:08

objecrt変数についての理解が深まってエラーが発生した根本の原因がわかった(気がする)ので追記しておきます。 元々、IEで読込が終わっていないならSetの時点でエラーが出るのでは?と考えていましたが、 object変数(今回のコードで言うClass1)は保管した変数へたどり着くための目印のようなものと理解しました。そのため、Setでは目印をつけただけなので異常は出ない。そしてClass1のテキスト情報を読み出そうとした時、実際にはページの読込途中で存在していない、IEのテキスト情報を読み出す処理を行っているためにエラーが発生しているということでした。 下記が参考になりました。 https://excel-ubara.com/excelvba4/EXCEL_VBA_423.html
guest

回答1

0

ベストアンサー

IE待機処理でループを抜ける条件を厳しくし、エラー軽減できる可能性があります。

VBA

1Sub IEWait(ByRef ie As Object) 2 3 Dim timeout As Date 4 Dim cnt As Integer 5 Dim IEretry As Boolean 6 7 timeout = DateAdd("s", 20, Now()) 8 Do 9 DoEvents: Sleep 1: DoEvents 10 '下記ステータス連続一致確認 11 If ie.Busy = False And ie.readyState = 4 Then 'READYSTATE_COMPLETE = 4 12 cnt = cnt + 1 13 If cnt >= 50 Then 14 Exit Do 15 End If 16 End If 17 'タイムアウトチェック 18 If timeout < Now() Then 19 If IEretry = False Then 20 '1回限りでIE再読み込み 21 IEretry = True 22 ie.Refresh 23 timeout = DateAdd("s", 20, Now()) 24 Else 25 Exit Do 26 End If 27 End If 28 Loop 29 30 timeout = DateAdd("s", 10, Now()) 31 Do While ie.Document.readyState <> "complete" 32 DoEvents: Sleep 1: DoEvents 33 'タイムアウトチェック 34 If timeout < Now() Then Exit Do 35 Loop 36End Sub

投稿2022/01/03 00:08

TanakaHiroaki

総合スコア1063

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

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

mo-mo-mo

2022/01/03 01:09

ご回答ありがとうございます。 教えて頂いたコードでエラー発生回数が0回になりました。 (改善前は1件あたり600回でした) ベストアンサーにさせていただきます。 下記、参考までに教えていただきたいです。 Setを1回しか実行していないのでIE側は関係無いものと思い込んでいたのですが、実際にはIE側の読込(生成?)に追従してSetの処理が進んでいるということでしょうか? ソフトウェア側の仕様なのかなとも思いますが、解説のあるサイト等ご存知でしたらご紹介いただけますと幸いです。
TanakaHiroaki

2022/01/03 01:23

良かったです。 経験的なことしか言えないのですが、下記サイトのページの読み込みが完了していない のに「readyState」が「4(完了)」を返して待機処理のループを抜け、Setの処理で 実行時エラー'91'となるのではないでしょうか。 https://rabbitfoot.xyz/post-354/
mo-mo-mo

2022/01/03 02:32

readyStateが変化する可能性があるのですね…。 サイトの紹介もありがとうございます。 大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問