編集:すばらしい、ワークシートに更新と削除を戻して、質問の大部分を見逃していることに気付きました。それが可能かどうかはまったくわかりませんが、それによって私のソリューションは価値がないと思います。とにかくここに残しておきます。何らかの形で役立つかもしれません。
なぜVSTOが必要なのですか? 私の知る限り、VSTO は Office アドインに使用されています。しかし、DataGridView にデータを表示したいので、ワークブックにアクセスするだけの WinForms アプリケーションがあると仮定します。この場合、Office Interop を使用してブックを開くだけです。Microsoft.Office.Interop.Excel への参照をプロジェクトに追加し、using Microsoft.Office.Interop.Excel;
ステートメントを追加するだけです。
Excel Interop の MSDN リファレンス ドキュメントは、http: //msdn.microsoft.com/en-us/library/ms262200%28v=office.14%29.aspxにあります。
エクセルの部分だけあげますが、残りは他の人がやってくれるかもしれません。
まず、Excel とブックを開きます。
Application app = new Application();
// Optional, but recommended if the user shouldn't see Excel.
app.Visible = false;
app.ScreenUpdating = false;
// AddToMru parameter is optional, but recommended in automation scenarios.
Workbook workbook = app.Workbooks.Open(filepath, AddToMru: false);
次に、どういうわけか正しいワークシートを取得します。いくつかの可能性があります:
// Active sheet (should be the one which was active the last time the workbook was saved).
Worksheet sheet = workbook.ActiveSheet;
// First sheet (notice that the first is actually 1 and not 0).
Worksheet sheet = workbook.Worksheets[1];
// Specific sheet.
// Caution: Default sheet names differ for different localized versions of Excel.
Worksheet sheet = workbook.Worksheets["Sheet1"];
次に、正しい範囲を取得します。必要なデータがどこにあるかを知る方法を指定しなかったので、固定列にあると仮定します。
// If you also know the row count.
Range range = sheet.Range["A1", "D20"];
// If you want to get all rows until the last one that has some data.
Range lastUsedCell = sheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell);
string columnName = "D" + lastUsedCell.Row;
Range range = sheet.Range["A1", columnName];
値を取得します。
// Possible types of the return value:
// If a single cell is in the range: Different types depending on the cell content
// (string, DateTime, double, ...)
// If multiple cells are in the range: Two dimensional array that exactly represents
// the range from Excel and also has different types in its elements depending on the
// value of the Excel cell (should always be that one in your case)
object[,] values = range.Value;
この 2 次元オブジェクト配列は、DataGridView のデータ ソースとして使用できます。私は何年も WinForms を使用していないので、直接バインドできるのか、最初にデータを特定の形式にする必要があるのか わかりません。
最後にもう一度 Excel を閉じます。
workbook.Close(SaveChanges: false);
workbook = null;
app.Quit();
app = null;
// Yes, we really want to call those two methods twice to make sure all
// COM objects AND all RCWs are collected.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
COM オブジェクトへのすべての参照が解放されていることを確認する必要があるため、Interop を使用した後に Excel を正しく閉じること自体がタスクです。これを行う最も簡単な方法は、Excel とワークブック (最初と最後のコード ブロック) を開いたり閉じたりする以外のすべての作業を別の方法で行うことです。これにより、そのメソッドで使用されるすべての COM オブジェクトは、Quit
が呼び出されたときにスコープ外になります。