また教えて頂きたいことがあります。
環境は以下の通りで
・Windows8.1
・Delphi6
・Excel2013
CreateOleObject('Excel.Application')を使ったプログラムで
開発環境で実行(F9)しますとエラーになります。
しかしコンパイルしたEXEで実行しますと正常に動きます。
このプログラムは元々、WinXP + Delphi6 + Excel2000で作ったもので
Win8.1 + Delphi6 + Excel2000でも問題無く動いていましたが
Excelを2013にしますと上記のような状態になります。
上記の開発環境(Excel2013)で動かしたいのですが
何かいい方法は無いでしょうか?
よろしくお願いします。
元のプログラムは大きいので小さいもので確認しました。
以下がそのソースです。
procedure TForm.test;
var
ExcelFile1,ExcelFile2:string;
Excel: Variant;
WorkBook: Variant;
begin
ExcelFile1 := 'D:\work\srce.xls';
ExcelFile2 := 'D:\work\dest.xls';
if FileExists(ExcelFile1) then begin
CopyFile(PChar(ExcelFile1),PChar(ExcelFile2),false);
end;
try
CoInitialize(nil);
Excel := CreateOleObject('Excel.Application'); // ここでエラーになります。
Excel.Visible := true;
WorkBook :=Excel.WorkBooks.Open(FileName := ExcelFile2, readOnly := False);
WorkBook.WorkSheets[1].Cells[1,1].Value := 'ABCDEF';
WorkBook.saved := true ;
Excel:=unAssigned;
finally
CoUninitialize ;
end;
end;
検証できる環境が無いのでお役に立てませんが、気になったことがあるので三点ほど。
>開発環境で実行(F9)しますとエラーになります。
まずはそのエラー内容を提示していただくべきかと。
以下、割とどうでも良いことかもしれませんが一応。
・ CoInitialize/CoUninitializeは、ComObjユニットのinitialization/finalizationで実行されるので不要、とのことです。
・ この用途にはVariantでなく、OleVariantの方が一般的なのでは。(なお、私はヘルプのOleVariantの説明が理解できてません。)
CreateOleObjectでExcelが開いているときにエラーになります。
Excelは見えませんが常駐しているのでは内でしょうか?
私は下記で対応しています。
try
Excel := GetActiveOleObject('Excel.Application'); //動作中の場合
except
Excel := CreateOleObject('Excel.Application'); //起動させる
end;
Harryさんご回答ありがとうございます。
エラーメッセージは以下の通りで
-------------------------------------------------
申し訳ございません。エラーが発生したため、正常に機能できなくなりました。
Excelを終了する必要があります。
今すぐ修復しますか?
「今すぐ修復」「ヘルプ」「終了」
-------------------------------------------------
..と、表示されますが
■「今すぐ修復」をクリックしても特に状況は変わりません。
■「ヘルプ」をクリックしますと以下のURLに飛びますが
内容は一般的なオフィス(エクセル/ワード)のトラブル対応のようです。
http://answers.microsoft.com/ja-jp/office/forum/office_home?tab=question&status=all&auth=1
後、CoInitialize/CoUninitializeにつきましてはかなり前に
つけないと問題が出るとか言う話(噂?)で、おまじないみたいな感じでつけていましたが
外しても通常問題は無い様な感じですね。
それと、OleVariantについてもVariantを差し替えて試しましたが特に変化はないですね。
両方とも確認はしましたが、エラーは残ります。
HOtaさん、ご回答ありがとうございます。
早速提示して頂きました内容を確認しましたが結果は変わりませんでした。
ただ、この内容はExcelが重複して起動した場合の対応で
今回の場合は、コンパイルしたEXEでは何も問題なく動作しますので
直接関係はしてないと思います。
しかし何かの時に重複起動もあり得ますのでそれに対しての
予防策として利用できそうですので現状のプログラムに組み込まさせて頂こうと思います。
ありがとうございました。
参考になるかどうか分かりませんが,
私のところでは,以下の環境で,そのような現象は確認できていません.
Windows 8.1 Pro(64 ビット版) + Delphi 6 Pro(UP2) + Excel 2013 (32 ビット版)
Mr.XRAYさん、貴重な情報ありがとうございます。
似た様な環境で確認をして頂いたようですが出ないと言う事ですね。
こちらの環境をもうちょっと詳しく書きますと...
・Windows8.1(32ビット版)
・Delphi6 Ent(UpdatePack2)
・Excel2013(32ビット版)
なのですが...
Excelに関しましては、最初Excel2000+Excel2013が入っておりましたが
前述のように動作がおかしかったので、Excel2000は削除した環境になっています。
もしかしたら、それらが何らかの影響を及ぼしているのでしょうか。
もう少し調べてみます。
以下のように,バージョンの 15 を指定するとどうなるでしょうか ?
Excel := CreateOleObject('Excel.Application.15');
>以下のように,バージョンの 15 を指定するとどうなるでしょうか ?
>
> Excel := CreateOleObject('Excel.Application.15');
あるいは,コマンドプロンプトを管理者権限で起動して,以下のコマンドを実行した場合はどうなるでしようか.,
"C:\Program Files\Microsoft Office 15\root\office15\EXCEL.EXE" /regserver
私が確認した Excel の詳細なバージョンは以下の通りです.
Microsoft Excel 2013(15.0.4787.1002) MSO(15.2.4787.1002) 32 ビット
Mr.XRAYさん
いろいろな案のご提供本当にありがとうございます。
早速試してみました。
> Excel := CreateOleObject('Excel.Application.15');
この方法につきましては既に試していますが
悪化してDelphiそのものがフリーズする結果になりました。
> "C:\Program Files\Microsoft Office 15\root\office15\EXCEL.EXE" /regserver
これを行いますと...
「Microsoft Excelは現在、スプレッドシートの表示や編集に使う既定のプログラムではありません。
Excelで開くファイルの種類を選びますか?」
と言うメッセージが出ます。
その後それに従ってエクセルで関連付けをしても結果は同じでした。
(実行プログラム(EXE)では問題なく動き、開発環境での実行はNG)
本日は所用で外出しますが帰りましたら更に調べてみたいと思います。
ありがとうございます。
>「Microsoft Excelは現在、スプレッドシートの表示や編集に使う既定のプログラムではありません。
>Excelで開くファイルの種類を選びますか?」
これは正常ではないですね.
これが原因かどうかはともかく,直しておく必要があると思います.
また,レジストリの以下の値も確認しておいた方がいいと思います.
[HKEY_LOCAL_MACHINE\SOFTWARE\Classe\ 階層下の
Excel.Applcation
+ CLSID
+ CurVer <-- このキーの (既定) 値が Excel.Application.15 になっているか
ただし,この値が Excel.Application.15 となっていても,
Excel 2013 がカレントバージョンである保証はありません.
(Excel 2003 (Office 2003) までは,この値だけで判定できました.
Excel 2007 以降はちょっと複雑になっています)
Mr.XRAYさん
更なる情報ありがとうございます。
> >「Microsoft Excelは現在、スプレッドシートの表示や編集に使う既定のプログラムではありません。
> >Excelで開くファイルの種類を選びますか?」
> これは正常ではないですね.
> これが原因かどうかはともかく,直しておく必要があると思います.
そうですね今の症状は私のところだけで起きているようなので
Excelの環境がおかしくなっている可能性が高いですね。
後レジストリに関しましては以下のデータは
既に「Excel.Application.15」になっていますので問題ないようです。
> HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.Application\CurVer
となりますと...
後はExcel2013をインストールし直すくらいしか手は無さそうですが...
ただ開発環境でExcelとの連携がうまくいかない事を除けば他は問題ありませんし
(実行プログラムからは動きますので)Excelの再インストール時の認証の手間を考えれば
現状の開発の中では今はそっとしておいて後日試してみたいと思います。
EXE 直接実行と,IDE でコンパイルして実行した場合で違うということは,
他に考えられるのは,仮想化かな ?
C:\ユーザ\ユーザ名\AppData\Local\VirtualStore
(全てのフォルダとファイルを表示する設定でないと見えない場合あり)
この階層下に何があるか,またレジストリの以下に何があるかですね.
一応確認しておいた方がいいかも知れません.
[HKEY_CURRENT_USER\SOFTWARE\SOFTWARE\Classe\VirtualStore
上のフォルダと,レジストリ内に,Delphi 6 または Excel 2013 関係の情報があるかですね.
あるとすれば,その内容によっては怪しい場合があります.
>[HKEY_CURRENT_USER\SOFTWARE\SOFTWARE\Classe\VirtualStore
まちがえました.コピペしないで ON 書きやってしまいました.
(でも,また ON 書きです ^^; )
[HKEY_CURRENT_USER\SOFTWARE\Classe\VirtualStore
Mr.XRAYさん
教えて頂いた内容ですが...
> C:\ユーザ\ユーザ名\AppData\Local\VirtualStore
> HKEY_CURRENT_USER\SOFTWARE\Classe\VirtualStore
どちらもDelphi6に関しての記述は特に見当たりませんが
Office15.0(Excel2013)に関してのデータは何か入ってるようですが
このレベルの事になりますと未知の領域でどういう繋がりになるのか分かりません。
これから先の状況はちょっとレベルが深そうで意味不明です...すみません m(__)m
何とかして,自分のところでも同じエラーが発生すれば,
解決への道が見つかる可能性があるかも知れませんが...
で,ちょっとお願いしたいことがあるんですが,
以下のコードをテストしていただけませんか ?
mook さんのような環境で,
IDE からの実行と,EXE を直接実行した場合の違いを知りたいのです.
正常に動作すれば,ExcelApplication.15 と表示されるハズです.
StringToGUID, ClassIDToProgID の使用には,uses に ComObj が必要です.
procedure TForm1.Button2Click(Sender: TObject);
var
LGUID : TGUID;
LText : string;
begin
LText := '{00024500-0000-0000-C000-000000000046}';
LGUID := StringToGUID(LText);
//登録されていればProgIDが表示される
ShowMessage(ClassIDToProgID(LGUID));
end;
Mr.XRAYさん
ありがとうございます。
> 何とかして,自分のところでも同じエラーが発生すれば,
> 解決への道が見つかる可能性があるかも知れませんが...
私の環境をお見せ出来れば解決が早いのかも知れませんが...
ご丁寧に確認用のソースまで用意して頂いて恐縮です。
教えて頂きましたソースで確認しましたが
開発環境 及び EXE の両方の動作確認で
「Excel.Application.15」が表示されます。
>開発環境 及び EXE の両方の動作確認で
>「Excel.Application.15」が表示されます。
えっ !?
> Excel := CreateOleObject('Excel.Application'); // ここでエラーになります。
でエラーになるんですよね ?
では,以下ではどうでしょう.前回の逆のテストです.
procedure TForm1.Button3Click(Sender: TObject);
var
LGUID : TGUID;
LText : string;
begin
LText := 'Excel.Application';
LGUID := ProgIDToClassID(LText);
//登録されていればCLSIDが表示される
ShowMessage(GUIDToString(LGUID));
end;
スミマセンね.
私のサイトにエクセル関係の記事を書いているものですから,
少しでも情報が欲しいので.申し訳ないです.
スミマセン.もう 1 つだけお願いしたいのですが.
以下ではどうでしょう.
procedure TForm1.Button4Click(Sender: TObject);
var
LGUID : TGUID;
LText : string;
Lpv : TGUID;
begin
LText := 'Excel.Application';
LGUID := ProgIDToClassID(LText);
OleCheck(CoCreateInstance(LGUID,
nil,
CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
IDispatch,
Lpv));
ShowMessage(IntToStr(Lpv.D1));
end;
Mr.XRAYさん
少し遅れましたが、頂いたソースを実行しますと...
-----------------------------------------------------
申し訳ございません。エラーが発生したため、正常に機能できなくなりました。
Excelを終了する必要があります。
今すぐ修復しますか?
「今すぐ修復」「ヘルプ」「終了」
-----------------------------------------------------
と言う以前と同じメッセージが出ますね。
いろいろテストしていただき,ありどとうございます.
解決のお手伝いはできませんでしたが,今後の参考にさせていただきます.
Mr.XRAYさん
いろいろと案など出して頂きありがとうございました。
私の方だけで発生していると言う事が分かった時点で
これは再インストールとかをしないとダメかなと大半諦めていまして
それでも何かいい方向に行けば..と思っていましたがやはり無理ですね。
今のままでもEXEでのエクセル連携の確認は出来ますので
暫く続行しまして何かの時にエクセルを再インストールするなりしてみたいと思います。
解決ではありませんが、取敢えず終了したいと思います。
ありがとうございました。
ツイート | ![]() |