質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

Q&A

解決済

4回答

31193閲覧

C# Excel出力を高速化したい

Roines

総合スコア18

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

0グッド

0クリップ

投稿2016/07/21 04:06

現在業務内で、DataGridViewへと表示している内容をExcelへと出力する処理を書いています。

現在行っているやり方は↓

C#

1int row = 0; 2for (i = 2; i <= (maxRowcount + 1); i++) 3 { 4 int clm = 0; 5 for (n = 1; n <= maxColumncount; n++) 6 { 7 //列番を条件式の回数に入れてループさせる 8 w_rgn = xlWs.Cells; 9 rgn = w_rgn[i, n]; 10 11 try 12 { 13 //書き込み処理 14 rgn.Value2 = Convert.ToString(dgvSample.Rows[row].Cells[clm].Value); 15 } 16 finally 17 { 18 //オブジェクトの開放 19 Marshal.ReleaseComObject(w_rgn); 20 Marshal.ReleaseComObject(rgn); 21 w_rgn = null; 22 rgn = null; 23 //列数カウント 24 clm = clm+1; 25 } 26 } 27 //行数カウントを+1 28 row = row + 1; 29 } 30//変数宣言等は書いてある範囲外で行っているものもあります。上記はあくまで一部です。

といった感じなのですが、書き込み部分をループで回しているため、データ量に比例して時間がかかってしまいます。
一応自分なりに調べてみたんですが、分かりにくかったこともあり、解決には至りませんでした。

是非詳しく教えて頂ければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

ozwk さんの回答と同様なのですが、せっかくコードイメージを書いたので載せておきます。
※動作確認はしていません。あくまでコードのイメージです。

c#

1// DataGridViewの値を二次元配列に詰め替える 2object[,] dgvValues = new object[maxRowcount, maxColumncount]; 3for (row = 0; row < maxRowcount; row++) 4{ 5 for (clm = 0; clm < maxColumncount; clm++) 6 { 7 dgvValues[row, clm] = Convert.ToString(dgvSample.Rows[row].Cells[clm].Value); 8 } 9} 10 11// 出力対象Rangeの取得 12w_rgn = xlWs.Cells; 13var targetRangeFirstCell = w_rgn[2, 1]; 14var targetRangeLastCell = w_rgn[maxRowcount + 1, maxColumncount]; 15var targetRange = w_rgn[targetRangeFirstCell, targetRangeLastCell]; 16// 出力対象Rangeの各セルに値を出力 17targetRange.Value2 = dgvValues; 18 19// 後始末 20Marshal.ReleaseComObject(w_rgn); 21Marshal.ReleaseComObject(targetRangeFirstCell); 22Marshal.ReleaseComObject(targetRangeLastCell); 23Marshal.ReleaseComObject(targetRange);

投稿2016/07/21 04:40

alg

総合スコア2019

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

  1. 書き込みたいデータを予め二次元配列で生成します。巨大な場合は適宜分割します。
  2. 書き込みたい領域:rangeを取得します。シートのRangeで取れます。
  3. rangeのValue2に配列を代入します。

具体的なコード例(開放操作してないので注意)

又は、Microsoft.Office.Interop.Excelを使わず、別のライブラリを使う。
(ClosedXMLやEPPlusなど)
Microsoft.Office.Interop.Excelは開放まわりで危険だし面倒だし遅いしで
正直あまりオススメできません。

投稿2016/07/21 04:31

編集2016/07/21 04:35
ozwk

総合スコア13512

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

1回の書き込み処理のたびに開放を行っていますが、Loopの外で1回だけ行うやり方で高速化しそうです。

投稿2016/07/21 04:22

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

同じ質問ではないですか?

投稿2016/07/21 04:19

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Roines

2016/07/21 04:26

ちょっと違うと思います!
Zuishin

2016/07/21 04:47

もう一つ別のアプローチでの方法を一応書いておきます。 まず書き出すエクセルファイルのテンプレートをあらかじめ作っておきます。 データを読み出してタブ区切りテキストを作ってクリップボードにコピーするか、CSV として保存します。 テンプレートを開き、クリップボードのデータを貼り付け、あるいは CSV をインポートして別名で保存します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問