Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1908to1912
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Drittprogramm fernsteuern

Drittprogramm fernsteuern
22.11.2022 15:44:04
Chris
Hallo VBAler,
Ich möchte ein Drittprogramm mit folgendem Makro unter Verwendung von sendkeys fernsteuern.
Das funktioniert soweit prima, wenn ich - nachdem die Arbeitsmappe mit untenstehendem Makro geöffnet wurde - zuerst das Drittprogramm per Maus anklicke und einmal in
das Fenster hineinklicke, so dass das Programm das aktive ist.
Schließe ich Excel während das Drittprogramm geöffnet ist, starte Excel erneut und lass das Makro laufen, wird das Fenster des Drittprogramms nicht aktiviert, so dass ich falsche Inhalte erhalte.
Hat jmd. eine Idee, woran dies liegt und was man verändern muss?
Schon mal Danke.
Chris

Option Explicit
Private Declare Function FindWindow Lib "User32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowText Lib "User32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "User32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetWindow Lib "User32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Declare Function IsWindowVisible Lib "User32" (ByVal hWnd As Long) As Boolean
Private Declare Function SetForegroundWindow Lib "User32" (ByVal hWnd As Long) As Long
Private Const GW_HWNDNEXT = 2
Private 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)
Private Declare Function GetCursorPos Lib "User32" (cPoint As POINTAPI) As Long
Private Declare Function SetCursorPos Lib "User32" (ByVal x As Long, ByVal y As Long) As Long
Private Type POINTAPI
x As Long
y As Long
End Type
Public Const MOUSE_LEFT = 0
Public Const MOUSE_MIDDLE = 1
Public Const MOUSE_RIGHT = 2
Private Declare Sub keybd_event Lib "User32" ( _
ByVal bVk As Byte, _
ByVal bScan As Byte, _
ByVal dwFlags As Long, _
ByVal dwExtraInfo As Long)
Const KEYUP = &H2
Public Sub SendMausklick(ByVal mButton As Long)
Const MOUSEEVENTF_LEFTDOWN = &H2
Const MOUSEEVENTF_LEFTUP = &H4
Const MOUSEEVENTF_MIDDLEDOWN = &H20
Const MOUSEEVENTF_MIDDLEUP = &H40
Const MOUSEEVENTF_RIGHTDOWN = &H8
Const MOUSEEVENTF_RIGHTUP = &H10
If (mButton = MOUSE_LEFT) Then
Call mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
Call mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
ElseIf (mButton = MOUSE_MIDDLE) Then
Call mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0)
Call mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
Else
Call mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
Call mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)
End If
End Sub
Private Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean
Dim lhWndP As Long
Dim sStr As String
GetHandleFromPartialCaption = False
lhWndP = FindWindow(vbNullString, vbNullString)
Do While lhWndP  0
sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
GetWindowText lhWndP, sStr, Len(sStr)
sStr = Left$(sStr, Len(sStr) - 1)
If InStr(1, sStr, sCaption) > 0 Then
GetHandleFromPartialCaption = True
lWnd = lhWndP
Exit Do
End If
lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
Loop
End Function
Sub DP()
Dim sTxt As String * 255, t As String, sSuch As String, i, ii
Dim lhWndP As Long
If GetHandleFromPartialCaption(lhWndP, "Drittprogramm") = True Then
SetForegroundWindow lhWndP
End If
Call keybd_event(91, 0, 0, 0) 'Windows Taste
Call keybd_event(38, 0, 0, 0) 'UP
Call keybd_event(91, 0, KEYUP, 0)
Call keybd_event(38, 0, KEYUP, 0)
SendKeys "x", True
SendKeys "%v", True
Call Timer40
SendKeys "s", True
Call Timer40
SendKeys "a", True
Call Timer40
i = 0
For i = 1 To 6
SendKeys i & "+^{RIGHT}", True
Call Timer40
Next i
Call Move_Cursor_to
SendMausklick MOUSE_LEFT
ii = 0
For ii = 1 To 22
SendKeys ii & "{down}", True
Call Timer40
Next ii
Call Move_Cursor_to2
SendMausklick MOUSE_LEFT
SendMausklick MOUSE_LEFT
Call Timer1000
SendKeys "{F2}", True
Call Timer750
SendKeys "%s", True
If GetHandleFromPartialCaption(lhWndP, "Mustermappe.xlsm - Excel") = True Then
SetForegroundWindow lhWndP
End If
'AppActivate ThisWorkbook.Name
'Application.WindowState = xlMaximized
End Sub
Sub Move_Cursor_to()
Dim x As Long, y As Long, n As Long
x = 600
y = 270
n = SetCursorPos(x, y)
End Sub
Sub Move_Cursor_to2()
Dim x As Long, y As Long, n As Long
x = 900
y = 770
n = SetCursorPos(x, y)
End Sub

9
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Drittprogramm fernsteuern
22.11.2022 17:49:16
volti
Hallo Chris,
falls noch Bedarf besteht, hier noch ein Vorschlag zur Optimierung. Konnte ich aber leider in Ermangelung einer Testdatei nicht umfänglich testen.
Du kannst da deutlich code einsparen. So reicht es z.B. aus, statt zweier Mausklicks Down und Up das in einem zu machen. Außerdem brauchst Du ja nur den Linksklick.
Kann vielleicht noch mehr weg.
Die Ermittlung des Drittfensterhandles kann auch etwas schlanker ausfallen. Statt dessen sollte lieber vor jedem Click oder Sendkey das Drittfenster in den Vordergrund gesetzt werden. Dann kann sich da auch kein anderes Fenster vorschieben.
Die Timer-Subs habe ich durch Sleep ersetzt.
Keyboard-Event und SendKeys machen übrigens das Gleiche. Aber da habe ich nichts dran gemacht.
Kannst Du ja mal ausprobieren.
PS: Aufgrund Deiner angegebenen Version habe ich den Code für 32/64-Bit umgeschrieben.
Code:


Option Explicit Private Declare PtrSafe Function FindWindowA Lib "user32" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function GetWindowTextA Lib "user32" ( _ ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long Private Declare PtrSafe Function GetWindowTextLengthA Lib "user32" ( _ ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long Private Declare PtrSafe Sub keybd_event Lib "user32" ( _ ByVal bVk As Byte, ByVal bScan As Byte, _ ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr) Private Declare PtrSafe Sub mouse_event Lib "user32" ( _ ByVal dwFlags As Long, ByVal dx As Long, _ ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As LongPtr) Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Const KEYUP = &H2 Dim mhWnd As LongPtr Sub Mausklick(mCX As Long, mCY As Long, Optional iButton As Long) ' Führt Mausklick an gewünschter Position durch If mhWnd = 0 Then Exit Sub ' Kein Handle, Fehler=>raus SetForegroundWindow mhWnd ' Drittfenster in den Vordergrund SetCursorPos mCX, mCY ' Klick-Position setzen Select Case iButton ' Buttoncode ermitteln Case 0: iButton = &H6 ' LEFT ' MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP Case 1: iButton = &H60 ' MIDDLE ' MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP Case 2: iButton = &H18 ' RIGHT ' MOUSEEVENTF_MIDDLEDOWN Or MOUSEEVENTF_MIDDLEUP End Select mouse_event iButton, 0, 0, 0, 0 ' Maus-Button klicken Sleep 50 ' Zur Sicherheit etwas warten End Sub Sub SendeTaste(sText As String, Optional iWait As Long) ' Sendet Tastenanschläge an das Vordergrundfenster If mhWnd = 0 Then Exit Sub If iWait > 0 Then Sleep iWait SendKeys "x", True End Sub Private Function GetHandleFromPartialCaption(ByVal sCaption As String) As LongPtr ' Ermittelt das Handle des gesuchten Fensters Dim hWnd As LongPtr, sStr As String hWnd = FindWindowA(vbNullString, vbNullString) Do While hWnd <> 0 sStr = String(GetWindowTextLengthA(hWnd) + 1, Chr$(0)) GetWindowTextA hWnd, sStr, Len(sStr) sStr = Left$(sStr, Len(sStr) - 1) If InStr(1, sStr, sCaption) > 0 Then GetHandleFromPartialCaption = hWnd Exit Do End If hWnd = GetWindow(hWnd, 2) ' 2 = GW_HWNDNEXT Loop End Function Sub DP() Dim i As Integer mhWnd = GetHandleFromPartialCaption("Drittprogramm") If mhWnd = 0 Then Exit Sub ' Kein Handle Fehler=>raus SetForegroundWindow mhWnd Call keybd_event(91, 0, 0, 0) 'Windows Taste Call keybd_event(38, 0, 0, 0) 'UP Call keybd_event(91, 0, KEYUP, 0) Call keybd_event(38, 0, KEYUP, 0) SendeTaste "x" SendeTaste "%v" SendeTaste "s", 40 SendeTaste "a", 40 For i = 1 To 6 SendeTaste (i & "+^{RIGHT}"), 40 Next i Mausklick 600, 270 ' Linksklick an Position For i = 1 To 22 SendeTaste "{down}", 40 Next i Mausklick 900, 770 ' Linksklick an Position Mausklick 900, 770 ' Linksklick an Position, 2 mal? SendeTaste "{F2}", 1000 SendeTaste "%s", 750 End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz

Anzeige
AW: Drittprogramm fernsteuern
22.11.2022 18:04:14
volti
Hallo,
ein Update. Es war noch eine Unschärfe drin.
Code:


Option Explicit Private Declare PtrSafe Function FindWindowA Lib "user32" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function GetWindowTextA Lib "user32" ( _ ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long Private Declare PtrSafe Function GetWindowTextLengthA Lib "user32" ( _ ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long Private Declare PtrSafe Sub keybd_event Lib "user32" ( _ ByVal bVk As Byte, ByVal bScan As Byte, _ ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr) Private Declare PtrSafe Sub mouse_event Lib "user32" ( _ ByVal dwFlags As Long, ByVal dx As Long, _ ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As LongPtr) Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Const KEYUP = &H2 Dim mhWnd As LongPtr Sub Mausklick(mCX As Long, mCY As Long, Optional iButton As Long) ' Führt Mausklick an gewünschter Position durch If mhWnd = 0 Then Exit Sub ' Kein Handle, Fehler=>raus SetForegroundWindow mhWnd ' Drittfenster in den Vordergrund SetCursorPos mCX, mCY ' Klick-Position setzen Select Case iButton ' Buttoncode ermitteln Case 0: iButton = &H6 ' LEFT ' MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP Case 1: iButton = &H60 ' MIDDLE ' MOUSEEVENTF_MIDDLEDOWN Or MOUSEEVENTF_MIDDLEUP Case 2: iButton = &H18 ' RIGHT ' MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP End Select mouse_event iButton, 0, 0, 0, 0 ' Maus-Button klicken Sleep 50 ' Zur Sicherheit etwas warten End Sub Sub SendeTaste(sText As String, Optional iWait As Long) ' Sendet Tastenanschläge an das Vordergrundfenster If mhWnd = 0 Then Exit Sub If iWait > 0 Then Sleep iWait SendKeys sText, True End Sub Private Function GetHandleFromPartialCaption(ByVal sCaption As String) As LongPtr ' Ermittelt das Handle des gesuchten Fensters Dim hWnd As LongPtr, sStr As String hWnd = FindWindowA(vbNullString, vbNullString) Do While hWnd <> 0 sStr = String(GetWindowTextLengthA(hWnd) + 1, Chr$(0)) GetWindowTextA hWnd, sStr, Len(sStr) sStr = Left$(sStr, Len(sStr) - 1) If InStr(1, sStr, sCaption) > 0 Then GetHandleFromPartialCaption = hWnd Exit Do End If hWnd = GetWindow(hWnd, 2) ' 2 = GW_HWNDNEXT Loop End Function Sub DP() Dim i As Integer mhWnd = GetHandleFromPartialCaption("Drittprogramm") If mhWnd = 0 Then Exit Sub ' Kein Handle Fehler=>raus SetForegroundWindow mhWnd Call keybd_event(91, 0, 0, 0) 'Windows Taste Call keybd_event(38, 0, 0, 0) 'UP Call keybd_event(91, 0, KEYUP, 0) Call keybd_event(38, 0, KEYUP, 0) SendeTaste "x" SendeTaste "%v" SendeTaste "s", 40 SendeTaste "a", 40 For i = 1 To 6 SendeTaste (i & "+^{RIGHT}"), 40 Next i Mausklick 600, 270 ' Linksklick an Position For i = 1 To 22 SendeTaste "{down}", 40 Next i Mausklick 900, 770 ' Linksklick an Position Mausklick 900, 770 ' Linksklick an Position, 2 mal? SendeTaste "{F2}", 1000 SendeTaste "%s", 750 End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz

Anzeige
AW: Drittprogramm fernsteuern
23.11.2022 06:20:50
Chris
Hallo Volti,
danke für das Makro und die Erklärungen, die grundsätzlich funktionieren.
Ich habe erst nach meinem Post bemerkt, dass ein Mausklick nicht nötig ist und das Drittprogramm sich nur über Tasten steuern lässt.
Den Mauszeiger zu positionieren hat den Nachteil, dass bei einer Änderung der Bildschirmauflösung die Koordinaten nicht mehr stimmen und angepasst werden müssen...
Deshlab versuche ich es ausschließlich per Tasten.
Folgendes habe ich nun umgesetzt, siehe unten.
Frage:
Weshalb ist eine Verzögerung überhaupt nötig? Der Bildschirmaktualisierung wegen? Die Zeilen
For i = 1 To 30
SendeTaste "{ENTER}", 45
Next i
senden 30 Mal die Enter Taster. Bei manueller Bedienung muss man nur 21 Mal die Enter-Taste betätigen, nicht 30 Mal.
Stelle ich auf 21 innerhalb der Schleife um, kommt es zu falschen Ergebnissen bei der Bedienung des Drittprogramms.
Am Ende wechselt das Makro nicht immer automatisch zu Excel zurück, der Paste-Vorgang klappt jedoch insofern der Makro das Drittprogramm richtig durchläuft.
Nach dem Pastevorgang sind die Zellen alle grau selektiert. Wie bekomme ich dies weg? Application.cutCopyMode=false/true funktioniert nicht.
Viele Grüße
Chris

Option Explicit
Private Declare PtrSafe Function FindWindowA Lib "user32" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetWindowTextA Lib "user32" ( _
ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare PtrSafe Function GetWindowTextLengthA Lib "user32" ( _
ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr
Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Private Declare PtrSafe Sub keybd_event Lib "user32" ( _
ByVal bVk As Byte, ByVal bScan As Byte, _
ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
Private Declare PtrSafe Sub mouse_event Lib "user32" ( _
ByVal dwFlags As Long, ByVal dx As Long, _
ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As LongPtr)
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Const KEYUP = &H2
Dim mhWnd As LongPtr
Sub Mausklick(mCX As Long, mCY As Long, Optional iButton As Long)
' Führt Mausklick an gewünschter Position durch
If mhWnd = 0 Then Exit Sub            ' Kein Handle, Fehler=>raus
SetForegroundWindow mhWnd             ' Drittfenster in den Vordergrund
SetCursorPos mCX, mCY                 ' Klick-Position setzen
Select Case iButton                   ' Buttoncode ermitteln
Case 0: iButton = &H6   ' LEFT        ' MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP
Case 1: iButton = &H60  ' MIDDLE      ' MOUSEEVENTF_MIDDLEDOWN Or MOUSEEVENTF_MIDDLEUP
Case 2: iButton = &H18  ' RIGHT       ' MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP
End Select
mouse_event iButton, 0, 0, 0, 0       ' Maus-Button klicken
Sleep 50                              ' Zur Sicherheit etwas warten
End Sub
Sub SendeTaste(sText As String, Optional iWait As Long)
' Sendet Tastenanschläge an das Vordergrundfenster
If mhWnd = 0 Then Exit Sub
If iWait > 0 Then Sleep iWait
SendKeys sText, True
End Sub
Private Function GetHandleFromPartialCaption(ByVal sCaption As String) As LongPtr
' Ermittelt das Handle des gesuchten Fensters
Dim hWnd As LongPtr, sStr As String
hWnd = FindWindowA(vbNullString, vbNullString)
Do While hWnd  0
sStr = String(GetWindowTextLengthA(hWnd) + 1, Chr$(0))
GetWindowTextA hWnd, sStr, Len(sStr)
sStr = Left$(sStr, Len(sStr) - 1)
If InStr(1, sStr, sCaption) > 0 Then
GetHandleFromPartialCaption = hWnd
Exit Do
End If
hWnd = GetWindow(hWnd, 2)      ' 2 = GW_HWNDNEXT
Loop
End Function
Sub DP()
Dim i As Integer
ActiveSheet.UsedRange.ClearContents
mhWnd = GetHandleFromPartialCaption("Drittprogramm")
If mhWnd = 0 Then Exit Sub              ' Kein Handle Fehler=>raus
SetForegroundWindow mhWnd
Call keybd_event(91, 0, 0, 0) 'Windows Taste
Call keybd_event(38, 0, 0, 0) 'UP
Call keybd_event(91, 0, KEYUP, 0)
Call keybd_event(38, 0, KEYUP, 0)
SendeTaste "x"
SendeTaste "%v"
SendeTaste "s", 40
SendeTaste "a", 40
For i = 1 To 6
SendeTaste (i & "+^{RIGHT}"), 40
Next i
'Mausklick 600, 270            ' Linksklick an Position
SendKeys "{ENTER}", 40
For i = 1 To 30
SendeTaste "{ENTER}", 45
Next i
SendKeys "^{ENTER}", 40
' Mausklick 900, 770            ' Linksklick an Position
'Mausklick 900, 770            ' Linksklick an Position, 2 mal?
SendeTaste "{F2}", 1000
SendeTaste "%s", 750
AppActivate "Excel"
ActiveSheet.Range("A1").Select
ActiveSheet.Paste
With ActiveSheet
.Range("A1:Z1").Font.Bold = True
.Range("A1:Z1").Font.Size = 16
.UsedRange.HorizontalAlignment = xlCenter
.Columns.AutoFit
End With
End Sub

Anzeige
AW: Drittprogramm fernsteuern
23.11.2022 06:38:23
Chris
Hallo nochmal
Aktualsierung:
Mir ist noch etwas aufgefallen: Statt die Enter Taste funktioniert auch die Bild-Runter Taste. Das ist wesentlich genauer. Folgendes funktioniert nun, siehe unten.
Fragen bleiben: Wie mache ich den Rahmen weg, weshalb ist der Timer nötig, Optischer Wechsel zu Excel funktioniert nicht immer, kann man noch etwa verbessern?

Option Explicit
Private Declare PtrSafe Function FindWindowA Lib "user32" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetWindowTextA Lib "user32" ( _
ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare PtrSafe Function GetWindowTextLengthA Lib "user32" ( _
ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr
Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Private Declare PtrSafe Sub keybd_event Lib "user32" ( _
ByVal bVk As Byte, ByVal bScan As Byte, _
ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
Private Declare PtrSafe Sub mouse_event Lib "user32" ( _
ByVal dwFlags As Long, ByVal dx As Long, _
ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As LongPtr)
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Const KEYUP = &H2
Dim mhWnd As LongPtr
Sub Mausklick(mCX As Long, mCY As Long, Optional iButton As Long)
' Führt Mausklick an gewünschter Position durch
If mhWnd = 0 Then Exit Sub            ' Kein Handle, Fehler=>raus
SetForegroundWindow mhWnd             ' Drittfenster in den Vordergrund
SetCursorPos mCX, mCY                 ' Klick-Position setzen
Select Case iButton                   ' Buttoncode ermitteln
Case 0: iButton = &H6   ' LEFT        ' MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP
Case 1: iButton = &H60  ' MIDDLE      ' MOUSEEVENTF_MIDDLEDOWN Or MOUSEEVENTF_MIDDLEUP
Case 2: iButton = &H18  ' RIGHT       ' MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP
End Select
mouse_event iButton, 0, 0, 0, 0       ' Maus-Button klicken
Sleep 50                              ' Zur Sicherheit etwas warten
End Sub
Sub SendeTaste(sText As String, Optional iWait As Long)
' Sendet Tastenanschläge an das Vordergrundfenster
If mhWnd = 0 Then Exit Sub
If iWait > 0 Then Sleep iWait
SendKeys sText, True
End Sub
Private Function GetHandleFromPartialCaption(ByVal sCaption As String) As LongPtr
' Ermittelt das Handle des gesuchten Fensters
Dim hWnd As LongPtr, sStr As String
hWnd = FindWindowA(vbNullString, vbNullString)
Do While hWnd  0
sStr = String(GetWindowTextLengthA(hWnd) + 1, Chr$(0))
GetWindowTextA hWnd, sStr, Len(sStr)
sStr = Left$(sStr, Len(sStr) - 1)
If InStr(1, sStr, sCaption) > 0 Then
GetHandleFromPartialCaption = hWnd
Exit Do
End If
hWnd = GetWindow(hWnd, 2)      ' 2 = GW_HWNDNEXT
Loop
End Function
Sub DP()
Dim i As Integer
ActiveSheet.UsedRange.ClearContents
mhWnd = GetHandleFromPartialCaption("Drittprogramm")
If mhWnd = 0 Then Exit Sub              ' Kein Handle Fehler=>raus
SetForegroundWindow mhWnd
Call keybd_event(91, 0, 0, 0) 'Windows Taste
Call keybd_event(38, 0, 0, 0) 'UP
Call keybd_event(91, 0, KEYUP, 0)
Call keybd_event(38, 0, KEYUP, 0)
SendeTaste "x"
SendeTaste "%v"
SendeTaste "s", 40
SendeTaste "a", 40
For i = 1 To 6
SendeTaste (i & "+^{RIGHT}"), 40
Next i
SendeTaste "{ENTER}", 100
SendeTaste "{ENTER}", 1000
SendeTaste "{PGDN}", 100
SendeTaste "^{ENTER}", 100
SendeTaste "{F2}", 1000
SendeTaste "%s", 750
AppActivate "Excel"
ActiveSheet.Range("A1").Select
ActiveSheet.Paste
With ActiveSheet
.Range("A1:Z1").Font.Bold = True
.Range("A1:Z1").Font.Size = 16
.UsedRange.HorizontalAlignment = xlCenter
.Columns.AutoFit
'SendMausklick MOUSE_LEFT
End With
End Sub

Anzeige
AW: Drittprogramm fernsteuern
23.11.2022 08:49:40
volti
Hallo Chris,
wenn Du die Mausaktionen nicht benötigst, kann der code dafür ja auch weg.
Anstatt der AppActivate "Excel" kannst Du Excel auch mit SetForegroundWindow in den Vordergrund holen....
Ansonsten kenne ich weder das Drittprogramm, noch die Vorgänge die nach Deiner Intention nach zu machen sind und auch keine Reaktionen des Drittprogramms.
Damit kann ich Deine Fragen leider auch nicht beantworten.
Den Timer habe ich nur eingebaut, weil ich anhand Deines Codes annahm, dass dort Zeitverzug sein muss.
Aber, ich steuere auch oft über einen "virtuellen Mitarbeiter" Drittprogramme, auch Web-Sites. Die Seitenaufbauten verzögern sich häufig oder Reaktionen des Drittprogramms dauern schon mal ein paar Millisekunden. Im Gegensatz zum realen User ist so ein Programm halt sehr schnell, so dass eine gewisse Pause nicht schaden kann.
Ob das bei Dir nötig ist, kann ich Dir nicht sagen. Im Übrigen kann ich ohne Testumgebung auch keine konkreten Aussagen machen.
Im Bestcase reicht Dir ja vielleicht auch die Variante von lapos.
Code:


Option Explicit Private Declare PtrSafe Function FindWindowA Lib "user32" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function GetWindowTextA Lib "user32" ( _ ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long Private Declare PtrSafe Function GetWindowTextLengthA Lib "user32" ( _ ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Long Private Declare PtrSafe Sub keybd_event Lib "user32" ( _ ByVal bVk As Byte, ByVal bScan As Byte, _ ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr) Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Const KEYUP = &H2 Dim mhWnd As LongPtr Sub SendeTaste(sText As String, Optional iWait As Long) ' Sendet Tastenanschläge an das Vordergrundfenster If mhWnd = 0 Then Exit Sub If iWait > 0 Then Sleep iWait SendKeys sText, True End Sub Private Function GetHandleFromPartialCaption(ByVal sCaption As String) As LongPtr ' Ermittelt das Handle des gesuchten Fensters Dim hWnd As LongPtr, sStr As String hWnd = FindWindowA(vbNullString, vbNullString) Do While hWnd <> 0 sStr = String(GetWindowTextLengthA(hWnd) + 1, Chr$(0)) GetWindowTextA hWnd, sStr, Len(sStr) sStr = Left$(sStr, Len(sStr) - 1) If InStr(1, sStr, sCaption) > 0 Then GetHandleFromPartialCaption = hWnd Exit Do End If hWnd = GetWindow(hWnd, 2) ' 2 = GW_HWNDNEXT Loop End Function Sub DP() Dim i As Integer ActiveSheet.UsedRange.ClearContents mhWnd = GetHandleFromPartialCaption("Drittprogramm") If mhWnd = 0 Then Exit Sub ' Kein Handle Fehler=>raus SetForegroundWindow mhWnd Call keybd_event(91, 0, 0, 0) 'Windows Taste Call keybd_event(38, 0, 0, 0) 'UP Call keybd_event(91, 0, KEYUP, 0) Call keybd_event(38, 0, KEYUP, 0) SendeTaste "x" SendeTaste "%v" SendeTaste "s", 40 SendeTaste "a", 40 For i = 1 To 6 SendeTaste (i & "+^{RIGHT}"), 40 Next i SendeTaste "{ENTER}", 100 SendeTaste "{ENTER}", 1000 SendeTaste "{PGDN}", 100 SendeTaste "^{ENTER}", 100 SendeTaste "{F2}", 1000 SendeTaste "%s", 750 ' AppActivate "Excel" SetForegroundWindow Application.hWnd ActiveSheet.Range("A1").Select ActiveSheet.Paste With ActiveSheet .Range("A1:Z1").Font.Bold = True .Range("A1:Z1").Font.Size = 16 .UsedRange.HorizontalAlignment = xlCenter .Columns.AutoFit End With End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz

Anzeige
AW: Drittprogramm fernsteuern
23.11.2022 10:03:40
Volti
Nachtrag:
Bei den Sendkeys braucht man die Wartezeit m.E. eher nicht, da die Angabe True ja auf die Verarbeitung wartet.
Gruß KH
AW: Drittprogramm fernsteuern
23.11.2022 14:09:28
Chris
ok, danke. hab nun die Änderungen eingebaut, und es läuft. Gruß Chris
AW: Drittprogramm fernsteuern
22.11.2022 18:03:02
Lapos
Hallo Chris,
ich löse das bei mir so..

Sub app()
AppActivate "FireFox"
SendKeys "{TAB 18}", True
SendKeys "{DOWN}", True
SendKeys "{TAB}", True
SendKeys "^(V)", True
SendKeys "{TAB}", True
SendKeys "{ }", True
SendKeys "{TAB}", True
SendKeys "{DOWN 2}", True
SendKeys "{TAB}", True
SendKeys "{ }", True
SendKeys "{TAB}", True
Application.Wait (Now() + TimeValue("00:00:05"))
SendKeys "{TAB}", True
SendKeys "{ }", True
AppActivate "Excel"
End Sub
Damit aktiviere ich Firefox und wenn ich durch bin aktiviere ich wieder Excel.
VG
Lapos
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige