Как мне проанализировать этот CSV-файл, поскольку в нем много запятых, состоящих из трех частей, которые мне нужны для получения информации? - PullRequest
0 голосов
/ 02 марта 2019

Я занимаюсь разбором текстовых и CSV-файлов.У меня есть определенный CSV-файл, который я пытаюсь проанализировать в течение нескольких часов, но я не могу найти правильную логику для этого, так как, согласно анализу 19 строк, мне нужно получить информацию о первых двух строках.Я должен показать всю информацию ниже.CSV-файл выглядит следующим образом

Titular,Cuenta #,Moneda,Fecha del reporte,,
MyCompany,123654897,Dollar,26/6/2010,,
,,,,,
Períod,,,,,
From:,31/01/2010,Until:,25/06/2019,,
,,,,,
Date,Description,Númber reference,Débit,Crédit,Balance
31/01/2019,Credito por Intereses,710504251714-50398277,,132.16,"3,073.55"
8/2/2019,Depositos,S9091B19,,"74,258.74","9,722.29"
8/2/2019,ACH Debito,F1999ZV,"8,748.35",,"2,073.55"
14/02/2019,Creditos Varios,F90BRF,,"7,429.77","4,391.32"
18/02/2019,ACH Debito,FT0SMD,"4,824.77",,"3,073.55"
21/02/2019,ACH Credito,F8PH,,"8,000.98","3,673.53"
21/02/2019,Transferencia entre Cuentas,2DMFRG,"7,005.96",,"2,667.57"
22/02/2019,Pago de Comision,R2SHX,20.00,,"5,647.57"
25/02/2019,ACH Credito,FT1905,,"4,083.08","4,490.65"
25/02/2019,Transferencia entre Cuentas,FT254354,"4,437.10",,"3,053.55"
25/02/2019,ACH Credito,ASF455MZQT,,222.15,"3,675.70"
25/02/2019,Transferencia entre Cuentas,GHVF456Q1XLG,"5,536.33",,"5,453.55"

Я провел некоторый тест и отлаживал, чтобы увидеть поведение и спросить себя;Нужно ли указывать строку, в которой я нахожусь, чтобы я мог получить информацию?Если да, то как мне это сделать?

Вот мой код:

using System;
using System.Collections.Generic;
 using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace T_2060_ParserEstadoDeCuenta
{
 class Program
 {
    static void Main(string[] args)
    {
        Console.WriteLine("Parsing the csv file");

        List<clsEstadoCuenta> resp = new List<clsEstadoCuenta>();
        var lines = File.ReadAllLines("d:\\ztemp\\parseEstcta.csv");
        for (int i = 1; i < lines.Count(); i++)
        {
            try
            {
                /*

                 */
                var campos = lines[i].Split(',');
                clsEstadoCuenta nR = new clsEstadoCuenta();

                nR.NumeroCuenta = (String.IsNullOrEmpty(campos[1])) ? "" : campos[1];
                nR.CodigoPais = 504;
                nR.Banco = "Fichosa";
                nR.Moneda = (String.IsNullOrEmpty(campos[2])) ? "" : campos[2];
                nR.TasaCambio = 24.6;
                var tmpFecha = campos[0].Split('/');
                nR.FechaTransaccion = new DateTime(Convert.ToInt32(tmpFecha[2]), Convert.ToInt32(tmpFecha[1]), Convert.ToInt32(tmpFecha[0]));
                nR.Descripcion = (String.IsNullOrEmpty(campos[1])) ? "" : campos[1];
                nR.Referencia = (String.IsNullOrEmpty(campos[2])) ? "" : campos[2];
                nR.Debito = (String.IsNullOrEmpty(campos[4])) ? 0 : Convert.ToDouble(campos[4]);
                nR.Credito = (String.IsNullOrEmpty(campos[5])) ? 0 : Convert.ToDouble(campos[5]);
                nR.Payee = "A";




            }
            catch (Exception ex)
            {

                Console.WriteLine("error on line {0} : {1}", i, ex.Message);
                continue;
            }
        }
        Console.WriteLine("Parsing has ended, we have {0} rows \n", resp.Count);

        foreach (var item in resp)
        {

            Console.WriteLine(item.NumeroCuenta+"\t" +item.CodigoPais+"\t"+item.Banco+"t"+item.Moneda+"\t"+item.Debito);
        }
        Console.ReadLine();
    }

    class clsEstadoCuenta
    {
        private string _NumeroCuenta;

        public string NumeroCuenta
        {
            get { return _NumeroCuenta; }
            set { _NumeroCuenta = value; }
        }
        private int _CodigoPais;

        public int CodigoPais
        {
            get { return _CodigoPais; }
            set { _CodigoPais = value; }
        }

        private string _Banco;

        public string Banco
        {
            get { return _Banco; }
            set { _Banco = value; }
        }

        private string _Moneda;

        public string Moneda
        {
            get { return _Moneda; }
            set { _Moneda = value; }
        }

        private double _TasaCambio;

        public double TasaCambio
        {
            get { return _TasaCambio; }
            set { _TasaCambio = value; }
        }

        private double _Debito;

        public double Debito
        {
            get { return _Debito; }
            set { _Debito = value; }
        }

        private double _Credito;

        public double Credito
        {
            get { return _Credito; }
            set { _Credito = value; }
        }

        private DateTime _FechaTrasaccion;

        public DateTime FechaTransaccion
        {
            get { return _FechaTrasaccion; }
            set { _FechaTrasaccion = value; }
        }

        private string _Payee;

        public string Payee
        {
            get { return _Payee; }
            set { _Payee = value; }
        }

        private string _Descripcion;

        public string Descripcion
        {
            get { return _Descripcion; }
            set { _Descripcion = value; }
        }

        private string _Referencia;

        public string Referencia
        {
            get { return _Referencia; }
            set { _Referencia = value; }
        }

        private string _CodigoBancario;

        public string CodigoBancario
        {
            get { return _CodigoBancario; }
            set { _CodigoBancario = value; }
        }

        private string _Categoria;

        public string Categoria
        {
            get { return _Categoria; }
            set { _Categoria = value; }
        }

        private string _Sector;

        public string Sector
        {
            get { return _Sector; }
            set { _Sector = value; }
        }

        private double _ValorLocal;

        public double ValorLocal
        {
            get
            {
                _ValorLocal = Credito - Debito;
                return _ValorLocal;
            }
            //set { _ValorLocal = value; }
        }

        private double _ValorDolares;

        public double ValorDolares
        {
            get
            {
                _ValorDolares = ValorLocal / TasaCambio;
                return _ValorDolares;
            }
           // set { _ValorDolares = value; }
        }

        private string _NombreEmpresa;

        public string NombreEmpresa
        {
            get { return _NombreEmpresa; }
            set { _NombreEmpresa = value; }
        }

    }
  }
}

Ответы [ 4 ]

0 голосов
/ 03 марта 2019

Хотя форматирование этого CSV не самое лучшее, так как он смешивает числа с запятой и точкой, а разделение полей - запятая.Тем не менее, с ним можно работать, нужно лишь немного логики собрать числа, которые будут разделены с помощью lines.Split(',').

. Ниже приведен пример, в котором перечислены данные на экране и добавленызначения в clsEstadoCuenta.

Логика для установки сломанных чисел заключается в следующем.

     if (!string.IsNullOrEmpty(campos[i]))
     {
         if (campos[i][0] == '\"')
         {
             campos[i] = campos[i] + campos[i + 1];
             campos[i + 1] = "";
             campos[i] = campos[i].Replace("\"","");
         }
     }

Когда он проходит через поля, он проверяет сломанное и, если он, он беретостаток значения в следующем поле и объединяет их.

Вот полный код ниже.

    static void Main(string[] args)
    {
        ReadCsv();

        Console.WriteLine("...");
        Console.ReadLine();
    }

    private static void ReadCsv()
    {
        string desk = System.IO.Directory.GetParent(@"../../").FullName;
        String path = $@"{desk}\filecsv.csv";
        var csvlines = File.ReadAllLines(path);

        Console.WriteLine("Parsing the csv file");


        //build header
        var header = csvlines[1].Split(',');

        clsEstadoCuenta nR = new clsEstadoCuenta();
        nR.NumeroCuenta = (String.IsNullOrEmpty(header[1])) ? "" : header[1];
        nR.CodigoPais = 504;
        nR.Banco = "Fichosa";
        nR.Moneda = (String.IsNullOrEmpty(header[2])) ? "" : header[2];
        nR.TasaCambio = 24.6;


        //build list of data
        foreach (var lines in csvlines.Skip(7))
        {
            var campos = lines.Split(',');

            //mount line
            string newline = "";
            for (int i = 0; i < campos.Count(); i++)
            {
                //Here the numbers that were divided by the Spli (',') 
                //are reassembled and saved in their respective fields.
                if (!string.IsNullOrEmpty(campos[i]))
                {
                    if (campos[i][0] == '\"')
                    {
                        campos[i] = campos[i] + campos[i + 1];
                        campos[i + 1] = "";
                        campos[i] = campos[i].Replace("\"","");
                    }
                }

                newline += $"{campos[i]} \t";
            }

            //puts the values in the clsEstadoCuenta
            var tmpFecha = campos[0].Split('/');
            nR.FechaTransaccion = new DateTime(Convert.ToInt32(tmpFecha[2]), Convert.ToInt32(tmpFecha[1]), Convert.ToInt32(tmpFecha[0]));
            nR.Descripcion = (String.IsNullOrEmpty(campos[1])) ? "" : campos[1];
            nR.Referencia = (String.IsNullOrEmpty(campos[2])) ? "" : campos[2];
            nR.Debito = (String.IsNullOrEmpty(campos[4])) ? 0 : Convert.ToDouble(campos[4]);
            nR.Credito = (String.IsNullOrEmpty(campos[5])) ? 0 : Convert.ToDouble(campos[5]);
            nR.Payee = "A";

            Console.WriteLine($"{newline}");
        }
    }

РЕШЕНИЕ 2

ЭтоДля корректной работы кода необходимы некоторые модификации. Некоторые атрибуты clsStateCount.cs должны быть List, а затем yes может быть Add(), например nR.Debito.Add()

. Классу clsStateCount.cs понадобится конструктор, который создаетLists.

    public clsEstadoCuenta()
    {
        _FechaTrasaccion = new List<DateTime>();
        _Descripcion = new List<string>();
        _Referencia = new List<string>();
        _Payee = new List<string>();
        _Debito = new List<double>();
        _Credito = new List<double>();
        _Payee = new List<string>();
    }

Также атрибуты Date, Description, Númber Reference, Débit, Crédit и Balance должны быть List, так как они будутполучить несколько данных.

    private List<DateTime> _FechaTrasaccion;
    public List<DateTime> FechaTransaccion
    {
        get { return _FechaTrasaccion; }
        set { _FechaTrasaccion = value; }
    }

Вот полный код для класса:

class clsEstadoCuenta
{

    //you will need a builder to create the lists
    public clsEstadoCuenta()
    {
        _FechaTrasaccion = new List<DateTime>();
        _Descripcion = new List<string>();
        _Referencia = new List<string>();
        _Payee = new List<string>();
        _Debito = new List<double>();
        _Credito = new List<double>();
        _Payee = new List<string>();
    }


    //method GetTransactionsNumber() 
    //heck how many items there are in the lists below
    public int GetTransactionsNumber()
    {
        return _FechaTrasaccion.Count;
    }


    //the methods below will be List since it 
    //will receive several values
    private List<DateTime> _FechaTrasaccion;
    public List<DateTime> FechaTransaccion
    {
        get { return _FechaTrasaccion; }
        set { _FechaTrasaccion = value; }
    }

    private List<string> _Descripcion;
    public List<string> Descripcion
    {
        get { return _Descripcion; }
        set { _Descripcion = value; }
    }

    private List<string> _Referencia;
    public List<string> Referencia
    {
        get { return _Referencia; }
        set { _Referencia = value; }
    }

    private List<double> _Debito;
    public List<double> Debito
    {
        get { return _Debito; }
        set { _Debito = value; }
    }

    private List<double> _Credito;
    public List<double> Credito
    {
        get { return _Credito; }
        set { _Credito = value; }
    }

    private List<string> _Payee;
    public List<string> Payee
    {
        get { return _Payee; }
        set { _Payee = value; }
    }



    //private double _ValorLocal;
    //public double ValorLocal
    //{
    //    get
    //    {
    //        _ValorLocal = Credito - Debito;
    //        return _ValorLocal;
    //    }
    //    //set { _ValorLocal = value; }
    //}

    //private double _ValorDolares;
    //public double ValorDolares
    //{
    //    get
    //    {
    //        _ValorDolares = ValorLocal / TasaCambio;
    //        return _ValorDolares;
    //    }
    //    // set { _ValorDolares = value; }
    //}




    private string _NumeroCuenta;
    public string NumeroCuenta
    {
        get { return _NumeroCuenta; }
        set { _NumeroCuenta = value; }
    }
    private int _CodigoPais;
    public int CodigoPais
    {
        get { return _CodigoPais; }
        set { _CodigoPais = value; }
    }

    private string _Banco;
    public string Banco
    {
        get { return _Banco; }
        set { _Banco = value; }
    }

    private string _Moneda;
    public string Moneda
    {
        get { return _Moneda; }
        set { _Moneda = value; }
    }

    private double _TasaCambio;
    public double TasaCambio
    {
        get { return _TasaCambio; }
        set { _TasaCambio = value; }
    }

    private string _NombreEmpresa;
    public string NombreEmpresa
    {
        get { return _NombreEmpresa; }
        set { _NombreEmpresa = value; }
    }

    private string _CodigoBancario;
    public string CodigoBancario
    {
        get { return _CodigoBancario; }
        set { _CodigoBancario = value; }
    }

    private string _Categoria;
    public string Categoria
    {
        get { return _Categoria; }
        set { _Categoria = value; }
    }

    private string _Sector;
    public string Sector
    {
        get { return _Sector; }
        set { _Sector = value; }
    }
}

Уже код, который читает CSV и то, что отображается, я добавил с отдельными функциями, чтобы его было легче увидеть.

    static void Main(string[] args)
    {
        ReadCsvList();

        Console.WriteLine("...");
        Console.ReadLine();
    }


    private static void ReadCsvList()
    {
        string desk = System.IO.Directory.GetParent(@"../../").FullName;
        String path = $@"{desk}\filecsv.csv";
        var csvlines = File.ReadAllLines(path);


        //build header
        var header = csvlines[1].Split(',');

        clsEstadoCuenta nR = new clsEstadoCuenta();
        nR.NumeroCuenta = (String.IsNullOrEmpty(header[1])) ? "" : header[1];
        nR.CodigoPais = 504;
        nR.Banco = "Fichosa";
        nR.Moneda = (String.IsNullOrEmpty(header[2])) ? "" : header[2];
        nR.TasaCambio = 24.6;


        //build list of data
        foreach (var lines in csvlines.Skip(7))
        {
            var campos = lines.Split(',');

            //mount line
            string newline = "";
            for (int i = 0; i < campos.Count(); i++)
            {
                //Here the numbers that were divided by the Spli (',') 
                //are reassembled and saved in their respective fields.
                if (!string.IsNullOrEmpty(campos[i]))
                {
                    if (campos[i][0] == '\"')
                    {
                        campos[i] = campos[i] + campos[i + 1];
                        campos[i + 1] = "";
                        campos[i] = campos[i].Replace("\"", "");
                    }
                }

                newline += $"{campos[i]} \t";
            }

            //puts the values in the clsEstadoCuenta
            var tmpFecha = campos[0].Split('/');
            nR.FechaTransaccion.Add(new DateTime(Convert.ToInt32(tmpFecha[2]), Convert.ToInt32(tmpFecha[1]), Convert.ToInt32(tmpFecha[0])));
            nR.Descripcion.Add(String.IsNullOrEmpty(campos[1]) ? "" : campos[1]);
            nR.Referencia.Add(String.IsNullOrEmpty(campos[2]) ? "" : campos[2]);
            nR.Debito.Add(String.IsNullOrEmpty(campos[4]) ? 0 : Convert.ToDouble(campos[4]));
            nR.Credito.Add(String.IsNullOrEmpty(campos[5]) ? 0 : Convert.ToDouble(campos[5]));
            nR.Payee.Add("A");
        }

        //I will only display on the screen in 
        //this function below, it gets cleaner code.
        ListDataCSV(nR);
    }

    private static void ListDataCSV(clsEstadoCuenta data)
    {
        Console.WriteLine("Parsing the csv file");

        Console.WriteLine($"Conta: {data.NumeroCuenta} \t Pais: {data.CodigoPais} \t Banco: {data.Banco}");
        Console.WriteLine($"Moeda: {data.Moneda} \t\t Cambio: {data.TasaCambio}");

        Console.WriteLine($"");
        Console.WriteLine($"Date \t\t Description \t\t Númber Reference \t\t Débit \t Crédit \t Balance");

        for (int i = 0; i < data.GetTransactionsNumber(); i++)
        {
            var vdata = data.FechaTransaccion[i].ToString("dd/MM/yy HH:mm");
            var vdescription = data.Descripcion[i];
            var vreference = data.Referencia[i];
            var vdebito = data.Debito[i];
            var vcredito = data.Credito[i];
            var vpayee = data.Payee[i];

            Console.WriteLine($"{vdata} \t {vdescription} \t\t {vreference} \t\t {vdebito} \t {vcredito} \t {vpayee}");
        }
    }
0 голосов
/ 03 марта 2019

Используйте CSV-парсер , соответствующий RFC 4180 - Общий формат и тип MIME для файлов CSV .

Важно понимать, что использование двойногокавычки в вашем примере CSV, вероятно, будут обрабатывать такие случаи, как "74,258.74", где запятая не должна использоваться в качестве разделителя.Как указано в стандарте:

Каждое поле может быть или не быть заключено в двойные кавычки (однако некоторые программы, такие как Microsoft Excel, вообще не используют двойные кавычки).Если поля не заключены в двойные кавычки, то двойные кавычки могут не появляться внутри полей.Например:

  "aaa","bbb","ccc"
   zzz,yyy,xxx

Вот страница Getting Started для самого популярного совместимого парсера на NuGet .

0 голосов
/ 03 марта 2019

это ответ на вопрос Разобрать CSV с разделителями в .NET ..

Хороший способ разбора CSV в .NET заключается в использовании парсера vb.NET CSV.

https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.fileio.textfieldparser?view=netframework-4.7.2

вот дополнительная информация: тип или пространство имен "TextFieldParser" не найдено

0 голосов
/ 02 марта 2019

Проблема в том, что вы пытаетесь разделить ячейки, разделяя ',', но часть ячеек содержит ',' char.Пример: "9,722.29".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...