映画のエンドロール観る派?観ない派?

下記のSub test01のマクロでは、画面は常に最初のシートのままで全シートに作業が行なわれます。
ところが、同じマクロですが単にシートを保護するという1行を追加すると(それがSub test02です。)、画面が各シートに切り替わるようになるのです。
しかし、保護されてないシートにSub test02をはしらせると、最初の一回は画面は常に最初のシートのままで全シートに作業が行なわれ、その結果全シートが保護された状態になってから再度実行すると、画面が切り替わるのです。同様に、保護されたシートにSub test01を実行しても画面が切り替わります。

しかし不思議な事に、アクティブなシート名を表示させるようにしたステータスバーには常に最初のシート名しか表示されません。つまりシートがアクティブではないのに画面に表示されるようです。

もちろんScreenUpdatingをFalseにすれば画面が切り替わらなくなるのは存じておりますが、疑問なのはなぜシートがアクティブではないのに画面に表示されるのか?(しかもシートを保護あるいは保護解除する場合に限って)ということです。
どうか、ご教示下さい。

Sub test01()
For Each st In Worksheets
Application.StatusBar = ActiveSheet.Name
st.Unprotect
With st.Range("E5")
For i = 50000 To 1 Step -500
.Value = Int(i / 500)
Next i
End With
Next st
End Sub

Sub test02()
For Each st In Worksheets
Application.StatusBar = ActiveSheet.Name
st.Unprotect
With st.Range("E5")
For i = 50000 To 1 Step -500
.Value = Int(i / 500)
Next i
End With
st.Protect
Next st
End Sub

A 回答 (2件)

こんばんは。



>違います。Activeにならないのに画面上にシートが表示されるということです。

私は、とても何か、つまらないことを書いてしまったようですね。所詮、私には、現象面から捕らえるしかないし、厳密に、「Active」とは何という問題を掘り下げるような力は、私にはありません。

ただ、一応、その点のことは、自分なりに考えを書いたつもりでしたが、的外れということでしたので、一応、この後、言い訳程度に書いておく以外は、何も書くことはありません。

「Active」 という範囲は、マニュアル操作や VBAのActivate や Select 以外にシートの表示が現実にはあって、マクロ動作中には捕らえられない原因は、アプリケーションの内部とVBAの取得の問題だと思います。もともと、シート側とVBA側の取得するオブジェクトは、一枚岩のように表裏一体になっているわけではないのは、釈迦に説法かもしれませんが、それが一枚岩ではないから、と言っても、どうしようもないと思っています。それは、他のメソッドでも往々にして、別の実質的な問題を持っていることもあります。

その状況を踏まえて、処理しなくてはならないわけだと思います。場合によっては、バグはバグのままで、それを踏まえて処理しなくてはならないこともあります。私は、そのように捉えています。MSでは、Ver.4マクロ関数からVBAに換えたときに、そういう部分の問題は解決していないものもあるはずです。

また、それ自体は設計者がどういうプログラムで書いたのか、というようなレベルの話でしょうから、今の私には、手の届かない話です。しかし、MSサポートにバグ報告なのか、クレームなのか、ある程度の反応は意外に示してくれることもあると思います。(ただし、概ね、次バージョンで処理するのですが。)

現行の作業中シートの明示なら、ループ中に、各々取れえて表示するだけの問題だと思うのですが、そういう質問ではないのですよね。

ただ、

>このコードを入れたら、最後にStatusBar表示が消えてしまいますので最後にアクティブになったシート名が分かりません。

マクロの場合は、必ず、後を戻しておくというのは、VBAのコードの暗黙のルールだと思っています。何かを入れないと、そのままずっと残ってしまいます。

以上です。余計なお世話でしたね。
    • good
    • 0
この回答へのお礼

Wendy02さま、いつも丁寧にご回答くださり、本当に有難うございます。

> もともと、シート側とVBA側の取得するオブジェクトは、一枚岩のように表裏一体になっているわけではない

なるほど・・・。
つまりは、VBAでシートをSelectするなり、Activateしなければ隠れているシートは画面上では見えないはずではないか、というのはわたしの勝手な思い込みで、Mirosoftではそんなことは約束してないということなんですよね。
わかりました。

> マクロの場合は、必ず、後を戻しておくというのは、VBAのコードの暗黙のルールだと思っています。何かを入れないと、そのままずっと残ってしまいます。

はい、これもおっしゃる通です。
今回は、ふと疑問に思ったことを再現させるためのテスト用のコードだったので、最後にアクティブになったシート名を、コード実行終了後にも消えずに表示させておくため、わざと残しておいたのでしたが、大変失礼な返答になってしまったようで、お詫び申し上げます。平にご容赦くださいませ。

これからもご指導のほどよろしくお願い申し上げます。
(o。_。)oペコッ

お礼日時:2007/06/18 11:49

こんばんは。



>シートがアクティブではないのに画面に表示されるようです。

おおよその質問の意味は分かったつもりです。

たぶん、これ自体は、
Application.StatusBar = ActiveSheet.Name

オブジェクトのアクティブ化される方法によっての表示だと思います。
もし必要なら、st.Activate とすればよいだけですからね。

なお、
Application.StatusBar = ""
というコードが最後に必要だと思います。

それはともかくとして、

ご質問の要点としては、こういうことかな?

「Protect から Unprotect」では、シートオブジェクトが取得されActive になるけれども、単に、「Unprotect」 状態からでは、シートオブジェクトが取得されないで、Active にならない、

ということでしょうか?

ただ、この回答は、私では無理ですね。開発者の設計の問題ですからね。

想像するしかないと思います。

Protect に関しては、どうも、プロパティに近いなって思います。値を与えるだけですからね。では、Unprotect も同じだといえば、そうなんですが、その点で仕組みに違いがあるということだろうとは思います。おそらく、パスワード情報が、アプリケーション側ではなくて、シートに属していて、それで、照合をしないといけないのだろうと思うのです。だから、実際のシートをアクティブにしなければならない、という理由にはなりませんが、しかし、Protect として値を与えた時とは違う作業をそこでさせている、ということではないか、と思うのです。そして、これは、VBA言語ではなくて、Excel側のシートオブジェクトに属している問題だと思います。

解答にはなっていませんが。
    • good
    • 0
この回答へのお礼

> Application.StatusBar = ""
> というコードが最後に必要だと思います。

このコードを入れたら、最後にStatusBar表示が消えてしまいますので最後にアクティブになったシート名が分かりません。
Sheet1~Sheet3までのBOOKで実行して、それぞれのシートがアクティブになったのなら最後はSheet3になってなくてはいけないですよね?

> 「Protect から Unprotect」では、シートオブジェクトが取得されActive になるけれども、単に、「Unprotect」 状態からでは、シートオブジェクトが取得されないで、Active にならない、

> ということでしょうか?

違います。Activeにならないのに画面上にシートが表示されるということです。

お礼日時:2007/06/17 21:07

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!