■80527 |
Re[1]: excelのセルからテキストと文字色を取得 |
□投稿者/ 魔界の仮面弁士 -(2016/07/25(Mon) 20:32:56)
| ■No80517 (さい さん) に返信 > 設定するセルがかなり多いため処理に相当時間がかかってしまいます。
同じコードを、VBA で処理させてみました。
その場合、VBA コードと同じ Excel 上で開かれたブックであれば、 2000行×20列であってもわずか 0.36 秒で取得できました。
しかし VBA といえども、自身以外の Excel.Application インスタンスに 対する操作の場合、20行×20列で 0.60〜0.61秒、 200行×20列で 5.30〜5.43秒 という速度しか得られません。
VB.NET から操作する場合も、当然ながら別プロセスへの 操作となりますから、同様の低速化は避けられません。 しかも COM Interop のオーバーへッドが加わるので、さらに遅くなるでしょう。
たとえば下記の場合、100行×20列で 4.2 秒かかります。 (1 行当たりの所要時間は 30ミリ秒〜50ミリ秒でした)
Dim cells = ws.Cells
For r = 1 To MaxRow For c = 1 To 20 Dim cell = DirectCast(cells(r, 1), Excel.Range) Dim itr = cell.Interior Dim o As Object = itr.Color Dim p As Color = ColorTranslator.FromOle(CInt(o))
Marshal.ReleaseComObject(itr) Marshal.ReleaseComObject(cell) Next Next Marshal.ReleaseComObject(cells)
ColorTranslator クラス や ReleaseComObject メソッドの 所要時間は微々たるもので、やはり別プロセスに対する COM 操作の部分がボトルネックになっているようです。
Cells(行, 列) の代わりに、Range(文字列) や、 newRange = range.Offset(行数) を使っても大差無し。
> 処理速度を上げる方法をご存じの方はいらっしゃいませんでしょうか
値(Range.Value)や書式(Range.NumberFormat)であれば、 二次元配列を使って一括操作できるのですが、 Interior や Font が相手だと、そういうわけにもいきません。
上記の結果から、セル数が多い場合は、列挙処理を インプロセスの VBA に担当させることで高速化するものと予想します。
VBA 側で列挙された結果は、一時ファイルなどを通じて受け取るようにするか、 あるいは Range.Value 経由で 2 次元配列として受け取るなどすれば良いかと。
そのために必要な VBA コードは、あらかじめ マクロブックとして用意しておく方法と、 VB.NET 側から動的に作成する方法が考えられます。 もしも動的に作成する場合は、下記を参考にしてみてください。
https://support.microsoft.com/ja-jp/kb/219905 https://support.microsoft.com/ja-jp/kb/303871 http://nasunoblog.blogspot.jp/2013/10/excel-vbavbprojectvbe.html |
|