Seite 1 von 9

Problem mit Sendkeys() in Word/Excel

Verfasst: 01.06.2009 23:16
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

Verfasst: 02.06.2009 14:49
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.

Verfasst: 02.06.2009 14:56
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.

Verfasst: 02.06.2009 15:04
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.

Verfasst: 02.06.2009 15:08
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.

Verfasst: 02.06.2009 17:02
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)

Verfasst: 02.06.2009 17:17
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.

Verfasst: 02.06.2009 17:33
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..

Verfasst: 02.06.2009 18:52
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

Verfasst: 02.06.2009 18:59
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: