当我循环遍历第一个文件时不想添加 header 行
Dont want to add header rows when i have looped through first file
我想做什么
基本上我会循环遍历我的所有文件夹以捕获是否有 .txt 文档。
当我循环遍历此文件时,我想将此文档中的 header 和行添加到 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();
}
}
}
}
我的问题是什么
好吧,在我的代码中,我尝试将数据添加到名为 eachfile 的 DataTable
。但是我不能将它添加到我的主DataTable csvData
,因为它每次都会被覆盖。我真正想要的是将我所有的数据收集到一个 DataTable csvData 中,但只添加一次 HeaderRows(从我循环的第一个文件开始)
我需要什么
我需要 re-write 我认为的代码,所以当我遍历第一个文件时,它使用此处的代码将我的 header 添加到 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");
完成后,我已从第一个文件插入数据,我不想为下一个文件再次添加 header 行,因为它会因名称重复而失败。但是只将数据添加到已经存在的 csvData(而不是覆盖之前添加的数据)
我觉得我能做什么?
我想我需要计算它是否是第一个文件,然后做这样的事情
我在哪里计算完整路径的数量,如果是 1,我会通过 headers 否则我会去我的其他地方,我首先读取行所以我不会得到第一行?
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);
}
}
提前致谢!
您的问题似乎与检测 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 */
}
当然,这假设所有文件都具有相同数量和类型的列,顺序相同。
我想做什么
基本上我会循环遍历我的所有文件夹以捕获是否有 .txt 文档。
当我循环遍历此文件时,我想将此文档中的 header 和行添加到 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();
}
}
}
}
我的问题是什么
好吧,在我的代码中,我尝试将数据添加到名为 eachfile 的 DataTable
。但是我不能将它添加到我的主DataTable csvData
,因为它每次都会被覆盖。我真正想要的是将我所有的数据收集到一个 DataTable csvData 中,但只添加一次 HeaderRows(从我循环的第一个文件开始)
我需要什么
我需要 re-write 我认为的代码,所以当我遍历第一个文件时,它使用此处的代码将我的 header 添加到 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");
完成后,我已从第一个文件插入数据,我不想为下一个文件再次添加 header 行,因为它会因名称重复而失败。但是只将数据添加到已经存在的 csvData(而不是覆盖之前添加的数据)
我觉得我能做什么?
我想我需要计算它是否是第一个文件,然后做这样的事情 我在哪里计算完整路径的数量,如果是 1,我会通过 headers 否则我会去我的其他地方,我首先读取行所以我不会得到第一行?
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);
}
}
提前致谢!
您的问题似乎与检测 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 */
}
当然,这假设所有文件都具有相同数量和类型的列,顺序相同。