質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

3254閲覧

C#で、既に開いているExcelを操作したい。

miiiiiiiisuke

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2023/09/28 06:48

編集2023/09/28 07:17

実現したいこと

既に開いているExcelファイルを操作したい。

前提

以下のソースで「_soukumiExcelPath」にあたる、
既に開いているExcelを操作したいのですが、
別で「読み取り専用」で開いてきます。

Microsoft.Office.Interop.Excel.Application xlApp = null; Microsoft.Office.Interop.Excel.Workbooks xlBooks = null; Microsoft.Office.Interop.Excel.Workbook xlBook = null; Microsoft.Office.Interop.Excel.Sheets xlSheets = null; Microsoft.Office.Interop.Excel.Worksheet xlSheet = null; Microsoft.Office.Interop.Excel.Range xlCells = null; // Excelアプリケーション生成 xlApp = new Microsoft.Office.Interop.Excel.Application(); // ExcelOpenメソッド xlBooks = xlApp.Workbooks; xlBook = xlBooks.Open(_soukumiExcelPath); // シートを選択する xlSheets = xlBook.Worksheets; xlSheet = xlSheets[1] as Microsoft.Office.Interop.Excel.Worksheet; // 1シート目を操作対象に設定する // 表示 xlApp.Visible = true; // セルのオブジェクト  xlCells = xlSheet.Cells;
エラーメッセージ

該当のソースコード

C#

1 // Excelアプリケーション生成 2 xlApp = (Microsoft.Office.Interop.Excel.Application)Marshal.GetActiveObject("Excel.Application"); 3 4 5 // 開かれているすべてのワークブックを調べる 6 foreach (Microsoft.Office.Interop.Excel.Workbook workbook in xlApp.Workbooks) 7 { 8 if (workbook.Name == Path.GetFileNameWithoutExtension(_soukumiExcelPath)) 9 { 10 xlBook = workbook; 11 break; // 見つかったらループを終了 12 } 13 }``` 14 15### 試したこと 16 17上記のソースをchatGPTが書き出してくれて、試したのですが、 18なぜか、xlApp.Workbooks を in する時に、 19勝手にforeachのループを外れて、次の処理へいってしまいます。 20  21ただ開いているExcelを指定したいだけなのに、どんづまってしまいました。 22ご教授のほど、なにとぞよろしくお願いいたします。 23 24### 補足情報(FW/ツールのバージョンなど) 25 26ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toge_

2023/09/28 08:26

6行目のforeach内が実行されてないのですね。 確認となりますが、xlApp.Workbooks.Count の値を表示させるとどうなっているでしょうか?
miiiiiiiisuke

2023/09/28 10:33 編集

コメントをありがとうございます。 それは試しておりません。 仕事の案件でして、自宅に帰ってきてしまい、明日もお休みをいただいているため、来週の勤務時間に確認してみます。
toge_

2023/09/28 15:09

ああ、では来週ですね。 KOZ6.0さんの回答の方がより簡単にできると思いますので、そちらを優先して試されるのをおすすめします。 もし仕事環境や案件の制限でnugetができない場合には、私の提示した内容を確認いただいて、地道に解決するしかないかなと思います。
miiiiiiiisuke

2023/09/28 22:40

ありがとうございます。そうします。 カウント自体されてなかったら、、、と思うと気が重いです。。。
miiiiiiiisuke

2023/10/02 04:44

こんにちは!さきほど、確認してみたところ、カウント「0」でした。。。認識さえしていなかったのですね。   KOZ6.0さんの回答で、「追記:既存の Excel を捕まえる手段」で教えていただいた方法で試してみたところ、できるようになりました!!   toge_さんにアドバイスいただいたように、「nugetが仕事環境でよいかどうか、確認する」という行為自体を考えていなかったので、nugetなしの方で進めるという判断が出来ました。アドバイスいただなかったら、新しいもの好きの自分はすぐに試していたと思います💦   結構、完成に近いアプリなので、新しいことは避けて一旦作り上げたいと思います。 次回以降、新規でアプリを作る際に、nugetを導入して、解放処理など簡便にしていきたいと思います。 本当にお世話になりました。ありがとうございました!!
guest

回答1

0

ベストアンサー

NetOfficeFw.Excel を使ってみませんか?nuget から取得できます。

https://www.nuget.org/packages/NetOfficeFw.Excel

こんな具合に既存の Excel を操作できます。

csharp

1using Excel = NetOffice.ExcelApi; 2using System.IO; 3 4string _soukumiExcelPath = @"z:\test.xlsx"; 5string path = Path.GetFileName(_soukumiExcelPath); 6Excel.Application xlApp = Excel.Application.GetActiveInstance(); 7Excel.Workbook xlBook; 8 9foreach (Excel.Workbook workbook in xlApp.Workbooks) { 10 if (string.Compare(workbook.Name, path, true) == 0) { 11 xlBook = workbook; 12 break; 13 } 14}

他に Word/PowerPoint/Outlook/Access 等もあります。
https://www.nuget.org/packages/NetOfficeFw.Core

NetOfficeFw のいいところ

(1) Marshal.ReleaseComObject を一切書かなくて良い。
全オブジェクトが IDisposable を実装しており、Dispose すれば内部で ReleaseComObject を使って解放してくれます。
また、最上位である NetOffice.ExcelApi.Application を Dispose すれば、配下のオブジェクトをすべて解放してくれます。

(2) レイトバインドしているので、Office のバージョンに依存しません。

といったところです。


追記

既存の Excel を捕まえる手段としては、こんなのもあります。
こちらは、Microsoft.Office.Interop.Excel を使います。

csharp

1using Excel = Microsoft.Office.Interop.Excel; 2using System.Runtime.InteropServices; 3 4 object workbook = Marshal.BindToMoniker(@"z:\test.xlsx"); 5 Excel.Workbook xlBook = workbook as Excel.Workbook; 6 Excel.Application xlApp = xlBook.Application;

インスタンスが無い場合は起動しちゃいます。


さらに追記

Marshal.BindToMoniker の戻り値を NetOfficeFw.Excel に取り込むことも出来ました。

csharp

1 object book = Marshal.BindToMoniker(@"z:\test.xlsx"); 2 Excel.Workbook xlBook = new Excel.Workbook(null, book); 3 Excel.Application xlApp = xlBook.Application;

投稿2023/09/28 09:27

編集2023/09/28 10:36
KOZ6.0

総合スコア2721

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miiiiiiiisuke

2023/09/28 10:38

ご回答をありがとうございます! 仕事の案件でして、自宅に帰ってきてしまい、明日もお休みをいただいているため、次に触るのは来週月曜以降となりますが、試してみます!! どちらの方法も、速く試してみたいです。 分かりやすく書いていただいて、本当にありがとうございました。
miiiiiiiisuke

2023/10/02 04:49

KOZ6.0さん、ありがとうございます! 「追記」でいただいた方法を試したところ、無事に捕まえることができました!! nugetの方も試してみたいのですが、新しいことを今から取り入れて、影響がどこまで出るか分からないので、一旦、既存の方法のまま進めてまいります。 近日中に新しいアプリに取り組む予定なので、その際は最初からnugetを導入して、作り上げていこうと思います。 この短いコメントの中に、素晴らしい知恵のご教授をいただき、本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問