| ■No88223 (ユウタ さん) に返信 > forを使わずにエクセルのセル範囲をstring型で1次配列に格納したいのですが、可能でしょうか。 > (大量の値を格納するためforだと処理が遅くなるため高速化したいです)
No88228 で既に回答がついていますが、2 次元配列で読み書きすることなら可能です。
Range が単一のセル範囲を表す場合 Value プロパティは単一の値を返します。
Range が連続した複数のセル範囲を含む場合 Value プロパティは 2 次元配列を返します。 1 次元目が行方向(縦)、2 次元目が列方向(横)を意味します。
Range が非連続のセル範囲を含む場合 Values からは最初の連続領域のみの内容が返されます。 すべてを取り出す場合は、Areas プロパティを使って 連続領域ごとの Range に分解してから それぞれの Value プロパティを呼び出すようにします。
なお、Value プロパティからの返却値を受け取る場合、 C# では先頭が 1 から始まる特殊な配列として返却される可能性があります。 (VB.NET の場合は、常に 0 始まりに補正されます)
using System; using System.Linq; using System.Runtime.InteropServices; using usgExcel = Microsoft.Office.Interop.Excel; namespace Test_エクセルを1次配列化 { class Program { static void Main(string[] args) { string FilePath = @"C:\AAA.xlsx";
usgExcel.Application myExcel = new usgExcel.Application(); myExcel.Visible = true; usgExcel.Workbooks myWorkBooks = myExcel.Workbooks; usgExcel.Workbook myWorkBook = myWorkBooks.Open(FilePath); usgExcel.Sheets mySheets = myWorkBook.Sheets; usgExcel.Worksheet myWorkSheet = mySheets["Sheet1"];
usgExcel.Range myCells = myWorkSheet.Cells; usgExcel.Range myCells1 = myCells[1, 1]; usgExcel.Range myCells2 = myCells[5000, 1]; usgExcel.Range myRange = myWorkSheet.Range[myCells1, myCells2];
// 二次元配列として取得されます // 1..5000 になるか、0..4999 になるかは環境依存 object[,] values = myRange.Value;
Marshal.FinalReleaseComObject(myCells1); Marshal.FinalReleaseComObject(myCells2); Marshal.ReleaseComObject(myRange); Marshal.ReleaseComObject(myCells); Marshal.ReleaseComObject(myWorkSheet); Marshal.ReleaseComObject(mySheets); Marshal.ReleaseComObject(myWorkBook); Marshal.ReleaseComObject(myWorkBooks);
// myExcel.Quit(); Marshal.ReleaseComObject(myExcel);
// object[,] を string[] に変換します string[] strValues = new string[values.Length];
// 元の配列が 0 ベースの場合と 1 ベースの場合がありえるため、 // GetLowerBound を利用して列挙しています。 for (int x = values.GetLowerBound(0), i = -1; x <= values.GetUpperBound(0); x++) { for (int y = values.GetLowerBound(1); y <= values.GetUpperBound(1); y++, i++) { if (values[x, y] != null) { strValues[i] = values[x, y].ToString(); } } }
Console.WriteLine(strValues[0]); Console.WriteLine(strValues[1]); Console.WriteLine(strValues[2]); Console.WriteLine(strValues[3]);
Console.ReadKey(); } } }
# 2 次元配列のまま LINQ 処理できるよう、拡張メソッドを用意しておいたほうが楽かも。 |