我有一个文本文件,它存储有关生产信息和过程的信息。该过程由Stripping、Cleaning、Paint等几个阶段组成,这些阶段存储的日期可以是expected date、start date、finished date、delay date。
一个示例.txt文件:
567,Eindhoven,21岁,汽提_e=20/05/2020,汽提_s=21/05/2020,剥落_f=22/05/2020,清洁_e=23/05/2020,清洁_s=27/05/2020,清洁_f=28/05/2020,油漆_e=28/05/2020,Panint_s=28/05/2020,油漆_f=29/05/2020,内阁_e=29/05/2020,内阁_s=31/05/2020,Cabinet_f=,Table_e=,Table_s=,Table_f=,Stand_e=,Stand_s=,Stand_f=,Display_e=,Display_s=,Display_f=,UControls_e=,UControls_s=,UControls_f=,Test_e=,Test_s=,Test_f=,Prepack_e=,Prepack_s=,Prepack_f=,Endpack_e=,Endpack_s=,Endpack_f=,Release_e=,Release_s=,Release_f=,
在读取此.txt文件后,我将其存储在dataGridView中,如下所示:

但是,我不知道如何将最新的日期添加到相应的列中。如果在文本文件中看到Stripping_e,则希望重写Stripping列中的Stripping_f值。其余的列也是一样。这也是我不一定有一个日期(预期,开始,完成或推迟)的专栏。
下面是我目前使用的代码:
private void IGT_Load(object sender, EventArgs e)
{
table.Columns.Add("SalesNr", typeof(int));
table.Columns.Add("PName", typeof(string));
table.Columns.Add("Type", typeof(int));
table.Columns.Add("Stripping", typeof(string));
table.Columns.Add("Cleaning", typeof(string));
table.Columns.Add("Paint", typeof(string));
table.Columns.Add("Cabinet", typeof(string));
table.Columns.Add("Table", typeof(string));
table.Columns.Add("Stand", typeof(string));
table.Columns.Add("Display", typeof(string));
table.Columns.Add("User Controls", typeof(string));
table.Columns.Add("Test", typeof(string));
table.Columns.Add("Pre-pack", typeof(string));
table.Columns.Add("End-pack", typeof(string));
table.Columns.Add("Release for Delivery", typeof(string));
dataGridView1.DataSource = table;
Import();
}
private void Import()
{
// get lines from the text file
string[] lines = File.ReadAllLines(@"..\..\567.txt");
string[] values;
for (int i = 0; i < lines.Length; i++)
{
values = lines[i].ToString().Split(',', '=');
string[] row = new string[values.Length];
for (int j = 0; j < values.Length; j++)
{
if(values[j] == "Stripping_e")
{
row[j] = values[j + 1].Trim();
j++;
}
else if (values[j] == "Stripping_s")
{
row[j-2] = values[j+1].Trim();
j++;
}
else if(values[j] == "Cleaning_s" || values[j] == "Cleaning_e" || values[j] == "Cleaning_f" || values[j] == "Cleaning_d")
{
row[j] = values[j + 1].Trim();
}
else
{
row[j] = values[j].Trim();
}
}
table.Rows.Add(row);
}
}table是以DataSource的形式连接到dataGridView1的DataTable。
我以前从未处理过文本文件,所以我非常感谢您的帮助!
发布于 2020-12-10 14:23:45
读一个半非结构化的CSV可能是很棘手的,你必须对CSV文件有很大的信心总是正确的。示例,如果类别的日期之一拼写错误,如…“Panint_s=28/05/2020”…在发布的数据…中然后,在下面的代码中,这种拼写错误不会抛出任何类型的错误或消息,它将永远不会被使用。所以编码器要小心。下面是这样一种“讨厌”的方法。
您可能遇到的一个复杂问题是当前代码是如何使用字符串数组(string[])的。这会使事情变得更复杂。当代码到达SomeCategory=SomeDate点时,它很有用。下面是一个字符串数组,用于这些拆分来获取类别的日期。在代码的其他部分,它使用一个List<string>来分隔数据中的行。当我们想要获得“特定”类别的日期时,这将有所帮助。下面会有更多。
因此,给出一个数据的string,例如string是网格中的“单一”行,那么我将在逗号上“拆分”这个字符串。然后将字符串数组转换为List<string>。它可能看起来像…
List<string> SplitRow = curRow.Split(',').ToList();考虑到发布的单行数据,这个List<string> allData看起来可能类似于…。

可以看到,我们将使用这个List<string>来获取网格中前三个单元格的数据,当我们到达代码中我们想要获得特定类别的“最新”日期的部分时,我们可以“过滤”这个List<string>,使其只包含我们想要的类别。如果allData是上面的List<string>,那么要筛选列表仅包含我们想要的类别,代码可能看起来类似于…。
String targetCategory = “Stripping”;
List<string> categoryData = allData.Where(x => x.Contains(targetCategory)).ToList();这将产生一个只有“剥离”类别的List<string> categoryData。就像下面的…

使用此列表,我们可以循环遍历所有字符串,解析日期,并从所有给定日期返回最新日期。如果我们创建一个返回此日期字符串的方法,那么我们可以使用它为每一行分配网格中的每个类别列。
因此,采用allData列表和string类别进行…筛选的方法。也许会派上用场。此方法可能类似于…下面的内容。
private string GetLatestDateForCategory(List<string> allData, string targetCategory) {
List<string> categoryData = allData.Where(x => x.Contains(targetCategory)).ToList();
DateTime latestDate = DateTime.MinValue;
string[] splitArray;
foreach (string catLine in categoryData) {
splitArray = catLine.Split('=');
if (splitArray.Length >= 2) {
if (DateTime.TryParseExact(splitArray[1], "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date)) {
if (date > latestDate) {
latestDate = date;
}
}
}
}
if (latestDate != DateTime.MinValue) {
return latestDate.ToShortDateString();
}
return "";
}遍历此方法将从“过滤”所有数据开始,以获得targetCategory字符串值的列表。然后创建一个DateTime变量来比较日期,并将其用作最新日期。我们将把日期设置为“min”值,并使用这个“min”日期来指示类别中没有日期。接下来是字符串数组splitArray,用于拆分“=”字符上的每个字符串。
将启动一个遍历列表中所有筛选字符串的循环。在拆分“=”字符上的字符串后,将进行检查,以确保字符串中有日期。如果存在日期字符串,则将该日期解析为DateTime对象,以便进行比较。如果日期分析成功,则代码将检查已解析的日期到最新日期。如果分析的日期晚于当前latestDate,则更新该日期以反映此更新的最新日期。
检查完所有日期后,代码将检查latestDate。如果latestDate仍然是“Min”值,那么这意味着没有为该类别找到日期,并且返回一个空字符串,否则代码将返回最新的日期字符串。
如果代码循环遍历有许多行的数据中的每个字符串,那么当我们想从特定类别获得最新的日期时,上面的方法就会派上用场了。
因此,将这些放在一起可能类似于下面的…
private void Import() {
List<string> allLines = File.ReadAllLines(@"D:\Test\CSV\567.txt").ToList();
DataRow dr;
List<string> SplitRow;
int value;
foreach (string curRow in allLines) {
dr = table.NewRow();
SplitRow = curRow.Split(',').ToList();
if (SplitRow.Count >= 3) {
value = 0;
if (int.TryParse(SplitRow[0], out value)) {
dr["SalesNr"] = value;
}
if (int.TryParse(SplitRow[2], out value)) {
dr["Type"] = value;
}
dr["PName"] = SplitRow[1];
dr["Stripping"] = GetLatestDateForCategory(SplitRow, "Stripping");
dr["Cleaning"] = GetLatestDateForCategory(SplitRow, "Cleaning");
dr["Paint"] = GetLatestDateForCategory(SplitRow, "Paint");
dr["Cabinet"] = GetLatestDateForCategory(SplitRow, "Cabinet");
dr["Table"] = GetLatestDateForCategory(SplitRow, "Table");
dr["Stand"] = GetLatestDateForCategory(SplitRow, "Stand");
dr["Display"] = GetLatestDateForCategory(SplitRow, "Display");
dr["User Controls"] = GetLatestDateForCategory(SplitRow, "UControls");
table.Rows.Add(dr);
}
}
}从从CSV文件中获取List<string>开始,遍历此方法。在已发布的数据中,这将是列表中的单个字符串。接下来定义一个DataRow dr,我们将使用此行来添加从数据中获得的值。另一个List<string> SplitRow用于列表中的“每个”字符串。最后,一个int value,用于解析int值SalesNr和Type。
从所有数据开始遍历每个字符串的循环,从现有的DataRow中创建一个新的table,然后在逗号“;”上拆分当前字符串。检查以确保SalesNr、PName和Type至少有三个(3)值。解析SalesNr和Type值,然后将PName字符串值设置为新行。然后,每个“类别”将使用上面的方法来设置每个类别的日期字符串。最后,该行被添加到table中。注意:并非所有类别都填写在代码中。
我希望这是合理的。它很讨厌,但在我的测试中起了作用。祝好运。
发布于 2020-12-10 15:32:11
我就是这样做的。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Globalization;
namespace WindowsFormsApplication71
{
public partial class Form1 : Form
{
const string FILENAME = @"c:\temp\test.csv";
public Form1()
{
InitializeComponent();
StreamReader reader = new StreamReader(FILENAME);
string line = "";
int row = 0;
DataTable dt = new DataTable();
while ((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length > 0)
{
string[] columns = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
List<object> newRow = new List<object>(); ;
if (++row == 1)
{
dt.Columns.Add("SalesNr", typeof(string));
dt.Columns.Add("PName", typeof(string));
dt.Columns.Add("Type", typeof(int));
}
for (int col = 0; col < columns.Length; col++)
{
switch (col)
{
case 0:
newRow.Add(columns[0]);
break;
case 1:
newRow.Add(columns[1]);
break;
case 2:
newRow.Add(columns[2]);
break;
default:
string[] keyValue = columns[col].Split(new char[] { '=' });
if (row == 1)
{
dt.Columns.Add(keyValue[0], typeof(DateTime));
}
if (keyValue[1].Trim().Length > 0)
{
newRow.Add(DateTime.ParseExact(keyValue[1], "dd/MM/yyyy", CultureInfo.InvariantCulture));
}
else
{
newRow.Add(null);
}
break;
}
}
dt.Rows.Add(newRow.ToArray());
}
}
dataGridView1.DataSource = dt;
}
}
}https://stackoverflow.com/questions/65233281
复制相似问题