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

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

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

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

解決済

C# 遅延バインディングで実行しているExcel COMオブジェクトのイベントをフックする方法

naitou
naitou

総合スコア31

C#

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

3回答

0評価

1クリップ

700閲覧

投稿2022/01/05 03:36

編集2022/01/06 06:05

前提として、Excelバージョンに依存しない様にラッパークラスであるMicrosoft.Office.Interop.Excelは利用せずに、遅延バインディングしたいと思っております。

64ビットビルドすると、
Type.GetTypeFromProgID("Excel.Application")
で取得したTypeからGetEventsメソッドやGetMethodsメソッドを呼んでも
Microsoft.Office.Interop.Excel.Applicationクラスの
のイベントやメソッドが取得できません。

ここでイベントが取れない為、イベントハンドラーが登録できず困りました。

まさに下記ページの方法を行おうとしておりますが、64ビットビルドだとGetEventメソッドの戻り値がnullになってしまいイベントが取れません。32ビットビルドでは正常に動作します。
https://littlepower-suesan.hatenadiary.org/entry/20110628/1309266642

このページの方法は試しておりませんが、GUID指定によりExcelバージョンに依存してしまう為除外しています。
https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/dc59b406-3f86-4fac-817a-f4fafd3ffdb9/36933243101249612452125311248712451125311246412391excel1239812452?forum=csharpgeneralja

見識のある方がいらっしゃいましたら、よろしくお願いします。


2020年1月5日18時00分追記

環境検証、ソースコード、実行結果を記載します。

検証環境
OS:Windows10 20H2
ビルド環境:Microsoft Visual Studio Professional 2019 Version 16.11.3
フレームワーク:.NET Framework4.8
Excel2013 15.0.5381.1000 32ビット

C#

using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; namespace WindowsFormsApp13 { static class Program { [STAThread] static void Main() { Console.WriteLine("ビルド:"+(IntPtr.Size==4?"32ビット":"64ビット")); Type objeType = Type.GetTypeFromProgID("Excel.Application"); dynamic _APPLICATION = Activator.CreateInstance(objeType); _APPLICATION.Visible = true; EventInfo eventInfo = _APPLICATION.GetType().GetEvent("SheetSelectionChange"); if(eventInfo!=null){ Console.WriteLine("OK"); Type eventType = eventInfo.EventHandlerType; Type type = typeof(Program); MethodInfo methodInfo = type.GetMethod("SheetSelectionChangeEvent"); Delegate d = Delegate.CreateDelegate(eventType, methodInfo); eventInfo.AddEventHandler(_APPLICATION, d); }else{ Console.WriteLine("NG"); } Console.ReadKey(); } public static void SheetSelectionChangeEvent(object sheet, object range){ Console.WriteLine("SheetSelectionChangeEvent"); } } }

実行結果はビルド毎に下記の通りとなりました。

・32ビットビルド時
※起動したエクセルで新規ファイルを開いてセル選択を何度か実行

ビルド:32ビット
OK
SheetSelectionChangeEvent
SheetSelectionChangeEvent
SheetSelectionChangeEvent
SheetSelectionChangeEvent

・64ビットビルド時

ビルド:64ビット
NG


2020年1月6日15時00分追記

現象が出るマシンと出ていないマシンがあり、
環境に依存して現象が発生しているようです。
現象が出るマシンと出ていないマシンの違いは次の通りでした。

現象が出ているマシンで64ビットビルドしたものは、
Type.GetTypeFromProgID("Excel.Application")で
Typeとして、「System.__ComObject」が返って来ていました。

しかし32ビットビルドだと
Typeとして、「Microsoft.Office.Interop.Excel.ApplicationClass」が
返って来ます。

現象が出ていないマシンでは、
32ビットと64ビットのどちらでも、
Typeとして、「Microsoft.Office.Interop.Excel.ApplicationClass」が返って来ます。

COMオブジェクトの場合はGetType()をすると「System.__ComObject」という
クラスで取得されることもあるようです。
どのようなケースでそうなるか明確な情報は見つけられませんでした。

下記URLでも類似の現象が出ており、
Excel(ストアアプリ)→ オフィス2016のデスクトップ版
の変更により解消した様です。
しかしストアアプリでも遅延バインディングは利用できる為、今回現象とは関係ないかもしれません。
https://social.technet.microsoft.com/Forums/Windows/ja-JP/77942146-7be9-4409-81cc-aa19e1ba4ad9/1245012503125221236312425excel12364216281240320986123791239412356?forum=Office2016ITProJP

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

Zuishin

2022/01/05 03:45

参考にしたソースコードをコピペしてそのまま使い、記載されていることができるかどうかをまず確認してください。 それでできるなら、あなたが応用して書いた部分が間違っているので、それを記述してください。
退会済みユーザー

退会済みユーザー

2022/01/05 04:48 編集

そりゃCOM側とアーキテクチャ合わせないと動かないのでは。
退会済みユーザー

退会済みユーザー

2022/01/05 05:12 編集

後から判明した原因等は、元の質問文は変えずに追記してください。 最初の質問文と解決方法が変わってくるので、既にした回答と食い違いが出てきます。
naitou

2022/01/05 05:31

すみません。質問分は今後気を付けます。
退会済みユーザー

退会済みユーザー

2022/01/05 06:31 編集

上のアーキテクチャ合わせるというのは勘違いだったようです、失礼しました。 こちらでリンク先の記事と同じように試した所、64bit・32bit共に問題なくイベントは動作しました。(Excel2013 32bit) そちらで動作確認に使用したソースコードを載せてみてください。
naitou

2022/01/05 09:12

ソースコードを記載しました。こちらもExcel2013ですが、64bitの場合はダメです。アーキテクチャを合わせるといのは、64ビット版のExcelでないとダメなのかと思いました。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。