none
El indice y la longitud deben hacer referencia a una ubicación en la cadena

    Pregunta

  • Hola, Tengo una función que tomo los caracteres de un bloc de notas y lo estoy tomando con el SubString()

    código que uso para guardar:

                

      If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
                'Try
                txtdireccion.Text = openFileDialog1.FileName
                'myStream = openFileDialog1.OpenFile()

                Dim linetotal, fecha, hora, tlinea, Ext, tiempo, NumTelf, TLlamada As String
                Dim horasaux, minutoaux, segundoaux As String
                Dim x, y, z, total As String
                Dim subtotal As Double

                FileOpen(1, openFileDialog1.FileName, OpenMode.Input)

                Dim cmd As New SqlClient.SqlCommand("InsertLlamadas")
                cmd.CommandType = CommandType.StoredProcedure
                'todos los datos podemos obtener los siguientes valores de los datos podemos 

                cmd.Connection = New SqlClient.SqlConnection(conexion)
                cmd.Connection.Open()

                Do Until EOF(1)
                    linetotal = LineInput(1) 'la funcion  lineInput(Me lee toda la linea entera)
                    fecha = linetotal.Substring(0, 8)
                    hora = linetotal.Substring(8, 9)
                    tlinea = linetotal.Substring(18, 1)
                    Ext = linetotal.Substring(22, 3)

                    tiempo = linetotal.Substring(30, 8)
                    NumTelf = linetotal.Substring(38, 8)
                    TLlamada = linetotal.Substring(46, 30).Trim()

                    horasaux = linetotal.Substring(31, 1)
                    minutoaux = linetotal.Substring(33, 2)
                    segundoaux = linetotal.Substring(36, 2) 'fin del guardado de horas, minutos y segundo

                    cmd.Parameters.Add("@fecha", SqlDbType.DateTime).Value = (fecha)
                    cmd.Parameters.Add("@hora", SqlDbType.DateTime).Value = (hora)
                    cmd.Parameters.Add("@Linea", SqlDbType.Int).Value = CInt(tlinea)
                    cmd.Parameters.Add("@Extension", SqlDbType.NVarChar, 50).Value = (Ext)

                    'validar que donde esta el caracter NumTelf esta vacio grabar 0 de lo contrario guardar datos optenido de la del notepad
                    cmd.Parameters.Add("@Tiempo", SqlDbType.NVarChar, 50)
                    If tiempo.ToString.IndexOf(vbEmpty) Then
                        cmd.Parameters("@Tiempo").Value = ("0")
                    Else
                        cmd.Parameters("@Tiempo").Value = (tiempo)
                    End If

                    'validar que donde esta el caracter NumTelf esta vacio grabar 0 de lo contrario guardar datos optenido de la del notepad
                    cmd.Parameters.Add("@Telefono", SqlDbType.NVarChar, 50)
                    If NumTelf.ToString.IndexOf(vbEmpty) Then
                        cmd.Parameters("@Telefono").Value = ("0")
                    Else
                        cmd.Parameters("@Telefono").Value = (NumTelf)
                    End If

                    'validar que donde esta el caracter Hora hablado esta vacio grabar 0 de lo contrario guardar datos optenido de la del notepad
                    cmd.Parameters.Add("@segundo", SqlDbType.Int)
                    If horasaux.ToString.IndexOf(vbEmpty) Then
                        cmd.Parameters("@segundo").Value = CInt("0")
                    Else
                        x = Convert.ToDouble(horasaux * 3600)
                        y = Convert.ToDouble(minutoaux * 60)
                        z = Convert.ToDouble(segundoaux)

                        subtotal = x + y
                        total = subtotal + z

                        cmd.Parameters("@segundo").Value = CInt(total)
                    End If

                    cmd.Parameters.Add("@CodTipoLlamada", SqlDbType.Int).Value = CInt(TLlamada)
                    cmd.ExecuteNonQuery()

                Loop
                ProgressBarX1.Value = 0.0
                ProgressBarX1.Maximum = 100
                Timer1.Interval = 50
                Timer1.Enabled = True
                If ProgressBarX1.Maximum = 100 Then
                    MsgBox("Los datos se han grabado correctamente", MsgBoxStyle.Information)
                    txtdireccion.Text = ""
                    cmd.Connection.Close()
                End If

                'Catch Ex As Exception
                '    MessageBox.Show("No se puede leer el archivo.: " & Ex.Message)
                'Finally

                If (myStream IsNot Nothing) Then
                    myStream.Close()
                End If
                'End Try
            End If

    y estoy utilizando un ciclo del do until EOF(1) para tomar todas las filas del bloc de notas pero cuando mando a 

    guardar a la base de datos me manda este error en la fila  tiempo = linetotal.Substring(30, 8) y me dice = "El índice y la longitud deben hacer referencia a una ubicación en la cadena."





    martes, 29 de noviembre de 2016 17:18

Respuestas

Todas las respuestas

  • Alexander Valle,

    El mensaje de la excepción es bastante claro, intentas acceder a una posición de la cadena que no existe, ¿estás seguro que la cadena tiene 30 caracteres de longitud y de manera adicional 8 o mas caracteres?, si contiene menos es de esperar la excepción. 

    Como punto adicional, puedes utilizar el método ReadAllLines() para iterar por las líneas de un archivo, te dejo un ejemplo de su uso conteniendo una validación para que lo tomes como referencia:

    Dim rutaArchivo As String = OpenFileDialog1.FileName
    
    For Each item As String In File.ReadAllLines(rutaArchivo, Encoding.Default)
    	If item.Length < 38 Then
    		'La cadena no contiene la longitud deseada
    	End If
    Next



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 29 de noviembre de 2016 17:30
  • Hola,

    Para mi el error esta aqui: fecha = linetotal.Substring(0, 8), deberia ser fecha = linetotal.Substring(1, 8).


    Victor Koch

    martes, 29 de noviembre de 2016 18:16
  • Con la pregunta que me haces: ¿estás seguro que la cadena tiene 30 caracteres de longitud y de manera adicional 8 o mas caracteres?

    es que en esta linea de codigo:   "tiempo = linetotal.Substring(30, 8)"  estoy tomando donde inicia el caracter 30 del bloc de nota y que me tome 8 en adelante es decir me va a tomar el 31,32,33,34,35,36,37,38 caracter de la primera linea del bloc de nota

    martes, 29 de noviembre de 2016 18:37
  • Hola Victor Koch, en caso a tu repuesta.

    para mi seria que no inicie fecha = linetotal.Substring(1, 8).  

    por que  no me tomaria el primer caracter por ejemplo  tengo esta cadena "hola" asi como dices tu no me toma la "h"

    martes, 29 de noviembre de 2016 18:43
  • Alexander Valle,

    La validación va en el orden de asegurarte que la sub-cadena a extraer existe dentro de los índices de la cadena, ¿estás seguro de ello?:

    If linetotal.Length >= 37 Then
    	tiempo = linetotal.Substring(30, 8)
    Else
    	'La subcadena no existe para los índices indicados
    End If



    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 29 de noviembre de 2016 18:46
  • HOLA Willams Morales

    Me mando el mensaje de error : 'La subcadena no existe para los índices indicados


    martes, 29 de noviembre de 2016 18:56
  • Alexander Valle,

    Creo que el problema viene en el sentido de que no se está entendiendo la excepción que obtienes. La excepción la obtienes porque la longitud de la cadena es menor a la longitud de la subcadena que deseas extraer, por ejemplo:

    Dim Cadena As String = "Hola"
    Dim SubCadena As String = Cadena.SubString(0, 5)
    'Obtienes la excepción IndexOutOfRangeException

    Nota que la longitud de la cadena es de 4 caracteres y tú intentas extraer 5 caracteres, dicha operación genera una excepción porque la longitud que deseas extraer sobre-pasa a la longitud real de la cadena. Cuando sucede ese caso tu sabrás que acciones tomar, por ejemplo establecer un valor vacío a la variable tiempo (en caso sea un tipo string)

    tiempo = If(linetotal.Length >= 37, linetotal.Substring(30, 8), String.Empty)


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 29 de noviembre de 2016 19:09
  • Willams Morales

    cuando puse el codigo que me dijiste: 

    tiempo = If(linetotal.Length >= 37, linetotal.Substring(30, 8), String.Empty)

    me manda el error:

    An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

    Additional information: startIndex no puede ser mayor que la longitud de la cadena.
    martes, 29 de noviembre de 2016 19:44
  • Alexander Valle,

    Tuve un error al escribir la longitud, no es 37, es 38:

    tiempo = If(linetotal.Length >= 38, linetotal.Substring(30, 8), String.Empty)


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 29 de noviembre de 2016 20:37
  • Willams Morales

    ultima pregunta hay disculpa.  fijate que ya resolvimos los de los indices de los caracteres,  pero cuando se ejecuta el procedimiento almacenado me manda esto : "Error al convertir el valor del parámetro de String a DateTime."

    el detalle esta que noce adonde voy a convertir?

    martes, 29 de noviembre de 2016 20:56
  • Alexander Valle,

    ¿En que línea obtienes la excepción?

    Debes verificar el valor que obtiene la variable que intentas convertir a un tipo datetime, si obtienes la excepción 'FormatException' es posible que la variable contenga una cadena de longitud cero (string.Empty) o que el formato de fecha sea incorrecto o no soportado para realizar la conversión.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Propuesto como respuesta Joyce_ACModerator miércoles, 30 de noviembre de 2016 17:37
    martes, 29 de noviembre de 2016 23:14