[[20130513223611]] 『手動でブックを閉じたとき(赤×で閉じたとき)とユ』(田吾作) >>BOT

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

 

『手動でブックを閉じたとき(赤×で閉じたとき)とユーザーフォームから呼び出したマクロでブックを閉じたときのThisWorkbook.Pathの挙動の違い』(田吾作)

 こんばんは、よろしくお願いいたします。
 ちょっと理解できない挙動がありましたので質問させていただきます。

 エクセルは2002、ウィンドウズは来年サポートが切れるXP(SP3)です。

 ThisWorkbookモジュールにブックを閉じるときのイベントでThisWorkbook.Pathを取得する
 マクロを記述しています。

 エクセルの右上の赤×でブックを閉じたときは
 Workbook_BeforeCloseイベントで
   twpt = "twpt:" & ThisWorkbook.Path
   fulnm = ThisWorkbook.FullName
 の両方ともブックが格納されているフォルダのパスを取得できます。
 結果は

  twpt:C:\Documents and Settings\hoge\デスクトップ
   fol:C:\Documents and Settings\hoge\デスクトップ

 となります。

 ところが、ユーザーフォームのコマンドボタンから標準モジュールの「cls」を呼び出したら挙動
 がおかしくなります。

 「cls」には、他にブックが開いていたら自ブックのみを閉じ、他にブックが開いていなかったら
 アプリケーションも閉じるコードを記述しています。

 ですので、「cls」から間接的に「Workbook_BeforeClose」イベントが起動しています。

 ユーザーフォームのコマンドボタンから「cls」を呼び出したときは、
 Workbook_BeforeCloseイベントで
   twpt = "twpt:" & ThisWorkbook.Path
   fulnm = ThisWorkbook.FullName
 のtwptの方しかパスを取得できていません。

   MsgBox msgstr
 で結果は
  twpt:C:\Documents and Settings\hoge\デスクトップ
   fol:

 となります。
 つまり、ThisWorkbook.Pathの方がパスを取得できていないのです。
 FullaNameからパスを取り出す、という代替方法でパスを取得できているので問題はない
 のですが、なぜ?という疑問が残っています。

 ご教示お願いいたします。

 以下はコードです。

 'ThisWorkbookモジュール
 Private Sub Workbook_BeforeClose(Cancel As Boolean)
  Dim fulnm As String
  Dim fol As String
  Dim twpt As String
  Dim msgstr As String
   twpt = "twpt:" & ThisWorkbook.Path
   fulnm = ThisWorkbook.FullName
   If UBound(Split(fulnm, "\")) <> 0 Then
      fol = "fol:" & Left(fulnm, InStrRev(fulnm, "\") - 1)
      msgstr = twpt & vbCrLf & fol
   Else
      msgstr = "保存されていません。"
   End If
   MsgBox msgstr
 End Sub

 '標準モジュール
 Sub cls()
  'ブックが一つなら(自ブックのみなら)
  If Workbooks.Count = 1 Then
    'アプリケーションを閉じる
    Application.Quit
  '他にブックが開いていたら
  Else
    'ブックを閉じる
    ThisWorkbook.Close
  End If
 End Sub

 'ユーザーフォーム
 'clsを呼び出す
 Private Sub CommandButton1_Click()
  Call cls
 End Sub

 確かに。ユーザーフォームは関係なく、たとえば

 ThisWorkbookモジュール

 Private Sub Workbook_BeforeClose(Cancel As Boolean)
    MsgBox ThisWorkbook.Path
 End Sub

 標準モジュール

 Sub test1()
    Application.Quit
 End Sub

 Sub test2()
    ThisWorkbook.Close
 End Sub

 XボタンやTest2 は、パスが表示されるけど、Test1 の場合、Workbook_BeforeClose の時点では
 ThisWorkbook.Path が "" になってるね。Quit が、このプロパティをクリアしてるのかな?

 そうなっているので、これは仕様??

 (ぶらっと)

 ぶらっとさん、ご回答ありがとうございます。

 自ブックのみが開いている場合は、ユーザーフォームのコマンドボタンから
 clsをCallした時は

   twpt:C:\Documents and Settings\hoge\デスクトップ
    fol:

 となり、赤×でブックのみを閉じた場合もアプリケーション自体を閉じた場合も

   twpt:C:\Documents and Settings\hoge\デスクトップ
    fol:C:\Documents and Settings\hoge\デスクトップ

 となりました。

 自ブック以外にもブックが開いているときは、ユーザーフォームのコマンドボタン
 からclsをCallした場合も、赤×でブックのみを閉じた場合もアプリケーション自体
 を閉じた場合も

   twpt:C:\Documents and Settings\hoge\デスクトップ
    fol:C:\Documents and Settings\hoge\デスクトップ

 となりました。

 >Quit が、このプロパティをクリアしてるのかな?
 >そうなっているので、これは仕様??

 そうかもしれません。
 実は、特定のマクロブックを閉じるときにユーザーフォームのリストボックスなどの
 状態を自ブックのフォルダ内にテキストファイルにログとして残すのですが、時々ログ
 が保存されないことがあったので調べたらCドライブ直下にログのテキストファイルが
 生成されていました。

 テキストファイルのパスは

 ThisWorkbook.Path & "\mylog.txt"

 のような感じで指定していました。
 そこで「ThisWorkbook.Path」を疑って調べていたらパスが""となることがあったので
 色々場合分けして調べたらどうやらブックを閉じるときの状態によるらしい、という
 ことで質問させていただきました。

 アドインなどもあるのでそれが悪さしてるのかな?とも思いましたが、ぶらっとさんも
 再現した、ということでしたので逆に安心しました。

 仕様だと考え「ThisWorkbook.Path」はブックを閉じるときは使わないことにします。

 ありがとうございました。

 (田吾作)

 単純に

 sub test()
    msgbox thisworkbook.path
    application.quit
    msgbox thisworkbook.path
 end sub

 これでも現象、確認できますねえ!!

 私は、通常、Excel本体まで終わらせるようなことはしない仕様にしているので
 気が付きませんでたが、バグでしょう? これ!!
 この現象、Pathプロパティだけならいいですけどねえ(よくはないか)
 こんなバグがあるなら、他にもあるんじゃないかと不安になりますねえ!!

 Fullnameプロパティを代用すればよいのでこれだけならよいのですが・・・。

 Quit実行前なら正常なんですから・・・・

 Thisworkbookのモジュールに

 Sub Workbook_BeforeClose(Cancel As Boolean) 'Privateを取る
   MsgBox "PATH: " & ThisWorkbook.Path & vbCrLf & _
           "FULLNAME:  " & ThisWorkbook.FullName
 End Sub

 標準モジュールに

 Sub cls()
    ThisWorkbook.Workbook_BeforeClose False
    Application.Quit
    Application.EnableEvents = False
 End Sub

 なんて方法も考えられます。

 検討してみてください

 ichinose


 ichinoseさん、ご回答ありがとうございます。
 勉強になります。ありがとうございました。

 (田吾作)

コメント返信:

[ 一覧(最新更新順) ]


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