C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

■88231 / 1階層)  c# エクセルのセル範囲を1次配列に格納する方法
□投稿者/ 魔界の仮面弁士 (1778回)-(2018/08/10(Fri) 11:18:47)
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 処理できるよう、拡張メソッドを用意しておいたほうが楽かも。
編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←c# エクセルのセル範囲を1次配列に格納する方法 /ユウタ 返信無し
 
上記関連ツリー

c# エクセルのセル範囲を1次配列に格納する方法 / ユウタ (18/08/09(Thu) 22:06) #88223
Re[1]: c# エクセルのセル範囲を1次配列に格納する方法 / furu (18/08/10(Fri) 09:57) #88228
c# エクセルのセル範囲を1次配列に格納する方法 / 魔界の仮面弁士 (18/08/10(Fri) 11:18) #88231 ←Now
Re[1]: c# エクセルのセル範囲を1次配列に格納する方法 / WebSurfer (18/08/10(Fri) 13:59) #88232
  └ Re[2]: c# エクセルのセル範囲を1次配列に格納する方法 / ユウタ (18/08/11(Sat) 00:25) #88236
    └ Re[3]: c# エクセルのセル範囲を1次配列に格納する方法 / 魔界の仮面弁士 (18/08/11(Sat) 02:36) #88237
      └ Re[4]: c# エクセルのセル範囲を1次配列に格納する方法 / ユウタ (18/08/11(Sat) 17:53) #88238 解決済み

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信