別プロセスでオープン済みのExcelファイルへ値を追記したい

タグの編集
投稿者 オジやまさん  (社会人) 投稿日時 2024/3/26 15:17:34
いつも拝見しております。

VB.netを使用して別プロセスでオープン済みのExcelファイルに値を追記する
処理を作成しております。

以下のソースにある「Book1.xlsx」は画面上に表示済みです。
実行すると、プログラムはエラーになりませんが、なぜか値がセルに反映されません。
何かを間違えているのだろうと思うのですが、技術力が不足しているため
分からない状況です。

やり方が良くないのか、どうすれば出来るのか、ご教示願います。
宜しくお願いいたします。

以下、ソースと開発環境です。

■ソース
--------------------------------------------------------------------------------
Dim FilePath as String = "C:\Users\ojiyama\Desktop\Book1.xlsx"
Using oExcel As ExcelPackage = New ExcelPackage()
    Using stream As System.IO.FileStream = New System.IO.FileStream(FilePath,
                                                                                                        IO.FileMode.Open,
                                                                                                        IO.FileAccess.Read,
                                                                                                        IO.FileShare.ReadWrite)  
        oExcel.Load(stream)
        Dim oSheet As OfficeOpenXml.ExcelWorksheet = oExcel.Workbook.Worksheets(1)
        oSheet.Cells(1,1).Value = "テスト"
        '↑エラーにはならないが、セルに"テスト"が反映されない
    End Using
End Using
--------------------------------------------------------------------------------

■開発環境
 ・Visual Studio 2019 Community Edition
 ・EPPlus 4.5.3.3
 ・Microsoft365 App for business
  Excel 2308(16731.20170)
            
投稿者 とくま  (社会人) 投稿日時 2024/3/26 17:09:18
とりあえず「アプリケーションファイル」と「データ保存ファイル」は別の存在であることを理解してください。

例えばメモ帳の場合、「アプリケーションファイル」は notepad.exe であり、
単体で起動すると新規メモ帳が開きます。
これにデスクトップの test.txt からデータを読み込めば test.txt に保存した内容が表示されます。

この状態で画面上で色々と編集します。
[上書き保存]を実行せずにデスクトップの test.txt をもう一度開くとどうなりますか?
編集前のデータが test.txt から読み込まれて表示されるはずです。
notepad.exe が画面上に表示しているデータは test.txt からコピーされた
データであり「保存」処理前に停電で電源が落ちたりすれば、消えてしまう存在です。

ここで質問文の、
①別プロセスでオープン済みで画面に表示されているExcelデータ(Book1.xlsxからコピーして表示)
②C:\Users\ojiyama\Desktop\Book1.xlsx「データ保存ファイル」
③EPPlusという「アプリケーション(正確にはライブラリだけど)」がBook1.xlsxからコピーし操作しているExcelデータ
この3つは全部別の場所(メモリ)に存在するデータになります。

①メモ帳で開いて画面表示されている test.txt
②デスクトップの保存ファイル test.txt
③Wordで開いて画面表示されている test.txt
と同じです。Wordの画面で編集してもメモ帳の画面が変更されませんという質問内容と同じになります。
変更されなくて当然だと思われます。

ところで別プロセスとは? Excel.exe ですか?
投稿者 オジやまさん  (社会人) 投稿日時 2024/3/27 08:19:51
> ところで別プロセスとは? Excel.exe ですか?
 「Excel.exe」です。

> ①メモ帳で開いて画面表示されている test.txt
> ②デスクトップの保存ファイル test.txt
> ③Wordで開いて画面表示されている test.txt
> と同じです。Wordの画面で編集してもメモ帳の画面が変更されませんという質問内容と同じになります。
> 変更されなくて当然だと思われます。
 仰る通りですね。
 なぜ、気が付かなかったのか。
 知っていたつもりになっていた気がします。
 ご教示ありがとうございました。
 自分が何を実現したいのか、再考いたします。
投稿者 とくま  (社会人) 投稿日時 2024/3/27 09:31:18
ある程度、次の回答を書いちゃってたので備忘録追記(汗)。

>> ところで別プロセスとは? Excel.exe ですか?
> 「Excel.exe」です。
一般的に起動済みのアプリケーションに割り込みをかける(=アタッチする)場合は、
アタッチ先のアプリケーションと同等のプログラムが必要になります。
この場合、Excel.exe 本体を利用しないとほぼ実現不可能です。

EPPlus は「データ保存ファイル」編集ライブラリです。
Excelデータ保存ファイルの実態は、XMLファイルをZIP圧縮したものです。
このため、ZIP解凍機能と、テキスト編集機能があれば編集できます。
機能を最小限にしているため、高速です。

これに対し、起動済みのアプリケーションである Excel が展開している機能は
セルに分割された表示機能、セルによる編集機能、セル参照式演算機能、etc...
何百倍ものプログラムが動いていて、その一つのセル表示機能を利用して
画面の表示を変更する流れになります。

なので、
【案1】ユーザが「Excel.exe」を実行していることが前提であるなら、
COM参照の解放など問題を多く含むものの、エクセルの機能を最大限利用できる
「Excel.exe」本体に頼むのが王道となります。使い古されたサンプルプログラムを
参考に、
System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")
から起動中のエクセル本体に割り込みをかける方法になります。

【案2】EPPlusで「データ保存ファイル」を編集するなら、
一度、起動済みのExcelプロセスを終了するため、編集中の画面表示データを「保存」し、
閉じた後、「データ保存ファイル」を編集してから開きなおす必要があります。

【案3】自分のプログラム(VB.NET)でExcel表示プログラムを作ってしまう。
つまりスプレッドシートなどを利用すれば、Excel表示編集アプリは比較的簡単に
作成できます。最初から自分のプログラムでExcelを表示しているなら、それを
編集するのは容易となります。

などが考えられると思います。