Board logo

標題: 詢問 .WebBrowser1的幾個問題 [打印本頁]

作者: mark15jill    時間: 2020-11-26 11:55     標題: 詢問 .WebBrowser1的幾個問題

目前編寫 利用userform 查詢excel 名稱 的googlemap  
(不要問我為啥不直接用 我的地圖反查是個坑... 用經緯度反查會找不到地點)

遇到幾個問題...
1.maps.google 變數一直在改變 要如何克服抓取關鍵ID參數?  
固定的ID >> searchbox-searchbutton [搜尋的那個ID] 跟 searchboxinput [輸入查詢的文字框ID]  
變動的ID >> sb_cb50 [取消搜尋的那個按鈕ID] << 這個時不時就改變,要怎讓他固定?

2.如果不理會變動ID 直接設定 更動後 直接搜尋,將會造成 搜尋到第二筆資料時,緩存還停留在第一筆。
例如combobox1 內有 景點1 跟 景點2
如果設定搜尋 景點1 然後按下搜尋鍵時 WebBrowser1 會顯示 景點1的定位
但如果接著搜尋景點2 然後按下搜尋鍵時 WebBrowser1 仍然顯示 景點1的定位

                    Set tet(0) = .TextBox1
                    Set tet(1) = .TextBox2
                    Set cmb(0) = .ComboBox1
                    Set cmb(1) = .ComboBox2
                    Set cmb(2) = .ComboBox3
                    

                With .WebBrowser1
               
                    With .Document
                        
                        .GetElementById("searchboxinput").Value = cmb(2).Text  '在搜尋textbox搜尋 名稱
                        .GetElementById("searchbox-searchbutton").Click  '點擊搜尋放大鏡的按鈕
                        .GetElementById("gs_lc50").Click                                  '取消搜尋
                        .GetElementById("searchboxinput").Value = cmb(2).Text  '在搜尋textbox搜尋 名稱
                        .GetElementById("searchbox-searchbutton").Click  '點擊搜尋放大鏡的按鈕                     
                         '正常來說 取消搜尋後 重新輸入新的名稱,應該是要搜尋新的名稱,但他的暫存依舊是舊的
                        
                        Do
                           DoEvents
                        Loop
                        

                    End With
作者: Joforn    時間: 2020-11-26 22:39

速度太快,WebBrowser沒反應過來。
WebBrowser是異步的加載的,最好是在每一個命令之后等待WebBrowser完全加載完成再繼續下一個命令。
作者: mark15jill    時間: 2020-11-27 09:42

速度太快,WebBrowser沒反應過來。
WebBrowser是異步的加載的,最好是在每一個命令之后等待WebBrowser完全 ...
Joforn 發表於 2020-11-26 22:39



    感謝回覆~
目前改成下列程式碼~ 會啟動搜尋的功能(定位) ,但依舊只會讀取第一項...QQ
增加項目>> 按鍵模擬 與時間停頓
  1.                 With .WebBrowser1
  2.                
  3.                     With .Document
  4.                         
  5.                         '.GetElementById("gs_taif50").Click   
  6.                         
  7.                         .GetElementById("searchboxinput").Value = cmb(2).Text
  8.                         .GetElementById("searchbox-searchbutton").Click
  9.                         
  10.                         .GetElementById("searchboxinput").Value = cmb(2).Text
  11.                                 Application.Wait Now + TimeValue("0:00:05")

  12.                         .GetElementById("gs_lc50").Click
  13.                         Application.OnKey "+^{a}"   '模擬按鍵 ctrl  + a
  14.                         Application.OnKey "{del}" '模擬按鍵 del
  15.                         .GetElementById("searchboxinput").Value = cmb(2).Text
  16.                             Application.OnKey "+^{ENTER}"  '模擬按鍵ctrl + enter
  17.                         .GetElementById("searchbox-searchbutton").Click
  18.                         Do
  19.                             DoEvents
  20.                         Loop
  21.                         

  22.                     End With
  23.                 End With
複製代碼

作者: Joforn    時間: 2020-11-27 10:16

回復 3# mark15jill
你的代碼中有一句:
  1.                          Do
  2.                             DoEvents
  3.                         Loop
複製代碼
第一次執行后程式將進入永久死循環,建議去掉。
作者: mark15jill    時間: 2020-11-27 10:18

本帖最後由 mark15jill 於 2020-11-27 10:31 編輯
回復  mark15jill
你的代碼中有一句:第一次執行后程式將進入永久死循環,建議去掉。
Joforn 發表於 2020-11-27 10:16



目前改成下列code ~
但會造成...
資料1 << 讀取沒點擊
資料2 << 有時讀取到資料1 有時沒反應
資料3 << 有時讀取到資料1 有時讀取到資料2 有時沒反應

如果時間延遲讀取設置過大~ 又會造成卡卡QQ

                With .WebBrowser1
                    
                    With .Document
                        
                        '.GetElementById("gs_taif50").Click
                        
                        .GetElementById("searchboxinput").Value = cmb(2).Text
                        .GetElementById("searchboxinput").Select
                            Application.OnKey "+^{ENTER}"
                        .GetElementById("searchbox-searchbutton").Click
                        '.GetElementById("searchbox-searchbutton").Click
                                                
                        .GetElementById("searchboxinput").Select
                            Application.OnKey "+^{a}"
                            Application.OnKey "+^{del}"
                            Application.OnKey "+^{ENTER}"
                        Application.Wait (Now + TimeValue("0:00:3"))
                            cmb(2).Copy
                        .GetElementById("searchboxinput").Select
                            Application.OnKey "+^{v}"
                           
                        '.GetElementById("searchboxinput").Value = cmb(2).Text
                            Application.OnKey "+^{ENTER}"
                        .GetElementById("searchbox-searchbutton").Click
                        Application.Wait (Now + TimeValue("0:00:3"))
                        
                           
                           
                    End With
                End With


感覺根本是把VBA當按鍵精靈在寫...
作者: Joforn    時間: 2020-11-27 11:41

本帖最後由 Joforn 於 2020-11-27 11:47 編輯

回復 5# mark15jill
很久都不用WebBrowser控件了。只能跟你大致說下處理流程。
在發送命令后,一般用
  1. IsBusy=True   '這個是全局變量,由WebBrowser的加載完成事件去將其值改變。
  2. Times=0
  3. Do While IsBusy And (Times<100)       '檢測Times是否小于100,大于100判斷為程序出問題了,加載時間過長,強行中止程式運行。100次循環與后面的Sleep 200組合,表示最長等待20秒(Sleep參數以毫秒為單位)。
  4.      Sleep 200             '這個是API函數,使用前要先聲明。加入這條語句是為了釋放CPU控制權,沒有這條,VBA的CPU使用率一直占99%
  5.      DoEvents             '釋放程序控制權,防止WebBrower出問題后無法退出,也是為了讓WebBrower有相應的CPU運行權去繼續加載頁面。
  6.      Times=Times + 1
  7. Loop
複製代碼
然后還要再引用WebBrower控件的DocumentComplete
  1. Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
  2.    IsBusy = False
  3. End Sub
複製代碼
上面兩組代碼相結合,那么就可以完成一個等待頁面加載完成后,程式才繼續執行后續代碼過程。

但是,要注意:在WebBrower加載頁面開始后,并不一定只激活一次DocumentComplete,所以還要在WebBrowser1的DocumentComplete事件處理過程中進行一定的判斷來是否是真正的最后一次頁面加載完成事件。可以對比URL是否是當前頁面的URL來判斷:
  1. Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
  2.     If IsBusy Then IsBusy = URL<>DocumentURL '注意,這里的DocumentURL需要你自己根據你當前的頁面去獲取或是設置。
  3. End Sub
複製代碼
最后是你可能需要用到的函數和變量聲明:
  1. #If VBA7 Then
  2.     Private Declare PtrSafe Sub Sleep Lib "Kernel32.dll" (ByVal dwMilliseconds As Long)
  3. #Else
  4.     Private Declare Sub Sleep Lib "Kernel32.dll" (ByVal dwMilliseconds As Long)
  5. #End If
  6. Private IsBusy As Boolean
複製代碼

作者: mark15jill    時間: 2020-11-27 14:20

回復  mark15jill
很久都不用WebBrowser控件了。只能跟你大致說下處理流程。
在發送命令后,一般用然后還 ...
Joforn 發表於 2020-11-27 11:41



    沒關係... 我改用vb.net寫看看~ 感謝
作者: mark15jill    時間: 2021-1-2 15:20

回復  mark15jill
很久都不用WebBrowser控件了。只能跟你大致說下處理流程。
在發送命令后,一般用然后還 ...
Joforn 發表於 2020-11-27 11:41



    後來發現..... 有個更快的方法解決...
cmb(0).text >> combobox.text >> 要查詢的物件

            .Navigate ("about:blank")
            .Navigate ("https://www.google.com.tw/maps/search/" & cmb(0).Text)

不管他的搜尋元件參數,強制模擬手動搜尋的方式...


    只是新產生幾個問題...  
1、用上面的方法,雖然會自動變化與定位,可是畫面因為vba與ie元件切換讀取,需要等的時間更久。
2、googlemap 把id 跟 span 隱藏掉... 沒法直接看 "分享" 的ID 跟類別




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)