2017-08-22 18 views
1

私のPCで実行されている他のソフトウェアとExcel VBAに関する質問があります。他のソフトウェアからExcelファイルにデータを取得

私はExcelファイルを作成し、DDEを使用してトレーディングソフトウェア(SPTrader)からのデータを正常に接続しました。

他の目的のために、交換されたレコードをExcelファイルに戻したいと思います。

次に、私はWinAPI FindWindowとFindWindowEXを使用して、SPTraderのアカウントセクションの取引レコードフィールドのウィンドウを探しました。また、ShowWindow(SW_MAXIMIZE/SW_RESTORE)を使用してウィンドウをテストし、正しい領域を取得したことを証明できます。

これらの領域では、ソフトウェアはマウスの右クリックだけを使用してから、[すべての貿易をコピー]ドロップダウンリストから選択します。 Ctrl + Cは使用できません。

しかしとき今、私はちょうどにVBAコードを使用して、私はレコードを取得するためのSendMessage(CB_GETLBTEXT、CB_SELECTSTRING、LB_GETTEXT、LB_GETITEMDATA、LB_GETTEXTLEN)と窓指さ(HWNDによる)を使用しますが、それは0

を返しますウィンドウ全体の位置とサイズを指定するようにソフトウェア全体を設定します。次に、マウスカーソルをその場所に呼び出し、右クリックして「すべての取引をコピー」を選択し、Excelファイルに貼り付けます。

私の質問は次のとおりです。 VBAによって取引記録領域からデータを取り出すことは可能ですか? このエリアのタイプは何ですか?テーブル、リストボックス、レコードセット...? 関数を手動で実行せずに取引が完了したときにデータを取り出す方法は?

ありがとうございました!エクセルVBAで

Public Sub TradesOrder() 
    Dim mainwnd As String 
    Dim mainwnd_ac As String 
    Dim hwnd As String 
    Dim Chwnd1 As String 
    Dim Chwnd2 As String 
    Dim Chwnd3 As String 
    Dim Chwnd4 As String 
    Dim Chwnd5 As String 
    Dim Chwnd6 As String 
    Dim Chwnd7 As String 

    Dim wkb As Workbook 
    Dim wb As String 
    Dim sht As String 
    Dim dirty As Long 

    wb = "SPTrader_Excel_KK.xlsm" 

    sht = "SPTrader_XLS" 

    On Error Resume Next 
    Set wkb = Workbooks("SPTrader_Excel_KK.xlsm") 

    If wkb Is Nothing Then 
     Workbooks.Open (ThisWorkbook.Path & "\" & wb) 
     Workbooks(wb).Activate 
     Worksheets(sht).Activate 
    Else 
     Workbooks(wb).Activate 
     Worksheets(sht).Activate 
    On Error GoTo 0 
    End If 

    mainwnd = Worksheets(sht).Range("AC1").Value 
    mainwnd_ac = Worksheets(sht).Range("AC2").Value 

    hwnd = FindWindow(vbNullString, mainwnd) 
    Chwnd1 = FindWindowEx(hwnd, 0&, "MDIClient", vbNullString) 
    Chwnd2 = FindWindowEx(Chwnd1, 0&, "TfrmAccBox", vbNullString) 
    Chwnd3 = FindWindowEx(Chwnd2, 0&, "TPageControl", vbNullString) 
    Chwnd4 = FindWindowEx(Chwnd3, 0&, "TTabSheet", "Order") 
    Chwnd5 = FindWindowEx(Chwnd4, 0&, "TAdvStringGrid", vbNullString) 
    Chwnd6 = FindWindowEx(Chwnd5, 0&, "TAdvRichEdit", vbNullString) 'TAdvRichEdit 'TGridDatePicker 

    SetWindowPos hwnd, HWND_NOTOPMOST, 0, 0, 850, 620, SWP_SHOWWINDOW 
    BringWindowToTop Chwnd2 
    BringWindowToTop Chwnd4 
    ShowWindow Chwnd4, SW_NORMAL 
    SetCursorPos 500, 540       'x and y mouse position 
    mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0 'RightClick 
    mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0  'RightClick 
    Sleep 100 
    mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0 'RightClick 
    mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0  'RightClick 
    SendKeys "{DOWN}" 
    SendKeys "{DOWN}" 
    Sleep 100 
    SendKeys "{ENTER}" 

    Worksheets(sht).Activate 
    Worksheets(sht).Range("C25").Select 
    Range("C25").PasteSpecial xlPasteAll 

End Sub 

enter image description here enter image description here

+0

「取引記録」のウィンドウクラスとは何ですか? Spy ++を試しましたか? – EylM

+0

こんにちは! EyIM、 ありがとう、面白い! Spy ++ under classページから、クラス名はウィンドウTAdvRichEdit、クラススタイルは00000008&CS_DBCLKS、クラスバイトは0です。 – Kosan

+0

これはカスタムコントロールのようです。複合グリッドコントロールから単一のセルを読み取る可能性は、そのコントロールが自動化インターフェイスを実装していない限り、実質的にゼロです。プロセスの境界を越えてランダムなメッセージを送信することは、あなたを非常に遠ざけることにはなりません。これは明らかにリストボックスやコンボボックスではないので、リストボックスやコンボボックスに固有のメッセージには何の役にも立たないでください。 – IInspectable

答えて

0

、あなたはEnumChildWindowsを使用することができ、まず「SPSytem」のウィンドウタイトルからSPウィンドウハンドラを見つけるために機能し、第二にもから、今日の取引記録のためにその子ウィンドウハンドラを見つけます"Account Info"のタイトル、 "Order"のタイトル、 "TAdvStringGrid"のクラス名(レコードエリアのテキストはタイトルのEdit textにないので)SetForegroundWindow()とSetCursorPos()を使用して、ボタンをクリックしてください。mouse_eventを使用してコピーボタンを右クリックして、レコードをシステムクリップボードに保存します。 VBAコード付きExcelワークシートあなたの参照のための以下の添付コード。新しいxlsシートを開いたら、VBAモジュールでテストできます。最後にレコードの結果が範囲( "A10:Z100")に貼り付けられます

あなたのSPトレーダーのタイトルをVBAコードで置き換えます:str = "SPSystem R8.75.3"あなたのものはR8.74.2です。他のクラス名と名前は同じでなければなりません。

注意:取引記録領域は、VBAの実行中に常に表示され、ウィンドウに表示され、非表示にする必要があります。安全のために、ShowWindow()がコードで使用されています。 VBAコードは以下のとおりです。


    Private Declare Function SendMessageSTRING Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long 
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long 
    Public Declare Function SendDlgItemMessageW Lib "user32" (ByVal hdlg As Long, ByVal nIDDlgItem As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 
    Private Const WM_GETTEXT = &HD 
    Public Const CWP_ALL = 0 
    Public Const CWP_SKIPINVISIBLE = 1 
    Public Const CWP_SKIPDISABLED = 2 
    Public Const CWP_SKIPTRANSPARENT = 3 
    Public Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _ 
     As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long 
    Public Declare Function GetWindowText Lib "user32" _ 
     Alias "GetWindowTextA" _ 
     (ByVal hwnd As Long, _ 
     ByVal lpString As String, _ 
     ByVal cch As Long) As Long 
    Public Declare Function GetClassName Lib "user32" _ 
     Alias "GetClassNameA" _ 
     (ByVal hwnd As Long, _ 
     ByVal lpClassName As String, _ 
     ByVal nMaxCount As Long) As Long 
    Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long 
    Private Type RECT 
    Left As Long 
    Top As Long 
    Right As Long 
    Bottom As Long 
    End Type 
    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 
    Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long 
    Private Const BM_CLICK = &HF5 
    Private Const BM_SETSTATE = &HF3 
    Private Const WM_LBUTTONDOWN = &H201 
    Private Const WM_LBUTTONUP = &H202 
    Private Const MK_LBUTTON = &H1 
    Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long 
    Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long) 
    Public Const MOUSEEVENTF_LEFTDOWN = &H2 
    Public Const MOUSEEVENTF_LEFTUP = &H4 
    Public Const MOUSEEVENTF_RIGHTDOWN As Long = &H8 
    Public Const MOUSEEVENTF_RIGHTUP As Long = &H10 
    Public Declare Function ShowWindow Lib "user32" _ 
     (ByVal lHwnd As Long, _ 
     ByVal lCmdShow As Long) As Boolean 
    Declare Function GetCursorPos Lib "user32" (lpPoint As RECT) As Long 
    Dim cReturn As Long, lParam As Long, parHwnd As Long 
    Dim str As String, fhwnd As Long 
    Sub traderecord() 
    Range("A10:Z100").ClearContents 
    str = "SPSystem R8.75.3" 
    cReturn = EnumChildWindows(0, AddressOf EnumChildProc, lParam) 
    Debug.Print str 
    Debug.Print fhwnd 
    str = "Account Info" 
    cReturn = EnumChildWindows(fhwnd, AddressOf EnumChildProc, lParam) 
    Debug.Print str 
    Debug.Print Hex(fhwnd) 
    fhwnd2 = fhwnd 
    ShowWindow fhwnd2, 3 
    str = "Order" 
    cReturn = EnumChildWindows(fhwnd, AddressOf EnumChildProc, lParam) 
    Debug.Print str 
    Debug.Print fhwnd 
    Range("A9") = "HWND" 
    Range("B9") = Hex(fhwnd) 
    str = "TAdvStringGrid" 
    cReturn = EnumChildWindows(fhwnd, AddressOf EnumChildProc, lParam) 
    Debug.Print str 
    Debug.Print Hex(fhwnd) 
    Range("A9") = "HWND" 
    Range("B9") = Hex(fhwnd) 
    ForegroundHwnd2 = SetForegroundWindow(fhwnd) 
    Dim rt As RECT 
    GetCursorPos rt 
    x = rt.Left 
    y = rt.Top 
    Debug.Print x & "==" 
    GetWindowRect fhwnd, rt 
    Debug.Print rt.Top 
    SetCursorPos rt.Left + 10, rt.Top + 30 
    Sleep 200 
    mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0 
    mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0 
    SetCursorPos rt.Left + 30, rt.Top + 60 
    Sleep 200 
    mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0 
    mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0 
    Sleep 500 
    ShowWindow fhwnd2, 1 
    'Range("A1").Copy 
    'Dim DataObj As MSForms.DataObject 
    'Set DataObj = New MSForms.DataObject 
    'DataObj.GetFromClipboard 
    ' strPaste = DataObj.GetText(1) 
    'Debug.Print strPaste 
    Set ws = ThisWorkbook.Worksheets("Sheet1") 
    ws.Activate 
    ws.Range("A10").Select 
    ws.Paste 
    SetCursorPos x, y 
    str = "Microsoft Excel" 
    cReturn = EnumChildWindows(0, AddressOf EnumChildProc, lParam) 
    Debug.Print str 
    Debug.Print Hex(fhwnd) 
    ForegroundHwnd2 = SetForegroundWindow(fhwnd) 
    ws.Range("A10").Select 
    End Sub 
    Private Function EnumChildProc(ByVal lHwnd As Long, ByVal lParam As Long) As Long 
     Dim RetVal As Long 
     Dim WinClassBuf As String * 255, WinTitleBuf As String * 255 
     Dim WinClass As String, WinTitle As String 
     Dim ChildCount As Integer ' Number of Child Windows 
     Dim cLV As Long     ' Child window handle 
     RetVal = GetClassName(lHwnd, WinClassBuf, 255) 
     WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces 
     RetVal = GetWindowText(lHwnd, WinTitleBuf, 255) 
     WinTitle = StripNulls(WinTitleBuf) 
     ChildCount = ChildCount + 1 
     If WinClass = "ListView20WndClass" Then ' ListView Window 
      cLV = lHwnd 
      EnumChildProc = False 
     Else 
      EnumChildProc = True 
     End If 
     If (InStr(WinClass, str) > 0 Or InStr(WinTitle, str) > 0) Then 
     Debug.Print ChildCount & " Child Handle: " & Hex(lHwnd); lHwnd; " Child Class = "; WinClass; ", Title = "; WinTitle 
     fhwnd = lHwnd 
     EnumChildProc = False 
     End If 
     End Function 
     Private Function StripNulls(OriginalStr As String) As String 
     If (InStr(OriginalStr, Chr(0)) > 0) Then 
      OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1) 
     End If 
     StripNulls = OriginalStr 
     End Function 
関連する問題