Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
【報告】他のシートの値のFindは可能か? でScreenUpdating が勝手に無効に
投稿日時: 19/10/30 23:03:56
投稿者: taichi

次のような感じで、Sheet1上から
Sheet2のセル範囲.SpecialCells(xlCellTypeConstants, 2) の検索をしています。
  
  For Each rr In セル範囲.SpecialCells(xlCellTypeConstants, 2) <--- Sheet2
        myKey =rr.Value
        myRow = Sheet2.Range("C:C").Find(What:=myKey, LookAt:=xlWhole).row
        myCol = rr.Column
    Cells(myRow,myCol+2)= ……   <--- Sheet1
    ……
  Next
 
必ずFindできる状況なのでエラー処理は記述していません。
のようなコードを動かしたところ、スピードUPのために、
事前に Application.ScreenUpdating = False を入れていますが、他のシートの
検索をかけているためでしようか、
勝手に Application.ScreenUpdating =Ture 状態になりマクロが実行されました。
 
以上報告です。これは既知のことでしようか?

回答
投稿日時: 19/10/30 23:24:53
投稿者: simple

>勝手に Application.ScreenUpdating =Ture 状態になりマクロが実行されました。
それは何をもとにそう判断されたのですか?
状況を説明してください。

投稿日時: 19/10/31 10:01:40
投稿者: taichi

うまく表現できないのですが、Sheet1上でSheet2で検索したセル番地の情報を基に
Sheet1上のセルに書き込んでいるのですが、次ぐ次とあちらこちらに書き込まれていく
様子が見えるのです。
 
所々で Msgbox Application.ScreenUpdating で確かめていくと、
  
下のコードに入る直前は False のままです
  For Each rr In セル範囲.SpecialCells(xlCellTypeConstants, 2) <--- Sheet2
        myKey =rr.Value
        myRow = Sheet2.Range("C:C").Find(What:=myKey, LookAt:=xlWhole).row
        myCol = rr.Column
    Cells(myRow,myCol+2)= ……   <--- Sheet1
    ……
 Msgbox Application.ScreenUpdating <--- 最初のrr が終わった時点で True に変わりました
end
 
  Next

回答
投稿日時: 19/10/31 11:01:39
投稿者: simple

同じく、ちょっと考えにくいという印象です。
 
Sub から End Sub まで、
変数宣言もきちんとしたコードを提示してもらえますか?
事象が再現する最低限の動作するコードを提示してもらえば、
回答が寄せられるんじゃないでしょうか。
 
千里眼を持っていないので、あなたのPC画面は見えません。
書いていないコードが影響していることもありえますから、
回答者が色々推察しても無駄になりますし、まったくもって益がありません。

回答
投稿日時: 19/10/31 14:09:56
投稿者: simple

例えば、こんなコードを試した。
 
(1)コード上はセルへの書き込みが行われるが、
   そのあとで実行される
   Msgbox ""
   の段階ではセルは変わっておらず、
   プロシージャ実行が終了して、同時に.ScreenUpdatingがTrueとなって、
   はじめて画面が更新される。
(2)むろん、途中はずっと、ScreenUpdatingはFalseと表示される。
 
これが普通の振る舞いだと思います。
そうならないのであれば、それを再現するコードを提示してもらわないと、
誰も検証できない。(なんらかの不具合に遭遇しているのかもしれない。)
 

Sub test()
    Dim rr As Range
    Dim myKey
    Dim myCol
    Dim myRow
    
    Application.ScreenUpdating = False
    For Each rr In Sheet1.Columns("A:C").SpecialCells(xlCellTypeConstants, 2)
        myKey = "aaa"
        myRow = Sheet2.Range("C:C").find(What:=myKey, LookAt:=xlWhole).Row
        myCol = rr.Column
        Sheet1.Cells(myRow, myCol + 2) = 100
        Debug.Print Application.ScreenUpdating
    Next
    MsgBox ""
End Sub

投稿日時: 19/10/31 15:05:44
投稿者: taichi

【報告】今度は少し時間がかかる作業だったので、操作してくれる人が不安にならないように、
逆に Application.ScreenUpdating = True したほうがいいと思って実行すると
Application.ScreenUpdating = False のような状態ですが作業は正常が終わりました。
 
おかしいな、おかしいなと色々試している途中、マクロ実行中に、立ちあげていた Audials 2019 という録音ソフト(立ちあげていただけで作業はさせていませんでした。)がエラー発生したと画面に表示したので、
それを終了させてからは、Application.ScreenUpdating は意図通りに動くようになりました。
 
詳しいことは分かりませんが、エクセルとこのソフトを同時に立ちあげていたことが原因のような気がします。
 
これで1、2日したら解決にしたいとおもいます。
 
simple さん色々ありがとうございました。これからもよろしくお願いいたします。

回答
投稿日時: 19/11/03 11:53:18
投稿者: simple

Application.ScreenUpdating = True
を明示的に入れなかったのは、
テーマが「いつのまにかTrueになってしまう」だったからです。あえてそうしています。
 
これも昔からあるテーマで、よく承知しています。
たいていの場合は、プロシージャの終了に任せていいのだけれど、
図形描画などが関係するときに、影のようなものが描かれる事象がたまにある。
だから、明示的に最後に
Application.ScreenUpdating = True
に入れるのがよい、というのが(私の知る限り)コンセンサスだと思っています。
 
なお、繰り返しになりますが、
想定どおりに行かない、といったテーマの時は、
読んでいるかたが事象を再現できる、
最低限動作するコードを提示するべき
だと思います。
 
そこに書かれなかったこと
・例えば変数宣言が省略されており、適切な型ではなかった。
・Option Explicit が省略されていて変数名が違っていた。
・提示されていなかったコードが悪さをしていた
のために解決に支障が出るからです。
お互いに無駄な時間を使うことになりますから、マナーと言ってもよいと思います。

投稿日時: 19/11/04 22:02:37
投稿者: taichi

simple さん
 
色々ご教授ありがとうございました。
一応これで閉めたいと思います。