Access - Cuadros combinados inteligentes

 
Vista:
sin imagen de perfil

Cuadros combinados inteligentes

Publicado por anonymous (2 intervenciones) el 20/12/2018 12:04:38
Hola. Estoy probando los cuadros combinados inteligentes de Sveinbjorn (de forma que me vaya filtrando a medida que escribo). Pero hay un cuadro combinado que no consigo hacerlo funcionar correctamente, y es el que más me interesa (muestra un listado de productos para un TPV). Estuve hablando con Sveinbjorn, pero el no consigue ver dónde está el fallo. Necesito una segunda opinión, a ver si vosotros sabéis decirme dónde error:

He creado un formulario en blanco con el mismo desplegable del formulario del TPV y las configuraciones que indica en el PDF sobre los cuadros combinados inteligentes:

https://www.dropbox.com/s/ztypa9hntr6hzh2/941f1cc0aeece7c148a6a259d4f973f6.jpg
https://www.dropbox.com/s/unnmwn18t8b7rxo/3b394483b465c598c5c2342b7820bb58.jpg
https://www.dropbox.com/s/6c3uvt0kdk7sbuk/deda492a6f295f8f568721dbd8b17106.jpg

He puesto en VBA para analizar el código. Así, cuando escribo, mira lo que pasa:

https://www.dropbox.com/s/8vh9tldb4cemk22/1.jpg
https://www.dropbox.com/s/etspqph6opqchn0/2.jpg

En la imagen no sale, pero el valor que toma el campo CboArticulo es "a". Justo lo que he escrito en el desplegable.

Además, si pruebo el código en una consulta, con un parámetro cualquiera, me funciona:

https://www.dropbox.com/s/l5mazog9pky2qqi/3.jpg
https://www.dropbox.com/s/2lm844l731cma3i/4.jpg

Sveinbjorn me dijo que pusiera la propiedad "Heredar lista de valores" en No, pero tampoco funciona.

Si necesitais la base de datos, más datos, queréis que pruebe otra cosa, no sé, cualquier cosa, decídmelo. Me interesa resolver este dilema.

Muchas gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil

Cuadros combinados inteligentes

Publicado por anonymous (2 intervenciones) el 18/01/2019 10:32:59
Buenos días, tengo la solución. Es distinta a la propuesta por Sveinbjorn.

Habría que añadir un módulo de clase, y copiar el siguiente código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
Option Compare Database
Option Explicit
 
 
'Class Module Name: FindAsYouTypeCombo
'Purpose: Turn any combobox into a "Find As You Type" 'Combobox
'Created by: MajP
'Demonstrates: OOP, and With Events
'
'To Use: Place this code in a Class Module
'   The class MUST be called "FindAsYouTypeCombo"
'
'*******START: Place Code like this in the Form *******************
'
' Option Compare Database
' Option Explicit
' Public faytProducts As New FindAsYouTypeCombo
'
' Form_Open(Cancel As Integer)
'   faytProducts.InitalizeFilterCombo Me.cmbProducts, "ProductName", False, True, False
' End Sub
'
'******* END: Form Code ******************
'
'
'Parameters of the InitializeFilterCombo:
'  TheComboBox: Your Combobox object passed as an object reference
'  FilterFieldName: The name of the field to Filter passed as a string variable
'  SearchType: Determines if you filter a field that
'    starts with the desired text or if the text appears anywhere in the record
'  HandleArrows: This controls the behavior to move up and down the list with arrow keys
'    and not select the first value. Boolean variable
'  HandleInternationalCharacters: This allows you to search for international characters. (a = á,N = Ñ, etc.)
'    This may slow down the procedure because it does a lot of replacements. Boolean
'
 
 
 
Private WithEvents mCombo As Access.ComboBox
Private WithEvents mForm As Access.Form
Private mFilterFieldName As String
Private mRsOriginalList As DAO.Recordset
Private mSearchType As SearchType
Private mHandleArrows As Boolean
Private mAutoCompleteEnabled As Boolean
Private mHandleInternationalCharacters As Boolean
Private mRowSource As String
Public Enum SearchType
  AnywhereInString = 0
  FromBeginning = 1
End Enum
 
 
'---------------------------------------- Properties --------------------------
'Only Needed for reassigning a new reocordsource. Not related to FAYT.  Still required to have a recordsource initially
Public Property Get RdSource() As String
  RowSource = mRowSource
 
End Property
Public Property Let RowSource(ByVal NewRowSource As String)
  Dim rs As DAO.Recordset
  mRowSource = NewRowSource
  'If mCombo.Recordset Is Nothing Then
     Set rs = CurrentDb.OpenRecordset(NewRowSource)
     Set mCombo.Recordset = rs
  'End If
  Set mRsOriginalList = mCombo.Recordset.Clone
End Property
Public Property Get FilterComboBox() As Access.ComboBox
  Set FilterComboBox = mCombo
End Property
Public Property Set FilterComboBox(TheComboBox As Access.ComboBox)
  Set mCombo = TheComboBox
End Property
 
Public Property Get FilterFieldName() As String
  FilterFieldName = mFilterFieldName
End Property
Public Property Let FilterFieldName(ByVal theFieldName As String)
  mFilterFieldName = theFieldName
End Property
Public Property Get HandleArrows() As Boolean
  HandleArrows = mHandleArrows
End Property
Public Property Let HandleArrows(ByVal TheValue As Boolean)
  mHandleArrows = TheValue
End Property
'------------------------------------------- Handled Events ----------------
Private Sub mCombo_Change()
  Call FilterList
  mAutoCompleteEnabled = True
 ' mCombo.Dropdown
End Sub
Private Sub mCombo_AfterUpdate()
  mAutoCompleteEnabled = True
  unFilterList
  'MsgBox "After" & mAutoCompleteEnabled
End Sub
Private Sub mForm_Current()
  Call unFilterList
End Sub
Private Sub mForm_Close()
   Call Class_Terminate
End Sub
Private Sub mCombo_Click()
  mAutoCompleteEnabled = False
End Sub
Private Sub mCombo_KeyDown(KeyCode As Integer, Shift As Integer)
  ' Handle keys that affect the auto-complete feel of the combobox.  BS 10/13/2015
    If mHandleArrows = True Then
    Select Case KeyCode
      Case vbKeyDown, vbKeyUp, vbKeyReturn, vbKeyPageDown, vbKeyPageUp
          ' When these special keys are hit they begin to select records
          ' from the dropdown list.  Without this, as soon as one record
          ' is selected (by highlighting it) then the entire filter is
          ' set to that item making it impossible to use the keyboard to
          ' scroll down and pick an item down in the list.
          mAutoCompleteEnabled = False
        Case Else
          mAutoCompleteEnabled = True
        End Select
    End If
End Sub
 
 
'----------------------------------  Class Procedures ----------------------------
Public Sub InitalizeFilterCombo(TheComboBox As Access.ComboBox, FilterFieldName As String, _
                      Optional TheSearchType As SearchType = SearchType.AnywhereInString, _
                      Optional HandleArrows As Boolean = True, _
                      Optional HandleInternationalCharacters As Boolean = True)
 
   On Error GoTo errLabel
   Dim rs As DAO.Recordset
   If Not TheComboBox.RowSourceType = "Table/Query" Then
      MsgBox "This class will only work with a combobox that uses a Table or Query as the Rowsource"
      Exit Sub
   End If
   Set mCombo = TheComboBox
   Set mForm = TheComboBox.Parent
   mHandleArrows = HandleArrows
   mAutoCompleteEnabled = True
   mHandleInternationalCharacters = HandleInternationalCharacters
   'HandleArrows allows you to use the arrow keys to move up and down without selecting the value
   mCombo.OnClick = "[Event Procedure]"
   If mHandleArrows = True Then
      mCombo.OnKeyDown = "[Event Procedure]"
      mCombo.OnClick = "[Event Procedure]"
   End If
   mFilterFieldName = FilterFieldName
   mSearchType = TheSearchType
   mForm.OnCurrent = "[Event Procedure]"
   mForm.OnClose = "[Event Procedure]"
   mCombo.OnGotFocus = "[Event Procedure]"
   mCombo.OnChange = "[Event Procedure]"
   mCombo.OnClick = "[Event Procedure]"
   mCombo.AfterUpdate = "[Event Procedure]"
   mForm.OnClose = "[Event Procedure]"
 
   With mCombo
      .AutoExpand = False
   End With
   If mCombo.Recordset Is Nothing And Not mCombo.RowSource = "" Then
     Set rs = CurrentDb.OpenRecordset(TheComboBox.RowSource)
     Set mCombo.Recordset = rs
   End If
   If Not mCombo.Recordset Is Nothing Then
     Set mRsOriginalList = mCombo.Recordset.Clone
   End If
   Exit Sub
errLabel:
    MsgBox Err.Number & " " & Err.Description
End Sub
 
Private Sub FilterList()
  On Error GoTo errLable
  Dim rsTemp As DAO.Recordset
  Dim strText As String
  Dim strFilter As String
  strText = mCombo.Text
  strText = Replace(strText, "'", "''")
  strText = Replace(strText, "#", "[#]")
  If mHandleInternationalCharacters Then
    strText = InternationalCharacters(strText)
  End If
  If mFilterFieldName = "" Then
    MsgBox "Must Supply A FieldName Property to filter list."
    Exit Sub
  End If
  'Debug.Print mAutoCompleteEnabled
  If mAutoCompleteEnabled = False Then Exit Sub
  If mSearchType = SearchType.FromBeginning Then
    strFilter = mFilterFieldName & " like '" & strText & "*'"
  Else
    strFilter = mFilterFieldName & " like '*" & strText & "*'"
  End If
  Set rsTemp = mRsOriginalList.OpenRecordset
  rsTemp.Filter = strFilter
  Set rsTemp = rsTemp.OpenRecordset
 
  If Not (rsTemp.EOF And rsTemp.BOF) Then
    rsTemp.MoveLast
    rsTemp.MoveFirst
    'Debug.Print rsTemp.RecordCount & " Count " & strFilter
  Else
    Beep
    mAutoCompleteEnabled = True
  End If
  Set mCombo.Recordset = rsTemp
  If rsTemp.RecordCount > 0 Then
 
    mCombo.Dropdown
  End If
 
  Exit Sub
errLable:
  If Err.Number = 3061 Then
    MsgBox "Will not Filter. Verify Field Name is Correct."
  Else
    MsgBox Err.Number & "  " & Err.Description
  End If
End Sub
Private Sub unFilterList()
  On Error GoTo errLable
  Set mCombo.Recordset = mRsOriginalList
   Exit Sub
errLable:
  If Err.Number = 3061 Then
    MsgBox "Will not Filter. Verify Field Name is Correct."
  Else
    MsgBox Err.Number & "  " & Err.Description
  End If
End Sub
'------------------------------------ To Handle International Characters  ---------------------------
Private Function InternationalCharacters(ByVal strText As String) As String
   InternationalCharacters = strText
   'If you type international turn first to english
    'Type international and get english
    InternationalCharacters = Replace(InternationalCharacters, "á", "a")
    InternationalCharacters = Replace(InternationalCharacters, "é", "e")
    InternationalCharacters = Replace(InternationalCharacters, "í", "i")
    InternationalCharacters = Replace(InternationalCharacters, "ó", "o")
    InternationalCharacters = Replace(InternationalCharacters, "ú", "u")
    InternationalCharacters = Replace(InternationalCharacters, "ü", "u")
    InternationalCharacters = Replace(InternationalCharacters, "ñ", "n")
    'Add others as necessary á, é, í, ó, ú, ü, ñ
 
 
   'Type english and get international
    InternationalCharacters = Replace(InternationalCharacters, "A", "[AÁÀÂÄaá]")
    InternationalCharacters = Replace(InternationalCharacters, "E", "[EÉÈÊËeé]")
    InternationalCharacters = Replace(InternationalCharacters, "I", "[IÍÌÎÏií]")
    InternationalCharacters = Replace(InternationalCharacters, "O", "[OÓÒÔÖ0oóøØ]")
    InternationalCharacters = Replace(InternationalCharacters, "U", "[UÚÙÛÜuú]")
    InternationalCharacters = Replace(InternationalCharacters, "N", "[NnñÑ]")
    InternationalCharacters = Replace(InternationalCharacters, "C", "[CcçÇ]")
 
End Function
'-----------------------------------------End --------------------------------------------
Private Sub Class_Terminate()
    Set mForm = Nothing
    Set mCombo = Nothing
    Set mRsOriginalList = Nothing
End Sub

Además de filtrar a medida que vas escribiendo, también te permite moverte mediante el teclado por los resultados filtrados; y no hace distinción con las tildes y la ñ, en ambos sentidos.

Para añadirlo a un formulario que tenga una lista desplegable, habría que hacerlo de la siguiente forma:

1
2
3
4
5
6
'At the top of the code
Public faytArticulo As New FindAsYouTypeCombo
 
Private Sub Form_Open(Cancel As Integer)
   faytArticulo.InitalizeFilterCombo Me.CboArticulo, "Articulo", StartBeginning, True, True
End Sub

Además, si tienes combos relacionados, habría que hacerlo de esta forma:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Public faytProducts As New FindAsYouTypeCombo
Public faytProductsNoInt As New FindAsYouTypeCombo
Public faytProductForward As New FindAsYouTypeCombo
Public faytForwardNoHandles As New FindAsYouTypeCombo
Public faytCascade As New FindAsYouTypeCombo
 
Private Sub Form_Load()
  faytProducts.InitalizeFilterCombo Me.cmbProducts, "ProductName", AnywhereInString, True
  faytProductsNoInt.InitalizeFilterCombo Me.cmboProductNoInternational, "ProductName", AnywhereInString, , False
  faytProductForward.InitalizeFilterCombo Me.cmboProductForward, "ProductName", FromBeginning, True
  faytForwardNoHandles.InitalizeFilterCombo Me.cmboBeginningNoHandles, "ProductName", FromBeginning, False
  faytCascade.InitalizeFilterCombo Me.cmboCascadeProducts, "ProductName"
End Sub
 
Private Sub cmboCascadeProducts_Enter()
  Dim strSql As String
  strSql = "SELECT Products.ProductID, Products.ProductName FROM Products where SupplierName = '" & Nz(Me.cmboSupplier, "") & "' ORDER BY Products.[ProductName]"
  Me.cmboCascadeProducts.RowSource = strSql
  Me.cmboCascadeProducts.Requery
  faytCascade.RowSource = strSql
End Sub

Espero que os sirva.

Gracias, y un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar