Board logo

標題: [發問] 代碼應該如何撰寫才能忽視 因查詢不到而產生的網頁訊息呢? [打印本頁]

作者: justintoolbox    時間: 2015-7-16 21:13     標題: 代碼應該如何撰寫才能忽視 因查詢不到而產生的網頁訊息呢?

各位前輩大家好,

目前遇到的問題是:『有什麼方法可以忽視網頁訊息?例如:在網頁http://www.tdcc.com.tw/smWeb/QryStock.jsp,資料日期為20150529 證券代號為6456,會出現查無訊息的視窗』
如下圖:
[attach]21400[/attach]

我有試過 Application.DisplayAlerts = False ,不過這只對excel本身產生問題可以忽略,對網頁產生的問題就行不通了。
請各位前輩們出手相救,感謝!
  1. my_url = "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
複製代碼

作者: GBKEE    時間: 2015-7-17 07:46

回復 1# justintoolbox
  1. .Document.getElementsByName("sub")(0).Click                    '按下查詢鍵
  2.         Do While .Busy Or .ReadyState <> 4                             '等候網頁下載完畢
  3.             DoEvents
  4.             Application.SendKeys "~", True                '按 ENTER 按鍵 ,預防 "證券代號"有錯誤
  5.          Loop
複製代碼

作者: justintoolbox    時間: 2015-7-17 09:18

回復  justintoolbox
GBKEE 發表於 2015-7-17 07:46


真的太棒了!!!
非常感謝GBKEE出手相救!
讓我學到該如何克服這方面的問題,感謝!
作者: joey0415    時間: 2015-7-17 20:20

回復 2# GBKEE

有改了!但按下去時,vba處會一直出現圈圈,有問題,請G大幫忙
  1. Declare Sub Sleep Lib "kernel32" (ByVal dwMS As Long)
  2. Sub ex()

  3. Set iea = CreateObject("internetexplorer.application")
  4.         With iea
  5.             .Visible = True
  6.             .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  7.             Do Until .ReadyState = 4
  8.                 DoEvents
  9.             Loop
  10.             
  11.              Set x = iea.document.all.tags("option") '查下拉選單
  12.                  x(6).Selected = True '選取該子項目
  13.                        
  14.               iea.document.getElementsByName("StockNo")(0).Value = "6456"
  15.              iea.document.getElementsByName("sub")(0).Click                    '按下查詢鍵
  16.             
  17.              Sleep 2000
  18.             
  19.                 Do While .Busy Or .ReadyState <> 4                             '等候網頁下載完畢
  20.                     DoEvents
  21.                     Application.SendKeys "~", True                '按 ENTER 按鍵 ,預防 "證券代號"有錯誤
  22.                     Sleep 1000
  23.                  Loop
  24.            .Quit
  25.     End With
  26.    

  27. End Sub
複製代碼

作者: GBKEE    時間: 2015-7-18 05:13

回復 4# joey0415
ie8 執行沒這問題.
作者: joey0415    時間: 2015-7-18 14:30

回復 5# GBKEE

我是win7  ie11 就無法抓到

失焦抓不到
作者: no3-taco    時間: 2015-7-18 20:01

我剛剛ie10測試,也沒有問題,alert訊息框會跳到最上層,所以沒問題
如果執行時有亂點,好像就沒辦法了。
作者: joey0415    時間: 2015-7-23 22:01

回復  joey0415
ie8 執行沒這問題.
GBKEE 發表於 2015-7-18 05:13


請問版大如果是用我自己寫的範例網頁,我自己是抓不到的,能指點一下嗎?
https://dl.dropboxusercontent.com/u/40393708/test1.htm

[attach]21465[/attach]

[attach]21466[/attach]
作者: azrael19    時間: 2015-7-24 00:55

  1. Option Explicit

  2. #If Win64 = 1 Then
  3. Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal HWND As Long, ByVal wCmd As Long) As Long
  4. Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
  5. #Else
  6. Private Declare Function GetWindow Lib "user32" (ByVal HWND As Long, ByVal wCmd As Long) As Long
  7. Private Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
  8. #End If

  9. Private Const GW_HWNDNEXT = 2
  10. Private Const GW_CHILD = 5

  11. Sub ex()
  12.     Dim lHwndChild&
  13.    
  14.     With CreateObject("InternetExplorer.Application")
  15.         .Visible = True
  16.         .Navigate "https://dl.dropboxusercontent.com/u/40393708/test1.htm"
  17.         Do While .Busy Or .ReadyState <> 4
  18.             DoEvents
  19.             If 3 = .ReadyState Then
  20.                 lHwndChild = GetWindow(.HWND, GW_CHILD)
  21.                 Do While lHwndChild
  22.                     SetForegroundWindow .HWND 'HWND is the HWND of the myIEWindow
  23.                     Application.SendKeys "~", True
  24.                     lHwndChild = GetWindow(lHwndChild, GW_HWNDNEXT)
  25.                 Loop
  26.             End If
  27.         Loop
  28.     End With
  29.    
  30. End Sub
複製代碼
回復 8# joey0415
作者: joey0415    時間: 2015-7-24 10:08

回復 9# azrael19

超級感謝真的可以動了!抓到我要的資料

從你引用的函式來看好像是找到視窗並確認是哪個窗後,送出enter並關閉它

請問一下
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5
是什麼設定值呢?

謝謝

後來我修改了,送出後要sleep一下,效果會比較好
作者: azrael19    時間: 2015-7-24 10:49

回復 10# joey0415
大概就是確認IE是否有任何子視窗顯示(ex:訊息視窗),有就將IE切換成最上層顯示後再送出ENTER鍵將訊息視窗關閉。
設定值請參考下列網址:
https://msdn.microsoft.com/zh-tw/ms633515
另外我寫的過於簡化,設想如果發生子視窗無法用ENTER鍵關閉的情況,你最好加上錯誤處理機制(ex:送出ENTER鍵幾次無效後就不再執行改顯示錯誤訊息),不然有可能會進入死迴圈...
作者: joey0415    時間: 2015-7-24 12:21

回復 11# azrael19

若改成這樣的網頁,雖然可以點擊,但之後卻失焦了,如果重新再往下點擊呢?
謝謝

感謝指點
  1. Sub 點擊()
  2.     Cells.Clear
  3.     Dim lHwndChild&
  4.     Set ie = CreateObject("InternetExplorer.Application")
  5.     With ie
  6.         .Visible = True
  7.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  8.         
  9.                 Do While .Busy Or .ReadyState <> 4  '等候網頁下載完畢
  10.                     DoEvents
  11.                  Loop
  12.         Set x = .document.all.tags("option") '查下拉選單
  13.             x(7).Selected = True '選取該子項目
  14.             
  15.             .document.getElementsByName("StockNo")(0).Value = "6456"
  16.             .document.getElementsByName("sub")(0).Click

  17.         Sleep 2000

  18.             lHwndChild = GetWindow(.HWND, GW_CHILD)

  19.               If lHwndChild <> 0 Then
  20.                 Do While lHwndChild
  21.                     SetForegroundWindow .HWND 'HWND is the HWND of the myIEWindow
  22.                     Application.SendKeys "~", True
  23.                     
  24.                     lHwndChild = GetWindow(lHwndChild, GW_HWNDNEXT)
  25.                 Loop
  26.                
  27.                 Sleep 2000
  28.             End If
  29.                         '-------------------以下為失焦處,無法點擊
  30.             Stop
  31.             .document.getElementsByName("StockNo")(0).Value = "1101"
  32.             .document.getElementsByName("sub")(0).Click
  33.             
  34.         Do While .Busy Or .ReadyState <> 4  '等候網頁下載完畢
  35.             DoEvents
  36.          Loop

  37.         Stop
  38.         .Quit
  39.     End With   

  40. End Sub
複製代碼

作者: azrael19    時間: 2015-7-24 15:06

回復 12# joey0415
我用你上面貼的程式碼及GBKEE版主教的方法都沒有出現問題(用 Win7 + IE11 + Office2013),所以我也不曉得出了什麼問題...
這問題如果短時間內無法解決你又急需這些資料,下列網址可以抓到最新一期的資料(csv檔):
http://data.gov.tw/node/11452
作者: joey0415    時間: 2015-7-24 17:51

回復 13# azrael19

超級感謝您的回答

我有兩台電腦

一台 win7 64位元  office 2010 32位元  IE 11 32位元 不行

一台 win7 64位元  office 2010 32位元  IE 10 32位元 可以

其實抓的方法我會,只是要多學一種

感謝教學相長
作者: azrael19    時間: 2015-7-24 22:32

回復 14# joey0415
另一種方式,試試看...
  1. Option Explicit

  2. #If Win64 Then
  3. Private Declare PtrSafe Function GetWindow Lib "USER32" (ByVal hWnd As LongPtr, ByVal wCmd As LongPtr) As LongPtr
  4. Private Declare PtrSafe Function SetForegroundWindow Lib "USER32" (ByVal hWnd As Long) As Long
  5. Private Declare PtrSafe Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
  6. Private Declare PtrSafe Function FindWindowEx Lib "USER32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
  7. Private Declare PtrSafe Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
  8. #Else
  9. Private Declare Function GetWindow Lib "user32" (ByVal HWND As Long, ByVal wCmd As Long) As Long
  10. Private Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
  11. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  12. Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
  13. Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
  14. #End If

  15. Private Const WM_CLOSE = &H10
  16. Private Const GW_HWNDNEXT = 2
  17. Private Const GW_CHILD = 5
  18. Private Const BM_CLICK = &HF5

  19. Sub 點擊()
  20.     Cells.Clear
  21.     Dim hWndChild, hWndPopup, x, Retries As Integer: Retries = 10
  22.    
  23.     With CreateObject("InternetExplorer.Application")
  24.         .Visible = True
  25.         .Navigate "http://www.tdcc.com.tw/smWeb/QryStock.jsp"
  26.         
  27.         Do While .Busy Or .ReadyState <> 4  '等候網頁下載完畢
  28.             DoEvents
  29.         Loop
  30.         Set x = .document.all.tags("option") '查下拉選單
  31.         x(7).Selected = True '選取該子項目
  32.         
  33.         .document.getElementsByName("StockNo")(0).Value = "6456"
  34.         .document.getElementsByName("sub")(0).Click
  35.         
  36.         Do While (.Busy Or .ReadyState <> 4) And 0 < Retries
  37.         
  38.             hWndChild = GetWindow(.hWnd, GW_CHILD)
  39.         
  40.             If 0 <> hWndChild Then
  41.                 Do While hWndChild
  42.                     hWndPopup = FindWindow("#32770", "網頁訊息") '#32770 The class for a dialog box
  43.                     If 0 <> hWndPopup Then
  44.                         SendMessage FindWindowEx(hWndPopup, 0, "Button", "確定"), BM_CLICK, 0, 0
  45.                     Else
  46.                         Exit Do
  47.                     End If
  48.                     'SetForegroundWindow .hWnd 'HWND is the HWND of the myIEWindow
  49.                     'Application.SendKeys "~", True
  50.                     hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)
  51.                 Loop
  52.             
  53.             End If
  54.             Application.Wait Now + #12:00:01 AM#
  55.             DoEvents
  56.             Retries = Retries - 1
  57.         Loop
  58.         If 0 = Retries Then
  59.             AppActivate Application.Caption
  60.             MsgBox "無法關閉訊息視窗!", vbCritical
  61.             Exit Sub
  62.         End If
  63.         '-------------------以下為失焦處,無法點擊
  64.         Stop
  65.         .document.getElementsByName("StockNo")(0).Value = "1101"
  66.         .document.getElementsByName("sub")(0).Click
  67.             
  68.         Do While .Busy Or .ReadyState <> 4  '等候網頁下載完畢
  69.            DoEvents
  70.         Loop
  71.         
  72.         Stop
  73.         .Quit
  74.     End With

  75. End Sub
複製代碼

作者: joey0415    時間: 2015-7-25 10:22

回復 15# azrael19
回覆!這個也可以哦!

我自己發現我這台的ie是11版 64位元的,所以之前的都無效
移除後,雖然 無法改裝成11版 32位元,系統為64位元的
只好用10版的,不過就可以啦

我想一定是ie是11版 64位元的關係,有某些函式不能用

謝謝

有空加個好友

請問  "#32770"  從哪看出來的
作者: bobomi    時間: 2015-7-25 10:39

回復 16# joey0415


"#32770" 用  vbNullString 替代即可




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