2

SQL から Excel にデータ行をエクスポートしようとしていますが、挿入コマンドが毎回失敗するようです。これを作るのにかなりの時間を費やしましたが、ついに壁にぶつかりました。

Excel ドキュメントは IRS によって生成されたものであり、行 16 より上は変更する必要はありません。行 16 はヘッダー行であり、それより下のすべては SQL からのデータである必要があります。ヘッダー名にはすべてスペースが含まれており、それが問題になっているようです。

行 16 から始まる列名は次のとおりです。出席者の名、出席者の姓、出席者の PTIN、プログラム番号、CE 時間授与プログラム、完了日

これは私がExcelに書き込もうとしている方法です

private void GenerateReport()
{
    FileInfo xlsFileInfo = new FileInfo(Server.MapPath(CE_REPORTS_PATH + CE_PTIN_TEMPLATE + EXTENSION));

    string connectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes'", xlsFileInfo.FullName);

    //create connection
    OleDbConnection oleDBConnection = new OleDbConnection(connectionString);
    oleDBConnection.Open();

    //create the adapter with the select to get 
    OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$A16:F16]", oleDBConnection);

    // Create the dataset and fill it by using the adapter.
    DataTable dataTable = new DataTable();
    adapter.FillSchema(dataTable, SchemaType.Source);
    adapter.Fill(dataTable);

    string[] colNames = new string[dataTable.Columns.Count];
    string[] colParms = new string[dataTable.Columns.Count];

    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        colNames[i] = String.Format("[{0}]", dataTable.Columns[i].ColumnName);
        colParms[i] = "?";
    }

    // Create Insert Command
    adapter.InsertCommand = new OleDbCommand(String.Format("INSERT INTO [Sheet1$] ({0}) values ({1})", string.Join(",", colNames), string.Join(",", colParms)), oleDBConnection);

    // Create Paramaters
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        OleDbParameter param = new OleDbParameter(String.Format("@[{0}]", dataTable.Columns[i].ColumnName), OleDbType.Char, 255, dataTable.Columns[i].ColumnName);
        adapter.InsertCommand.Parameters.Add(param);
    }

    // create a new row
    DataRow newCERecord = dataTable.NewRow();

    // populate row with test data
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        newCERecord[i] = "new Data";
    }
    dataTable.Rows.Add(newCERecord);

    // Call update on the adapter to save all the changes to the dataset
    adapter.Update(dataTable);

    oleDBConnection.Close();     
}

adapter.Update(dataTable) が呼び出されたときに発生するエラーは次のとおりです。

$exception  {"The INSERT INTO statement contains the following unknown field name: 'Attendee First Name'. Make sure you have typed the name correctly, and try the operation again."}   System.Exception {System.Data.OleDb.OleDbException}

colNames[i] = String.Format("[{0}]", dataTable.Columns[i].ColumnName) で取得した列名から各フィールドを直接取得するため、これはイライラします。列名のスペースを説明するために [] が必要であることを発見しましたが、この時点では何が問題なのかわかりません。Excelファイルを見ると、すべてが正しいようです。

4

1 に答える 1

4

コード全体が完成した Microsoft の記事を実際に見つけました。最も好きなソリューションをコピーして貼り付けることができます。リンクは次のとおりです。

http://support.microsoft.com/kb/306023

CopyRecordset私が言及したもの(タブ区切りファイルを使用)については説明していますが、最も簡単な方法のようです。

編集:完全を期すために、これが私の元の答えです。詳細と考えられるより良い解決策については、代わりに上記のリンクを参照してください。

これはあなたの質問への回答ではなく、アプローチを変更するための提案です (可能であれば)。COM 呼び出しを介してデータを追加する場合、Excel は非常に遅くなる傾向があり、OleDB は内部で COM を使用していると思います。私の経験では、データを Excel に出力する最速の (そして偶然にも最も苦痛の少ない方法) は、すべてのデータを含むタブ区切りのテキスト ファイルを生成し、そのファイルを Excel にインポートし、COM 相互運用機能を使用してシートの書式設定を実行することでした。 . この方法で Excel レポートを生成したとき、ほとんどのレポートは、Excel COM オブジェクト モデルを使用するよりもほぼ 100 倍速く生成されていました。(私は Excel で OleDB を使用したことがないので、これが OleDB 呼び出しと同じになるかどうかはわかりませんが、OleDB アダプターが内部で COM を使用することは間違いありません。)

タブが列区切りになるため、これにより埋め込みスペースの問題も処理されます。

あなたの特定の状況では、テキスト ファイルを Excel の新しいシートにインポートし、それをコピーして IRS シートの適切な場所に貼り付けます。完了したら、一時シートを削除できます。

于 2012-10-09T19:53:37.140 に答える