2017-08-09 53 views
0

我想下面這個方案:嘗試添加行時,行已經屬於另一個表錯誤?

This Row already belongs to another table error when trying to add rows?

我有一個包含597列和20行,並試圖將數據導出到Excel數據表。但是,Excel的最大列數爲256,因此我需要將源數據分成3個數據表以使導出工作正常。

下面是我寫的代碼。

var dtmasterdata = data.Tables[name]; 

for (int j = 1; j < datatableNumberCount; j++) 
         { 
          DataTable dt2 = new DataTable(); 
          dt2.TableName = "Master_" + j; 
          dt2 = dtmasterdata.Copy(); 

          foreach (DataColumn col in dtmasterdata.Columns) 
          { 
           DataColumn dtcol = new DataColumn(); 
           dtcol = col; 
           dt2.Columns.Add(dtcol.ColumnName, dtcol.DataType); 
          } 

          for (int k = 0; k < dtmasterdata.Rows.Count; k++) 
          { 
           DataRow dr = dt2.NewRow(); 
           dr = dtmasterdata.Rows[k]; 
           dt2.ImportRow(dtmasterdata.Rows[k]); 
           //dt2.Rows.Add(dr.ItemArray); 
          } 

之後,我需要刪除類似下面幾列,我要創建3個數據表

foreach (DataColumn col in dtmasterdata.Columns) 
          { 
           if (j == 1) 
           { 
            // condition 1 
            if (col.Ordinal >= 255) 
            { 
             dt2.Columns.RemoveAt(col.Ordinal); 
            } 
           } 

           if (j == 2) 
           { 
            // condition 2. 
            if (col.Ordinal < 255 || col.Ordinal >= 510) 
            { 
             dt2.Columns.RemoveAt(col.Ordinal); 
            } 
           } 

           if (j == 3) 
           { 
            // condition 3. 
            if (col.Ordinal <= 510 || col.Ordinal >= 765) 
            { 
             dt2.Columns.Add(col); 
            } 
           } 
          } 

int worksheetNumber = 1; 
          string worksheetNameWithNumber = "Master Data"; 
          if (worksheetNumber > 1) 
           worksheetNameWithNumber = String.Format("{0}_{1}", ws1, worksheetNumber.ToString()); 
          Infragistics.Excel.Worksheet worksheet = wb.Worksheets.Add(worksheetNameWithNumber); 
          Infragistics.WebUI.UltraWebGrid.UltraWebGrid masterData1 = new Infragistics.WebUI.UltraWebGrid.UltraWebGrid("masterDataGrid"); 
          masterData1.Browser = Infragistics.WebUI.UltraWebGrid.BrowserLevel.UpLevel; 
          masterData1.DataSource = dt2; 
          masterData1.DataMember = "Master_" + j; 
          masterData1.DisplayLayout.HeaderStyleDefault.Font.Bold = true; 
          masterData1.DisplayLayout.HeaderStyleDefault.Font.Name = "Arial"; 
          masterData1.DisplayLayout.HeaderStyleDefault.Font.Size = FontUnit.Parse("10px"); 
          masterData1.DisplayLayout.HeaderStyleDefault.BackColor = System.Drawing.Color.LightGray; 
          masterData1.DisplayLayout.RowStyleDefault.Font.Name = "Arial"; 
          masterData1.DisplayLayout.RowStyleDefault.Font.Size = FontUnit.Parse("10px"); 
          Infragistics.WebUI.UltraWebGrid.UltraGridBand masterBand1 = new Infragistics.WebUI.UltraWebGrid.UltraGridBand(); 
          masterData1.Bands.Add(masterBand1); 
          dgResults.Controls.Add(masterData1); 
          masterData1.DataBind(); 
          wb.ActiveWorksheet = worksheet; 
          this.ugWebGridExporter.Export(masterData1, worksheet); 
          worksheetNumber++; 
+0

@kapli這種方式進行 - 你有沒有看到我的回答呢? – Wheels73

回答

2

你的錯誤是因爲你正嘗試將列添加到已經屬於一個DataTable你源數據表。

dt2.Columns.Add(col); 

你不能只遍歷數據表的列並將它們添加到另一個。

我有一個解決方案,這涉及克隆源數據和刪除你不需要的東西。

1,製作你需要的數據表的3個克隆。以下是我用596列創建自己的源表的例子。注意克隆只需要數據表結構,沒有數據!

var source597ColsTable = new DataTable("Source"); 

for (var i = 0; i <= 596; i++) 
{ 
    source597ColsTable.Columns.Add(new DataColumn("Column" + i , typeof(string))); 
} 

DataRow newRow = source597ColsTable.NewRow(); 
source597ColsTable.Rows.Add(newRow); 

var cols0To199Table = source597ColsTable.Clone(); 
var cols200To399Table = source597ColsTable.Clone(); 
var cols400To596Table = source597ColsTable.Clone(); 

接下來將源表中的所有行復制到克隆中。以下是一個簡單的功能。

private DataTable CopyRowsFromSource(DataTable sourceTable, DataTable destinationTable) 
    { 
    foreach (DataRow row in sourceTable.Rows) 
    { 
     destinationTable.Rows.Add(row.ItemArray); 
    } 

     return destinationTable; 
    } 

然後爲每個表調用此函數。

cols0To199Table = CopyRowsFromSource(source597ColsTable, cols0To199Table); 
    cols200To399Table = CopyRowsFromSource(source597ColsTable, cols200To399Table); 
    cols400To596Table = CopyRowsFromSource(source597ColsTable, cols400To596Table); 

最後,從數據表中刪除所有列,以便爲您分割。

private DataTable RemoveColumns(DataTable table, int startCol, int endCol) 
{ 
     var colsToRemove = new List<DataColumn>(); 

     for (var colCount = startCol; colCount <= endCol; colCount++) 
     { 
      colsToRemove.Add(table.Columns[colCount]); 
     } 

     foreach (DataColumn col in colsToRemove) 
     { 
      table.Columns.Remove(col); 
     } 

     return table; 
} 

然後再次爲每個克隆表調用..

cols0To199Table = RemoveColumns(cols0To199Table, 200, 596); 

cols200To399Table = RemoveColumns(cols200To399Table, 0, 199); 
cols200To399Table = RemoveColumns(cols200To399Table, 200, 396); 

cols400To596Table = RemoveColumns(cols400To596Table, 0, 399); 

運行此操作後,您將有3個數據表,0-199,200-399和400-596列。

希望有所幫助。

1

我不確定是否真的瞭解了所有代碼,但要將列的子集複製到另一個數據表中,DataView類中有一個非常簡單的方法,名爲ToTable,您可以在其中列出所需的列表。作爲額外的獎勵,此方法還會複製原始表的20行中的數據。

所以唯一的困難是列出這些列的方法。

您可以使用LINQ在DataColumn的集合

string[] firstCols = dtmasterdata.Columns 
         .Cast<DataColumn>() 
         .Take(255) 
         .Select(x => x.ColumnName).ToArray(); 
string[] secondCols = dtmasterdata.Columns 
          .Cast<DataColumn>() 
          .Skip(255) 
          .Take(255) 
          .Select(x => x.ColumnName).ToArray(); 
string[] thirdCols = dtmasterdata.Columns 
         .Cast<DataColumn>() 
         .Skip(510) 
         .Select(x => x.ColumnName).ToArray(); 

DataTable t1 = dtmasterdata.DefaultView.ToTable("Master_1", false, firstCols); 
DataTable t2 = dtmasterdata.DefaultView.ToTable("Master_2", false, secondCols); 
DataTable t3 = dtmasterdata.DefaultView.ToTable("Master_3", false, thirdCols); 
相關問題