[[20220715100804]] 『Thisworkbook.Closeが効かない』(うなぎ食べたい) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『Thisworkbook.Closeが効かない』(うなぎ食べたい)

お世話になります。
ユーザーフォームのコードについての相談です。

現在のコード
ThisWorkbookモジュール

 Private Sub Workbook_Open()
    UserForm1.Show
 End Sub

UserForm1モジュール

 Private Sub CommandButton1_Click()
    Stop
    ThisWorkbook.Close
 End Sub

ブック起動時にUserForm1を起動、
UserForm1上に置かれたコマンドボタンを押すとブックを閉じる、
という動作を実現したいのですが、最初の1回はThisWorkbook.Closeがスルーされてしまいます。
一度フォームを閉じ、再び開くとボタン押下でブックを閉じることが出来ます。

もしかしたらWorkbook_Openプロシージャが完結していないのが原因かもしれない、と思い

 Private Sub Workbook_Open()
    UserForm1.Show False
 End Sub

に書き換えたところ、最初の1回でもブックを閉じることができました。
しかし、できればモーダルなままフォームを開きたいです。

そこで

 Workbook_Openは終了させる
 UserForm1はモーダルで開き最初の1回でも終了ボタン押下でブックを閉じる

こんな方法はないでしょうか?
お教えいただけるとありがたいです。

< 使用 Excel:Excel2019、使用 OS:Windows10 >


 >Private Sub CommandButton1_Click()
 >   Stop
 >   ThisWorkbook.Close
 >End Sub

 なんで、Stopなんて物があるのか摩訶不思議?

(疑問) 2022/07/15(金) 10:16


当たり前の話ですが、UserFormを閉じたら、UserForm.Showの次の行が実行されます

 Private Sub Workbook_Open()
   UserForm1.Show
   ThisWorkbook.Close
 End Sub

(とおりすがり) 2022/07/15(金) 10:23


すみません。この件はいったん保留とさせてください。

さっきまでできなかった(ステップ実行でスルーされていることも確認)のに
質問投稿後に実行したところ、できるようになっています。
再現性がなくなってしまったのでいったん保留にさせてください。
お騒がせしてすみませんでした。

疑問さん
ステップ実行して確認するためにStopを差し込んでいました。

とおりすがりさん
アドバイスありがとうございます。
この方法も試行してみたいと思います。
(うなぎ食べたい) 2022/07/15(金) 10:24


経過報告です。
どうやらこれはエクセルを先に起動して、ホームメニューからブックを開くときにだけ起きる現象のようです。
この方法だと、通りすがりさんの教えてくださったコードでもブックを閉じることができませんでした。
エクスプローラー等からブックのアイコンをダブルクリックして起動した場合、閉じることができていました。

なんなんでしょうか。よくわからなくなってきました。
(うなぎ食べたい) 2022/07/15(金) 10:39


自己解決、というか経過報告、というか。

もしかしたらWorkbook_Openの仕様ミスなのかもしれないと考え
標準モジュールにAuto_Openで記述したところ望み通りの動作になりました。

お騒がせしてすみませんでした。
(うなぎ食べたい) 2022/07/15(金) 10:55


追加報告です。
他のブックを開いた状態でエクセルのホームメニューから当該ブックを開くと、Auto_OpenでもThisWorkbook.Closeを無視してしまう現象が発生します。

Workbook_OpenはEnableEventsプロパティの影響を受けるから仕方ないのかもしれない、とも思ったのですが
Auto_Openでもこうなってしまうのではもうお手上げなんでしょうか。
(うなぎ食べたい) 2022/07/15(金) 11:31


 2016ですが、ちゃんとブックは閉じます
 該当のブックを開く前に、別のブックを開いている場合、
 該当のブックは閉じますが、最初に開いていたブックが開かれたままなので、
 アプリケーションは終了しません

 2019でも同じだと思います
 アプリケーションを終了する場合、Applicaiton.Quitする必要があります。
(´・ω・`) 2022/07/15(金) 11:39

 「Closeで全ファイルを閉じても、カラのExcelファイルが表示されたままになります。」だそうです。
 こちらでも試してみましたがそのようになりましたね。
 「ブックを閉じる=エクセルを終了させる」と思っているのではないですか。
(???) 2022/07/15(金) 12:08

 Private Sub Auto_Open()
    UserForm1.Show
    'ThisWorkbook.Close '※動作確認のためコメントオフ中
 End Sub
 Private Sub CommandButton1_Click()
    Dim wb As Workbook
    Dim c As Long
    c = 1
    For Each wb In Workbooks
        If wb.Name Like "PERSONAL.XLS?" Then
            c = c + 1
            Exit For
        End If
    Next
    If Workbooks.Count > c Then
        ThisWorkbook.Close
    Else
        Application.Quit
    End If
    Unload Me
    MsgBox ThisWorkbook.Name & "を閉じることができませんでした", vbInformation
 End Sub
(´・ω・`) さんアドバイスありがとうございます。
いろいろ試行錯誤していて今のコードはこうなっています。
1.別ブックを開いていない状態でエクセルのホームメニューから当該ブックを開く
  →メッセージボックスを開いてその後エクセル終了
2.別ブックを開いている状態でエクセルのホームメニューから当該ブックを開く
  →メッセージボックスを開いてエクセル終了しない
3.別ブックを開いていない状態でエクスプローラーでブックアイコンダブルクリックで当該ブックを開く
  →メッセージボックスを開いてその後エクセル終了
4.別ブックを開いている状態でエクスプローラーでブックアイコンダブルクリックで当該ブックを開く
  →メッセージボックスなしでエクセル終了
こんなありさまです。
UnLoad Meの前にStopを差し込むと1と3でもメッセージボックスなしでエクセル終了しますが
その次に当該ブックを開くとVBEが開きStopのところでコードが止まっている(反転表示)状態からになります。

(うなぎ食べたい) 2022/07/15(金) 12:10


1.別ブックを開いていない状態でエクセルのホームメニューから当該ブックを開く
  →メッセージボックスを開いてその後エクセル終了
2.別ブックを開いている状態でエクセルのホームメニューから当該ブックを開く
  →メッセージボックスを開いて当該ブック終了しない
3.別ブックを開いていない状態でエクスプローラーでブックアイコンダブルクリックで当該ブックを開く
  →メッセージボックスを開いてその後エクセル終了
4.別ブックを開いている状態でエクスプローラーでブックアイコンダブルクリックで当該ブックを開く
  →メッセージボックスなしで当該ブック閉じる(別ブックが残る)

こうでした。
(???)さんアドバイスありがとうございます。
空のエクセル状態にはなってくれませんでした。
(うなぎ食べたい) 2022/07/15(金) 12:12


 Unload する前に Application.Quit すると、
 メモリ上にUserFormが残ったままアプリを閉じるので、その後どんなことが起きるのか分かりません

 順序よく片付けましょう
(´・ω・`) 2022/07/15(金) 12:39

ブックが閉じないっていうのは、×ボタンでユーザーフォームを終了してるからでは?

他には特に閉じないという場面に出くわしませんでした。Excel2019
(まっつわん) 2022/07/15(金) 15:12


 >メッセージボックスを開いて
 どのようにして開いているのでしょうか。
 >当該ブックを開く
 このブックに上記のマクロが入っているんですよね。
 このマクロで他のブックも閉じようとしているんでしょうか。
(???) 2022/07/15(金) 16:32

皆さんアドバイスありがとうございます。

(´・ω・`)さん

 > Unload する前に Application.Quit すると、
 > メモリ上にUserFormが残ったままアプリを閉じるので、その後どんなことが起きるのか分かりません
 > 順序よく片付けましょう

ありがとうございます。この点修正しました。
しかし終了するケースでも終了前にメッセージボックスが開いてしまう点はそのままでした。

まっつわんさん

 > ブックが閉じないっていうのは、×ボタンでユーザーフォームを終了してるからでは? 
 > 他には特に閉じないという場面に出くわしませんでした。Excel2019

フォーム上に置いたCommandButton1を押したときの動作です。
同じエクセル2019でも起きないということですね。ますますわけがわかりません。

???さん

 >>メッセージボックスを開いて
 > どのようにして開いているのでしょうか。

コードは2022/07/15(金) 12:10のとおりです。
自動でブックをCloseできない場合の次の動作で
ThisWorkbook.CloseまたはApplication.Quitのあとにメッセージボックスを開き
ブックが自動で閉じられなかったことを知らせようとしましたが
自動で閉じるケースでもメッセージボックスが開いてしまいました。
これはブックを閉じる前にUnload Meを記述しても同様の動作でした。

 >>当該ブックを開く
 >このブックに上記のマクロが入っているんですよね。

はい

 > このマクロで他のブックも閉じようとしているんでしょうか。

他のブックを閉じるコードはありません。
(うなぎ食べたい) 2022/07/16(土) 05:08


 >はい
 「個人用マクロブック」で保存していませんね。
 「XLStartフォルダ」に"PERSONAL.XLS?"が存在していません。
 "PERSONAL.XLS?" これが原因かもしれません。
 違っていたらスルーしてください。

 "PERSONAL.XLS?は自動的に読み込まれるので
  For Each wb In Workbooks
        If wb.Name Like "PERSONAL.XLS?" Then
            c = c + 1
            Exit For
        End If
    Next
 のコードは意味がないです。
 これで何をしようとしているのですか。
(???) 2022/07/16(土) 10:30

 1.)〜4.)を読んでも分からないので最初に戻って
 >ブック起動時にUserForm1を起動、 
 >UserForm1上に置かれたコマンドボタンを押すとブックを閉じる、 
 >という動作を実現したいのですが
「ブックを閉じる」とは起動したブックのみと言うことですか。
 それとも複数のブックも含むのですか。
(???) 2022/07/16(土) 10:43

<ThisWrokbookモジュール>
Option Explicit

Private Sub Workbook_Open()

    Dim sw As Long

    UserForm1.Show

    Stop

    sw = UserForm1.myModal()
    Unload UserForm1

    If sw = 2 Then Exit Sub
    If sw = 0 Then GoTo ErrH

    With Me
        .Save
        If GetMyCount > 1 Then
            .Close False
        Else
            Application.Quit
        End If
    End With

    Exit Sub

ErrH:

    MsgBox "異常終了"
End Sub

Private Function GetMyCount() As Long

    Dim wb As Workbook
    Dim i As Long
    Dim j As Long
    Dim s As Long

    For Each wb In Workbooks
        s = wb.Name
        i = InStrRev(s, ".")
        If i > 0 Then
            s = Mid(s, i + 1)
            If s = "xlsx" Or s = "xlsm" Then j = j + 1
        End If
    Next

    GetMyCount = j
End Function

<UserForm1モジュール>
Option Explicit

Dim n As Long

Private Sub CommandButton1_Click()

    n = 1
    Me.Hide
End Sub

Private Sub UserForm_DblClick(ByVal Cancel As MSForms.ReturnBoolean)

    n = 2
    Me.Hide
End Sub

Private Sub UserForm_Initialize()

    n = 0
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)

    If CloseMode = 0 Then Cancel = True
End Sub

Public Function myModal() As Long

    myModal = n
End Function

よくわからないけど書いてみました。
こんな感じの流れになるのでは?
自分の事ではないので動作確認はしてません。
同じ環境を作ることが困難なので。
バグがあるような気はしますが。。。。
(まっつわん) 2022/07/20(水) 09:25


まっつわんさん
アドバイスとコードをありがとうございます。
このコードでは1〜4どのケースでもブックを閉じることができました。

実は今週に入ってからまたエラーの再現性がなくなりいろいろ試行錯誤していたところでした。
どうやらエクセル立ち上げのときに「PERSONAL.XLSBは編集のためロックされています」というダイアログが出て、
そのまま作業を続行しているとこのエラーが発生する、という蓋然性が浮かんでいたところです。

教えていただいたコードについて詳しく調べてみたいと思います。
どうもありがとうございます。
(うなぎ食べたい) 2022/07/20(水) 12:09


 >どうやらエクセル立ち上げのときに「PERSONAL.XLSBは編集のためロックされています」というダイアログが出て

あぁ、原因はそれかもしれませんね。

エクスプローラーをプレビューにしてたらそうなるかも。
(まっつわん) 2022/07/20(水) 13:03


???さんありがとうございます。

 > 「ブックを閉じる」とは起動したブックのみと言うことですか。
 > それとも複数のブックも含むのですか。

ブックを閉じるのは起動したブック、すなわちコードでいうところのThisWorkbookだけです。

 >
 > For Each wb In Workbooks
 >     If wb.Name Like "PERSONAL.XLS?" Then
 >         c = c + 1
 >         Exit For
 >     End If
 > Next
 >

このコードの狙いは、開いているブックが他にない場合にApplication.Quitをしたい、です。
PERSONAL.XLSB等があると自動的に読み込まれるので
PERSONAL.XLS?がある→開いているブックが2以下ならApplication.Quit
PERSONAL.XLS?がない→開いているブックが1以下ならApplication.Quit
にしようと考えました。

(うなぎ食べたい) 2022/07/20(水) 13:14


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.