1

すべて、DataTablesをExcelに(.xlsと.xlsxの両方のファイルタイプに)エクスポートするユーティリティがあります。DataTable(SQL Serverから取得された)列または行の制限に達したら、DataTableを子に分割し、それぞれが制限に従います(.xls 256列と65,536行、および.xlsx 16,384列と1,048,576行の場合)。

これまでのところ、私は自分がやりたいことをするために次のメソッドを書きました

public static List<DataTable> SplitDataTable(DataTable mother, int nColLimit)
{
    List<int[]> rangeList = new List<int[]>();
    int primaryCols = mother.Columns.Count;
    int nSplitCount = Convert.ToInt32(primaryCols / nColLimit);
    int max = -1;

    // Get the child ranges.
    int tmpSup = 0;
    for (int splits = 0; splits < nSplitCount; splits++)
    {
        if (rangeList.Count == 0)
            tmpSup = (splits + 1) * (nColLimit - 1);
        else
            tmpSup = rangeList[splits - 1][1] + nColLimit;
        rangeList.Add(new int[2] { splits * nColLimit, tmpSup });
        if (max < tmpSup)
            max = tmpSup;
    }
    rangeList.Add(new int[2] { ++max, primaryCols });

    // Build child DataTables.
    List<DataTable> childList = new List<DataTable>();
    int childIndex = 0;
    foreach (int[] range in rangeList)
    {
        childList.Add(new DataTable());
        for (int i = range[0]; i < range[1]; i++)
            for (int j = 0; j < mother.Rows.Count; j++)
                childList[childIndex].Rows[j][i] = mother.Rows[j][i];
        childIndex++;
    }
    return childList;
}

indexOutOfRangeExceptionただし、これは「位置0に行がありません。」というメッセージとともにをスローします。エラーがどこから来ているのかはわかりますが、列全体をからmother子にコピーするための最良の方法は何ですか?

私も試しました

List<DataTable> childList = new List<DataTable>();
int childIndex = 0;
foreach (int[] range in rangeList)
{
    childList.Add(new DataTable());
    foreach(DataRow row in mother.Rows)
    {
        DataRow tmpRow = childList[childIndex].NewRow();
        for (int i = range[0]; i < range[1]; i++)
            tmpRow[i + 1] = row[i + 1];
    }
    childIndex++;
}

同じ範囲の例外が発生します。

御時間ありがとうございます。

編集:私がこの短期間にどのようにしたか

foreach (int[] range in rangeList)
{
    childList.Add(new DataTable());
    string strSqlTmp =
    String.Format("declare @columns varchar(max) " +
        "select  @columns = case when @columns is null " +
        "then '' " +
        "else @columns + ', ' " +
        "end + name " +
             "from sys.columns " +
             "where object_id = object_id('{0}') and name in " +
                 "(SELECT COLUMN_NAME " +
                     "FROM [{1}].INFORMATION_SCHEMA.COLUMNS " +
                     "WHERE TABLE_NAME = N'{0}' " +
                     "AND ORDINAL_POSITION > {2} AND ORDINAL_POSITION < {3}) " +
        "declare @query varchar(max) " +
        "set @query = 'select ' + @columns + ' from {0}' " +
        "exec (@query);
    // Then get each DataTable from SQL Server and fill the child list...
4

2 に答える 2

1

データ テーブルを分割するためのメソッドを作成しました。「.Batch」メソッドは、MoreLinq から参照されます。

private static List<DataTable> SplitTable(DataTable originalTable, int batchSize)
        {
            List<DataTable> tables = new List<DataTable>();

            foreach (var rowBatch in originalTable.Rows.Cast<DataRow>().Batch(batchSize))
            {
                var batchTable = new DataTable(originalTable.TableName);

                foreach (DataColumn column in originalTable.Columns)
                    batchTable.Columns.Add(column.ColumnName, column.DataType);

                foreach (DataRow row in rowBatch)
                    batchTable.Rows.Add(row.ItemArray);

                tables.Add(batchTable);
            }
            return tables;
        }

念のため、これは誰にとっても役立つでしょう:)

于 2013-05-02T08:11:05.573 に答える
1

例外が発生する理由は、存在しないnew で sIndexOutOfRangeを参照しようとしているためです。この行:ColumnDataTable

childList.Add(new DataTable()); 

DataTableは確かに newをに追加しますchildListが、これにDataTableは列と行がありません。

通常、メソッドを使用して、メソッドが呼び出されたのと同じ構造をDataTable.Clone()持つ新しいメソッドを作成するかもしれませんが、明らかにこれはうまくいきません。あなたの場合、メソッド を使用して明示的に s を追加する必要があります。DataTableDataTableDataColumnDataTable.Columns.Add

何かのようなもの:

for (int i = 0; i < numberOfColumns; i++) {
    dataTable.Columns.Add(string.Format("Column {0}", i));
}

上記のスニペットは非常に単純化されています。s は自分で作成するので、DataColumnそれぞれに名前を付けて入力する必要がありDataColumnます。

于 2012-05-23T19:42:06.713 に答える