• 締切済み

JscriptでsetTimeout

JscriptでIEを操作してあるページのリンクをクリックしたいです。 リンクにjavascriptが入っているため同期処理でクリックすると、 その先に進みません。 そのため非同期処理でクリックしたく、setTimeoutを使って 関数を作りましたが動きません。 setTimeout('function ck(ie,ID){ ie.document.querySelector(ID).click();}',10); ※ieはIEオブジェクト、iDはリンクのID属性です。 ちなみに上記をVBAから呼び出して動かしています。 setTimeoutをはずせば普通に動きました。 setTimeoutはwindowオブジェクトが必要なので、 それを省略しているのが悪いとも考えましたが、 VBAでどうやってIEのwindowオブジェクトを作るのかが分かりません。 setTimeout以外にも非同期実行できる方法があれば それでも構いません。 どうかご教授お願いいたします。

みんなの回答

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.1

setTimeout の第1引数は object または、関数名の文字列、です。関数宣言を文字列で与えてもobjectにはなりません。 文字列にせず、関数宣言 を書くと関数objectになり、これを無名関数といいます。 しかし引数を与えると実行してしまうので、実行結果が関数objectになるようにしなければならないので、return にさらに関数宣言を書くということになる。 よって、無名関数を2重に書く形になる。 まず、外側は、関数宣言を()で括ってさらに引数を与える(ie,ID)をつける  (function(ie,ID) { })(ie,ID)  この関数は、setTimeout行の引数判定時点で実行される。 次にこの関数の内部では return function(){} ; で引数無しの関数objectを返す この関数objectが setTimeoutに対する第1引数としてわたされる。この関数objectは、setTimeoutの第2引数で指定した時間経過後に実行される。 全体を見やすく、改行と字下げをつけると以下のように。 setTimeout(  (function(ie,ID) {   return function(){    ie.document.querySelector(ID).click();   };  })(ie,ID) , 10); // 全角空白で字下げしてるので、半角空白に置換または削除して実行ソースとすること // 外側の関数を省略すると、ieとID変数がメモリリークとなるので注意のこと。

momomo100
質問者

補足

ありがとうございます。 VBAから呼び出すためには関数名が必要みたいだったので、 以下のようにしてみました。 function clk(ie,id) { setTimeout(  (function (ie,id) { return function () { ie.document.querySelector(id).click(); }; })(ie,id) , 10); } これを変数ieを省略してIEのF12ツールで試したところ 問題なく動きました。 しかしVBAから呼び出ししようとすると js.CodeObject.clk IE, IDの部分でオブジェクトがありませんの エラーが出てしまいます。 ※js.CodeObject.関数名 引数1, 引数2で 変数cdに入っているJscriptを呼んでいます。 URLは非同期処理じゃないとクリックしても 進まないサイトがあったのでお借りしました。 どうか引き続きご教授お願いいたします。 Sub click_test() Dim IE As InternetExplorer Dim js As New ScriptControl js.Language = "JScript" Dim cd As String cd = cd & "function clk(ie,id) {" cd = cd & "setTimeout(" cd = cd & "(function (ie,id) {" cd = cd & "return function () {" cd = cd & "ie.document.querySelector(id).click();" cd = cd & "};" cd = cd & "})(ie,id)" cd = cd & ", 100);" cd = cd & "}" js.AddCode (cd) Set IE = CreateObject("InternetExplorer.Application") IE.Visible = True IE.Navigate "http://kamicha1.web.fc2.com/Excel/Test20090726.html" Do While IE.Busy Or IE.readyState < READYSTATE_COMPLETE DoEvents Loop Dim ID As String ID = "#popOK" js.CodeObject.clk IE, ID msgbox"OK" End Sub

関連するQ&A