2

私はこれを別の場所に投稿しましたが、要件についての私の理解は、私を助けてくれたモデレーター @ShaiCohen にとって間違っていたため、再投稿するよう提案されました。

さまざまな列と行を持つことができる供給されるデータを編集する必要がDataTableありますが、最初の 2 つの列は一定です。データは次のようになります (行頭の数字はデータの一部ではありません)。

    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 には「重大なダウンタイム」サブカテゴリのみがあり、残りは 3 つの組み合わせになっています。

要件は、存在しない場所に「修理コード エントリ」サブカテゴリを挿入することです。それらが存在しない理由は、データベースにデータがないためですが、クライアントは、対応するデータがなくても不足している言葉遣いが表示されることを望んでおり、次のようにグループを区切るために空の行を挿入したいと考えています。

    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        

ただし、現在配置されているコードは、データには常に 3 つのサブカテゴリのグループがあると想定しているため、そうでない場合は、前の行のサブカテゴリが現在の行のサブカテゴリを上書きします。

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.

4

1 に答える 1

3

これらの要件については、以前とは異なるアプローチを採用しました。これらの新しい要件では、以前は欠落していたサブカテゴリを挿入するために「後方に移動」する必要があります。

このアプローチでは、元のテーブルに存在する各カテゴリの正しい数のサブカテゴリを設定する新しいテーブルが作成されます。新しい行が作成されたら、古いテーブルをチェックして、新しいテーブルにコピーする必要のあるデータがあるかどうかを確認します(例:例の「2012年6月1日」と「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);
}
于 2013-03-07T19:30:35.903 に答える