喫茶XRAYトップページ

[スレッド全体
]

[8158] Re3:DelphiからExcelファイルを開いたときのダイアログについて返信 削除
2014/10/31 (金) 17:57:14 Mr.XRAY
▼ Nagaさん

> 自分も拡張子で制御を提案したのですが却下されました...
> (今度ファイル形式が変わったときの拡張子が何かわからないからとか・・・)


というより,新しいバージョンを導入した時に,その新しいバージョンの
ファイルが扱えなる可能性の問題ではないかと.

完全な回避策はないと思います.
考えられる方法としては,次のようなものでしょうか.

(方法 1 )
将来のことを考慮して,ダイアログをスキップしないで導入する
http://support.microsoft.com/kb/919026/ja

(方法 2)
エクセルのバージョンと拡張子の条件によってダイアログを表示しないようにする
そうすれば,Excel 2007 以降のエクセルを導入してもアプリはそのまま使用可能となる
当然,判定には Excel 2007 以降の拡張子名を使用しないようにする
古いエクセルのブックの拡張子名は確実に既知なので,問題はない,と思う
  ExcelObj.DisplayAlerts := False;
にすれば,警告関係のダイアログは一切現れなくなる

  if (ExcelObj.Version <= 11.0) and (FileExt = '.xls') then begin
                                     ^^^^^^^^^^^^^^^^^
                                     この部分は必要に応じて変更
    //開いてもいいよん
  end else
  if (ExcelObj.Version > 11.0) then begin
    //開いてもいいよん
  end else begin
    //ダメ!! ダメよ! ダメ!
  end;
等...
もちろん,この方法でも,更に新しい拡張子を扱うバージョンが現れると
対応コードを追加する必要があります.

(方法 3)
ダイアログの表示をフックして,表示開始前に終了させてしまう.
そのダイアログは,エクセルが表示しています.
エクセルは別アプリです.
したがって,グロバールフックということになります.
Excel 2007 以上では,そのダイアログは現れないので,このあたりも工夫が必要です.
これらの警告ダイアログのクラス名は全て #32770 です.
ダイアログのタイトルには必ず Microsoft Excel があります.

もちろん,この方法でも,更に新しいバージョンが現れると,
どんなダイアログが使われるかは予想できません.

http://mrxray.on.coocan.jp/Delphi/plSamples/270_HookCBTCreate.htm
http://mrxray.on.coocan.jp/Delphi/plSamples/280_HookCBTActivate.htm
等...

-----------  方法の説明終り -------------------------------

結果:
未来は予測,予想できない.ということになります.



[8165] Re4:DelphiからExcelファイルを開いたときのダイアログについて返信 削除
2014/10/31 (金) 23:20:18 Mr.XRAY
「互換パックをダウンロード」のダイアログがエラーで表示されるのであれば,
対処方法もあるんですけどね.
残念ながらエラーでないですからね.


[8168] Re5:DelphiからExcelファイルを開いたときのダイアログについて返信 削除
2014/11/1 (土) 23:22:42 Mr.XRAY
作ってみました.
Excel 2007 以降の環境の方には関係ないテストプログラムです

http://mrxray.on.coocan.jp/Delphi/zip/Excel_DialogHook_Test.zip

[04_ExcelDialogHook_ShellExecute] 内の OtherAppHook_ShellExecute.exe
を実行してみてください.
これは,フォルダ内の Test.xlsx を読み込んで表示するものです.
結果によって,詳しい説明をしたいと思います.

当方のバーチャルマシンの Windows XP に Excel 2003 が入ってしました.
テスト結果の図です.


[8169] 互換パックダウンロードのダイアログ操作返信 削除
2014/11/2 (日) 17:51:08 Mr.XRAY
プログラムは,なんでもやってみると,いい経験になります.
で,やってみたわけです.

今回の現象はこういうことです.
まだ Excel 2003 を使用している環境で,Excel 2007 で追加されたブック形式,
これの拡張子は主に .xlsx です.
これを Delphi のプログラムで読み込もうとすると図のようなダイアログが現れます.
このダイアログの表示を回避したいということです.

テストのコードは,このような場合に用意している以下のサンプルを使用しました.
[09_エクセル操作のテスト用基本コード ( 起動時に指定ブックを開く )]
http://mrxray.on.coocan.jp/Delphi/plSamples/400_Excel_CreateObject.htm#09

動作確認は以下です.これ以降の書込みで全て同じです.
EXE 作成環境 Windows 7 U64(SP1) + Delphi XE(UP1) Pro + Excel 2010
EXE 実行環境 Windows XP(SP3) + Excel 2003



[8170] Re:互換パックダウンロードのダイアログ操作返信 削除
2014/11/2 (日) 17:55:57 Mr.XRAY
> このダイアログの表示を回避したいというこです.

さて,回避と言ってもいろいろあります.
このダイアログで [いいえ] クリックすると,ブックのファイルは読み込みません.
[はい] をクリックした場合は,以下の記事を参考にしてください.

[以前のバージョンの Microsoft Office で新しいファイル形式を開く方法]
http://support.microsoft.com/kb/924074/ja

[Microsoft Office 互換機能パックをインストールして、Office Open XML 形式
を以前のバージョンの Microsoft Office で開いたり保存したりできるように
する方法]
http://support.microsoft.com/kb/923505/ja

[互換機能パックで「.docx」「.xlsx」を旧Officeで開く方法 ]
http://hpc.blog0.jp/archives/2669


[8171] Re2:互換パックダウンロードのダイアログ操作返信 削除
2014/11/2 (日) 17:58:55 Mr.XRAY
> さて,回避と言ってもいろいろあります.

プログラムのコードで,このダイアログを表示しないようにすることができます.
それには,次のように,DisplayAlerts の値を False にします.

  ExcelObj  := CreateOleObject('Excel.Application');
  ExcelObj.DisplayAlerts := False;

これでダイアログは表示されなくなりますが,
ブックのファイルは読み込まれます.
その結果,読み込まれた内容は下図のように文字化けしていまいます.

このダイアログは,
  ExcelObj.DisplayAlerts := False;
なし(つまり True) にしても,例外ではとらえることができません.



[8172] Re3:互換パックダウンロードのダイアログ操作返信 削除
2014/11/2 (日) 18:18:35 Mr.XRAY
>
>   ExcelObj  := CreateOleObject('Excel.Application');
>   ExcelObj.DisplayAlerts := False;
>
> これでダイアログは表示されなくなりますが,
> ブックのファイルは読み込まれます.


前に書いた
http://mrxray.on.coocan.jp/Delphi/zip/Excel_DialogHook_Test.zip

は,ダイアログを表示しないようにして,
かつ,ブックのファイルを読み込まない方法の 1 つです.

グローバルフックを使用しています.
このグローバルフックは,DLL 内にないと機能しません.
そこで,DLL を作成しています.
コードは以下のサンプルのものを使用しています.

[03_ユーザ定義メッセージ WM_APP を使用する ]
http://mrxray.on.coocan.jp/Delphi/plSamples/280_HookCBTActivate.htm#03

ただし,TListView への表示は必要ないので,そのコードは削除しています.
また,メッセージの値も,自由に変更可能なように,以下のコードで定義しています.

const
  CBT_DLL_MESSAGE = WM_APP+222;


ダイアログは以下のように,検出しています.
エクセルのバージョンや拡張子名は使用していません.

(1) アプリが起動したら,クラス名が #32770 のウィンドウを探す
(2) 見つかったら,タイトル(キャプション) が Microsoft Excel か確認する
(3) そのウィンドウの中にクラス名が Static というウィンドウがあるかを探す
(4) 見つかったら,そのウィンドウのテキストを取得する

そのテキストの中に「互換パック」と「ダウンロード」という文字列が存在したら,
問題のダイアログと決定します.
そのダイアログのウィンドウに文字,N 押下のコードを実行します.
すると,[いいえ] をクリックしたのと同じになります.

このままだと,ブックが読み込まれてしまいます.
そこで,例外処理で捉えます.

というわけです.

自分が未熟だと思ったら,いろいろなことをやってみることです.
≪コンポーネントがいいのか,OCX がいいのか≫
と悩む前に実際にやってみることです.ハイ.


[8173] Re4:互換パックダウンロードのダイアログ操作返信 削除
2014/11/2 (日) 18:44:22 Mr.XRAY
> ≪コンポーネントがいいのか,OCX がいいのか≫

この文章はちょっとへんですけどね (^^;
まっ,深く考えないでくださいませ.
あまり考えると,頭がハゲますから.ハハハッ


[8174] Re4:互換パックダウンロードのダイアログ操作返信 削除
2014/11/2 (日) 18:54:42 Mr.XRAY
> そのテキストの中に「互換パック」と「ダウンロード」という文字列が存在したら,
> 問題のダイアログと決定します.


このテキストの取得ですが,
当サイトのサンプルでは,ほとんど次のコードを使用しています.
これは,主に,ウィンドウのタイトル(キャプション) 文字列の取得としています.

function GetWindowTitleStr(hWindow: HWND): String;
var
  Buffer : array[0..MAX_PATH - 1] of Char;
  Len    : Integer;
begin
  FillChar(Buffer, SizeOf(Buffer), #0);
  Len := GetWindowText(hWindow, Buffer, Length(Buffer));
  if Len > 0 then Result := Buffer else Result := '';
end;

今回の場合は,これでは長い文字列の取得に失敗する可能性があります.
そこで,次のコードを使用しています.
(実際には上のコードでも十分でしたが)

function GetWindowTitleStr(hWindow: HWND): String;
var
  Len    : Integer;
  Buffer : PChar;
begin
  Result := '';
  Len := GetWindowTextLength(hWindow);
  Buffer := StrAlloc(Len + 1);  //SetLength を使用したサンプルもある
  try
    Len := GetWindowText(hWindow, Buffer, StrBufSize(Buffer));
    SetString(Result, Buffer, Len + 1);  //実際には代入互換性がある
  finally
    StrDispose(Buffer);
  end;
end;

こういうことも,実際にやってみると気づくわけです.


[8175] Re6:DelphiからExcelファイルを開いたときのダイアログについて返信 削除
2014/11/4 (火) 10:33:38 Naga
▼ Mr.XRAYさん

確認ありがとうございます。本当に感謝しています。

これから試させてもらいます。
方向が決まったらまた報告します。

よろしくお願いします。


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82