アプリ版:「スタンプのみでお礼する」機能のリリースについて

ワークシート内コードの記述で、
シート上のテキストボックスの値を変えています。
テキストボックスのChangeイベントで動かしていますが、起動した際や、他シートからテキストボックスのvalueを変えたりしています。

1.テキスト1.value = activesheet.range("a1")
2.テキスト1.value = me.range("a1")
3.テキスト1.value = range("a1")

3にすると上手く動かない場合があるので現在は2で記述しています。
1~3の違いはなんでしょうか・・

A 回答 (6件)

>range("a1")とすると、activesheetのrangeになるのか、sheet1のrange("a1")になるのか・・



ActiveSheetです。Range("A1") は ActiveSheet.Range("A1") を省略した記述方法ですね。したがって、1と3は同意ですから、3の記述で「うまくいかない」のであれば、1の記述も「うまくいかない」はずです。

うまくいかない理由は、恐らくコードの実行過程で他シートを Activate する場合があり、 ActiveSheet が変わってしまうからではないですか?

ctrlzr さんや Wendy02 さんのご指摘のとおり、シートを明示的に指定すれば良いと思います。

2の記述についてですが、シートモジュール下では、こう解釈されています。例えば、Sheet1にコードを記述した場合、

Me.Range("A1").Value は WorkSheets("Sheet1").Range("A1").Value

と同意になります。したがって、2の方法ではOKなのです。Me キーワードの是非については、良くわかりませんのでコメントできません。

ただし、私も基本的に余計なトラブル回避およびコードの可読性向上の意味からシートを明示的に指定する記述をお勧めします。

EX) Worksheets("Sheet1").Range("A1").Value
    • good
    • 2
この回答へのお礼

最初に書くべきだったのですが・・・

Sheet1のテキストボックスで、
シートモジュールのテキストボックスchangeイベントでテキストボックスに入力されたものをrange("a1")に表示させています。(ここの書き方が疑問だったんです)
Sheet2からテキストボックスの中身を変更したときにChangeイベントが動いてしまい、Sheet2の"a1"にデータが入ってしまいます。

というのが困った点でした。
で、「このシートの」という記述はあるのかなと思った次第なのであります。
サボり心がいけなかったのですね・・。
なるべく略さずシート名を書くようにします。
有難うございました。

お礼日時:2005/05/13 13:15

tonjiruさん、こんにちは。



>有難うございます。色んなご意見があるんですね。
あまり、言葉に翻弄されないでくださいね。自分で試して、実証してみるのが一番です。

ExcelのVBAは、あるレベルになると、必要な部分とそうでない部分が分かるようになります。少なくとも、シート・オブジェクトの代わりのMeキーワードを、Me.Range("A1").Valueと書かなくてはならない場面は、少なくとも、Excel・VBAでは、そんなに多くは登場しないはずです。(私は知りません)Meキーワードは、Excel・VBAに関する限りは、通常、Class や Userformモジュールでしか使いません。

以下は、ご自分で、試してみてください。
>同じく「sheet1のシートモジュールで」
>range("a1")とすると、activesheetのrangeになるのか、sheet1のrange("a1")になるの
>か・・

例えば、
Sheet1モジュールに、以下のように書いて、
Sub test_1()
 MsgBox ActiveSheet.Range("A1").Value
End Sub

標準モジュールに、このように書いて、Sheet1のプロシージャを呼び出してみます。

Sub calling_test()
 Sheet1.Select
 Call Sheet1.test_1
 Sheet2.Select
 Call Sheet1.test_1
 Sheet1.Select False
 Sheet2.Select False
 Call Sheet1.test_1
 Sheet1.Select
End Sub

そうしたら、最初は、Sheet1のA1で、次に、Sheet2 のA1 ですね。最後は、Sheet2 ですね。
では、Sheet1モジュールに書いた以下のプロシージャの場合は、どうなるでしょうか?

次に、そのシートモジュールで書かれたものを、コピーして、次のように換えてみます。

Sub test_2()
 MsgBox Range("A1").Value
End Sub

これで、この答えはおわかりになったように、Sheet1のA1を指し示していますね。
これに、Me.Range("A1").Value と「Meキーワード」をつけても同じ結果です。

具体的に、オブジェクト名を付けないで、「Range("A1")」として使う特殊な例では、代表的なのはシートモジュールに設置するイベントプロシージャです。これは、通常、シートに属すイベントですから、Rangeの前のオブジェクト名が必要ありません。

また、シートモジュール上で、Sheet2のA1を示す方法としては、あまり芳しくはありませんが、
Sheet2.Select
'Worksheets("Sheet2").Select '一応、1行目と同義
MsgBox Range("A1").Value
というようにすることも出来ますね。

ここで、一番の前提になるのは、何が良いとかではなくて、そのモジュールの使い分けなのです。ThisWorkbookにしか書けないもの、標準モジュールにしか書けないもの、クラスモジュール、UserFormモジュール、シートモジュールと、それぞれは、それぞれに即したプロシージャ特有のコードや書き方があります。

該当するシート・モジュールで、
>2.テキスト1.value = me.range("a1")
>3.テキスト1.value = range("a1")

すくなくとも、これは、同義であって、Meを付けたからエラーが出ないなんていうことは、私には考えられません。もし、エラーが出るとすれば、同じようにエラーが出るはずです。そして、また、該当するシートモジュール以外では、このような書き方が適用するとは思えないのです。

そのプロシージャのコードの単独の一行では、それが良い悪いなど分かりません。もし、気になるようでしたら、全体のコードを見せてもらわないと分からないのです。
    • good
    • 0
この回答へのお礼

詳しいご説明有難うございます。
me.はなんとなくAccsessのフォームをいじってた癖で必要なのかなと思っていたのですが、プロシージャによって書き方が異なるんですね。
とても参考になりました。

お礼日時:2005/05/13 13:06

シートモジュールで、Meキーワードを、本当に使用しなければならないのでしょうか。



シートモジュールに書くコードは、限定的な意味を持ちます。ある程度、Excel VBAを書く人間だったら、多くの一般的に使うコードは、Excelの場合は、標準モジュールに書き込みます。ですから、そのプロシージャ内で、必要な場合、Worksheets、Sheets など、明示的にオブジェクトを入れます。あたりまえですが、オブジェクトを持たない標準モジュールでは、Meキーワードは使えません。

>シート上のテキストボックスに、
TextBox1.Value = Range("A1").Value

これが悪いわけではなくて、書き込むモジュールの問題です。これを見て、エラーにならないで、値が表示するには、どこのモジュールに書くべきか、すぐ分かるレベルの人だったら、Me が何を指すのか分かるでしょうし、また、何をしたらエラーになるかも分かるはずです。また、シートモジュール内に、Meが必要か不要なのかも分かるはずなんですね。

この回答への補足

有難うございます。色んなご意見があるんですね。
えーと、つまりは
「sheet1のシートモジュールで」meを使用すると
me.range("a1")=worksheets("sheet1").range("a1")
と同じ意味になる?
同じく「sheet1のシートモジュールで」
range("a1")とすると、activesheetのrangeになるのか、sheet1のrange("a1")になるのか・・
そこのところはどうなんでしょう??
お答えを読み返してもよく分からなかったのものですみません。
ちゃんとすべてのコードを記述すればこんな問題は起こらない、という意見もごもっともです。

補足日時:2005/04/28 23:43
    • good
    • 0

Wendy02さん


質問者さん
#一般的には書かなくて済むものは、書かないようにするのは、VBAではふつうだと思います。
そうなんですよね。ふつうなのが困ったところです。
書かないでハマることはあっても、書いてハマることはありえません。
これを機会に書くようにしてみてください。

#書かないプログラマーがいたんですが、
#ほんとに勘弁してください!て感じでした
#直す私の方が大変^^;
    • good
    • 0

この場合のRangeオブジェクトは、どこに属しているか、というと、Worksheetですよね。

だから、Worksheetの配下(メンバ)として書きますね。
(オブジェクト・ブラウザで確認してみてください)

どこのシートのメンバにあるのか明確なら、省いてよいですし、そうでないなら、書かなくてはなりません。Me はオブジェクトを持つモジュール自身を指し、UserFormや他のモジュールから実行する場合は、Meの代わりに対象オブジェクトを明示的(explicit)に指定します。

今回のようなWorksheetメンバのRangeの前に、特定のシートのRangeオブジェクトを指すために、Me を書くことができるのは、シート・モジュール下でしかありません。その時に、Me を書いても書かなくてもよいのですが、一般的には書かなくて済むものは、書かないようにするのは、VBAではふつうだと思います。

だから、特定の場所を指し示すために、他のモジュールからでは、
 Worksheets("Sheet1").TextBox1.Value = Worksheets("Sheet2").Range("A1").Value
と明示的に書かざるをえないのです。
    • good
    • 0

1.テキスト1.value = activesheet.range("a1")


アクティブ(選択した前面)シートのA1
2.テキスト1.value = me.range("a1")
ワークシート内コードの記述とのことなので、そのシートのA1
3.テキスト1.value = range("a1")
不明(アクティブシートかコードを記述したシートの何れか)

コードを書くときは、所有者を明示するのは必須です。
(なにも省略しない)
おすすめは、
テキスト1.value = me.range("a1").value(フォーマット付きなら.text)
です。

activesheetも、ユーザー操作やコードで変わってしまうので、あまりお勧めできません。
    • good
    • 0

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