Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Fokus nach Öffnen eines Links zurückerhalten

Begonnen von hajott, November 23, 2024, 15:11:09

⏪ vorheriges - nächstes ⏩

hajott

Hallo Wissende,

ich habe eine Tabelle mit einer Liste von Wertpapieren (aktuell 17) und in einer anderen Tabelle verwalte ich die Kurse mit Kursdatum.

Um die Kurserfassung zu vereinfachen, habe ich ein kleines Formular gebastelt, welches mir alle Wertpapiere nacheinander anzeigt. Über ein Textfeld gebe ich dann Kurs und Kursdatum ein. Um nicht jedes Mal suchen zu müssen, öffnet mir Form_Current für jedes Wertpapier eine Internetseite, wo ich den Kurs ablesen und übertragen kann. So weit, so klappt.
Allerdings verliert Access durch Application.FollowHyperlink den Fokus, und ich muss nach Öffnen des Links immer wieder ins Fenster klicken, um ihn zurückzuholen. Ich habe auch schon Forms!Kurserfassung!txtKurs.SetFocus probiert, sowohl vor, aus auch nach dem FollowHyperlink. Ich bekomme den Fokus nicht zurück.

Habt ihr eine Idee, was ich noch probieren könnte?

Vielen Dank und viele Grüße

Hans-Jürgen

Knobbi38

Hallo Hans-Jürgen,

mit FollowHyperlink gibst du nicht nur den Fokus ab, sondern du veranlasst Windows zu einem Taskwechsel, d.h. ein anderer Prozess bekommt die CPU-Zeit zugeteilt, darauf hat das Access überhaupt keinen Einfluss. Folge ist, daß in dem Moment der VBA-Code noch nicht mal mehr abgearbeitet wird.

Um den Fokus wieder zu erhalten, müßtest du einen API Timer starten und dann im Timer-Eventhandler per API Funktionen einen Taskwechsel herbeiführen, so daß dem Access Prozess wieder CPU-Zeit zugeteilt wird und den Fokus erhält.

Ich weiß jetzt nicht, wie du deine Kurse ermittelst, aber vielleicht können die Kurse ja auch per REST-API ermittelt werden, dann hättest du so ein Problem nicht und müsstest auch nicht per Hand die Kurse übernehmen.

Gruß
Knobbi38


PhilS

Zitat von: hajott am November 23, 2024, 15:11:09Ich habe auch schon Forms!Kurserfassung!txtKurs.SetFocus probiert, sowohl vor, aus auch nach dem FollowHyperlink. Ich bekomme den Fokus nicht zurück.
Ein .SetFocus auf Formular- oder Steuerelement-Ebene funktioniert nicht, weil es nur innerhalb der Anwendung wirkt, aber das Access Hauptfenster in diesem Moment nicht den Focus hat.

Ein weiteres und deutlich gravierenderes Problem ist, dass die FollowHyperlink-Methode asynchron abläuft. Sie löst nur den Start des Browsers bzw. dass Öffnen eines weiteren Fensters aus. Dann läuft der VBA-Code weiter, der Focus wird aber erst einen Moment später auf das Browserfenster verschoben, wenn das Browserfenster vollständig geöffnet ist.

Der Timer-Vorschlag von @knobbi38 geht in die richtige Richtung, ist aber letztendlich genauso unzureichend wie der nachfolgende, etwas vereinfachte, Ansatz.

Im Prinzip funktioniert Folgendes (manchmal):
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Boolean

Private Sub Command0_Click()

    Application.FollowHyperlink Me.txtUrl.value

    Sleep 1000

    SetForegroundWindow Application.hWndAccessApp
   
 End Sub

Hier hat man ein Timing-Problem, weil man nicht wissen kann wie lange der Browser zum Start benötigt. Bei mir, mit Firefox, funktioniert das obige relativ zuverlässig, wenn der Browser bereits geöffnet ist und nur ein weiterer zusätzlicher Browser-Tab geöffnet wird. Wenn der Browser komplett neu gestartet werden muss, reicht die Zeit nicht aus. Außerdem sind bei einem Browserstart die Varianzen der Dauer relativ groß.

Wenn man das "besser" machen wollte, müsste man den Start des Browsers überwachen und den Focus zurücksetzen, wenn er fertig ist. - Das ist aber eine eher komplizierte Angelegenheit.


Für den konkreten Einsatzzweck würde ich auch eher versuchen diese komplette Bildschirmabtipperei zu eliminieren und die Kurse automatisch zu importieren.

 
Zitat von: knobbi38 am November 23, 2024, 17:55:20Folge ist, daß in dem Moment der VBA-Code noch nicht mal mehr abgearbeitet wird.
Diese Aussage halte ich (nicht nur) bei modernen Multi-Core Prozessoren für fragwürdig.

Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

andyfau

Hallo,
ich weiß nicht ob es eine gute Lösung ist die aktuellen Kurse von eine Website einzulesen, weil diese sich doch relativ häufig ändern und so schnell mal was nicht mehr passt. Die meisten Banken und Onlinebroker stellen doch heute eine Exportfunktion als csv, txt, oder xls zur Verfügung. Diese lassen sich ja dann über einen gespeicherten Import sehr einfach in eine Kurstabelle der Datenbank importieren.

Beste Grüße
Andreas
Beste Grüße
Andreas

Knobbi38

Hallo Phil,

Zitat von: PhilS am November 23, 2024, 19:26:28
ZitatFolge ist, daß in dem Moment der VBA-Code noch nicht mal mehr abgearbeitet wird.
Diese Aussage halte ich (nicht nur) bei modernen Multi-Core Prozessoren für fragwürdig.
Warum fragwürdig? Bis jetzt unterstützt VBA nur Singlethreading und das Access mehrere Prozesse/Tasks auf mehrere CPUs (Cores) verteilt, wäre mir neu. Es ist egal, wie viele CPUs (Cores) vorhanden sind, sobald der Windows Scheduler einen neuen Prozess startet, gibt der aktuelle Prozess seine Zeitscheibe ab und befindet sich dann im Wartezustand, bis dieser vom Scheduler neu aktiviert wird, d.h. der neue Prozess wird gestartet und Access läuft, sobald es die Zuteilung wieder bekommt, asynchron weiter. Das geht allerdings normalerweise so schnell, daß ein Anwender davon nichts mitbekommt und es so aussieht, als ob alles quasi parallel abläuft.
Mit Hilfe der API-Funktion Sleep() kann man übrigens auch per VBA diese Zeitscheibe sofort beenden und abgeben, so daß ein andere Prozess/Thread vom Scheduler direkt neu zugeteilt wird.

Vielleicht könnte man mit einer API WaitForXXX-Funktion auf eine bestimmte Aktion des Browsers warten. Das wäre aber auch nur eine Lösung für das Symptom.

Zitat von: PhilS am November 23, 2024, 19:26:28Für den konkreten Einsatzzweck würde ich auch eher versuchen diese komplette Bildschirmabtipperei zu eliminieren und die Kurse automatisch zu importieren.
Das wäre dann sicherlich ein besser Lösungsansatz, Stichwort Rest-API o.ä.

Grüße
Ulrich

   


hajott

Hallo zusammen,

herzlichen Dank für alle Antworten. Ich würde gern bei der Anzeige der Webseite bleiben (also nicht importieren), weil ich mir neben dem Kurs auch noch andere Sachen ansehe (z.B. bei Fonds, ob sich hier die Assetverteilung geändert hat)

Die Variante von Phil hat leider bei mir nicht funktioniert, aber das Zurückholen des Fokus ist ja nicht wirklich aufwändig, ich dachte, ich könne mir diesen Klick auch sparen.

VIele Grüße

Hans-Jürgen

Josef P.

Hallo!

Nur so als Gedanke: Was wäre, wenn man die Seite in einem Web-Browser-Control öffnet?

Gruß
Josef