locked
Error "System.IndexOutOfRangeException' en System.Data.dll" al realizar consulta con SqlDataReader RRS feed

  • Pregunta

  • Estoy intentando realizar una consulta en una tabla [tblUsuarios] con SqlDataReader  para asignar los valores obtenidos en varios controles, pero solo me toma los primeros 13 valores y me arroja el error "System.IndexOutOfRangeException' en System.Data.dll Información adicional: Índice fuera de los límites de la matriz." ¿Como puedo tomar el resto? Este es el codigo que utilizo:

                                        

                SqlConnection conect = new SqlConnection(conexion);
                conect.Open();
                string consulta = "select Clientes, Compras, Configuraciones, Corte_caja, Cotizaciones, Credito, Devoluciones, Facturas, Faltantes, Gastos, Historicos, Mov_alm, Ord_compra, P_entrega, Productos, Proveedores, Salidas_cajas, Usuarios, Ventas from tblUsuarios where id =" + ClsVariable.selecusu;

    SqlCommand cmd = new SqlCommand(consulta, conect);

                try
                {

                    SqlDataReader leer = cmd.ExecuteReader();
                    leer.Read();

                    tsbClientes.Visible = Convert.ToBoolean(leer.GetValue(5));
                    tssbCompras.Visible = Convert.ToBoolean(leer.GetValue(6));
                    tsbConfiguraciones.Visible = Convert.ToBoolean(leer.GetValue(7));
                    tssbCaja.Visible = Convert.ToBoolean(leer.GetValue(8));
                    tsbCotizaciones.Visible = Convert.ToBoolean(leer.GetValue(9));
                    tssbCredito.Visible = Convert.ToBoolean(leer.GetValue(10));
                    tssbDevolucio.Visible = Convert.ToBoolean(leer.GetValue(11));
                    tssbFacturacion.Visible = Convert.ToBoolean(leer.GetValue(12));
                    tsbFaltantes.Visible = Convert.ToBoolean(leer.GetValue(13));
                    tsbGastos.Visible = Convert.ToBoolean(leer.GetValue(14));
                    tssbHistorico.Visible = Convert.ToBoolean(leer.GetValue(15));
                    tssbMovAlmacen.Visible = Convert.ToBoolean(leer.GetValue(17));
                    tssbOrdenCompra.Visible = Convert.ToBoolean(leer.GetValue(18));
                    tsbPEntrega.Visible = Convert.ToBoolean(leer.GetValue(19));
                    tssbProductos.Visible = Convert.ToBoolean(leer.GetValue(20));
                    tsbProveedores.Visible = Convert.ToBoolean(leer.GetValue(21));
                    tssNotaCredito.Visible = Convert.ToBoolean(leer.GetValue(22));
                    btnCambiarUsuario.Visible = Convert.ToBoolean(leer.GetValue(23));
                    btnAdministrar.Visible = Convert.ToBoolean(leer.GetValue(23));
                    tssbVentas.Visible = Convert.ToBoolean(leer.GetValue(24));


                }

                catch (Exception)
                {
                    MessageBox.Show("¡Error al activar opciones!", "Error");
                }

    ¡Espero su respuesta, gracias de antemano!

    jueves, 8 de diciembre de 2016 2:28

Respuestas

  • ChrizZ1920,

    Siendo que la consulta de selección retorna 19 columnas (presumo de tipo entero) que permiten validar la propiedad 'Visible' de 20 objetos, pienso que hace falta una columna (en la lista de selección) para evaluar la propiedad 'Visible' del objeto 'btnAdministrar'.

    Por otro lado,  ¿por qué inicias con la lectura desde el índice 5 siendo que la posición ordinal de las columnas inician en 0?. Además, te recomiendo acceder al valor de cada columna utilizando los métodos según el tipo de dato origen, la idea es reducir/evitar el número de conversiones.

    SqlDataReader leer = cmd.ExecuteReader();
    leer.Read();
    
    tsbClientes.Visible = leer.GetInt32(0) > 0;
    tssbCompras.Visible = leer.GetInt32(1) > 0;
    tsbConfiguraciones.Visible = leer.GetInt32(2) > 0;
    //Resto de asignaciones



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Propuesto como respuesta Joyce_ACModerator jueves, 8 de diciembre de 2016 15:42
    • Marcado como respuesta ChrizZ1920 lunes, 12 de diciembre de 2016 0:33
    jueves, 8 de diciembre de 2016 4:50

Todas las respuestas

  • Hola ChrizZ1920,

    El error es claro, no puede encontrar una posición o índice dentro de los resultados obtenidos.

    En tu consulta haces uso de 19 campos (en el select), pero al leer la información estás queriendo obtener índices no existentes.

    leer.GetValues(19)   campo 20 no existente
    leer.GetValues(20)   campo 21
    leer.GetValues(21)   campo 22

    Lo cual produce ese tipo de excepción.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    jueves, 8 de diciembre de 2016 2:35
  • Hola ChrizZ1920

    porqué los índices que pones en el GetValue(?) sobrepasan el número de columnas que obtienes en el SELECT?

    En la consulta muestras 18 columna (del 0 al 17) pero al querer pasar los datos del DataReader a tus objetos, se ven índices hasta el 24

     Intenta así:
             SqlConnection conect = new SqlConnection(conexion);
                conect.Open();
                string consulta = "select Clientes, Compras, Configuraciones, Corte_caja, Cotizaciones, Credito, Devoluciones, Facturas, Faltantes, Gastos, Historicos, Mov_alm, Ord_compra, P_entrega, Productos, Proveedores, Salidas_cajas, Usuarios, Ventas from tblUsuarios where id =" + ClsVariable.selecusu;
    SqlCommand cmd = new SqlCommand(consulta, conect);
    
                try
                {
    
                    SqlDataReader leer = cmd.ExecuteReader();
                    leer.Read();
    
                    tsbClientes.Visible = Convert.ToBoolean(leer.GetValue(0));
                    tssbCompras.Visible = Convert.ToBoolean(leer.GetValue(1));
                    tsbConfiguraciones.Visible = Convert.ToBoolean(leer.GetValue(2));
                    tssbCaja.Visible = Convert.ToBoolean(leer.GetValue(3));
                    tsbCotizaciones.Visible = Convert.ToBoolean(leer.GetValue(4));
                    tssbCredito.Visible = Convert.ToBoolean(leer.GetValue(5));
                    tssbDevolucio.Visible = Convert.ToBoolean(leer.GetValue(6));
                    tssbFacturacion.Visible = Convert.ToBoolean(leer.GetValue(7));
                    tsbFaltantes.Visible = Convert.ToBoolean(leer.GetValue(8));
                    tsbGastos.Visible = Convert.ToBoolean(leer.GetValue(9));
                    tssbHistorico.Visible = Convert.ToBoolean(leer.GetValue(10));
                    tssbMovAlmacen.Visible = Convert.ToBoolean(leer.GetValue(11));
                    tssbOrdenCompra.Visible = Convert.ToBoolean(leer.GetValue(12));
                    tsbPEntrega.Visible = Convert.ToBoolean(leer.GetValue(13));
                    tssbProductos.Visible = Convert.ToBoolean(leer.GetValue(14));
                    tsbProveedores.Visible = Convert.ToBoolean(leer.GetValue(15));
                    tssNotaCredito.Visible = Convert.ToBoolean(leer.GetValue(16));
                    btnCambiarUsuario.Visible = Convert.ToBoolean(leer.GetValue(17));
                    btnAdministrar.Visible = Convert.ToBoolean(leer.GetValue(18));
                    tssbVentas.Visible = Convert.ToBoolean(leer.GetValue(19));
    
    
                }
    
                catch (Exception)
                {
                    MessageBox.Show("¡Error al activar opciones!", "Error");
                }
    SUerte

    Javier

    jueves, 8 de diciembre de 2016 2:38
  • ChrizZ1920,

    Siendo que la consulta de selección retorna 19 columnas (presumo de tipo entero) que permiten validar la propiedad 'Visible' de 20 objetos, pienso que hace falta una columna (en la lista de selección) para evaluar la propiedad 'Visible' del objeto 'btnAdministrar'.

    Por otro lado,  ¿por qué inicias con la lectura desde el índice 5 siendo que la posición ordinal de las columnas inician en 0?. Además, te recomiendo acceder al valor de cada columna utilizando los métodos según el tipo de dato origen, la idea es reducir/evitar el número de conversiones.

    SqlDataReader leer = cmd.ExecuteReader();
    leer.Read();
    
    tsbClientes.Visible = leer.GetInt32(0) > 0;
    tssbCompras.Visible = leer.GetInt32(1) > 0;
    tsbConfiguraciones.Visible = leer.GetInt32(2) > 0;
    //Resto de asignaciones



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Propuesto como respuesta Joyce_ACModerator jueves, 8 de diciembre de 2016 15:42
    • Marcado como respuesta ChrizZ1920 lunes, 12 de diciembre de 2016 0:33
    jueves, 8 de diciembre de 2016 4:50