none
エクセルのBeforeCloseイベントで他の非表示ブックを表示させると RRS feed

  • 質問

  • 複数のブックを開いてVBAで処理を行うプログラムを組んでいるときに奇妙な現象が起きました。

    下記のようにマクロを書いたBook1とBook2を開らきます。

    ただし、Book2はWorkbook_Openで非表示にしています。

    Book1を閉じた時にBook2を表示させたいので、

    Book1のBeforeCloseイベントでWindows(Book2.xlsm).Visible = Trueという処理を追加しました。

    すると下記のような現象が起きました。

    下に詳しいプログラムを提示してあります。それ以外のプログラムはこれらブックに書いていません。

    プログラム上のミスがあればご教授いただきたいです。

    また、このような現象を起こさないような方法があればこれもご教授いただきたいです。

    Windows10 64Bit

    Excel 2016

    上記二つのブック以外はエクセルで開いていません

    Book1.xlsmのWorkbook_BeforeCloseイベント

    Private Sub Workbook_BeforeClose(Cancel As Boolean)

        Dim wb As Workbook

        For Each wb In Workbooks

            If wb.Name = "Book2.xlsm" Then

                Application.Windows("Book2.xlsm").Visible = True

                Exit Sub

            End If

        Next

    End Sub

    Book2.xlsmのWorkbook_Openイベント

    Private Sub Workbook_Open()

        Application.Windows(ThisWorkbook.Name).Visible = False

    End Sub

    手順1:

    Book1を立ち上げたあと、Book2を立ち上げる。その後ウインドウ右上の×ボタンをクリック

    結果:Book2が表示されアクティブウインドウとなる。Book1は閉じない。

                    その後① Book1をアクティブにし、×をクリック

                                                    Book1は閉じる。

                    その後② Book2を非表示にする

                                                  Book1がアクティブになる。×をクリック

                                                    Book2に関する警告表示(保存するか?)

                                                    →1.「保存する」または「しない」をクリック

                                                                    Book1Book2ともに閉じられる。

                                                    →2.キャンセルをクリック

                                                                    →何も起こらない

                                                                    →その後×をクリック

                                                                    →手順2と同じ結果

    手順2:

    Book2を立ち上げた後(このときBook2は非表示)、Book1を立ち上げる。その後×をクリック

    結果:Book2はアクティブになるが全画面表示(リボン、×ボタン等が表示されない)のようになる。Book1は閉じない。その後Book1をアクティブにし、×をクリックするとBook1は閉じる。Book2については全画面表示の解除方法がわからないので、タスクマネージャーから強制終了。



    • 編集済み Joe_Hide 2018年7月5日 4:41 正しく伝えられない可能性があったため
    2018年7月5日 4:26

回答

  • 「全画面表示のように」は私の方でも再現しておりました。ただ、Book2自体がおかしくなっていたように思い、一度、起動時に非表示にしないようにして立ち上げ、再度、起動時に非表示にするなどすると、知らぬ間に直っていました。これは手順1での話です。
    今、再度、手順2を行ってみましたが、おっしゃるように「全画面表示のように」なってしまいますね。
    ただ、先にBook2を立ち上げると、私のところでは非表示にはならなくて、シートが全くないExcelが表れています。これは、Book2は非表示なのですが、大元のExcelというか、そういう感じのものが開いているようです。その後、Book1を立ち上げるとBook1の状態だけとなります。何となく先ほどの大元のExcelにBook1が表示された感じがします。

    C#からExcelを操作する際に、OpenXmlというものがあります。これはExcelの構造を知っていないと扱えないのですが、その際に、SpreadsheetDocumentというオブジェクトを生成し、そこにWorkBookオブジェクトなどが属するようになります。つまり、大元に見えているこのExcelがSpreadsheetDocumentオブジェクトではないかと想像しています。
    #ちなみにOpenXmlは面倒なので、それをラップしたClosedXmlを使った方がはるかに楽です。

    手順2に関してですが、仕組みはよくわかりませんが、以下のコードをBook1に追加するとうまく動いているようです。

    Private Sub Workbook_Open()
    
        Dim wb As Workbook
        
        For Each wb In Workbooks
            If wb.Name = "Book2.xlsm" Then
                Application.Windows("Book2.xlsm").Visible = True
                Application.Windows("Book2.xlsm").Visible = False
                Exit For
            End If
        Next
     
    End Sub
    う~ん、やっぱり完全にわかってないなぁ。



    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!



    2018年7月6日 11:41
    モデレータ

すべての返信

  • 確かにちょっとよくわからない動作をしますね。以前からのようです。

    Excelを編集した後、Bookを非表示にして保存
    https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12124503442

    Application.Windowsで全てのBookが参照できるように、Excelのブックはそれぞれ独立しているのではなく、どこかで一括して管理されているようですね。おそらくその関係で意図した通りにならないのだと思います。
    とりあえず対処療法ですが、以下のコードで何となく実現できている雰囲気です。

       '下のApplication.Windows(ThisWorkbook.Name).Closeで発生した2回目のWorkbook_BeforeCloseは何もせずに抜ける
       If Application.Windows("Book2.xlsm").Visible = True Then
            Exit Sub
       End If
    
    
        Dim wb As Workbook
        For Each wb In Workbooks
            If wb.Name = "Book2.xlsm" Then
                Application.Windows("Book2.xlsm").Visible = True
                Application.Windows(ThisWorkbook.Name).Close
                Cancel = True
                Exit For
            End If
        Next
        
    End Sub
    (補足)
    上のコードは、要するにBook1を閉じる動作と、Book2を表示する動作を分けることを意図しています。
    Book2を表示した後にBook1を閉じる動作をキャンセルし、その後、Book1を改めて閉じる動作となります。



    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!


    2018年7月6日 2:43
    モデレータ
  • ご返信ありがとうございます。

    ご提示いただいたコードで実行してみたら、Book1を閉じることができました。

    ただ、手順2を実行するとBook2は「全画面表示のように」なってしまいました。

    最初の投稿で私の表現が悪かったので誤解させてしまったようです。申し訳ありません。

    「全画面表示のように」とは、「タイトルバー、リボン(メニューバー)、ステータスバー」が表示されない、という状況です。これは通常のエクセルの全画面表示ではありません。ウインドウを最大化しないで手順2を実行するとウインドウの大きさはそのままで、「タイトルバー、リボン(メニューバー)、ステータスバー」が表示されない状態になります。通常の全画面表示ではESCキーを押すと全画面表示が解除になるはずですが、それもできません。

    もしかしたら、私のエクセルやパソコンの不具合が原因でこの状態になるかも知れません。私のエクセルを再インストールしてからもう一度ご提示いただいたコードを実行してみます。

    本当にご返答ありがとうございました。

    2018年7月6日 10:55
  • 「全画面表示のように」は私の方でも再現しておりました。ただ、Book2自体がおかしくなっていたように思い、一度、起動時に非表示にしないようにして立ち上げ、再度、起動時に非表示にするなどすると、知らぬ間に直っていました。これは手順1での話です。
    今、再度、手順2を行ってみましたが、おっしゃるように「全画面表示のように」なってしまいますね。
    ただ、先にBook2を立ち上げると、私のところでは非表示にはならなくて、シートが全くないExcelが表れています。これは、Book2は非表示なのですが、大元のExcelというか、そういう感じのものが開いているようです。その後、Book1を立ち上げるとBook1の状態だけとなります。何となく先ほどの大元のExcelにBook1が表示された感じがします。

    C#からExcelを操作する際に、OpenXmlというものがあります。これはExcelの構造を知っていないと扱えないのですが、その際に、SpreadsheetDocumentというオブジェクトを生成し、そこにWorkBookオブジェクトなどが属するようになります。つまり、大元に見えているこのExcelがSpreadsheetDocumentオブジェクトではないかと想像しています。
    #ちなみにOpenXmlは面倒なので、それをラップしたClosedXmlを使った方がはるかに楽です。

    手順2に関してですが、仕組みはよくわかりませんが、以下のコードをBook1に追加するとうまく動いているようです。

    Private Sub Workbook_Open()
    
        Dim wb As Workbook
        
        For Each wb In Workbooks
            If wb.Name = "Book2.xlsm" Then
                Application.Windows("Book2.xlsm").Visible = True
                Application.Windows("Book2.xlsm").Visible = False
                Exit For
            End If
        Next
     
    End Sub
    う~ん、やっぱり完全にわかってないなぁ。



    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!



    2018年7月6日 11:41
    モデレータ
  • 再びのご返信ありがとうございます。

    望み通りに動きました。

    ただ、別の問題が発生しました。

    パソコンにこのブックを保存させている場合は何も問題はありません。が、OneDrive上だと下記のようになります。

    私はこの二つのブックをOneDrive上に保存しています。後だしのようになってしまってすみません。私はここに保存していることで問題が起きるとは毛頭も思っていなかったので、最初の投稿には記述しませんでした。

    ご提示いただいたコードを追加したブックをOneDrive上に保存して、Book1,Book2を開きます。Book1が表示された状態で×ボタンをクリックすると、通常にBook2が表示されます。このとき×ボタンをクリックすると以下のメッセージが表示されます(手順1,2ともに)。

    タイトルバーに「Microsoft Excel」 アイコン「?」

    「他のユーザーと結合できない変更がサーバー上にあります。続けるにはサーバー上の変更内容を破棄するか、ファイルのコピーを保存してください。」

    ボタン「サーバー上の変更を破棄する」「コピーを保存」「キャンセル」

    OneDriveには私しかアクセスできません。また他のパソコンから私がBook2を変更していたわけでもありません。

    ただ、私はネットワークに詳しくないので、設定など正しく行っていない可能性があります。

    このようなことがあった、ということを情報として上げておきたいと思います。

    また、この問題はまた投稿したものとは異なるものなので、回答としてマークさせていただきます。

    trapemiya様,お付き合いいただきありがとうございました。

    2018年7月7日 2:02