*.這範例主要擷取自"超圖解excel vba 應用講座" 範例97
原本的範例用來偵測  "記事本 Notepad.exe" 是否被關閉, 以決定讓程式是否往下跑

 

我修改了一下, 中間的程式碼 , 改成telnet指令用法
因為如果透過VBA去連線Linux server , 有時可能需要透過telnet或是SSH去對server下指令, 做一些類似...搜尋(find), 擷取(grep) 檔案的動作

 

我是用SendKeys的方式去傳送,我要輸出的文字,
sendKeys的動作是模擬,鍵盤所key的指令去作輸入,他最大的缺點,就是 "作用視窗" 必須是在前景畫面,不能背景執行

 

下面幾個重點提示:

1. cmd.exe 後面必須加 /c ,否則程式結束,這個cmd視窗不會關閉
    "cmd.exe /c telnet ptt.cc", vbNormalFocus

2.  下面這行,可以讓VBA ,程式暫時停止,執行5秒, 你可斟酌 去修改,要停止的時間 (時:分:秒)
    Application.Wait Now() + TimeValue("00:00:05")

   

  *.還有另外一個 程式暫停執行的方式 

   先宣告     Declare Sub Sleep Lib "kernel32" (ByVal dwMS As Long)
   並且巨集中使用 ,  Sleep [millisecond]
   例如: Sleep 1000 即使程式暫停1秒

 

3. sendkey 用法有很多,請參考microsoft官方網站教學
    http://msdn.microsoft.com/en-us/library/office/ff821075%28v=office.15%29.aspx

 

4. shell內使用 vbNormalFocus , 也可以使用下面其他取代,也可使用value取代

    例如: 將vbNormalFocus  改成 1 , 意思是一樣的
    但記得telnet必須要使用前景模式, 所以就不能選擇vbHide,vbMinimized...之類的,
相反的,如果是ftp指令,我就會建議使用vbHide , 這樣避免下載資料時,一直有畫面跑出來

 

 

Constant Value Description
vbHide 0 Window is hidden and focus is passed to the hidden window.
vbNormalFocus 1 Window has focus and is restored to its original size and position.
vbMinimizedFocus 2 Window is displayed as an icon with focus.
vbMaximizedFocus 3 Window is maximized with focus.
vbNormalNoFocus 4 Window is restored to its most recent size and position. The currently active window remains active.
vbMinimizedNoFocus 6 Window is displayed as an icon. The currently active window remains active.

 

 

 

========= 程式範例 ========

Option Explicit

'-------------------------------------------------------
'範例97
'關閉以Shell函數啟動的應用程式之前進入待機狀態
'-------------------------------------------------------

'傳回既存物件控制代碼的函數
'傳回值 成功 = 指定處理的Open控制代碼
'     失敗 = NULL
Declare Function OpenProcess Lib "kernel32" _
    (ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long

Public Const PROCESS_QUERY_INFORMATION = &H400&


'傳回指定處理結束狀態的函數
'傳回值 成功 = 0以外的數值
'    失敗 = 0
Declare Function GetExitCodeProcess Lib "kernel32" _
    (ByVal hProcess As Long, _
    lpExitCode As Long) As Long
        
'判斷指定的處理是否結束
'(若尚未結束,將置入STILL_ACTIVE)
Public Const STATUS_PENDING = &H103&
Public Const STILL_ACTIVE = STATUS_PENDING


'關閉開啟中物件控制代碼的函數
''傳回值 成功 = 0以外的數值
'    失敗 = 0
Declare Function CloseHandle Lib "kernel32" _
    (ByVal hObject As Long) As Long


'程序
Sub GetExitCodeProcess_Sample()
    Dim lngProcessId As Long    'Shell函數的傳回值
    Dim lngProcess As Long      'OpenProcess函數的傳回值
    Dim lngExitCode As Long     '結束程式碼
    Dim rc As Long
     
              
    '啟動你要telnet的IP, 本範例 ptt.cc
    lngProcessId = Shell("cmd.exe /c telnet ptt.cc", vbNormalFocus)

     

    ' 等待五秒,再傳送 "登入帳號"  , 再等兩秒, 在按 "Enter"
    Application.Wait Now() + TimeValue("00:00:05")
    SendKeys "登入帳號", True
    Application.Wait Now() + TimeValue("00:00:02")
    SendKeys "{ENTER}", True
    

      ' 等待2秒,再傳送 "登入密碼"  , 再等2秒, 在按 "Enter"
    Application.Wait Now() + TimeValue("00:00:02")
    SendKeys "登入密碼", True
    Application.Wait Now() + TimeValue("00:00:01")
    SendKeys "{ENTER}", True
    
    '取得以Shell函數啟動的應用程式的處理物件的控制代碼
    lngProcess = OpenProcess(PROCESS_QUERY_INFORMATION, _
                            1, _
                            lngProcessId)
                            
    '以GetExitCodeProcess取得處理的結束狀態
    '若啟動的應用程式處於尚未關閉的狀態,將由DoEvent繼續對作業系統詢問其狀態


    Do
        rc = GetExitCodeProcess(lngProcess, lngExitCode)
        DoEvents
    Loop While lngExitCode = STILL_ACTIVE

    '關閉開啟中的物件控制代碼
    rc = CloseHandle(lngProcess)

End Sub


創作者介紹
創作者 lincco的部落格 的頭像
lincco

lincco的部落格

lincco 發表在 痞客邦 留言(3) 人氣( 2069 )