どー言うことだってばよ
2016/08/02は予報は雨だったけど、行けそうなので猿倉まで登ってきた。
EPPlusは、Excelの.xlsx
ファイルを直接編集できる便利なライブラリなのですが、Excelのファイルを取り扱うとき少し注意すべきことがあったので、備忘録的に。
具体的にはどーいうことなの?
主に、ExcelRangeBaseをforeachで使用とすると直感的では無い挙動を起こすことがある。
以下はそのサンプル。
using System;
using System.IO;
using System.Linq;
using OfficeOpenXml;
namespace EPPlusSurvey
{
class Program
{
static void Main(string[] args)
{
CreateNew();
LoadExists();
}
static void LoadExists()
{
using (var package = new ExcelPackage(new FileInfo("sample.xlsx")))
{
var sheet = package.Workbook.Worksheets[1];
var range = sheet.Cells["A1:B10"];
//セーブ後、ロードすると0になる。
Console.WriteLine(range.Count());
}
}
static void CreateNew()
{
using (var package = new ExcelPackage(new FileInfo("sample.xlsx")))
{
var sheet = package.Workbook.Worksheets.Add("SampleSheet");
var range = sheet.Cells["A1:B10"];
//予想としてA1から、B10の矩形範囲なので20が返ると思いがちだけど
//0が返ってくる。
Console.WriteLine(range.Count());
sheet.Cells["A1"].Value = "hello";
sheet.Cells["B2"].Value = "world";
//この段階では、2が戻ってくる。
Console.WriteLine(range.Count());
range.Value = null;
//20が戻ってくる。
Console.WriteLine(range.Count());
package.Save();
}
}
}
}
サンプル中の、コメントに有るように、基本的には、値の存在するCellを列挙している形となって、指定された矩形範囲の列挙では無いのでこの点は注意しないとマズいかと思います。また、ExcelRangeBaseのValueにnullを一括代入した場合、nullが入力されている状態なので、値が存在すると解釈されるようです。但し、そのような状態でセーブし、再び開いたときは、nullは無視されて再びValueが存在しないコトになって0となるようです。
まとめ
このようなことから、ExcelRangeBaseを用いてforeachする場合は、値の存在しないセルは無視されるので注意すべきかと。矩形範囲のすべての列挙なりを行うなら、単一セルのレンジをPivotにして、Offsetで舐めていくか、Cellプロパティに適宜アドレスをぶち込むが良いかと思います。