Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


6906 / 13646 ツリー ←次へ | 前へ→

【41354】BeforeSaveイベントでOnTimeを再セットで... ハチ 06/8/7(月) 13:20 質問[未読]
【41429】Re:BeforeSaveイベントでOnTimeを再セット... ichinose 06/8/10(木) 7:39 発言[未読]
【41432】Re:BeforeSaveイベントでOnTimeを再セッ... ハチ 06/8/10(木) 9:09 発言[未読]
【42333】Re:BeforeSaveイベントでOnTimeを再セッ... 漂流民 06/9/7(木) 0:10 発言[未読]
【42345】Re:BeforeSaveイベントでOnTimeを再セッ... ハチ 06/9/7(木) 13:47 発言[未読]
【42351】.Saveでは設定できないプロパティがある? ハチ 06/9/7(木) 16:52 発言[未読]
【42357】Re:.Saveでは設定できないプロパティがあ... 漂流民 06/9/8(金) 1:11 発言[未読]
【42362】Re:.Saveでは設定できないプロパティがあ... ハチ 06/9/8(金) 9:17 発言[未読]
【42386】Re:.Saveでは設定できないプロパティがあ... 漂流民 06/9/9(土) 0:40 発言[未読]
【42393】Re:.Saveでは設定できないプロパティがあ... ハチ 06/9/9(土) 7:50 発言[未読]
【42407】Re:.Saveでは設定できないプロパティがあ... ハチ 06/9/9(土) 20:25 発言[未読]
【42433】Re:.Saveでは設定できないプロパティがあ... 漂流民 06/9/11(月) 23:43 発言[未読]

【41354】BeforeSaveイベントでOnTimeを再セットで...
質問  ハチ  - 06/8/7(月) 13:20 -

引用なし
パスワード
   こんにちは。

「更新されていなければ、自動閉じる」処理を行おうとしているのですが、
BeforeSaveイベントからOnTimeを再セットできずに悩んでいます。

Open→Reset_OnTime→5秒後にBook_Chk→Book_ChkのSaveでBeforeSaveイベント
→Reset_OnTime→5秒後にBook_Chk→・・・・
となる予定だったのですがReset_OnTimeは実行されるのですが、
次回のスケジュールとステータスバーの更新がされません。
手動で上書き保存するとスケジュールとタスクバーの更新は、実行されます。

Book_Chk()内の*2の箇所で呼び出せば動作は問題ないのですが、
「なぜダメなのか?」知りたいです。
一通り、情報はチェックしたつもりなのですが、原因がわかりませんでした。
よろしくお願いします。

'標準モジュール

Public T As Date 'チェック実行時刻

Sub Reset_OnTime()
  MsgBox "Reset_OnTime" '*1 Reset_OnTimeの実行チェック用
  Const Intarval As String = "00:00:05" 'チェック間隔 テスト用に5秒間隔
  
  On Error Resume Next
    '次回チェックの削除
    Application.OnTime T, "Book_Chk", , False
    '次回チェックの再設定
    T = Now() + TimeValue(Intarval)
    Application.OnTime T, "Book_Chk"
    Application.StatusBar = "次回チェック:" & T
  On Error GoTo 0

End Sub

Sub Book_Chk()
  Dim WSH As Object 'WScript.Shell
  Dim Lmt As Date 'リミット時刻
  Dim Ans As Variant 'Popupの回答
  Dim Cnt As Integer 'Popupの表示時間(秒)
  
  Cnt = 3
  Set WSH = CreateObject("WScript.Shell")
  '更新されているかチェック
  If ThisWorkbook.Saved = True Then
    Lmt = T + TimeSerial(0, 0, Cnt) 'Lmtにチェック時間+Popup時間をセット
    Ans = WSH.Popup("未更新です。" & vbCr & Format(Lmt, "hh:mm:ss") & _
    "に自動終了します。" & vbCr & "更新を続けますか?", Cnt, , vbQuestion)
    If Ans <> 1 Then
      Set WSH = Nothing
      ThisWorkbook.Close True
    End If
  End If
  ThisWorkbook.Save '現在までの更新を上書き保存
  Set WSH = Nothing
  
  'Call Reset_OnTime '*2 BeforeSaveで実行されるので必要ないはず・・
End Sub


'ThisWorkBookモジュール

Private Sub Workbook_Open()
  '次回チェックの設定
  Call Reset_OnTime
End Sub

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  '次回チェックの再設定
  Call Reset_OnTime
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
  '次回チェック分のOnTimeを解除
  On Error Resume Next
    Application.OnTime T, "Book_Chk", , False
  On Error GoTo 0
End Sub

【41429】Re:BeforeSaveイベントでOnTimeを再セッ...
発言  ichinose  - 06/8/10(木) 7:39 -

引用なし
パスワード
   ▼ハチ さん:
おはようございます。

現象確認しました。

私の投稿の結論は、↑だけなんですが・・・。


同じ現象が Workbook_BeforeCloseイベントでも確認できました。

不思議ですよね!!

コードからイベントを発生させるメソッドを実行すると(Thisworkbook.Save)
イベントは確かに発生し、
イベントプロシジャーは、作動しているのにOntimeメソッドも作動しないし、
StatusBarも更新されません。

でも間にMsgboxなどを挿入すると、きちんと表示されますねえ!!

全てのイベントでそうなのかというと そうでもない・・・。
シートのイベントのWorksheet_SelectionChange等と絡ませると、
OnTimeメソッドによる繰り返し動作は行われました。

解決方法(回避方法)は、ご自身もわかっておられるようなので
記述しませんが、コード内でイベントによる連動を予定してコードを記述する場合は
事前の細かいチェックが必要ですね!!


ということで私も原因はわかりませんが、

せっかくの貴重な現象なのに、このままレスなしではもったいないと思ったので投稿しました。

以上、もう気分は夏休みのichinoseでした。

【41432】Re:BeforeSaveイベントでOnTimeを再セッ...
発言  ハチ  - 06/8/10(木) 9:09 -

引用なし
パスワード
   ▼ichinose さん:

返信ありがとうございます。
どなたのレスも頂けなかったので
環境依存の現象なのかと思ってました。
(ちなみにWin2000/SP4 Excel2000です)

>コードからイベントを発生させるメソッドを実行すると(Thisworkbook.Save)
>イベントは確かに発生し、
>イベントプロシジャーは、作動しているのにOntimeメソッドも作動しないし、
>StatusBarも更新されません。
>でも間にMsgboxなどを挿入すると、きちんと表示されますねえ!!

そうなんですよね〜 不思議です・・・
イベントからApplicationレベルのコードを実行するのがダメなのかというと
そうでもなさそうですし・・・

自分の中で一番解せないのが
>>手動で上書き保存するとスケジュールとタスクバーの更新は、実行されます。
↑なんです。
プロシージャの連動だからダメだとすると、モジュール構造自体が成り立たないような。
自分のコードの中に別の見落としがあるのではないかと思い、質問させて頂きました。
急ぎで困っている内容ではありませんので
気長に調査してみようと思っています。
ありがとうございました。

>以上、もう気分は夏休みのichinoseでした。

自分は、明日からです^^
脳ミソをリフレッシュさせたいなぁ〜 と思ってます。

【42333】Re:BeforeSaveイベントでOnTimeを再セッ...
発言  漂流民  - 06/9/7(木) 0:10 -

引用なし
パスワード
   ▼ハチ さん:
こんばんわ

古いスレを引っ張り出してすみません。
その後何か分かったことありますか?
私もちょっと気になっていたので・・・


参考にもなりませんが、その時私が検証用に使用していたコードです。

とりあえず、手動の上書き保存とコードからの上書き保存(Book_Save)との
挙動の違いを見るために簡素化してみました。
******************************************************************************************

'標準モジュール

Sub Book_Save()
  ThisWorkbook.Save
End Sub

Function Set_OnTime()
  MsgBox "Set_OnTime"
  Application.OnTime Now() + TimeValue("00:00:01"), "Exe_OnTime"
End Function

Function Exe_OnTime()
  MsgBox "Exe_OnTime"
End Function


'ThisWorkBookモジュール

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  Call Set_OnTime
End Sub


で、コード→イベント発生→プロシージャ呼び出し→OnTime
の手順のどこかが悪いのかもと考えてSaveの代わりにSelectでやってみました。
******************************************************************************************

'標準モジュール

Sub Cell_Select()
  Range("A1").Select
End Sub

Function Set_OnTime()
  MsgBox "Set_OnTime"
  Application.OnTime Now() + TimeValue("00:00:01"), "Exe_OnTime"
End Function

Function Exe_OnTime()
  MsgBox "Exe_OnTime"
End Function


'ThisWorkBookモジュール

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
  Call Set_OnTime
End Sub


Selectでは正常なようです^^

なので、今度はApplicationオブジェクトまわりかも?と思い
簡単にチェックできそうなものを並べてみました。
******************************************************************************************

'標準モジュール

Sub Book_Save()
  ThisWorkbook.Save
End Sub

Function Set_OnTime()
  MsgBox "Set_OnTime"
  tm = Now() + TimeValue("00:00:01")
  With Application
    .OnTime tm, "Exe_OnTime"
    .StatusBar = "次回チェック:" & tm
    .Dialogs(xlDialogProperties).Show
    .DisplayFormulaBar = Not .DisplayFormulaBar
    .ActiveCell = "次回チェック:" & tm
    .CommandBars("Formatting").Visible = Not .CommandBars("Formatting").Visible
  End With
End Function

Function Exe_OnTime()
  MsgBox "Exe_OnTime"
End Function


'ThisWorkBookモジュール

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  Call Set_OnTime
End Sub


特に気になったのが、似たような設定動作で、コードから.Saveした時
    .CommandBars("Formatting").Visible = Not .CommandBars("Formatting").Visible
は動作するのに
    .DisplayFormulaBar = Not .DisplayFormulaBar
は動作しないということです。
これはシートで設定する時、「表示(V)」直下にあるものと「表示(V)」ー「ツールバー(T)」
の階層化にあるものとの違いが関係ある?

以前、
http://www.vbalab.net/vbaqa/c-board.cgi?cmd=ntr;tree=38873;id=excel
こういうのがあったので、手動で上書き保存するのとコードから.Saveするのとでは
処理方法が違うのかもしれません。(この辺のことが影響ありそうな・・・)

結局何も分かりません、駄レス失礼しましたm(__)m

【42345】Re:BeforeSaveイベントでOnTimeを再セッ...
発言  ハチ  - 06/9/7(木) 13:47 -

引用なし
パスワード
   ▼漂流民 さん:
>古いスレを引っ張り出してすみません。

いえいえ^^
ご意見頂けるのはありがたいです。

>その後何か分かったことありますか?
>私もちょっと気になっていたので・・・
>参考にもなりませんが、その時私が検証用に使用していたコードです。

確認させて頂きました。
自分なりのその後に調査で判ったことと合わせてますと
Saveイベントからプロパティを設定しようとするとダメなプロパティがある。
取得はできるようなんですけど。

手動の上書き保存 と .Saveは違うようですね。

Sub Reset_OnTime()
  MsgBox "Reset_OnTime" '*1 Reset_OnTimeの実行チェック用
  Const Intarval As String = "00:00:05" 'チェック間隔 テスト用に5秒間隔
  
  On Error Resume Next
    '次回チェックの削除

    Application.OnTime T, "Book_Chk", , False
  On Error GoTo 0
    '次回チェックの再設定
    T = Now() + TimeValue(Intarval)
    Debug.Print T  '○
    With Application
      .OnTime T, "Book_Chk"  '×
      .StatusBar = "次回チェック:" & T  '×
      Debug.Print .StatusBar '○
      Debug.Print .UserName  '○
      .UserName = "Test" & Rnd(5) '×
      Debug.Print .UserName  '変更さてれいない(マグレで同じこともあるけど)
      .ActiveSheet.Name = Format(T, "mmss")  '×
    End With
End Sub

ActiveSheet.Name =  が×というのが予想外でした。
もうちょっとシンプルにしてみたところ・・

'ThisWorkbookモジュール
Option Explicit

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  Call Test
End Sub

Private Sub Workbook_NewSheet(ByVal Sh As Object)
  'Call Test  '○
  ThisWorkbook.Save  '呼んでいるけど先で×
End Sub

Private Sub Workbook_Open()
  Call Test  '○
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
  'Call Test '○
  ThisWorkbook.Save  '呼んでいるけど先で×
End Sub

'標準モジュール
Option Explicit

Sub Test()
  Dim T As Date
  T = Now
  Debug.Print Format(T, "mmss")
  With Application
    .ActiveSheet.Name = Format(T, "mmss") '×なこともある。
    .ActiveCell = Format(T, "mmss") '○
  End With
  
End Sub

ということで.OnTime と .Saveとの関係ではなく
.Save と 各プロパティの設定に問題がありそう。
との結論なのですがいかがでしょうか?

【42351】.Saveでは設定できないプロパティがある?
発言  ハチ  - 06/9/7(木) 16:52 -

引用なし
パスワード
   もうちょっと検証してみました。
先ほどのTest()だと、ActiveCellのところで2回動いてました。すいません。

Option Explicit

Sub Test()
  Dim T As Date
  T = Now
  Debug.Print Format(T, "mmss")
  With Application
    .ThisWorkbook.Worksheets(1).Name = Format(T, "mmss") & "_Test" '×
    '.ThisWorkbook.Worksheets(1).Visible = Not .ThisWorkbook.Worksheets(1).Visible '×
    '.ThisWorkbook.Worksheets(1).Move _
    After:=.ThisWorkbook.Worksheets(.ThisWorkbook.Worksheets.Count) '×
    .ActiveSheet.Name = Format(T, "mmss") '×
    
    .EnableEvents = False  '○
      .ActiveCell.Value = Format(T, "mmss") '○
      .ActiveSheet.Rows(1).Hidden = Not .ActiveSheet.Rows(1).Hidden  '×
    .EnableEvents = True  '○
    
    .Caption = Format(T, "mmss") & "_Cap" '○
    .CommandBars("Formatting").Visible = Not .CommandBars("Formatting").Visible '○
    .DisplayFormulaBar = Not .DisplayFormulaBar '×
    Debug.Print .DisplayFormulaBar '○
    
  End With
End Sub

なんとなくなんですが
「子オブジェクトがあるとダメっぽい」のかなぁと。
でも、.DisplayFormulaBar もダメですし・・・
わかりません><

【42357】Re:.Saveでは設定できないプロパティがあ...
発言  漂流民  - 06/9/8(金) 1:11 -

引用なし
パスワード
   ▼ハチ さん:
こんばんわ

>.Save と 各プロパティの設定に問題がありそう。
なるほど、Workbook_BeforeSaveイベントからプロシージャを呼び出して、
そこでのApplicationオブジェクト関係をみていましたが、
確かに言われてみるとそうですね^^
ということは、

******************************************************************************************

'標準モジュール
Sub Test()
  ThisWorkbook.Save
End Sub

'ThisWorkBookモジュール
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  With Application
    .CommandBars("Formatting").Visible = Not .CommandBars("Formatting").Visible
    .DisplayFormulaBar = Not .DisplayFormulaBar
  End With
  Worksheets(1).Visible = Not Worksheets(1).Visible
End Sub

******************************************************************************************

これだけで確認できました。

>なんとなくなんですが
>「子オブジェクトがあるとダメっぽい」のかなぁと。
>でも、.DisplayFormulaBar もダメですし・・・
>わかりません><
逆に私はApplication直下で、オブジェクトを持たないメソッド・プロパティ
の一部がダメなのかも?と睨んでいましたがそれもやはり違うようです(^^;

.Saveを使う時はこういう理由でこれが駄目、と言えないのがもどかしいですね^^

【42362】Re:.Saveでは設定できないプロパティがあ...
発言  ハチ  - 06/9/8(金) 9:17 -

引用なし
パスワード
   ▼漂流民 さん:
おはようございます。

>.Saveを使う時はこういう理由でこれが駄目、と言えないのがもどかしいですね^^

しかもエラーを返さないの厄介ですね。
Debug.Printで判るように「参照」はできるようです。

↓のマクロなどは普通にやってしまいそうです・・
手動で保存すれば、正常に動作するワケですしちょっと怖いですね。

'標準モジュール
Sub Test2()
'何らかの処理
'・・・・
ThisWorkbook.Save
End Sub

'ThisWorkbookモジュール
Option Explicit

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  With Worksheets(1)
    .Range("A1").Value = .Range("A1").Value + 1
    .Copy After:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = .Range("A1").Value
    .Activate
  End With
End Sub

【42386】Re:.Saveでは設定できないプロパティがあ...
発言  漂流民  - 06/9/9(土) 0:40 -

引用なし
パスワード
   ▼ハチ さん:
こんばんわ

>しかもエラーを返さないの厄介ですね。
>Debug.Printで判るように「参照」はできるようです。
>
>↓のマクロなどは普通にやってしまいそうです・・
>手動で保存すれば、正常に動作するワケですしちょっと怖いですね。
>
確かに普通に組みそうなマクロですね。
ちなみに、Excell2000と2003で確認したところ、共に現象が確認できたので
バージョンは関係なさそうです。
.Saveを使用する際は注意するより仕方ないということですかね?!

【42393】Re:.Saveでは設定できないプロパティがあ...
発言  ハチ  - 06/9/9(土) 7:50 -

引用なし
パスワード
   ▼漂流民 さん:

こちらのサイトで「ThisWorkbook.Save バグ」で検索すると
ちょっと意味あいが違いますけど、過去ログにもありました。
http://www.vbalab.net/vbaqa/c-board.cgi?cmd=one;no=8874;id=excel

>ちなみに、Excell2000と2003で確認したところ、共に現象が確認できたので
>バージョンは関係なさそうです。
>.Saveを使用する際は注意するより仕方ないということですかね?!

.Saveというかイベント全般なのかもしれません。

.SaveからのCellsオブジェクトへのアクセスは問題なさそうなので
.Saveで任意セルに書き込み → Changeイベントでプロシージャをキック
としてみたのですがこれもダメでした。

'標準モジュール
Sub Test2()
'何らかの処理
'・・・・
ThisWorkbook.Save
End Sub

'-----------------
'ThisWorkbookモジュール
Option Explicit

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
  With Worksheets(1)
    .Range("A1").Value = .Range("A1").Value + 1
  End With
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
  If Sh.Name <> Worksheets(1).Name Then Exit Sub
  If Target.Address <> "$A$1" Then Exit Sub
  
  With Worksheets(1)
    .Copy After:=Worksheets(Worksheets.Count)
    Worksheets(Worksheets.Count).Name = .Range("A1").Value
    .Activate
  End With
End Sub

【42407】Re:.Saveでは設定できないプロパティがあ...
発言  ハチ  - 06/9/9(土) 20:25 -

引用なし
パスワード
   訂正:>Saveというかイベント全般なのかもしれません。

Saveイベントが絡むと動作がおかしそう。 ですね。
失礼しました。

【42433】Re:.Saveでは設定できないプロパティがあ...
発言  漂流民  - 06/9/11(月) 23:43 -

引用なし
パスワード
   ▼ハチ さん:
こんばんわ

>訂正:>Saveというかイベント全般なのかもしれません。
>
>Saveイベントが絡むと動作がおかしそう。 ですね。
>失礼しました。

Saveメソッドがお騒がせの犯人(?)、のような気がします?!
また何か分かったら書き込みしたいと思います^^

6906 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free