開いているExcelファイルを操作する【C#, VB.NET】

Windows Formアプリケーション(C#、VB.NET)で、既に開いているExcelファイルを操作するプログラムを作ってみました。

準備

COM(Microsoft.Office.Interop.Excel)を使用してExcelを操作するので、プロジェクトに「Microsoft Excel XX.X Object Library」の参照を追加しておきます。

XX.Xの部分はバージョンです。インストールしているOfficeのバージョンによって変わります。

ソースコード

ボタンを押すと、現在開いているExcelファイルの先頭のシートのA1セルに文字列を書き込むプログラムです。

System.Runtime.InteropServices.Marshal.GetActiveObjectメソッドを使用して、ROT(Running Object Table)からオートメーションサーバーのCOMオブジェクトへの参照を取得します。

そのあとはネット上でもよく見かけるCOMを使用したExcel操作と同じです。

using Excel = Microsoft.Office.Interop.Excel;

// 省略

private void button1_Click(object sender, EventArgs e)
{
    Excel.Application xlApp;
    try
    {
        xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
    }
    catch (Exception ex)
    {
        MessageBox.Show("Excelが起動していません。\n" + ex.Message);
        return;
    }
    
    Excel.Workbooks xlBooks = null;
    Excel.Workbook xlBook = null;
    Excel.Sheets xlSheets = null;
    Excel.Worksheet xlSheet = null;
    Excel.Range xlCells = null;
    Excel.Range xlCell = null;
    try
    {
        xlBooks = xlApp.Workbooks;
        if (xlBooks.Count >= 2)
        {
            MessageBox.Show("Excelファイルを複数開かないでください。");
            return;
        }
        else if (xlBooks.Count == 0)
        {
            return;
        }
        // 先頭のシートのA1セルに文字列を書き込みます。
        xlBook = xlBooks.Item[1];
        xlSheets = xlBook.Sheets;
        xlSheet = xlSheets.Item[1];
        xlCells = xlSheet.Cells;
        xlCell = xlCells.Cells[1, 1];
        xlCell.Value = "C#から書き込み";
    }
    finally
    {
        // 解放処理
        foreach (object comObj in new object[] { xlCell, xlCells, xlSheet, xlSheets, xlBook, xlBooks })
        {
            if (comObj != null)
                System.Runtime.InteropServices.Marshal.ReleaseComObject(comObj);
        }
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
    }
}
Imports Microsoft.Office.Interop

' 省略

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim xlApp As Excel.Application
    Try
        xlApp = DirectCast(System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application"), Excel.Application)
    Catch ex As Exception
        MessageBox.Show("Excelが起動していません。\n" & ex.Message)
        Return
    End Try

    Dim xlBooks As Excel.Workbooks = Nothing
    Dim xlBook As Excel.Workbook = Nothing
    Dim xlSheets As Excel.Sheets = Nothing
    Dim xlSheet As Excel.Worksheet = Nothing
    Dim xlCells As Excel.Range = Nothing
    Dim xlCell As Excel.Range = Nothing
    Try
        xlBooks = xlApp.Workbooks
        If (xlBooks.Count >= 2) Then
            MessageBox.Show("Excelファイルを複数開かないでください。")
            Return
        ElseIf (xlBooks.Count = 0) Then
            Return
        End If

        ' 先頭のシートのA1セルに文字列を書き込みます。
        xlBook = xlBooks.Item(1)
        xlSheets = xlBook.Sheets
        xlSheet = xlSheets.Item(1)
        xlCells = xlSheet.Cells
        xlCell = xlCells.Cells(1, 1)
        xlCell.Value = "VB.NETから書き込み"

    Finally
        ' 解放処理
        For Each comObj As Object In New Object() {xlCell, xlCells, xlSheet, xlSheets, xlBook, xlBooks}
            If (comObj IsNot Nothing) Then
                System.Runtime.InteropServices.Marshal.ReleaseComObject(comObj)
            End If
        Next
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
    End Try
End Sub

注意点

複数のExcelプロセスが起動(※1)している場合は、それらを識別できず予期しないプロセスが返されることになるようです。

特定のプロセスの参照を取得するには、そのプロセスで開かれているファイル名でBindToMonikerを使用した方が良いと思われます。

(※1) Excel2013以降のバージョンでExcelを別プロセスで起動するには、[Alt]キーを押しながらメニューのExcelをクリックします。
タイトルとURLをコピーしました