-1

我想做什么

基本上我会遍历我的所有文件夹以捕获是否有 .txt 文档。当我通过这个循环时,我想将此文档中的标题和行添加到DataTable. 我的列在每个文件中总是相同的。

我到目前为止使用的代码

DataTable csvData = new DataTable();

string[] fullpath = Directory.GetFiles(@"D:\Stack", "*.txt", System.IO.SearchOption.AllDirectories);

            foreach(string s in fullpath)
            {

                DataTable eachfile = new DataTable();

            using (TextFieldParser csvReader = new TextFieldParser(s))
            {


                        csvReader.SetDelimiters(new string[] { ";" });
                        csvReader.HasFieldsEnclosedInQuotes = false;
                        string[] colFields = csvReader.ReadFields();
                        foreach (string column in colFields)
                        {
                            DataColumn datecolumn = new DataColumn(column);
                            datecolumn.AllowDBNull = true;
                        eachfile.Columns.Add(datecolumn);
                        }

                    eachfile.Columns.Add("SalesNo");
                    eachfile.Columns.Add("Date");


                    while (!csvReader.EndOfData)
                    {

                        csvReader.SetDelimiters(new string[] { "," });

                        string[] fieldData = csvReader.ReadFields();
                        //Making empty value as null
                        for (int i = 0; i < fieldData.Length; i++)
                        {
                            if (fieldData[i] == "")
                            {
                                fieldData[i] = null;
                            }
                        }

                        Match conum = Regex.Match(s, @"SalesNo\d+");
                        Match cycle = Regex.Match(s, @"Date\d{8}");


                        DataRow row = eachfile.NewRow();

                        //Alternativ
                        //row["FirstName"] = fieldData[0];
                        row[0] = fieldData[0];
                        row[1] = fieldData[1];
                        row[2] = conum;
                        row[3] = cycle;

                        eachfile.Rows.Add(row);

                        csvData = eachfile.Copy();
                    }



                }
            }
        }

我的问题是什么

那么在我的代码中,我尝试将数据添加到一个DataTable名为 eachfile 的文件中。但是我不能将它添加到我的 mainDataTable csvData中,因为它每次都会被覆盖。我真正想要的是将所有数据收集到一个 DataTable csvData 但只添加一次 HeaderRows (从我循环的第一个文件开始)

我需要什么

我需要重新编写我认为的代码,所以当我遍历第一个文件时,它使用此处的代码将我的标题添加到csvData DataTable

 csvReader.SetDelimiters(new string[] { ";" });
                        csvReader.HasFieldsEnclosedInQuotes = false;
                        string[] colFields = csvReader.ReadFields();
                        foreach (string column in colFields)
                        {
                            DataColumn datecolumn = new DataColumn(column);
                            datecolumn.AllowDBNull = true;
                        eachfile.Columns.Add(datecolumn);
                        }

                    eachfile.Columns.Add("CoNum");
                    eachfile.Columns.Add("CycleDate");

完成此操作并且我已从第一个文件中插入数据后,我不想为下一个文件再次添加标题行,因为它会由于名称重复而失败。但只将数据添加到已经存在的 csvData 中(而不是覆盖之前添加的数据)

我想我能做什么?

我想我需要计算它是否是第一个文件,并做这样的事情,我计算完整路径的数量,如果是 1,我会通过标题,否则我会转到我的 else,我首先读取行,所以我不会得到第一个排?

 if (fullpath.Count() == 1)
                    {

                        csvReader.SetDelimiters(new string[] { ";" });
                        csvReader.HasFieldsEnclosedInQuotes = false;
                        string[] colFields = csvReader.ReadFields();
                        foreach (string column in colFields)
                        {
                            DataColumn datecolumn = new DataColumn(column);
                            datecolumn.AllowDBNull = true;
                            csvData.Columns.Add(datecolumn);
                        }

                        csvData.Columns.Add("CoNum");
                        csvData.Columns.Add("CycleDate");


                        while (!csvReader.EndOfData)
                        {

                            csvReader.SetDelimiters(new string[] { "," });

                            string[] fieldData = csvReader.ReadFields();
                            //Making empty value as null
                            for (int i = 0; i < fieldData.Length; i++)
                            {
                                if (fieldData[i] == "")
                                {
                                    fieldData[i] = null;
                                }
                            }

                            Match conum = Regex.Match(s, @"CoNum\d+");
                            Match cycle = Regex.Match(s, @"CycleDate\d{8}");


                            DataRow row = csvData.NewRow();

                            //Alternativ
                            //row["FirstName"] = fieldData[0];
                            row[0] = fieldData[0];
                            row[1] = fieldData[1];
                            row[2] = conum;
                            row[3] = cycle;

                            csvData.Rows.Add(row);
                        }
                    }
                    else
                    {
                        csvReader.ReadLine();
                        while (!csvReader.EndOfData)
                        {

                            csvReader.SetDelimiters(new string[] { "," });

                            string[] fieldData = csvReader.ReadFields();
                            //Making empty value as null
                            for (int i = 0; i < fieldData.Length; i++)
                            {
                                if (fieldData[i] == "")
                                {
                                    fieldData[i] = null;
                                }
                            }

                            Match conum = Regex.Match(s, @"CoNum\d+");
                            Match cycle = Regex.Match(s, @"CycleDate\d{8}");


                            DataRow row = csvData.NewRow();

                            //Alternativ
                            //row["FirstName"] = fieldData[0];
                            row[0] = fieldData[0];
                            row[1] = fieldData[1];
                            row[2] = conum;
                            row[3] = cycle;

                            csvData.Rows.Add(row);
                        }


                    }

提前致谢 !

4

1 回答 1

1

您的问题似乎与检测 foreach循环的第一次迭代有关。所有其他构建块,如添加列和添加数据行,看起来都很好并且可以工作。

有很多选择。一种是改用for循环,并且仅当循环计数器具有其起始值时才添加列。一种是添加一个标志,以确保仅在第一次迭代中添加列:

var isfirstfile = true;
foreach(var file in files)
{
    if(isfirstfile)
    {
        /* add the columns */


        isfirstfile = false;
    }
    else 
    {
        /* skip the first row of the current input file */
    }
    /* add the data rows */

}

当然,这假设所有文件都以相同的顺序具有相同数量和类型的列。

于 2017-12-15T15:01:30.690 回答