Visual Basic Foro
Programación => Visual Basic .NET / C# => Mensaje iniciado por: ADONAIRAFA en Mayo 09, 2013, 11:35:45 am
-
Saludos a todos !!!
Tiempo que no posteaba una duda, una gran duda...
Se trata de lo siguiente: Tengo un form, y en el 4 ComboBox "entrelazados" (por decirlo así):
(http://imageshack.us/a/img706/4605/img01m.png)
(http://imageshack.us/a/img706/4605/img01m.png)
(http://imageshack.us/a/img855/4807/img03w.png)
El primer ComboBox "Estados", al seleccionar un Item, carga automáticamente el 2do ComboBox "Ciudades", con los respectivos Items relacionados a la primera selección; al seleccionar un Item del 2do Combo, carga un tercero referente a ""Barrio / Urb. / Zona", y así hasta cargar un cuarto Combo "Sector". se me olvidaba... los datos son cargados de una Base de Datos (FirebirdSQL).
Dichos ComboBox son cargados con esta subrutina:
Private Sub LoadComboBox(ByVal nSQL As Integer, _
ByVal cbx As ComboBox, _
ByVal tableName As String, _
ByVal displayMbr As String, _
ByVal valueMbr As String)
Dim FbCmd As FbCommand
Dim FbDad As FbDataAdapter
Dim Dtb As DataTable
'//
Try
Select Case nSQL
Case 1
sql = "SELECT * FROM Cesd ORDER BY Estado ASC;"
Case 2
sql = "SELECT * FROM Ccdd " & _
"WHERE Codigo_estado = '" & stateCode & "' " & _
"ORDER BY Ciudad ASC;"
Case 3
sql = "SELECT * FROM Cbur " & _
"WHERE Codigo_Ciudad = '" & cityCode & "' " & _
"ORDER BY Barrio_Urbanizacion ASC;"
Case 4
sql = "SELECT * FROM Cscr " & _
"WHERE Codigo_Barr_Urb = '" & suburbCode & "' " & _
"ORDER BY Sector ASC;"
End Select
FbCmd = New FbCommand(sql, FbConn)
FbDad = New FbDataAdapter(FbCmd)
Dtb = New DataTable
FbDad.Fill(Dtb)
With cbx
.DataSource = Dtb
.DisplayMember = displayMbr
.ValueMember = valueMbr
.Text = ""
End With
'//
Dtb = Nothing
FbCmd = Nothing
FbDad = Nothing
'//
cbx.Enabled = True
cbx.BackColor = Color.Azure
'//
If nSQL = 3 Then
txtAddressPress.Enabled = True
txtAddressPress.BackColor = Color.Azure
End If
Catch exFb As FbException
MsgBox(exFb.Message.ToString)
Catch ex As Exception
MsgBox(ex.Message.ToString)
End Try
End Sub
Esta Sub, no es nada del otro mundo, pero me funciona muy bien. Ahora EL PROBLEMA es que cuando quiero agregarle un Item opcional (por medio de código por supuesto) como por ejemplo "Otro Estado...", "Otra Ciudad...", etc. En caso de que el usuario desee agregar uno nuevo (bueno lo de insertar no es lo que trato aquí). NO PUEDO AGREGARLO, porque una vez establecida la propiedad DataSource del(os) ComboBox(s), No se puede realizar esta acción, es error (interceptado) que me arroja la aplicaciòn.
Probè esta otra Subrutina:
Private Sub LoadComboBox(ByVal nSQL As Integer, _
ByVal cbx As ComboBox, _
ByVal tableName As String, _
ByVal displayMbr As String, _
ByVal valueMbr As String)
Dim FbDad As FbDataAdapter
Dim Dst As DataSet
Dim Dtb As DataTable
Dim Dtr As DataRow
Dim _item As String = ""
Dim n As Integer = 0
'//
Try
Select Case nSQL
Case 1
sql = "SELECT * FROM Cesd ORDER BY Estado ASC;"
_item = "Otro Estado..."
Case 2
sql = "SELECT * FROM Ccdd " & _
"WHERE Codigo_estado = '" & stateCode & "' " & _
"ORDER BY Ciudad ASC;"
_item = "Otra Ciudad..."
Case 3
sql = "SELECT * FROM Cbur " & _
"WHERE Codigo_Ciudad = '" & cityCode & "' " & _
"ORDER BY Barrio_Urbanizacion ASC;"
_item = "Otro Barrio / Urb..."
Case 4
sql = "SELECT * FROM Cscr " & _
"WHERE Codigo_Barr_Urb = '" & suburbCode & "' " & _
"ORDER BY Sector ASC;"
_item = "Otro Sector..."
End Select
'//
FbDad = New FbDataAdapter(sql, FbConn)
Dst = New DataSet
Dtb = New DataTable
FbDad.Fill(Dst, tableName)
Dtb = Dst.Tables(tableName)
'//
With cbx
'// ----------------------------- Revisar este fragmento ----------------------------------
'n = .Items.Count
'For i As Integer = 0 To n - 1
' .Items.Remove(i)
'Next
'.Refresh()
'// ------------------------------------------------------------------------------------------------
For Each Dtr In Dtb.Rows
.Items.Add(Dtr.Item(displayMbr))
Next
'//
.Items.Add(_item)
.DisplayMember = displayMbr
.Text = ""
.Enabled = True
.BackColor = Color.Azure
End With
'//
If nSQL = 3 Then
txtAddressPress.Enabled = True
txtAddressPress.BackColor = Color.Azure
End If
'//
Dtr = Nothing
Dtb = Nothing
Dst = Nothing
FbDad = Nothing
Catch exFb As FbException
MsgBox(exFb.Message.ToString)
Catch ex As Exception
MsgBox(ex.Message.ToString)
End Try
End Sub
Y funciona muy bien (en apariencia)...
(http://imageshack.us/a/img407/9623/img04s.png)
(http://imageshack.us/a/img706/1140/img05z.png)
Pero fíjense lo que pasañ si cambio la selección de un Item, en el Combo que precede al último seleccionado por eejemplo:
(http://imageshack.us/a/img23/3371/img06w.png)
Una soberana cagada que he hecho. los items anteriormente cargados, no se borran y se suman a los nuevos (solo en el Combo, gracias a DIOS !!!), lo que no pasaba usando la primara subrutina.
Lo que necesito es agregarle los Items que mencioné antes, sin que me ocrra esta catástrofe !!!
Agradecido de antemano !!!
Saludos desde Venezuela.
Manuel F. Borrego S. 8)
-
Se me ocurren dos formas de resolverlo.
Me imagino que en tu tabla de ubigeo tienes con el respectivo indice cada registro, pues consideraría que el primer registro sea "Otro Estado..." u "Otra Ciudad..." según corresponda, y luego hacer un select con unión, en el primero el select a todos los registros menos el de ID 1 y ordenados alfabéticamente y el segundo select solo al id 1. Al hacer union aparecera todos ordenados y al final: "Otro..."
La segunda forma es manipulando el Select a nivel de ADO teniendo en cuenta de abrirlo con adOpenStatic, adLockBatchOptimistic. Entonces alli metes el registro "Otro...".
El problema del segundo metodo es para cuando el usuario escoja "Otro..." ¿que guardas en la tabla? por eso si ya le clavas a tus tablas ubigeas el indice 1 con "Otro..." ya podras relacionarlo.
Es una idea.
Fuerte abrazo y no te pierdas.
-
creo que lo podes solucionar de forma facil, "sin tocar ni agregar nada al combo", te explico como lo hice yo.
yo tambien hice eso alguna ves en un sistema, con hasta 5 combobox relacionados de ese modo, hasta ahi no hay problema es facil, simplemente hacer un select dependiendo el id del registro seleccionado ,a la tabla que se tenga que hacer y listo (como estas haciendo vos).
tambien tuve que hacer lo mismo que vos, o sea agregarle la opcion de que si el usuario no queria "ninguna" de las que estaba en el combo, pudiera "agregar una", lo que hice fue lo siguiente.
1 - al lado de cada combo puse un boton con el texto "..." (algo asi como el examinar de windows).
2 - cuando apretaban ese boton, se levantaba directamente la pantalla de ABM del combo que selecciono, por ejemplo: si el combo era de "localidades", se levantaba el "ABM de localidades", pero cuidado, no se levantaba la pantalla principal con la grilla de localidades del ABM, sino que se levantaba la pantalla para directamente ingresar los datos (id y nombre por ejemplo), o sea es como "un atajo" (era lo mismo que ir al ABM y darle al boton de "nuevo").
3 - una ves que el tipo completaba los datos en la pantalla, cuando "cerraba la pantalla", simplemente lo que hago es "refrescar el combo" (cargarlo de nuevo), entonces como la pantalla de ABM ya inserto el registro en esa tabla, pues en el combo ya te aparece el nuevo registro.
4 - de esta forma el usuario, puede hacer carga de localidades desde esa misma pantalla sin tener que ir a la pantalla de ABM, es una forma rapida y corta de hacerlo sin tocar nada de lo que ya tenes.
saludos.
-
Saludos Yvan y Seba !!! ;D
Yvan, en cuanto a la sugerencia que me diste, la había contemplado, sé que podía cumplir el cometido pero aún no me convencía ! :-\
Resulta, que de tanto darle, descubrí (vagando por la red, casi me pierdo de tanto vagar y divagar !!!) y resolví el problema (que me parecía del tamaño de una montaña) con una solución que me pareció de lo más simple, y de paso cumple con su objetivo perfectamente :o, y es la siguiente:
cbx.items.clear
Ese fragmento (cbx por el objeto 'ComboBox'), lo agrego justo de cargar el ComboBox, y al final de la lista, agrega el item "Otro Estado...", "Otra Ciudad...", etc. según el Combo. Ahora Seba, tomé en cuenta tu sugerencia (con una modificación)... Cuando el usuario hace click en 'Otro Estado...' o 'Otra Ciudad...', etc. Inmediatamente se abre un pequeño Form, invitando a escribir el nombre de la nueva localidad y luego pulsar 'ENTER'... Cuando se hace esto, se guarda la localidad en la tabla respectiva con su ID.
Todo muy bien !!! de maravillas, sorprendente !!!... A excepción de un mísero y asqueroso detalle: Que en el ComboBox no observo el cambio. Tengo que descargar el form que hace la llamada al "mini form" (para la nueva localidad), y volverlo a cargar (ahí si se ve el cambio) !!!
He Intentado abrir y cerrar la conexión, antes de cargar el Combo, luego de hacer inserción, y nada... sigo con el mismo "lindo detallito" >:( >:( >:(
Ilústrenme en su gran sabiduría, para ver donde errando (porque de que estoy en un error lo estoy -de lógica-)
Saludos !!!
Manuel F. Borrego S. 8)
Barcelona. Venezuela.
-
Buenas...
La funcion donde cargas el combo hazla PUBLICA, no PRIVADA...
Public Sub LoadComboBox
Y esta la llamas al cerrar la ventanita o el mini form. Así de simple...!
frmTuFormularioConCombo.cbx.items.clear
frmTuFormularioConCombo.LoadComboBox
Unload MiniForm
Debes tener en cuenta que (cbx.items.clear) yo lo cargaria en (LoadComboBox) como primera linea dentro de esa función. Esto de manera que al llamar la función, limpie o borre todo del combo y cargue lo nuevo. Así nos ahorramos lineas de codigo. Y harias esto.
frmTuFormularioConCombo.LoadComboBox
Unload MiniForm
Bueno eso haría yo en VB6. Debe ser igual.
Saludos y un abrazo bro..!
-
Epale Miguel !!!
Listo hermano, al volverla Public, se solucionó la vaina. De paso, decidí colocarla en un "class" para reutilizarla con otros ComboBox y no sobrecargar (visualmente hablando) de código en la clase del form.
Bueno en Vb 9.0 (Vb 2008), ya no se usa 'Unload NombreForm', se usa:
NombreForm.Dispose o
NombreForm.Close, según sea requerido. Cuando se trata de descargar un Form perteneciente a un MDI, uso la primera.
Gracias a Todos, por sus soluciones !!!
Manuel F. Borrego S. 8)
Barcelona. Venezuela.
PD: Por cierto Miguel, a ver cuando nos encontramos
y brindamos con unas chelas (que sea Solera 'Verde')
Un abrazo !!!