2013-03-07 82 views
2

我已經在其他地方發佈了這個記錄,但是我對該要求的理解對於主持人@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方法沒有得到rese當新行被處理時,t爲零。

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

@ShaiCohen,根據您的要求我重新張貼了這個。 – Risho 2013-03-07 17:30:59

+0

如果你的表格被標準化了,這會容易得多。 – 2013-03-07 19:35:46

+0

@JohnSaunders,這不是標準化的問題,查詢使用了一個數據透視表,這樣通常在單個列中的日期現在顯示爲列,而底層數據由查詢計算。 – Risho 2013-03-07 20:00:54

回答

3

對於這些要求,我採取了與以前不同的方法。有了這些新的要求,我們將不得不「倒退」插入先前缺失的子類別。

此方法創建一個新的表,該表填充了原始表中存在的每個類別的正確數量的子類別。一旦新行被創建,我們然後檢查舊的表,以查看是否有任何數據需要複製到新表表(即:「6/1/2012」和「2012年7月1日」 「從你的例子)。

試試這個代碼:

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); 
} 
+0

它幾乎可以工作,我得到的只是第一和第二列 - 沒有日期下的值。我跑了一趟,早上再次訪問。再次非常感謝! – Risho 2013-03-07 22:52:38

+0

我們正在接近!當您運行我提供的「測試設備」時會發生什麼?你有沒有得到「數據」欄?如果是這樣,請嘗試在此行上放置斷點'drOutput [column.ColumnName] = drResults [0] [column.ColumnName];'。如果代碼放在那裏,它應該添加所有附加列。 – 2013-03-07 23:56:13

+0

如果我運行'RunTest()'我得到了「數據」列中的值。 – Risho 2013-03-08 15:17:05