我已经在其他地方发布了这个但是我对这个要求的理解对主持人@ShaiCohen是不正确的,他正在帮我建议我重新发布它。
我需要编辑提供给DataTable
的数据,这些数据可能有不同的列和行,但前两列是常量。数据看起来像这样(行开头的数字不是数据的一部分):
Repair Repair
Code Code Entries 6/1/2012 7/1/2012 8/1/2012 9/1/2012
------ -------------------- -------- -------- -------- --------
1. 00000A Critical Down Time 1
2. 00000A Critical Outage 1
3. 00000A Total Repair Time 65
4. 00000B Critical Down Time 6
5. 00000B Total Repair Time 90
6. 00000C Critical Down Time 1 5
7. 00000C Critical Outage 1 5
8. 00000C Total Repair Time 30 240
9. 00000D Critical Down Time 2
10. 00000E Critical Down Time 1
11. 00000G Critical Down Time 1
12. 00000M Critical Down Time 1 3
13. 00000M Critical Outage 1 3
14. 00000M Total Repair Time 60 180
请注意,第1-3,6-8行具有相同的修复代码类别,因此被视为组。另一方面,第10-12行只有“严重停机时间”子类别,而其余部分则有三者的组合。
要求是在不存在的情况下插入“修复代码条目”子类别。它们不存在的原因是因为数据库中没有数据,但是即使没有相应的数据,客户也希望看到丢失的词汇,并插入一个空行来分隔这样的组:
Repair Repair
Code Code Entries 6/1/2012 7/1/2012 8/1/2012 9/1/2012
------ -------------------- -------- -------- -------- --------
1. 00000A Critical Down Time 1
2. 00000A Critical Outage 1
3. 00000A Total Repair Time 65
4. 00000B Critical Down Time 6
00000B Critical Outage
5. 00000B Total Repair Time 90
6. 00000C Critical Down Time 1 5
7. 00000C Critical Outage 1 5
8. 00000C Total Repair Time 30 240
9. 00000D Critical Down Time 2
00000D Critical Outage
00000D Total Repair Time
但是,当前的代码假定数据始终是三个子类别的分组,因此当它不是这样时,前一行的子类别将子类别写入当前行:
8. 00000C Total Repair Time 30 240
9. 00000D Total Repair Time (should be Critical Down Time) 2
00000D Critical Outage
在代码(下面)中,subCategoryOccurences
方法中的计数器CheckSubCategoryRequirements
在处理新行时不会重置为零。
public void PrepareDataTable(DataTable dtResults)
{
if (dtResults == null || dtResults.Rows.Count == 0)
return;
//initialize category
categoryPrevious = dtResults.Rows[0]["Category"].ToString();
do
{
//get the current category
categoryCurrent = dtResults.Rows[rowCount]["Category"].ToString();
//check if this is a new category. this is where all the work is done
if (categoryCurrent != categoryPrevious)
{
//check if we have fulfilled the requirement for number of subcategories
CheckSubCategoryRequirements(dtResults);
//at this point we have fulfilled the requirement for number of subcategories
//add blank (separator) row
dtResults.Rows.InsertAt(dtResults.NewRow(), rowCount);
rowCount++;
//reset the number of subcategories
subCategoryOccurences = 0;
categoryPrevious = categoryCurrent;
}
else
{
rowCount++;
categoryOccurences++;
}
} while (rowCount < dtResults.Rows.Count);
//check sub category requirements for the last category
CheckSubCategoryRequirements(dtResults);
}
private void CheckSubCategoryRequirements(DataTable dtResults)
{
if (subCategoryOccurences< subCategories.Length)
{
//we need to add rows for the missing subcategories
while (subCategoryOccurences< subCategories.Length)
{
//create a new row and populate category and subcategory info
rowFiller = dtResults.NewRow();
rowFiller["Category"] = categoryPrevious;
rowFiller["SubCategory"] = subCategories[subCategoryOccurences];
//insert the new row into the current location of table
dtResults.Rows.InsertAt(rowFiller, rowCount);
subCategoryOccurences++;
rowCount++;
}
}
}
我试图在方法调用之前移动计数器,但这会产生不良结果,因此我不确定从何处开始。我希望有建设性的意见。谢谢。 R上。
答案 0 :(得分:3)
对于这些要求,我采取了与以前不同的方法。有了这些新要求,我们就必须“向后”插入以前缺少的子类别。
此方法创建一个 new 表,用于为原始表中存在的每个类别填充正确数量的子类别。创建新行后,我们检查旧表,看看是否有任何数据需要复制到 new 表(即:“6/1 / 2012“和”7/1/2012“来自你的例子。”
试试这段代码:
public DataTable PrepareDataTable(DataTable dtResults)
{
string[] subCategories = new string[3] {"Critical Down Time", "Critical Outage", "Total Repair Time"};
//make a copy of the original table
DataTable dtOutput = dtResults.Clone();
DataRow drOutput = null;
DataRow[] drResults = null;
//retrieve the list of Categories
var categories = dtResults.AsEnumerable().Select(r => r["Category"]).Distinct().ToList();
//populate the new table with the appropriate rows (combinations of categories/subcategories)
foreach (string category in categories)
{
for (int i = 0; i < subCategories.Length ; i++)
{
//create the new row in the new table
drOutput = dtOutput.NewRow();
drOutput["Category"] = category;
drOutput["SubCategory"] = subCategories[i];
//here is where you will check to see if a row with the same category and subcategory exists in dtResults. if it does, then copy over the values for each column
drResults = dtResults.Select(String.Format("Category = '{0}' AND SubCategory = '{1}'", category, subCategories[i]));
if(drResults.Length > 0)
{
foreach(DataColumn column in dtResults.Columns)
{
drOutput[column.ColumnName] = drResults[0][column.ColumnName];
}
}
dtOutput.Rows.Add(drOutput);
}
//add filler/spacer row
drOutput = dtOutput.NewRow();
dtOutput.Rows.Add(drOutput);
}
return dtOutput;
}
这是“测试工具”:
public void RunTest()
{
DataTable dtResults = new DataTable();
dtResults.Columns.Add("Category");
dtResults.Columns.Add("SubCategory");
dtResults.Columns.Add("Data");
dtResults.Rows.Add("00000A", "Critical Down Time", "1");
dtResults.Rows.Add("00000A", "Critical Outage", "1");
dtResults.Rows.Add("00000A", "Total Repair Time", "1");
dtResults.Rows.Add("00000B", "Critical Down Time", "1");
dtResults.Rows.Add("00000B", "Total Repair Time", "1");
dtResults.Rows.Add("00000C", "Critical Down Time", "1");
dtResults.Rows.Add("00000C", "Critical Outage", "1");
dtResults.Rows.Add("00000C", "Total Repair Time", "1");
dtResults.Rows.Add("00000D", "Critical Down Time", "1");
dtResults.Rows.Add("00000E", "Critical Down Time", "1");
dtResults.Rows.Add("00000G", "Critical Down Time", "1");
dtResults.Rows.Add("00000M", "Critical Down Time", "1");
dtResults.Rows.Add("00000M", "Critical Outage", "1");
dtResults.Rows.Add("00000M", "Total Repair Time", "1");
DataTable dtOutput = PrepareDataTable(dtResults);
}