OleContainerを使用してExcelを制御するには

解決


SAKURA  2007-03-10 01:12:56  No: 25231

OleContainerを利用してExcelを制御しようとしています。
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/T_OleCont.htm
を参考にしてある程度、制御することはできました。

しかし、他の作業でExcelを起動させたまま
このプログラムを実行すると例外エラーになります。
どうも、ActiveWorkbook=nilになっているのが原因のようです。
Excelを起動させていてもエラーにならない方法はあるのでしょうか?

CreateOleObjectでやれば、うまくいくのですが、
この場合、Excelシートでの編集イベントが取れないため
TExcelApplicationを利用しようと思っています。
CreateOleObjectでExcelの変更イベントが取れれば
それでも良いのですが・・・


Hota  2007-03-10 01:45:08  No: 25232

Oleでの取得です。
    try
      Excel := GetActiveOleObject('Excel.Application'); //動作中の場合
    except
      Excel := CreateOleObject('Excel.Application');    //起動させる
    end;


SAKURA  2007-03-10 03:12:26  No: 25233

Hotaさん早速の回答ありがとうございます。

    try
      Excel := GetActiveOleObject('Excel.Application'); //動作中の場合
    except
      Excel := CreateOleObject('Excel.Application');    //起動させる
    end;

ここで言う、Excelは、Variant変数ですよね。
できれば、TExcelApplicationコンポーネントを利用したいのですが。

やはり、この方法しかないでしょうか?
この場合、OleContainerに埋め込まれている
Excelで値の変更などがあった場合、
編集フラグを立てるなどチェックすることが
できればよいのですが・・・

環境書くのを忘れてましたが、Delphi5です。


Mr.XRAY  URL  2007-03-10 05:23:51  No: 25234

>しかし、他の作業でExcelを起動させたまま
>このプログラムを実行すると例外エラーになります。

私のところではエラーになりませんが...。
(WindowsXP + Delphi7 )
もし、既に起動しているExcel(エクセル)とは別に、OleContainerで表示している
Excel(エクセル)を別のもの(インスタンス)で制御するのであれば以下のようにします。
質問の意図するところと違っていたらゴメンなさい。

     //OLEオブジェクトを表示可能状態にして表示
     OleContainer1.Visible:=True;
     OleContainer1.DoVerb(ovShow);
     OleContainer1.SetFocus;

     //既に起動中のエクセルとは別のエクセルとして制御する場合
     //ConnectKindのデフォルト値はckRunningOrNew              
     ExcelApplication1.ConnectKind:=ckRunningInstance;  //ここを明示的に指定
     ExcelApplication1.Connect;


Mr.XRAY  URL  2007-03-10 05:30:14  No: 25235

くどいようですが、解説しますと以下のことです。

ckRunningOrNew 
既に起動中(Running)があればそれ、または(or)なければ新しいExcel(New)

ckRunningInstance
既に起動中のインスタンス(RunningInstance)、つまり今回の場合は
OleContainer1に起動しているエクセルのインスタンスのこと。


SAKURA  2007-03-12 00:33:55  No: 25236

Mr.XRAYさん回答ありがとうございます。
一度、試してみます。
結果については、後日報告させて頂きます。


SAKURA  2007-03-12 19:59:12  No: 25237

ExcelApplication1.ConnectKind:=ckRunningInstance; 
を試してみました。
確かにエラーは出なくなりましたが、
作業中のExcelに遷移できなくなってしまいました。
しかも、OleContainerの終了時に作業中のExcelも
終了してしまいます。

OleContainer1のExcelはどの時点でExcelのインスタンスが
できあがっているのでしょうか?
どうも、OleContainerのインスタンスではなく、
作業中のExcelのインスタンスを使っているようなのですが・・・

Delphi7で出ないと言うことは、
WindowsXP+Delphi5の環境に問題があるのでしょうか?


SAKURA  2007-03-13 00:32:55  No: 25238

自己レスです。

ServerコンポーネントをExcel97からExcel2000に入れ替えると
起動中のExcelがあってもエラーは出なくなりました。
やはり、環境の問題だったようです。

Excelを起動しておいてから、サンプルプログラムを実行すると
先に起動しておいたExcelの画面に遷移できません。
先にプログラムを動かしておいてExcelを別で起動したときは、
画面の切替が問題なくできるのですが・・・

同時に終了してしまう件は、
ExcelApplication1.ConnectKind:=ckNewInstance;
とすることで回避できました。

普通に起動したExcelとプログラムからOleContainerを使用したExcelで
画面の切替は、できないのでしょうか?
ちなみに、OleContainerが貼り付けてあるフォームは、
ShowModalで開いています。このあたりに原因があるのでしょうか?


Mr.XRAY  URL  2007-03-13 04:33:16  No: 25239

失礼。

ExcelWorkbook1
ExcelWorksheet1
のConnectKindプロパティも変更する必要がありますね。
それでダメならお手上げです。


Mr.XRAY  URL  2007-03-13 04:35:41  No: 25240

追加です。

>先に起動しておいたExcelの画面に遷移できません。
これは全く分かりませんね。サンプルのプログラム(たとえ、他のFormから
ShowModalで表示したとしても)の場合。他に何か操作していないんですよね。


SAKURA  2007-03-13 06:04:00  No: 25241

Mr.XRAYさん回答ありがとうございます。

http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/T_OleCont.htm
をそのままコピーして試してみましたが、
やはり、Excelを起動してからプログラムを動かすと
プログラム実行中は、最初に起動していたExcelが
さわれません。画面は、後ろに見えているのですが・・・
ここから、もう一つExcelファイルを起動するとそちらは
Activeになります。何が違うのでしょうか・・・

起動時にExcelが立ち上がっていたらプログラムを
起動できなくするなど工夫する必要があるかもしれません。


Mr.XRAY  URL  2007-03-13 07:48:22  No: 25242

まさかとは思いますが、
>http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/T_OleCont.htm

(1)このサンプルのフォルダ内のOleTest.xlsを義堂
(2)サンプルのExcel_OleContainer.exeを起動

なんてことはしていませんよね。


SAKURA  2007-03-13 18:13:02  No: 25243

同じファイルは、起動していません。
こちらでは、以下の通りで再現します。

(1) [スタート]-[プログラム]からExcelを起動
(2)サンプルのExcel_OleContainer.exeを実行

このようにすると(1)で起動したExcelのシートが無くなってしまい
Excelアプリのみ起動した状態が後ろに残る。
さらに、(1)のExcelにカーソルが行かない。
しかも、Excel_OleContainer.exe終了時に(1)のExcelも
同時に終了してしまう。。。

やはり、環境の問題でしょうか???
それとも、OleContainerのプロパティの問題???


SAKURA  2007-03-13 21:17:15  No: 25244

いろいろと調べてみましたが、どうも環境のようです。

Office2000のSP-1を当てない状態で試してみると
現象は、起きずに画面遷移も問題ありませんでした。
SP-1にあげてから試してみると動きがおかしくなりました。
私が試していたのはOfficeSP-3だったのでSP-3でも問題がある?

Delphiの問題ではなさそうなので
ここでは、解決とさせて頂きます。


これじゃダメ?  2007-03-14 04:59:07  No: 25245

Mr.XRAYさんのサンプルで

procedure TForm1.FormShow(Sender: TObject);
var
     EFile: String;
begin
     ExcelApplication1.Connect;  //追加
     ExcelApplication1.IgnoreRemoteRequests[0] := True;  //追加
        :
        :
        :
    //ExcelApplication1.Connect;    //コメント


Mr.XRAY  URL  2007-03-14 05:41:52  No: 25246

SAKURAさん

>Excelアプリのみ起動した状態が後ろに残る。
>さらに、(1)のExcelにカーソルが行かない。
>しかも、Excel_OleContainer.exe終了時に(1)のExcelも
>同時に終了してしまう。。。

>う一つExcelファイルを起動するとそちらはActiveになります。何が違うのでしょうか・・・

上記の現象確認しました。Excelの設定、フォルダオプションをいろいろ変更
してみたら発生しました。ただ、何をどのように変えたかが...
そして、元に戻らなくなってしまいました(笑)。

当方 WindowsXP(SP2) + Delphi7 + Excel2000(SR-1)です。
ちなみに、ExcelはOffice2000インストール後、何も設定変更していません。
が、エクセル操作フォームとか、いろいろエクセルの操作をしていますので、
デフォルトがどのようになっているかも分かりません。

近日中に、ExcelまたはOfficeを再インストールして実験してみます。


SAKURA  2007-03-14 06:12:43  No: 25247

これじゃダメ?さん
回答ありがとうございます。

試してみましたが、現象は、かわりませんでした。

Mr.XRAYさん
わざわざ検証ありがとうございます。
それに環境までおかしくなってしまうなんて・・・
申し訳ありません。。。

調べてみると、OLEのバージョンのような気がします。
こちらの環境では、SYSTEM32フォルダの
STDOLE2.TLBの日付だけ古いのが気になります。
OLEAUT32.DLL、OLEPRO32.DLLとか同じバージョンでないといけないとか。

また、下記のようにVariant型にしてExcelのCreateを
しないとうまくいくこともわかりました。
しかし、この場合、ExcelでScreenUpdatingが使えないなど弊害も・・・

//OLEオブジェクトを表示可能状態にして表示
OleContainer.Visible:=True;
OleContainer.DoVerb(ovShow);
OleContainer.SetFocus;

//OLEオブジェクトに接続<−※ここをやめてみた
//objExcel := OleContainer.OleObject.Application;
//objExcel := CreateOleObject( 'Excel.Application' );
//開いているブックをobjWorkBookに接続
objWorkBook  := OleContainer.OleObjectInterface as _Workbook;
//シートを objWorkSheetに接続
objWorkSheet := objWorkBook.WorkSheets[1];



Mr.XRAY  URL  2007-03-15 08:06:42  No: 25248

少しテストした結果を報告しておきます。
結果的には分かりませんので、ご了承下さい。

エクスプローラで、
[ツール][フォルダオプション][ファイルの種類]で
XLS Microsoft Excelワークシートを選択し、[詳細設定]
ここで[Open]の[編集]を開きます。実行アプリケーションの
"C:\Program Files\Microsoft Office\Office\EXCEL.EXE" /e %1
最後の /e %1  を削除したり、また元に戻したりしました。
これによって当然動作が変化しますが、元に戻しても何故か元と同じ動作に
なりません。なんか変です。

当方、Office の SR-1となっていますか、たしかSR-2まで適用した記憶が
あるのですが、失念。
これは根性据えて調べるしかありません。いつか調べるつもりではいます。
解決策でなくて申し訳ありません。以上報告まで。


Mr.XRAY  URL  2007-03-15 08:14:05  No: 25249

>調べてみると、OLEのバージョンのような気がします。

OLEについても調べてみます。

>また、下記のようにVariant型にしてExcelのCreateを
>しないとうまくいくこともわかりました。

そうですね。OleContainerがExcelのインスタンスを生成するので、これが
正解でしょうね。ただ、そうするとExcelApplicationの方も...
と考えて、テストしてみたのですが... 変化なし...です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加