こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

エクセルVBAの記述の違い

下記の2つともA1:B2の中身を削除するものですが、test1の書き方だと対象となるシートがアクティブではないとエラーになります。test2は問題なし。
Cellsの書き方のほうが変数を使う時に便利なのですが、なんでこんな違いがでてしまうのでしょうか?

Sub test1()

Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")

ws1.Range(Cells(1, 1), Cells(2, 2)).ClearContents
ws2.Range(Cells(1, 1), Cells(2, 2)).ClearContents

End Sub

Sub test2()

Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")

ws1.Range("a1:b2").ClearContents
ws2.Range("a1:b2").ClearContents

End Sub

投稿日時 - 2003-08-10 16:56:45

QNo.624522

困ってます

質問者が選んだベストアンサー

答えは 簡単です。

ws1.Range("a1:b2").ClearContents
の場合の セルは ws1のセルであると 指定しているからです。

ws1.Rangeとした場合、 その Rangeは ws1を示すからですね。

test1のほうは
Cells(1, 1)と シートの指定がされていません。
ここで ws1.Cells(1, 1)としてあげれば
エラーは 出ないでしょう。

投稿日時 - 2003-08-10 17:03:21

お礼

大変遅くなりもうしわけありません。
ありがとうございました。
助かりました。

投稿日時 - 2003-08-27 14:07:18

ANo.1

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

#2です。
>#3の、「Cellsメソッド」とは何でしょう。に付いて
-->Cellsプロパティと書かなかった理由
(A)市販の5種類ぐらいの解説書
   Cellsプロパティとして解説あり。ほとんどこのタイ   プ。当然と言う形で説明無し。
(B)下記サイトなどの解説
   Cellsメソッドと言うものが使われ解説あるものもある。
http://homepage2.nifty.com/kasayan/vba/excel2a.htm
http://www2s.biglobe.ne.jp/~iryo/vba/vba05.html
http://www.ipe.tsukuba.ac.jp/~akira/2002/6203603/9/
http://www.uchidas.com/yasuo/vbaboard/vbaboard97.html
「もやもや」はあるものの、(B)が正しいのでは無いかと
思い敢えて書きました。実際のコードを書く上では、差が出ないし、哲学的?問題のようなので、もしそういう質問がでたら、ご高説を伺います。質問の主旨とはなれるので
この辺で失礼します。
他に質問と関係ありそうな記述
http://ws.31rsm.ne.jp/~pension/access/ota2002/7280.htm

投稿日時 - 2003-08-11 23:49:59

お礼

大変遅くなりもうしわけありません。
ありがとうございました。
勉強になりました。

投稿日時 - 2003-08-27 14:09:15

ANo.3

前Resで返って混乱したのではないでしようか。

No.1の回答でいいと思いますが、気になったので・・・

> ws1.Range(Cells(1, 1), Cells(2, 2)).ClearContents

この場合、Rangeオブジェクトを取得するために、Rangeプロパティの第1、2引数に
Cellsプロパティを使ってセル範囲を指定していますよね。

このCellsプロパティにシートを指定していないので、アクティブシートを指すことになります。

現在 ws1 がアクティブの場合、ws1. があると「当然でしょ! 何言っているの」って感じで、
まぁまぁ許してもらえますが、ws2. が付いていると、「ws2 のRangeオブジェクトで ws1 の
セル範囲で・・・」ということになり「何言ってんのよ! 訳わからん!」となって怒られます。

つまり、ws1.Range(Cells(・・・ の ws1. は、Cellsプロパティで指定する限り全て不要と
思います。
ということで Range(ws1.Cells(・・・ となればいいと思います。

ws1.Range("A1:B2") の場合、現在アクテイブになっているシートが何処であっても関係
ありませんので、ここで「指定したシート」の「指定した範囲」ということになります。

それにしても前Resが気になるのですが・・・

> Cellsメソッドが先に解釈され、・・・
> Cellsメソッドの出番は無いのでそういうことはない・・・

この「Cellsメソッド」とは何でしょう?
もうちょっと正しく書いた方がいいのではないかと思いますが・・・

投稿日時 - 2003-08-10 23:52:18

お礼

大変遅くなりもうしわけありません。
ありがとうございました。
勉強になりました。

投稿日時 - 2003-08-27 14:08:40

ANo.2

#1のご回答と同趣旨ですが、少し敷衍すると
(1)Sheet2をActiveにして下記を実行しても、エラーになります。
Sub test1()
Set ws1 = Worksheets("Sheet1")
ws1.Range(Cells(1, 1), Cells(2, 2)).ClearContents
End Sub
(2)Sub test1()
Range(Cells(1, 1), Cells(2, 2)).ClearContents
End Sub
はSheet1をActiveにしてあればSheet1を、Sheet2をActiveにしてあればSheet2をクリアします。
エラーにはならない。
従ってCellsは
(A)ActiveSheetのセルを指す。
(B)Worksheet指定がしてあると(Ws1)、ActiveSheetがWs1でなく、違うシートの時は食い違いとなる。
多分()内にあるCellsメソッドが先に解釈され、そのものと、あとでRangeプロパティを実行する時の、不一致を検出すると思う。test2のRangeだとCellsメソッドの出番は無いのでそういうことはない。
(3)下記はエラーは出ません
Sub test1()
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
ws1.Activate
ws1.Range(Cells(1, 1), Cells(2, 2)).ClearContents
ws2.Activate
ws2.Range(Cells(1, 1), Cells(2, 2)).ClearContents
End Sub
---
Sub test1()
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
ws1.Range(ws1.Cells(1, 1), ws1.Cells(2, 2)).ClearContents
ws2.Range(ws2.Cells(1, 1), ws2.Cells(2, 2)).ClearContents
End Sub
もエラーは出ません(#1回答)。

投稿日時 - 2003-08-10 18:14:00

お礼

大変遅くなりもうしわけありません。
ありがとうございました。
たすかりました。

投稿日時 - 2003-08-27 14:07:58

あなたにオススメの質問