VBA vs VB6. Diferencias en los Combos

Posted by in Visual Basic y VBA

Esta entrada es técnica sobre el uso del objeto combo en VBA y en VB6,  y que ha surgido a raiz de realizar  recientemente una pequeña aplicación en Excel que requería completar un combo con los datos de una tabla. El motivo fundamental de la misma es comprobar la diferente forma de preparar un combo, a partir de un recordset obtenido de una tabla.

Normalmente, en VB6, se emplea la propiedad ItemData para almacenar ahí el valor del ID, aunque se muestre su descripción. Para conectar con la base de datos he empleado oCon, que es un objeto ADODB.Connection, configurado como global para todo el módulo.

Private Sub EjemploCargaComboVB6()
Dim rs As ADODB.Recordset, sSQL As String, i As Integer
sSQL = "SELECT id, descripcion FROM tabla"


Set rs = oCon.Execute(sSQL)
If rs.EOF Then
' Sin Registros
GoTo Ending
End If
rs.MoveFirst


Me.combo.Clear ' Limpio el combo


Do While Not rs.EOF
Me.combo.AddItem rs.Fields("descripcion")
Me.combo.ItemData(me.combo.NewIndex) = rs.Fields("id")
rs.MoveNext
Loop


Ending:
End Sub

Para recuperar un valor del combo, utilizamos también ItemData, tal que así:

Private Sub combo_Click()
'Debug.Print Me.combo.ItemData(Me.combo.ListIndex)
End Sub

Combos en VBA

Sin embargo, en VBA de Excel (y también para el de Access también), no encontré dicha propiedad ItemData. La alternativa que he encontrado para trabajar de la misma forma es la siguiente:

Private Sub EjemploCargaComboVBA()
Dim rs As ADODB.Recordset, sSQL As String, i As Integer
sSQL = "SELECT id, descripcion FROM tabla"


Set rs = oCon.Execute(sSQL)
If rs.EOF Then
' Sin Registros
GoTo Ending
End If
rs.MoveFirst


Me.combo.Clear ' Limpio el combo
Me.combo.ColumnCount = 2
Me.combo.ColumnWidths = "0;150"
Me.combo.TextColumn = 2
Do While Not rs.EOF
Me.combo.AddItem rs.Fields("descripcion")
Me.combo.List(i, 1) = rs.Fields("descripcion")
Me.combo.List(i, 0) = rs.Fields("id")
i = i + 1
rs.MoveNext
Loop

Ending:
End Sub

La forma de «copiar» la propiedad ItemData consiste en crear un combo de múltiples columnas, en este caso 2, donde a una se le da un ancho, y a la otra ancho 0 (por tanto, no visible). Mediante un bucle se completan ambas columnas. Es una forma un poco más engorrosa, pero igual de efectiva!

Para recuperar un valor:

Private Sub combo_Click()
'Debug.Print Me.combo.List(Me.combo.ListIndex, 0)
End Sub

Espero que os sea de utilidad!