2016-06-30 6 views
0

これは実際にコード固有の質問ではありませんが、より興味深い(将来の問題を避けるための)何かがあるので、SOはそれを聞くのにふさわしい場所だと思いました。Application.ScreenUpdatingサブルーチン内で呼び出されるサブルーチン

私の質問の基礎はこれです:どのようにVBAはApplication.ScreenUpdatingとサブルーチン内で呼び出されるサブルーチンからの他のそのような呼び出しを扱うのですか?

たとえば、私はBackupDataというメソッドを持っていますが、これは非常に素早くアクティビティシートからデータを取り出し、同じ名前の "隠しシート"にコピーします(これを使用してユーザーにサブルーチンのアクションを元に戻すための通常のメソッドを使用することができないため、「元に戻す」マクロ)。 BackupDataでは、ScreenUpdatingをFalseとTrueに切り替えるだけで、アクションはエンドユーザーから完全に隠されます。問題の問題は、ユーザーにマクロの実行に自由にアクセスできるようにするだけでなく、ScreenUpdatingプロパティを切り替える他のマクロから呼び出すことも選択できるという事実から生じます。 BackupDataは、マクロがFalseにScreenUpdatingプロパティを切り替えたこと後マクロ内から呼び出された場合

ので、プロパティをTrueに設定するBackupDataコールは、このようにの残りの部分を残して、「外」のルーチンの呼び出しを上書きします画面を更新して実行するマクロ?

今、明らかに、私はこの問題に対する簡単な解決策がたくさんあることを知っています。私はBackupDataにブール値を格納して、ScreenUpdatingが既に偽であるかどうかをチェックし、それが真であればそれを返さないか、またはBackupDataを実行した後に単にScreenUpdating = Falseコールを繰り返すことができます。またはBackupDataそれは私がこれらの他のマクロの中から実行する値をトグルしませんが、この問題のポイントはその解決策を見出すことではありません。

これは、VBAがネストされたサブルーチン呼び出しでどのように動作するのかという疑問ですが、ここで誰かがVBAが私のために問題を処理するかどうかについての確定的な回答で私の好奇心を満たすことができます上記の回避策の1つを使用する必要がある場合

TL; DR

は、私はすでに働いているオプションの多くがあるので、回避策ソリューションを捜しているわけではありません。 VBAがこれらの種類のコールをどのように処理するかを知っている人は、興味があります(ScreenUpdatingプロパティだけでなく、他のアプリケーションプロパティも同様です)。

+0

最も一般的な推測はアプリケーション全体を参照する「アプリケーション」という言葉ですか、いいえ?すべてのサブブックや親ルーチンに適用されるアプリケーション全体のメソッドを呼び出しているので、スコープのサブルーチンは問題ありません。 –

答えて

3

Application.ScreenUpdatingアプリケーションの設定であり、設定及び設定解除でグローバルに非活性化/活性化されます。

あなたの前提は、あなたがサブルーチンではFalseに設定した場合、その後、再び偽それを設定ルーチン呼び出しBackupDataScreenUpdatingが呼び出しの残りのために、その後Trueで、呼び出し側にスコープを返す前に真のそれを設定していることという点で正しいですサブルーチン。

グローバルスコープの変数と考えることができます。それが設定されていれば、その値はグローバルに設定されます。これは、プログラムのインスタンスで開いているすべてのワークブック(この場合はexcel.exe)の親オブジェクトであるApplicationレベルに対してグローバルに設定されています。これを設定すると、インスタンス内のすべてのワークブックに影響します。別のexcel.exeプロセスを実行している場合、そのインスタンスのワークブックには影響しません。

+0

ありがとう、Dave。それをグローバルスコープにすることは、それを見るための良い方法です。 SOが許可している場合には、この解決策を正しくマークするでしょう。 – RGA

+0

グローバル変数以外の他のワークブックにも影響するため、グローバル変数を超えています。 –

+0

合意しました - 私は説明しようとしていましたが(明らかに不十分でしょうか?)、これは 'Workbooks'オブジェクトの親である' Application'のグローバルな設定です。したがって、Excel.exeのインスタンス内で開かれたすべてのワークブックに適用されます。 2番目の 'Excel.exe'インスタンスを開いている場合、1つで設定すると、もう1つの設定には影響しません... – Dave

2

これはこのような単純な使い方です。 screenupdatingをfalseに設定するよりも、画面更新の前の状態を保存するだけで済みます。また、screenupdatingを戻すように設定すると、バックアップから復元されます。したがって、既に画面がFALSEとして更新されている場合、FALSE後にFALSEになります。

Dim previousScreenUpdating as boolean 
previousScreenUpdating = application.screenUpdating 

application.screenUpdating = false 

// your code 

application.screenUpdating = previousScreenUpdating 
+0

私の質問を完全に読んだら、すでにこれを解決策として提案しています。おそらく、SOは問題を尋ねるのに適切な場所ではありませんが、回避策の解決策ではなく、VBAのデフォルトの練習の性質に関する答えを探しています – RGA

関連する問題