none
Validar tipos de datos traidos de un archivo de texto RRS feed

  • Pregunta

  • Buen día.

    Realizo una implementación en C#, en el cual deberá leer los datos un archivo de texto (esta parta ya la tengo) y cada uno de esos datos deberá ser de cierto tipo, es decir, en mi archivo de texto vienen precios, fechas, entre otros datos.

    Tengo detalle al validar el dato del precio, ya que me indica "La cadena de entrada no tiene el formato correcto", y continua con el proceso, y este no debería ser así, debería terminar la lectura de ese archivo y continuar con el siguiente.

            #region Producto
            //Metodo con arreglo, asigna los datos de cada linea de producto
            public static Productos[] Producto(string startFolder)
            {
                string fecha = DateTime.Now.ToString("MM/dd/yyyy");
    
                List<string> Datos = LeerArchvioTXT(startFolder);
    
                Productos[] lineas = new Productos[Datos.Count - 2];
                //FOR para leer los datos de los productos linea por linea
                for (int a = 2; a < Datos.Count; a++)
                {
                    try
                    {
                        char separador = '|';
                        string[] DatosCol;
                        DatosCol = Datos[a].Split(separador);
                        lineas[a - 2].Codigo = DatosCol[2];
                        //lineas[a - 2].Observaciones = DatosCol[6]; //Referencia
                        lineas[a - 2].Observaciones = DatosCol[6]; //Observaciones
                        lineas[a - 2].Cantidad = Convert.ToDouble(DatosCol[7]); //Cantidad
                        lineas[a - 2].Precio = Convert.ToDouble(DatosCol[8]); //Precio
                        //lineas[a - 2].Impuesto1 = Convert.ToDouble(DatosCol[4]);//impuesto1
    
                         
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
                return lineas;
            }
            #endregion

    El mensaje me lo arroja en el catch, lo que no logro hacer es que termine el proceso si encuentra una excepción.

    Anexo un ejemplo de un archivo de texto que manejo.

    00|AAA010101AAA
    01|1447AA|Paola Lizandra|AAA010101AAA|I|FA|9|04/13/2021|04|PUE|Pago en una sola exhibicion|P01|MXN||
    02|1|MTZ01|Licencia Comercial Premium|16.00|43231500|Comentario en movimiento|2|AA||2
    02|3|352|Carcinoembrionario Antígeno, Suero|16.00|85121800||1|494.7845||3
    02|4|355|CA 125 Antígeno, Suero|16.00|85121800||1|515.5172||

    jueves, 15 de abril de 2021 17:33

Respuestas

  • No se si entendí bien lo que queres. Pero así podes pasar a la siguiente linea del bucle cunado no se pueda convertir a double la cantidad o el precio.

        public Productos[] Producto(string startFolder)
        {
          string fecha = DateTime.Now.ToString("MM/dd/yyyy");
    
          List<string> Datos = LeerArchvioTXT(startFolder);
    
          Productos[] lineas = new Productos[Datos.Count - 2];
          //FOR para leer los datos de los productos linea por linea
          char separador = '|';
          string[] DatosCol;
    
          try
          {
            for (int a = 2; a < Datos.Count; a++)
            {
              DatosCol = Datos[a].Split(separador);
              lineas[a - 2].Codigo = DatosCol[2];
              lineas[a - 2].Observaciones = DatosCol[6]; //Observaciones
              
              Double cant = -1;
              if (!Double.TryParse(DatosCol[7].ToString(), out cant))
              {
                Console.WriteLine("Error de conversión en el campo Cantidad");
                continue;
              }
              Double precio = -1;
              if (!Double.TryParse(DatosCol[8].ToString(), out precio))
              {
                Console.WriteLine("Error de conversión en el campo Precio");
                continue;
              }
    
              lineas[a - 2].Cantidad = cant; //Cantidad
              lineas[a - 2].Precio = precio; //Precio
            }
          }
          catch (Exception ex)
          {
            Console.WriteLine(ex.Message);
          }
    
          return lineas;
        }


    • Editado AntiWork jueves, 29 de abril de 2021 22:40
    • Propuesto como respuesta EricRRModerator viernes, 30 de abril de 2021 22:16
    • Marcado como respuesta EricRRModerator martes, 18 de mayo de 2021 18:57
    jueves, 29 de abril de 2021 21:46

Todas las respuestas

  • Hola Geovani,

    Gracias por levantar tu consulta en los foros de MSDN.

    Eric Ruiz

    ____________________________

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.

    Si tiene algún cumplido o reclamo sobre el soporte de MSDN siéntase en la libertad de contactar MSDNFSF@microsoft.com.

    jueves, 15 de abril de 2021 21:48
    Moderador
  • Hola, yo hice una clase para solucionar los problemas de conversión y de datos Null. Te paso los la clase completa aunque quizás no necesites todos los métodos.

     public static class Conv
      {
    
    #region int
    
        public static int CInt(object Nro)
        {
          return CInt(Nro, -1);
        }
    
        public static int CInt(object Nro, int ValorParaNulo)
        {
          int rta = ValorParaNulo;
          if (Nro != null & !DBNull.Value.Equals(Nro))
            int.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion int
    
    #region Short
    
        public static short CShort(Object Nro)
        {
          return CShort(Nro, -1);
        }
    
        public static short CShort(Object Nro, short ValorParaNulo)
        {
          short rta = ValorParaNulo;
          if (Nro != null)
            short.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion Short, Int16
    
    #region long
    
        public static Int64 CLng(Object Nro)
        {
          return CLng(Nro,-1);
        }
    
        public static Int64 CLng(Object Nro, Int64 ValorParaNull)
        {
          Int64 rta = ValorParaNull;
          if (Nro != null)
            Int64.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion long
    
    #region byte
    
        public static byte CByte(Object Nro)
        {
          return CByte(Nro,0);
        }
    
        public static byte CByte(Object Nro, byte NumeroParaNul)
        {
          byte rta = NumeroParaNul;
          if (Nro != null)
            byte.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion byte
    
    #region byte[]
    
        public static byte[] CAbyte(Object ArrayBytes)
        {
          byte[] rta = new byte[0];
          if (ArrayBytes != DBNull.Value)
            rta = (byte[])ArrayBytes;
          return rta;
        }
    
        public static byte[] CAbyte(Object ArrayBytes, byte[] ArrayParaNul)
        {
          byte[] rta = ArrayParaNul;
          if (ArrayBytes != null)
            rta = (byte[])ArrayBytes;
          return rta;
        }
    
    #endregion byte[]
    
    #region float
    
        public static float CFloat(Object Nro)
        {
          return CFloat(Nro, -1f);
        }
        
        public static float CFloat(Object Nro, float ValorParaNull)
        {
          float rta = ValorParaNull;
          if (Nro != null && Nro.ToString().Trim()!="")
            float.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion float
    
    #region double
    
        public static double CDbl(Object Nro)
        {
          return CDbl(Nro, -1);
        }
    
        public static double CDbl(Object Nro, Double ValorParaNull)
        {
          double rta = ValorParaNull;
          if (Nro != null)
            double.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion double
    
    #region Decimal
    
        public static Decimal  CDmal(Object Nro)
        {
          return CDmal(Nro, -1);
        }
    
        public static Decimal CDmal(Object Nro, Decimal ValorParaNull)
        {
          Decimal rta = ValorParaNull;
          if (Nro != null)
            Decimal.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion Decimal
    
    #region char
    
        public static Char CChar(Object CaracterChar)
        {
          return CChar(CaracterChar, Char.MinValue);
        }
    
        public static Char CChar(Object CaracterChar, Char ValorParaNulo)
        {
          Char rta = ValorParaNulo;
          if (CaracterChar != null)
            Char.TryParse(CaracterChar.ToString(), out rta);
          return rta;
        }
    
    #endregion char
    
    #region bool
          // 1: true    0:false
        public static bool CBool(Object ValorBool)
        {
          return CBool(ValorBool, false);
        }
    
        public static bool CBool(Object ValorBool, bool ValorParaNull)
        {
          bool rta = ValorParaNull;
          if (ValorBool != null)
            bool.TryParse(ValorBool.ToString(), out rta);
          return rta;
        }
    
    #endregion bool
    
    #region DateTime
    
        public static DateTime CDate(Object Fecha)
        {
          return CDate(Fecha, new DateTime(1900, 1, 1));
        }
    
        public static DateTime CDate(Object Fecha, DateTime FechaParaNull)
        {
          DateTime rta = FechaParaNull;
          String sFec = "";
    
          if (Fecha != null && Fecha.ToString().Trim() != "")
          {
            sFec = Fecha.ToString().Trim();
            int dia = -1; int mes = -1; int anio = -1;
            char[] barra = { '/', ' ' };
            char[] guion = { '-', ' ' };
            int iGuion = sFec.IndexOf('-');
            int iBarra = sFec.IndexOf('/');
            string[] pFec = null;
    
            if (iBarra > -1)
              pFec = sFec.Split(barra);
            else if (iGuion > -1)
              pFec = sFec.Split(guion);
    
            if (pFec!=null && pFec.Length > 2)
            {
              int.TryParse(pFec[0], out dia);
              int.TryParse(pFec[1], out mes);
              int.TryParse(pFec[2], out anio);
              if (anio > -1 && anio < 100) anio += 2000;
              if (anio > 2000 & anio < 2100)
              {
                if (mes == 1 | mes == 3 | mes == 5 | mes == 7 | mes == 8 | mes == 10 | mes == 12)
                {
                  if (dia > 0 && dia < 32)
                    rta = new DateTime(anio, mes, dia);
                }
                else if (mes == 2)
                {
                  if (anio % 4 == 0)
                  {
                    if (dia > 0 && dia < 30)
                      rta = new DateTime(anio, mes, dia);
                  }
                  else
                    if (dia > 0 && dia < 29)
                      rta = new DateTime(anio, mes, dia);
                }
                else if (mes == 4 | mes == 6 | mes == 9 | mes == 11)
                  if (dia > 0 && dia < 31)
                    rta = new DateTime(anio, mes, dia);
              }
            }
          }
          
          return rta;
        }
    
    #endregion DateTime
    
    #region String
    
        public static String CStr(Object ValorString)
        {
          return CStr(ValorString, String.Empty);
        }
    
        public static String CStr(Object ValorString, String ValorParaNull)
        {
          string rta = ValorParaNull;
          if (ValorString != null)
            rta = ValorString.ToString();
          return rta;
        }
    
    #endregion String
    
    
    #region Metodos sobrecargados o auxiliares
    
        #region cInt16
    
        public static short CInt16(Object Nro)
        {
          return CShort(Nro, -1);
        }
    
        public static short CInt16(Object Nro, short ValorParaNulo)
        {
          return CShort(Nro, ValorParaNulo);
        }
    
        #endregion cInt16
    
        #region int32
    
        public static int CInt32(object Nro)
        {
          return CInt(Nro, -1);
        }
    
        public static int CInt32(object Nro, int ValorParaNulo)
        {
          return CInt(Nro, ValorParaNulo);
        }
    
        #endregion int32
    
        #region Int64
    
        public static Int64 CInt64(Object Nro)
        {
          return CLng(Nro,-1);
        }
    
        public static Int64 CInt64(Object Nro, Int64 ValorParaNull)
        {
          return CLng(Nro, ValorParaNull);
        }
    
        #endregion Int64
    
        #region Single
    
        public static float CSgl(Object Nro)
        {
          return CFloat(Nro, -1f);
        }
    
        public static float CSgl(Object Nro, float ValorParaNull)
        {
          return CFloat(Nro, ValorParaNull);
        }
    
        #endregion Single
    
        #region Boolean
    
        public static bool CBoolean(Object ValorBool)
        {
          return CBool(ValorBool, false);
        }
    
        public static bool CBoolean(Object ValorBool, bool ValorParaNull)
        {
          return CBool(ValorBool, ValorParaNull);
        }
    
        #endregion Boolean
    
    #endregion Metodos sobrecargados o auxiliares
     
       
      }

    Ejemplo de uso

          lineas[a - 2].Codigo = Conv.CInt(DatosCol[2]);
          lineas[a - 2].Observaciones = Conv.CStr(DatosCol[6]);
          lineas[a - 2].Observaciones = DatosCol[6];
          lineas[a - 2].Cantidad = Conv.CDbl(DatosCol[7]);
          lineas[a - 2].Precio = Conv.CDbl(DatosCol[8]);
          lineas[a - 2].Fecha = Conv.CDate(DatosCol[10]); //agrego para dar ejemplo de fecha

    viernes, 16 de abril de 2021 1:46
  • Hola @AntiWork, agradezco tu respuesta, es de gran utilidad, sin embargo, me podrías explicar un poquito esta parte del código, no logro comprenderla del todo. Ya que si lo implemento en mi código, la ejecución continua y me crea el dato con un precio 0, cuando debería terminar la ejecución.

    #region double
    
        public static double CDbl(Object Nro)
        {
          return CDbl(Nro, -1);
        }
    
        public static double CDbl(Object Nro, Double ValorParaNull)
        {
          double rta = ValorParaNull;
          if (Nro != null)
            double.TryParse(Nro.ToString(), out rta);
          return rta;
        }
    
    #endregion double
    

    martes, 20 de abril de 2021 16:45
  • Hola, a la primer funcion CDbl(Object Nro), le pasas solamente el número que querés convertir a Double, Esta función le pasará a la segunda el numero y el -1 para reemplazar si el numero es null. Si te interesa especificar que valor debe devolver si el numero pasado es null, entonces llamas a la segunda funcion.

    Ejemplos

          object a = null;
          double b = Conv.CDbl(a, 0.75); // b=0.75
          double c = Conv.CDbl(a); // c=-1
          
          
          object d = 5.47;
          double f = Conv.CDbl(d); // f=5.47
    La idea es que la función siempre devuelva un número.



    • Editado AntiWork miércoles, 21 de abril de 2021 23:35
    miércoles, 21 de abril de 2021 23:15
  • Hola @AntiWork, después de varios intento no he logrado que termine la ejecución, de hecho si un dato esta mal en el archivo de texto ni siquiera lo detecta y continua con la ejecución.
    miércoles, 28 de abril de 2021 18:11
  • No, definitivamente no es para eso la clase que subí. Para eso podés poner un if dentro del bucle For para comprobar que se cumpla alguna condición para salir. Se puede pasar a la linea siguiente con "Continue;" o bien salir definitivamente del bucle for con "break;". Quizás algo como esto también te sirva:

        public static Productos[] Producto(string startFolder)
        {
          string fecha = DateTime.Now.ToString("MM/dd/yyyy");
    
          List<string> Datos = LeerArchvioTXT(startFolder);
    
          Productos[] lineas = new Productos[Datos.Count - 2];
          //FOR para leer los datos de los productos linea por linea
          char separador = '|';
          string[] DatosCol;  
    
          try
            {
              for (int a = 2; a < Datos.Count; a++)
              {  
              DatosCol = Datos[a].Split(separador);
              lineas[a - 2].Codigo = DatosCol[2];
              //lineas[a - 2].Observaciones = DatosCol[6]; //Referencia
              lineas[a - 2].Observaciones = DatosCol[6]; //Observaciones
              lineas[a - 2].Cantidad = Convert.ToDouble(DatosCol[7]); //Cantidad
              lineas[a - 2].Precio = Convert.ToDouble(DatosCol[8]); //Precio
              //lineas[a - 2].Impuesto1 = Convert.ToDouble(DatosCol[4]);//impuesto1
              }
            }
            catch (Exception ex)
            {
              Console.WriteLine(ex.Message);
            }
          
          return lineas;
        }

    En este código, si existe algún error dentro del bucle, saldrá del bucle y escribirá el mensaje del error en la consola.

    para darte una solución mas precisa necesito saber  si tiene que salir del bucle o pasar a la siguiente vuelta y exactamente que condición tiene que cumplirse para eso. 

    jueves, 29 de abril de 2021 3:02
  • Hola @AntiWork, lo que intente realizar es que lea el archivo de texto, y que cada linea sea un cierto tipo de dato.

    Por ejemplo:

    00|AAA010101AAA
    01|1447AA|Paola Lizandra|AAA010101AAA|I|FA|9|03/17/2020|04|PUE|Pago en una sola exhibicion|P01|MXN||
    02|1|MTZ01|Licencia Comercial Premium|16.00|43231500|Vacio|1|a513.8362||2

    Este es un archivo de texto, el código lee cada linea 02 del archivo, un archivo puede tener varias lineas 02, entonces, en cada linea 02 existe un campo de precio que seria la linea 8, esta deberá ser de tipo double o de algún tipo que permita un precio. Si este dato o alguno de la linea esta mal, entonces deberá terminar la lectura de este archivo, mandar la excepción del dato que esta y pasar a la lectura del siguiente archivo de texto.

    Lo que actualmente realiza es leer el archivo, manda la excepción 3 veces aunque solo un dato esta mal, crea el documento en 0 y pasa a leer el siguiente archivo.

    De antemano gracias por la ayuda y disculpa si tengo errores pero no soy tan experto, voy aprendiendo.


    jueves, 29 de abril de 2021 18:41
  • No se si entendí bien lo que queres. Pero así podes pasar a la siguiente linea del bucle cunado no se pueda convertir a double la cantidad o el precio.

        public Productos[] Producto(string startFolder)
        {
          string fecha = DateTime.Now.ToString("MM/dd/yyyy");
    
          List<string> Datos = LeerArchvioTXT(startFolder);
    
          Productos[] lineas = new Productos[Datos.Count - 2];
          //FOR para leer los datos de los productos linea por linea
          char separador = '|';
          string[] DatosCol;
    
          try
          {
            for (int a = 2; a < Datos.Count; a++)
            {
              DatosCol = Datos[a].Split(separador);
              lineas[a - 2].Codigo = DatosCol[2];
              lineas[a - 2].Observaciones = DatosCol[6]; //Observaciones
              
              Double cant = -1;
              if (!Double.TryParse(DatosCol[7].ToString(), out cant))
              {
                Console.WriteLine("Error de conversión en el campo Cantidad");
                continue;
              }
              Double precio = -1;
              if (!Double.TryParse(DatosCol[8].ToString(), out precio))
              {
                Console.WriteLine("Error de conversión en el campo Precio");
                continue;
              }
    
              lineas[a - 2].Cantidad = cant; //Cantidad
              lineas[a - 2].Precio = precio; //Precio
            }
          }
          catch (Exception ex)
          {
            Console.WriteLine(ex.Message);
          }
    
          return lineas;
        }


    • Editado AntiWork jueves, 29 de abril de 2021 22:40
    • Propuesto como respuesta EricRRModerator viernes, 30 de abril de 2021 22:16
    • Marcado como respuesta EricRRModerator martes, 18 de mayo de 2021 18:57
    jueves, 29 de abril de 2021 21:46