none
「Application.Visible」の挙動について RRS feed

  • 質問

  • 環境は、Win8.1、Office2013Personal です。

     

    Win7、Excel2010Personal上で動作していたアプリを上記環境へ移行する際、

    「Application.Visible」使用箇所が正常動作せず、調べてみると以下の現象が原因だと分かりました。

    『Excelアドインにて新規Bookを開き、「ファイル」タブ内の「閉じる」よりBookを閉じた後、

    「Application.Visible = True」を実行すると、Excelアドインがもう1つ立ち上がり、

    最初に立ち上げたExcelアドインも含めて操作不可状態となる。』

     

    本現象についての情報、回避策を模索しています。

    よろしくお願いします。

     

    以下、再現手順です。(手順中の括弧はタスクマネージャーのExcelプロセス内の表示です。※Excelプロセス自体は増えません。)

    1.Excelを立ち上げ、VBAにてThisWorkbookに以下のコードを記述し、「Test.xlam」として保存後閉じる。

    ====================

    Sub AAA()

      Application.Visible = True

    End Sub

    ====================

    2.1.で作成した「Test.xlam」をマクロ有効にして開く。

    3.新規Bookを開く。(Excelプロセス内には、「Book1 - Excel」が表示される。)

    4.「ファイル」タブの「閉じる」よりBookを閉じる(Excelプロセス内には、「Excel」が表示される。)

    5.1.で記述したマクロ(Sub AAA())を実行する。

    6.Excelアドインが追加で1つ立ち上がる。(Excelプロセス内には、「Excel」が2つ表示される。)

    手順3.と手順4.を複数回行った後、手順5.を行うと、回数分のExcelアドインが追加で立ち上がる。

     

    どうもExcelプロセス内にBookが1つも無い状態でApplication.VisibleをTrueにすると発生するようです。

     

    #補足:

    根本原因と思われる箇所のみ書きましたが、

    実際のアプリでは、ExcelアドインでVisibleやScreenUpdatingをFalseにした状態で、

    Book閉じる→ファイルリネーム→Book開くのような処理を行っています。

    また、Bookが1つでもExcelプロセス内に存在する場合には本現象は発生しない為、

    ダミーのBookを用意し、必ずBookが1つある状態にして強引に回避するしかないのかなと思っています。

    (本現象はSDI仕様なのにExcelプロセス起動中に、Bookが1つも無い状態を作る事が出来る時点でExcelのバグだと思っています。。)



    • 編集済み abcdef912 2014年3月14日 7:13
    2014年3月14日 7:10

すべての返信

  • ご使用のアドインファイルは
    Private Sub Workbook_AddinInstall()
    を実行して使用するものだけれど、ここには便宜上簡単に説明するため、投稿内容のようになったと推察します。

    思いきって Application.Visible を使わないものにしてはどうでしょう。

    > Book閉じる→ファイルリネーム→Book開くのような処理を行っています。

    のところを

    1.ファイルをリネームして保存( SaveAs )
    2.元のファイルを削除。

    の順にしてはいかがでしょうか。そうするとリネームしたファイルは開かれたままです。

    (すみません Application.Visible が必要なアドインがどのようなものかイメージできなくて...)

    'テスト
    Dim strOldFile As String, strNewFile

    With ThisWorkbook
        strOldFile = .FullName
        strNewFile = .Path & "(2)" & .Name
    End With

    With Application
        .ScreenUpdating = False
        ThisWorkbook.SaveAs strNewFile
        .DisplayAlerts = False
        With CreateObject("Scripting.FileSystemObject")
            If .FileExists(strOldFile) Then .GetFile(strOldFile).Delete
        End With
        .DisplayAlerts = True
        .ScreenUpdating = True
    End With

    2014年3月15日 14:07
  • 返信ありがとうございます。

    > 1.ファイルをリネームして保存( SaveAs )
    > 2.元のファイルを削除。

    > の順にしてはいかがでしょうか。そうするとリネームしたファイルは開かれたままです。

    確かに上記の処理の方が良いと思いました。

    ただ、後出しとなってしまい申し訳ないですが以下に記載するようにBookオープン、クローズ時に必要な処理を行っている為、Bookを開き直す処理はそのままにしたいと思っています。

     

    > (すみません Application.Visible が必要なアドインがどのようなものかイメージできなくて...)

    もう少し詳しい処理を説明します。

    Excelアドインから『データ展開用DLL』(VB.Netで作成)をコールし、既に開かれているBookにマージする処理を行っており、その際、見た目上Bookが2つに見えないように「Application.Visible」を使用しています。

     『データ展開用DLL』: 新規BookをVisible=Falseで作成し、そのSheet上にデータを展開する処理。

     

    よって、Book1からDLLをコール→Book2がVisible=Falseで起動→Book2開く→Book1にBook2のデータをマージ→Book2閉じる→Book2削除→Book1閉じる→Book1ファイル名変更("Book1"⇒"Book2")→Book2表示(Visible=True)という流れになります。(Book1のファイル名はDLLで作成されたBook2のファイル名に変更する。)

    また、複数のBookをExcelアドインが管理する為、Bookの開閉の際にグローバルなBook管理情報を更新したり、SheetのSelectionChangeイベントを拾えるように新規Sheetをイベントリストに登録するような処理も行っています。

     

    何か良い案ありましたら、よろしくお願いします。


    2014年3月17日 9:04
  • abcdef912 様

    データ入力などの作業中に開く Book は1つに出来ないでしょうか。

    > Book1からDLLをコール→Book2がVisible ・・・ →Book2表示(Visible=True)という流れ・・・

    この一連の作業を ScreenUpdating = False で実行後 ScreenUpdating = True にすれば Visible を使用せずに済むし、複数の Book を開いたまま、という状況がなくなるのでは。

    必要なら、データ入力用に Sheet を作成し Visible = xlSheetHidden などで保存用データを保持し、終了時に更新(データ)、ということはできないでしょうか。

    2014年3月17日 21:26