Discussion:
FAQ 4.10 ZEILENWECHSEL MIT PFEILTASTEN
(zu alt für eine Antwort)
Werner Ewers
2003-12-17 17:19:51 UTC
Permalink
Hallo,
als ich von der im folgenden zitierten Lösung aus Karl Donaubauers
FAQs
erfuhr, war ich zunächst hoch erfreut über diese Lösung und habe
mehrere Formulare entsprechend umgebaut. Später habe ich jedoch
bemerkt, dass aufgeklappte Kombinationsfelder nun nicht mehr in der
gewünschten Weise funktionieren. Mit den Auf/Ab-Tasten läßt sich nicht
mehr im Kombinationsfeld navigieren, da sofort der Datensatz
gewechselt wird. (In der Datenblattansicht gibt es dieses Problem
nicht; ich vermute deshalb, dass Microsoft über eine tiefergehende
Lösung verfügt.)
Eine Lösung für das Problem könnte darin liegen, die beiden Codezeilen
vom Status eines Kombinationsfeldes, das gerade den Fokus besitzt,
abhängig zu machen.
Läßt sich der Status eines Kombinationsfeldes (aufgeklappt / nicht
aufgeklappt) ermitteln - evtl. unter Zuhilfenahme von API-Funktionen?
(Dieser Status gehört sicherlich nicht zu den einschlägig
veröffentlichten Eigenschaften eines Kombinationsfeldes.)
Gibt es evtl. noch andere Lösungen des in den FAQ genannten Problems,
das die Funktionsweise von Kombinationsfeldern nicht berührt?
Viele Grüße
Werner Ewers


Zitatanfang:
4.10 ZEILENWECHSEL MIT PFEILTASTEN

P r o b l e m
Du möchtest in der Formularansicht mit den Tasten PfeilAuf und PfeilAb
den Datensatz wechseln, ähnlich wie das in der Datenblattansicht oder
in Tabellen und Abfragen möglich ist.

L ö s u n g
Stelle die Eigenschaft "Tastenvorschau" des Formulares auf "Ja" ein.
In das Ereignis "Bei Taste Ab" des Formulares kopierst du folgendes:

On Error Resume Next ' falls 1. oder letzter Datensatz erreicht
If KeyCode = vbKeyDown Then KeyCode = 0: DoCmd.GoToRecord , , acNext
If KeyCode = vbKeyUp Then KeyCode = 0: DoCmd.GoToRecord , , acPrevious
Zitatende
Karl Donaubauer
2003-12-17 17:29:08 UTC
Permalink
Post by Werner Ewers
als ich von der im folgenden zitierten Lösung aus Karl Donaubauers
FAQs
erfuhr, war ich zunächst hoch erfreut über diese Lösung und habe
mehrere Formulare entsprechend umgebaut. Später habe ich jedoch
bemerkt, dass aufgeklappte Kombinationsfelder nun nicht mehr in der
gewünschten Weise funktionieren. Mit den Auf/Ab-Tasten läßt sich nicht
mehr im Kombinationsfeld navigieren, da sofort der Datensatz
gewechselt wird. (In der Datenblattansicht gibt es dieses Problem
nicht; ich vermute deshalb, dass Microsoft über eine tiefergehende
Lösung verfügt.)
Eine Lösung für das Problem könnte darin liegen, die beiden Codezeilen
vom Status eines Kombinationsfeldes, das gerade den Fokus besitzt,
abhängig zu machen.
Läßt sich der Status eines Kombinationsfeldes (aufgeklappt / nicht
aufgeklappt) ermitteln - evtl. unter Zuhilfenahme von API-Funktionen?
...
Joo. s. http://www.mvps.org/access/api/api0052.htm
--
HTH
Karl
********* Ich beantworte keine Access-Fragen per Email. *********
Access-FAQ: http://www.donkarl.com
Datenbankprofis: http://www.dbdev.org
Werner Ewers
2003-12-19 22:03:03 UTC
Permalink
Post by Karl Donaubauer
Post by Werner Ewers
als ich von der im folgenden zitierten Lösung aus Karl Donaubauers
FAQs
erfuhr, war ich zunächst hoch erfreut über diese Lösung und habe
mehrere Formulare entsprechend umgebaut. Später habe ich jedoch
bemerkt, dass aufgeklappte Kombinationsfelder nun nicht mehr in der
gewünschten Weise funktionieren. Mit den Auf/Ab-Tasten läßt sich nicht
mehr im Kombinationsfeld navigieren, da sofort der Datensatz
gewechselt wird. (In der Datenblattansicht gibt es dieses Problem
nicht; ich vermute deshalb, dass Microsoft über eine tiefergehende
Lösung verfügt.)
Eine Lösung für das Problem könnte darin liegen, die beiden Codezeilen
vom Status eines Kombinationsfeldes, das gerade den Fokus besitzt,
abhängig zu machen.
Läßt sich der Status eines Kombinationsfeldes (aufgeklappt / nicht
aufgeklappt) ermitteln - evtl. unter Zuhilfenahme von API-Funktionen?
...
Joo. s. http://www.mvps.org/access/api/api0052.htm
Hallo und vielen Dank,
über den Link (drei Zeilen weiter oben) und einiges Probieren bin ich
auf die gewünschte Lösung gestoßen.

a) Einfügen des folgenden Codes in das Formularereignis 'Bei Taste Ab'

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
On Error goto F
If Not fIsComboOpen() Then
If KeyCode = vbKeyDown Then KeyCode = 0: DoCmd.GoToRecord , , acNext
If KeyCode = vbKeyUp Then KeyCode = 0: DoCmd.GoToRecord , ,
acPrevious
End If

Ende:
Exit Sub

F:
'Falls der erste oder letzte Datensatz erreicht ist, Fehler abfangen
If Err = 2105 Then
Resume Next
Else
M = "Fehler " & Err.Number & " in '" & Me.Name & "." &
"Form_KeyDown"':" & _
vbNewLine & vbNewLine & Err.Description
End If
Resume Ende
End Sub

b) Tastenvorschau des Formulars auf 'Ja' einstellen

c) Kopieren des folgenden Codes in ein Modul z.B. namens 'modComboBox'

Option Compare Database
Option Explicit

'Written Dev Ashish 1999
'http://home.att.net/~dashish/

'******* Code Start *********
' This code was originally written by Dev Ashish.
' It is not to be altered or distributed,
' except as part of an application.
' You are free to use it in any application,
' provided the copyright notice is left unchanged.
'
' Code Courtesy of
' Dev Ashish

' retrieves the name of the class to which the specified window
belongs.
Private Declare Function apiGetClassName Lib "user32" _
Alias "GetClassNameA" _
(ByVal hwnd As Long, _
ByVal lpClassname As String, _
ByVal nMaxCount As Long) _
As Long

' retrieves a handle to the specified child window's parent window.
Private Declare Function apiGetParent Lib "user32" _
Alias "GetParent" _
(ByVal hwnd As Long) _
As Long

' retrieves information about the specified window. The function also
' retrieves the 32-bit (long) value at the specified offset into the
' extra window memory of a window.
Private Declare Function apiGetWindowLong Lib "user32" _
Alias "GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) _
As Long

' retrieves a handle to the top-level window whose class name and
' window name match the specified strings. This function does not
search
' child windows. This function does not perform a case-sensitive
search.
Private Declare Function apiFindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassname As String, _
ByVal lpWindowName As String) _
As Long

' retrieves a handle to a window that has the specified relationship
' (Z order or owner) to the specified window
Private Declare Function apiGetWindow Lib "user32" _
Alias "GetWindow" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) _
As Long

' The class name for an Access combo's drop down listbox window
Private Const ACC_CBX_LISTBOX_CLASS = "OGrid"
' Class name for the Access window
Private Const ACC_MAIN_CLASS = "OMain"
' Class name for an Access combo's drop down listbox's parent window
Private Const ACC_CBX_LISTBOX_PARENT_CLASS = "ODCombo"
' class name for an Access form's client window
Private Const ACC_FORM_CLIENT_CLASS = "OFormSub"
' class name for Edit controls in Access
Private Const ACC_CBX_EDIT_CLASS = "OKttbx"
' class name for VB combo's drop down listbox's parent window (SDI)
Private Const VB_CBX_LISTBOX_PARENT_CLASS = "#32769" ' // Desktop
' class name for VB combo's drop down listbox window
Private Const VB_CBX_LISTBOX_CLASS = "ComboLBox"
' handle identifies the child window at the top of the Z order,
' if the specified window is a parent window
Private Const GW_CHILD = 5
' Retrieves the window styles.
Private Const GWL_STYLE = (-16)
' flag denoting that a window is visible
Private Const WS_VISIBLE = &H10000000

Function fIsComboOpen() As Boolean
' returns true if a combo box on the form is dropped down
' only one combo can have the focus => only one drop down
'
Static hwnd As Long
Static hWndCBX_LBX As Long

hwnd = 0: hWndCBX_LBX = 0

' Start with finding the window with "ODCombo" class name
hwnd = apiFindWindow(ACC_CBX_LISTBOX_PARENT_CLASS, _
vbNullString)
' Parent window of ODCombo is the Access window
If apiGetParent(hwnd) = hWndAccessApp Then
' Child window of ODCombo window is the
' drop down listbox associated with a combobox
hWndCBX_LBX = apiGetWindow(hwnd, GW_CHILD)
' another check to confirm that we're looking at the right
window
If fGetClassName(hWndCBX_LBX) = _
ACC_CBX_LISTBOX_CLASS Then
' Finally, if this window is visible,
If apiGetWindowLong(hwnd, GWL_STYLE) And WS_VISIBLE Then
' the Combo must be open
fIsComboOpen = True
End If
End If
End If
End Function

Private Function fGetClassName(hwnd As Long)
Dim strBuffer As String
Dim lngLen As Long
Const MAX_LEN = 255
strBuffer = Space$(MAX_LEN)
lngLen = apiGetClassName(hwnd, strBuffer, MAX_LEN)
If lngLen > 0 Then fGetClassName = Left$(strBuffer, lngLen)
End Function
'******* Code End *********
Christian Schrammel
2003-12-27 13:45:20 UTC
Permalink
Post by Karl Donaubauer
Post by Werner Ewers
als ich von der im folgenden zitierten Lösung aus Karl Donaubauers
FAQs
erfuhr, war ich zunächst hoch erfreut über diese Lösung und habe
mehrere Formulare entsprechend umgebaut. Später habe ich jedoch
bemerkt, dass aufgeklappte Kombinationsfelder nun nicht mehr in der
gewünschten Weise funktionieren. Mit den Auf/Ab-Tasten läßt sich nicht
mehr im Kombinationsfeld navigieren, da sofort der Datensatz
gewechselt wird. (In der Datenblattansicht gibt es dieses Problem
nicht; ich vermute deshalb, dass Microsoft über eine tiefergehende
Lösung verfügt.)
Eine Lösung für das Problem könnte darin liegen, die beiden Codezeilen
vom Status eines Kombinationsfeldes, das gerade den Fokus besitzt,
abhängig zu machen.
Läßt sich der Status eines Kombinationsfeldes (aufgeklappt / nicht
aufgeklappt) ermitteln - evtl. unter Zuhilfenahme von API-Funktionen?
...
Joo. s. http://www.mvps.org/access/api/api0052.htm
Ich hab das ganz einfach mit

Me.KeyPreview = False

gelöst.

Bei Fokuserhalt des Kombofeldes schalte ich die Tastenvorschau ab, und bei
Fokusverlust (oder auch bei verlassen, oder auch bei beiden) wieder ein.
Oder war da was anderes gemeint?
Werner Ewers
2003-12-28 08:48:12 UTC
Permalink
Post by Christian Schrammel
Post by Karl Donaubauer
Post by Werner Ewers
als ich von der im folgenden zitierten Lösung aus Karl Donaubauers
FAQs
erfuhr, war ich zunächst hoch erfreut über diese Lösung und habe
mehrere Formulare entsprechend umgebaut. Später habe ich jedoch
bemerkt, dass aufgeklappte Kombinationsfelder nun nicht mehr in der
gewünschten Weise funktionieren. Mit den Auf/Ab-Tasten läßt sich nicht
mehr im Kombinationsfeld navigieren, da sofort der Datensatz
gewechselt wird. (In der Datenblattansicht gibt es dieses Problem
nicht; ich vermute deshalb, dass Microsoft über eine tiefergehende
Lösung verfügt.)
Eine Lösung für das Problem könnte darin liegen, die beiden Codezeilen
vom Status eines Kombinationsfeldes, das gerade den Fokus besitzt,
abhängig zu machen.
Läßt sich der Status eines Kombinationsfeldes (aufgeklappt / nicht
aufgeklappt) ermitteln - evtl. unter Zuhilfenahme von API-Funktionen?
...
Joo. s. http://www.mvps.org/access/api/api0052.htm
Ich hab das ganz einfach mit
Me.KeyPreview = False
gelöst.
Bei Fokuserhalt des Kombofeldes schalte ich die Tastenvorschau ab, und bei
Fokusverlust (oder auch bei verlassen, oder auch bei beiden) wieder ein.
Oder war da was anderes gemeint?
Hallo,
bei der von dir genannten Methode dürfte es nicht möglich sein, das
Kombinationsfeld (im nicht aufgeklappten Zustand) mit der Ab- oder
Auf-Taste wieder zu verlassen.
Gruß
Werner

Jörg Ackermann
2003-12-17 17:31:09 UTC
Permalink
Hi,

"Werner Ewers" <***@t-online.de> schrieb:

Ohne es jetzt getestet zu haben:

On Error Resume Next
Select case Screen.Activecontrol.name
case "cboFoo1", "cboFoo2", "cboFoo3"
'Tu nix
Case Else
If KeyCode = vbKeyDown Then KeyCode = 0: DoCmd.GoToRecord , , acNext
If KeyCode = vbKeyUp Then KeyCode = 0: DoCmd.GoToRecord , , acPrevious
End select

HTH
Gruß
Karl Donaubauer
2003-12-17 17:37:25 UTC
Permalink
Post by Werner Ewers
On Error Resume Next
Select case Screen.Activecontrol.name
case "cboFoo1", "cboFoo2", "cboFoo3"
'Tu nix
Case Else
If KeyCode = vbKeyDown Then KeyCode = 0: DoCmd.GoToRecord , , acNext
If KeyCode = vbKeyUp Then KeyCode = 0: DoCmd.GoToRecord , ,
acPrevious End select
Wenn der Status der Kombis wurscht wäre, ginge auch gleich:

If Screen.ActiveControl.ControlType <> acComboBox Then
If KeyCode = vbKeyDown Then KeyCode = 0: DoCmd.GoToRecord , , acNext
If KeyCode = vbKeyUp Then KeyCode = 0: DoCmd.GoToRecord , , acPrevious
End If
--
HTH
Karl
********* Ich beantworte keine Access-Fragen per Email. *********
Access-FAQ: http://www.donkarl.com
Datenbankprofis: http://www.dbdev.org
Jörg Ackermann
2003-12-17 17:45:26 UTC
Permalink
Hi,
Post by Karl Donaubauer
If Screen.ActiveControl.ControlType <> acComboBox Then
If KeyCode = vbKeyDown Then KeyCode = 0: DoCmd.GoToRecord , , acNext
If KeyCode = vbKeyUp Then KeyCode = 0: DoCmd.GoToRecord , , acPrevious
End If
Jo.
Aber wahrscheinlich mag er ja auch bei geschlossenem
Combo den DS wechseln. Insofern eher untauglich mein Ansatz.

Gruß
Loading...