Problem mit Sendkeys() in Word/Excel

Anfängerfragen zum Programmieren mit PureBasic.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Problem mit Sendkeys() in Word/Excel

Beitrag von Rebon »

Hallo!
Das Programm an dem ich gerade Arbeite schreibt
mit Hilfe der Funktion SendKeys(), Strings in eine
zuvor neu erstellte und mit MS Word geöffnete .doc Datei.
Diese Datei beinhaltet eine Exceltabelle, in die ich
ebenfalls mit SendKeys() schreibe.
Das merkwürdige hierbei ist, das ohne ersichtlichen Grund
und scheinbar zufällig mein Programm
in der zweiten Zelle dieser Tabelle mit dem schreiben der Strings abbricht oder auch nicht.
Wenn ich vor dem SendKeys()-Befehl für die zweite Zelle
ein Delay(300) in meinem Code schreibe, funktioniert
das schreiben in die zweite Zelle immer einwandfrei.
Nun Frage ich mich, wieso nicht die erste oder dritte Zelle?
Für Hilfen und Denkanstöße wäre ich sehr dankbar! :wink:

Rechts(0) = Den Corsur in Word eine Position nach rechts
Links(0) = nach links
Runter(0) = nach unten

Auszug aus meinem Programm:

Code: Alles auswählen

Procedure SendKey(Key.s)
VK.w = VkKeyScanEx_(Asc(Key),GetKeyboardLayout_(0))
If VK = -1
   ProcedureReturn
EndIf
If MapVirtualKey_(VK, 2) = 0
   Extended.l = #KEYEVENTF_EXTENDEDKEY
   Scan.l = MapVirtualKey_(VK, 0)
Else
   Extended = 0
   Scan = 0
EndIf
Shift.l = VK & $100
Ctrl.l = VK & $200
Alt.l = VK & $400
If Shift
keybd_event_(#VK_SHIFT, 0, 0, 0)
EndIf
If Ctrl
keybd_event_(#VK_CONTROL, 0, 0, 0)
EndIf
If Alt
keybd_event_(#VK_MENU, 0, 0, 0)
EndIf
VK & $FF
keybd_event_(VK, Scan, Extended, 0)
keybd_event_(VK, Scan, #KEYEVENTF_KEYUP | Extended, 0)
If Shift
keybd_event_(#VK_SHIFT, 0, #KEYEVENTF_KEYUP, 0)
EndIf
If Ctrl
keybd_event_(#VK_CONTROL, 0, #KEYEVENTF_KEYUP, 0)
EndIf
If Alt
keybd_event_(#VK_MENU, 0, #KEYEVENTF_KEYUP, 0)
EndIf
EndProcedure

Procedure SendKeys(String.s)
  For Letter.l = 1 To Len(String)
       SendKey(Mid(String, Letter, 1))
  Next
EndProcedure

Procedure Rechts(RIGHT)
VK.w = #VK_RIGHT
Scan.l = MapVirtualKey_(#VK_RIGHT, 0)
VK & $FF
keybd_event_(VK, Scan, #KEYEVENTF_EXTENDEDKEY, 0)
keybd_event_(VK, Scan, #KEYEVENTF_KEYUP | #KEYEVENTF_EXTENDEDKEY, 0)        
EndProcedure

Procedure Links(LEFT)
VK.w = #VK_LEFT
Scan.l = MapVirtualKey_(#VK_LEFT, 0)
VK & $FF
keybd_event_(VK, Scan, #KEYEVENTF_EXTENDEDKEY, 0)
keybd_event_(VK, Scan, #KEYEVENTF_KEYUP | #KEYEVENTF_EXTENDEDKEY, 0)        
EndProcedure

Procedure Runter(DOWN)
VK.w = #VK_DOWN
Scan.l = MapVirtualKey_(#VK_DOWN, 0)
VK & $FF
keybd_event_(VK, Scan, #KEYEVENTF_EXTENDEDKEY, 0)
keybd_event_(VK, Scan, #KEYEVENTF_KEYUP | #KEYEVENTF_EXTENDEDKEY, 0)
EndProcedure

keybd_event_(#VK_MENU,0,0,0)
keybd_event_(#VK_MENU, 0, #KEYEVENTF_KEYUP, 0)
SendKeys("bbb")
Delay(1000)

ForEach Liste()

If CountString(Liste(), "x") > 0
   Stueckzahl.q = ValQ(ReplaceString(Liste(), "x", ""))
   SendKeys(StrQ(Stueckzahl.q))
Else
   SendKeys(Liste())
EndIf

Rechts(0)
NextElement(Liste())

;DAS NÄCHSTE SENDKEYS SCHREIBT IN DIE ZWEITE 
;ZELLE UND DAS PROGRAMM BRICHT OHNE DELAY 
;IMMER MAL WIEDER AB ODER AUCH NICHT!

Delay(300)
SendKeys(Liste())
Rechts(0)
NextElement(Liste())
SendKeys(Liste())
Rechts(0)
SendKeys("C")
Rechts(0)
NextElement(Liste())
SendKeys(Liste())
Rechts(0)
NextElement(Liste())
If CountString(Liste(), ",") > 0 
   Einzelpreis.q = ValQ(ReplaceString(Liste(), ",", ""))
   SendKeys(Liste())
EndIf
Rechts(0)
NextElement(Liste())
SendKeys(Liste())
NextElement(Liste())
If GetGadgetState(16) = 1
Rechts(0)
Einzelpreis.q * Stueckzahl.q
Summe.q + Einzelpreis.q
Gesamtpreis$ = ReplaceString(StrQ(Einzelpreis.q), Right(StrQ(Einzelpreis.q), 2), "," + Right(StrQ(Einzelpreis.q), 2))
SendKeys(Gesamtpreis$) 
Links(0)
EndIf
For z = 0 To 5
Links(0)
Next z
Runter(0)
Next
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Ich glaube ich habe die Ursache gefunden.
Die zweite Zelle ist die erste, in die mehr als ein Zeichen
geschrieben werden.
Anscheinend verkraftet die Funktion SendKeys(), in einer
größeren Schleife,
mehr als ein oder zwei Zeichen nicht.
Ich hab jetzt versucht sie einzeln mit der
Unterprozedur von SendKeys(), SendKey() einzulesen:

Code: Alles auswählen

 Artiknr.s = Liste()
 For u.l = 1 To Len(Artiknr)
      SendKey(Mid(Artiknr, u, 1))
 Next
Leider ohne Erfolg.
Versuche jetzt mal die SendKey()-Funktion umzuschreiben,
da ja die Links(0)-Funktion mit kleineren Schleifen funktioniert.
Allerdings verstehe ich immer noch nicht,
warum beim zweiten oder dritten Durchlauf der Schleife, das
Programm nie in der zweiten Zelle abbricht.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Soll das eine richtige Anwendung werden?
Wenn ja, dann such mal nach einer anderen Lösung als SendKey, damit
wirste nicht weit kommen. Sobald z.B. Word den Fokus verliert erhält
sonstwer die Tastendrücke und dabei passieren dann richtig lustige Sachen.
Ist nicht ungefährlich, bzw. ich hab wegen solchem Mist schon öfters mal
neustarten müssen.

Guck Dir lieber COMate von srod an.

Du kannst nicht sicherstellen das die Tastendrücke auch wirklich dort
ankommen, wo Du sie gerne hättest.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> such mal nach einer anderen Lösung als SendKey

+1

... meiner Ansicht nach ist SendKey was für Aprilscherze, nicht für ernsthafte Anwendungen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

ts-soft hat geschrieben: Guck Dir lieber COMate von srod an.
Danke für den Tipp, ts-soft! :allright:
Werde ich sofort machen. :wink:
ts-soft hat geschrieben: Ist nicht ungefährlich, bzw. ich hab wegen solchem Mist schon öfters mal
neustarten müssen.
Stimmt!
Neustarten funktionierte einmal bei mir auch nicht mehr, mußte
den PC ausschalten.
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

Bevor ich anfange Procedures, Prototypes, Constants usw.
aus der COMate.pbi bzw. COMate_Residents.pbi
herauszusuchen, die ich benötige, hab ich noch Fragen:

Ich besitze PureBasic 4.00, erkennt diese
Version alle Befehle die ich benötige, um
in ein Word-Dokument zu schreiben?

Ist es mit diesen möglich in eine
in ein Word-Dokument integrierte Excel-Tabelle
zu schreiben?(Word läuft dann im Kompatibilitätsmodus)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

> Ich besitze PureBasic 4.00
Nicht Upgradeberechtigt?

COMate erfordert PB4.30, für 4.20 ist wohl auch noch eine ältere Version
erhältlich. Upgrade auf PB4.30 ist also sehr ratsam, ansonsten wirste mit
Codes/Libs von anderen kaum Erfolge erzielen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

ts-soft hat geschrieben:> Ich besitze PureBasic 4.00
Nicht Upgradeberechtigt?.
Ich hatte eine Email an Andre Beer geschickt.
Ich müßte ihm das Kaufdatum nennen, keine Ahnung
wann ich es genau gekauft habe.
Und Händler möglicherweise bei Pearl oder SMM.
Auf der Packung steht: C 2007 Fantasie Software,
Master Creating - Vertrieb: dtp entertainment AG usw..
Rebon
Beiträge: 263
Registriert: 20.05.2009 19:13

Beitrag von Rebon »

@ts-soft
Bei deiner SendKeys-Demo, ist das die
Zeile mit dem du den Fokus auf Word richtest?

Code: Alles auswählen

oWScript\Invoke("AppActivate(Title)")
Weil sowas ähnliches mache ich in meinem Programm auch:

Code: Alles auswählen

prog = RunProgram("C:\Programme\Microsoft Office\Office12\WINWORD.EXE", Dateiname$, "C:\AutoWrite\", #PB_Program_Open|#PB_Program_Read|#PB_Program_Write|#PB_Program_Error)
  Delay(4000)
  FensterName$ = Dateiname$ + " - Microsoft Word"
  Handle = FindWindow_(0,FensterName$)
  If Not Handle = GetForegroundWindow_()
  SetForegroundWindow_(Handle)
  EndIf
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Vergiß das mit SendKey einfach, das führt zu keinem nützlichem Ergebnis.

Ansonsten müßtest Du alle Hintergrundanwendungen beenden, den User weit
entfernt von Tastatur und Maus fesseln usw., selbst dann ist es nicht sicher :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten