dポイントプレゼントキャンペーン実施中!

エクセル2000です。

Sub test()
Range("A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21,A22,A23,A24,A25,A26,A27,A28,A29,A30,A31,A32,A33,A34,A35,A36,A37,A38,A39,A40,A41,A42,A43,A44,A45,A46,A47,A48,A49,A50,A51,A52,A53,A54,A55,A56,A57,A58,A59,A60,A61,A62,A63,A64,A65,A66,A67,").Select
End Sub

上記の67個のセルを選択するマクロを実行すると
「実行時エラー1004 Rangeメソッドは失敗しました。'Global'オブジェクト」となってしまいます。
一個へらして66個にすると問題なく選択されます。
Rangeに個別で記載できる引数は66個までなのでしょうか?
質問に書いたセルは、数が一目でわかるための例なので、Range("A1:A67").Selectという回答以外でお願いします。

A 回答 (6件)

こんばんは。



この種の制限というのは、引数の数ではなくて、文字数(character) 255 個だったと思います。上記は、最後の「,」の抜きで、258個になりますから、エラーになります。列に対してではなくて、1行目に対して、試してみてください。
    • good
    • 0
この回答へのお礼

Wendy02さま、いつもありがとうございます。
文字数でしたか!
1行目、ためしました。
A1からBR1までの70個選択できました。
255文字までなんですね、ありがとうございました。

お礼日時:2009/01/27 10:23

なんか書こうと考えたけど、これしか思いつきませんでした。


配列を使うのか、どこに使うのか、使うメリットを出せるか、
慎重に考えて、、、というのがアドバイスです。
Unionの話は伝えられないようなので、文字列処理の方だけ、そこそこのもの。

Sub MainC()
Cells.Clear
With Range("a:a"): .Value = "=ROW()": .Value = .Value: End With
Dim ar
fRefA ar
' 処理
End Sub

Private Sub fRefA(ar)
Dim vA, v, strB As String, c As Long, d As Long

vA = ActiveSheet.UsedRange.Resize(, 1).Value ' A列の値を配列に
strB = Space$(UBound(vA) * 7) ' about最大必要な長さのスペースをstrBに

' ' 参照の列挙開始
d = 1 ' 区切り位置の初期化
For Each v In vA
c = c + 1
If VarType(v) = vbDouble Then ' IsNumeric はEmptyでもTrueだし遅いから
If Not v And 1 Then ' 2進数の1の位が1ではない(関数や'=演算'より速い)
Mid(strB, d) = ",A" & c ' 順次先頭にあるスペースを参照文字に置換
d = InStr(d, strB, " ") ' スペースを検索して最初に見つかる位置
End If
End If
Next v
Erase vA
strB = Mid$(RTrim$(strB), 2) ' 空白を消し、2文字め以降
' ' 参照の列挙完了 / 255文字区切り開始
d = 0 ' 区切り位置の初期化
Do
' ' 直前に処理した区切り位置から256文字めの手前にある","を検索
d = InStrRev(strB, ",", d + 256)
' ' 残りの文字 が255文字以下or","がない なら処理終了
If d Then Mid(strB, d) = ";" ' dの位置にある","を";"に置換
Loop While d
' ' 255文字区切り完了
ar = Split(strB, ";") ' 参照文字列を配列化
End Sub
    • good
    • 0
この回答へのお礼

お礼が遅くなり申し訳ありません。

わたしの能力不足、理解力不足で消化不良を起こしています。
> If Not v And 1 Then ' 2進数の1の位が1ではない
なんてもう何がなんだか・・・
(;≧ロ≦)

すみません。時間のあるときじっくり勉強します。
お馬鹿なわたくしめにおつきあいいただき、ありがとうございました。
これからも見捨てずご指導のほど宜しくお願い申し上げます。

お礼日時:2009/02/04 10:43

 # んー、どうも説明が解りにくいように思えたので補足してみます。



私が伝えようとしているのは、例えば
 式A =SUM(A1,A2,B1,B2)
という式の場合は「引数が4つ」なんですが、
 式B =SUM((A1,A2,B1,B2))
という風に書くと 内側の()の中全体が、ひとつのセル参照(参照式)
というように意味が変わり「引数は1つ」
というような話なのです。

","カンマの意味で比較してみると、
 式Aでは
 カンマは「引数の区切り」、
 式Bでは
 カンマは「参照演算子」となります。

さらに、
参照演算子を言い換えると
","カンマは、
 「+」や「OR」の意味
" "スペースは、
 「*」や「AND」の意味
になります。

そのままRangeの参照文字列(参照式)に照らして考えると、
 Range("A1,A2,B1,B2")
は、ans = aX + aY + bX + bY のような式に喩えられます。
 Range("(A:A,B:B) (1:1,2:2)")
は、ans = (a + b) * (X + Y) のような式に喩えられます。

つまり、Rangeの引数としての参照文字列は
それ自体がひとつの「式」になっていて、演算子で結ばれている、
と考えるべきなのであって、
"A1,A2,A3,A4 ..."のように列挙されていると
恰かも引数の列なりのように見えるけれど、
これを「引数は何個?」という風に捉えるのは間違い、
ということになります。

 # やっぱ説明下手ですね
 # 反って解りにくかったらゴメンなさい


それと、#1さんへのコメントで気になったんですけれど、
ループでひとつのRange型変数に繰り返しUnionを実行すると、
エラーメッセージは出ずに、途中から何も処理しないケースが、
XL2000で何度か確認されているので、
実行中にローカルウィンドウで確かめてみた方が良いかも知れません。
No.4007086の時にも、
Set r = Union(r, Range("any"))
のような形でループした場合は途中までしか処理されてなくて
それでもエラーは出ませんでした。
この点は、まだ良く私も解ってない処なのですが、、、。

 # 大師様に「OKWaveで会いましょ」って言われてたのですが、ナカナカ、、、
 # 芋焼酎は適量で止めるの難しいですよね(笑)
ではまた
    • good
    • 0
この回答へのお礼

何度もご指導ありがとうございます。

> ","カンマは、「+」や「OR」の意味
> " "スペースは、 「*」や「AND」の意味

初めて知りました!わたしって無知ですねえ・・・。

> Set r = Union(r, Range("any"))

このようにテストしましたが問題なく2500セルがセレクトされました。

Sub TEST01()

Dim ar() As String, v As Variant
Dim UR As Range
With ActiveSheet
.Range("A1:A5000").Value = "=ROW()"
For Each c In Intersect(.UsedRange, .Range("A:A"))
If IsNumeric(c.Value) Then
If (c.Value Mod 2) = 0 Then
ReDim Preserve ar(i)
ar(i) = c.Address(0, 0)
i = i + 1
End If
End If
Next c
' Range(Join(ar(), ",")).Select 'Rangeの引数が255文字超でエラー!!
For Each v In ar()
If UR Is Nothing Then
Set UR = .Range(v)
Else
Set UR = Union(.Range(v), UR)
End If
Next v
UR.Select
MsgBox Selection.Count
Set UR = Nothing
End With
End Sub

お礼日時:2009/01/30 15:06

# こんにちは^^



既に回答は出ていますので、またオマケ程度の話ですが、
参照文字列に関する制限は、文字の長さに対して255です。
(非VBA Excel のセル参照に倣います)
引数の数や、領域(Areas)の数の問題ではありません。

■255文字で表せる領域(列|行、除く)の最大数を試してみました。

Sub Test_RngRef2Areas()' 非実践的なテストです。(ちょと遊び)
  Const S_REF = _
 "(A:A,B:B,C:C,D:D,E:E,F:F,G:G,H:H,I:I,J:J,K:K,L:L,M:M" _
& ",N:N,O:O,P:P,Q:Q,R:R,S:S,T:T,U:U,V:V,W:W,X:X,Y:Y,Z:Z)" _
& " " _
& "(1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,10:10,11:11" _
& ",12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19" _
& ",20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27)"
Rem ↑重複なし。領域数:26 * 27 = 702
Rem ↓重複あり。領域数:31 * 32 = 992
'  Const S_REF = _
 "(A:A,B:B,C:C,D:D,E:E,F:F,G:G,H:H,I:I,J:J,K:K,L:L,M:M,N:N,O:O,P:P" _
& ",Q:Q,R:R,S:S,T:T,U:U,V:V,W:W,X:X,Y:Y,Z:Z,A:A,B:B,C:C,D:D,E:E)" _
& " " _
& "(1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,1:1,2:2,3:3,4:4,5:5,6:6,7:7" _
& ",8:8,9:9,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,1:1,2:2,3:3,4:4,5:5)"

  Dim l: l = Len(S_REF)
  If l > 255 Then
    MsgBox l
  Else
    Range(S_REF).Select
    MsgBox "Len(Ref_Str) :" & l _
    & vbLf & ".Areas.Count :" & Selection.Areas.Count
  End If
End Sub

 参照演算子 ":" "," " "
 括弧 "(" ")"
 参照文字(A1形式)
すべての合計で255文字迄ということです。(勿論""は数えません)
引数の数で言えば、文字列(全体)として、1、なのです。
領域数の制限もある筈ですが、問題になり得ない証として以上を書きました。
 # No.4007086でも説明書いていたような、、、(^^;)
 # 以降は、ついでのような、書きたいことを書くような感もあり。

■参照演算子 スペース、(積、AND)の話。(今回の主題?オマケ?)
 Range("A:J 1:10")
と書いて、
 Range("A1:J10")
と同じ意味になります。
単領域では却って字数が多くなりますが、複数領域では、
 Range("(B:D,F:H) (2:4,6:8)").BorderAround , 3
のような書き方で、
 Range("B2:D4,F2:H4,B6:D8,F6:H8").BorderAround , 3
と同じ結果で、字数を少なく、範囲(多くの領域)を捉え易く、できます。
この特徴が、上記テストの702, 992という結果に出ています。

非VBA Excel では基本テクと呼べるのでしょうか、、、?
 =SUM((B:D,F:H) (2:4,6:8))
と似たような使い方です。(この数式内の引数の数は1です!)

■Rangeによる領域指定とUnion、Intersect
 Range("A1,B1,C1,D1")
は4つの領域を持ちます。これに対し、
 Union(Range("A1"),Range("B1"),Range("C1"),Range("D1"))
は(似たような命令ですが)結果的に
 Range("A1:D1")
と同じ意味になり、ひとつの領域です。

UnionやIntersectには、
共通した行範囲・列範囲にある連続した矩形(四角い)範囲を
纏めて整理する(規則性は複雑です)機能があります。
(その分、動作は少し重いようですね。XL2000では特に)

これに対して、
領域の数とその順列(インデックス)を
指定(間接的にアクティブセルも指定)できるのが、
Rangeによる領域指定という言い方になります。

 Range("(D:E,B:C) (4:5,2:3)").Select
と、(似たような命令ですが)
 Intersect(Range("D:E,B:C"), Range("4:5,2:3")).Select
を、
 Debug.? Selection.Address; vbLf; ActiveCell.Address
で、比較してみると違い(それぞれの特徴)が解ると思います。

■Rangeによる領域指定の用法
(スペース演算子なしで実践する機会は少ないと思います。)
例に挙げた.BorderAroundのような書式の一括処理などが主ですが、
プロパティやメソッドによって、
*全領域を処理
*.Areas(1)のみ処理
*エラー
と挙動が分れます。
(この点が、一般にはあまり馴染んでない理由だと私は考えています。)
ひとつひとつ挙動を確認しながらTipsにしていけば、
きっと役に立つ(活用の幅は広い)と思うのですが、、、。
書式全般(.Font .Interior .Locked .Borders ...)、
.Clear .Delete ...等の処理では、私には必要不可欠な手法です。
(∵私が作るファイルは殆ど、シートを持たないアドインなので余計に)

他の用法として、複数のセル範囲を其々Range型変数にSetする代わりに、
纏めてSetしてからArea毎に(ループなど)処理することで、
効率的になる場合もあるようです。
ただし、勿論、配列やコレクションへの理解が前提になりますし、
ご承知のように簡単にエラーが出ますから、全般に難易度はやや高めです。

 # まだよくわからないのですが、Unionにも(XL2000、02、03で確認済)、
 # .SpecialCellsにも(XL2000で確認済)、
 # 領域に対する何らか(数?or?)の制限があるようですね。(研究してみます)

■コメント:領域指定について(閲覧された方へ)
VBAを学ぶ課程として、
最初の内はループを用いながら、オブジェクトの扱いや条件分岐などに慣れ、
応用的なコーディング『経験』を重ねて、十分な知識を身に付けていきます。
その先のステップで、能率、効率、安定、等の課題が
「自然に向こうからやって来る」と思います。
今その必要を感じない方はこの話を、情報として「こんなのもある」程度に、
とどめておいて下さい。ショートカットして消化不良になりませんよう。
また、VBAを職場で扱う方は、「いつ担当引継があっても困らないように」
誰でも読める記述を心がけて欲しいです。(請負い仕事で今も閉口してます;)
今回の話はそういう意味では、あまり知られていない、使われない、手法
に関する話ですし、試験に基づく研究ネタとしてご理解ください。
趣味的?と言われても否定しません(^^;
が、
非VBA Excel の習熟が進んだ方なら、すんなり実践できるものとも思っています。
実はこれ、非VBA Excel の特性に関する理解の問題であって、根本的には
VBAやVisual Basicの題目ではないという旨のご意見を頂いたこともあります。
(ならばと、部分的にはVBAビギナーにこそ奨めてみたいというのが
私の本音なのですが、同じ意見に出会ったことはまだありません。)

 # それでは、、、また^^
    • good
    • 0
この回答へのお礼

cj_moverさま、いつもおせわになります。
4007086で教えをいただいていたのにすっかり忘却の彼方でした。
( ̄ロ ̄;)!! 
芋焼酎の飲みすぎでしょうか?・・・

今回もためになるご教示をありがとうございます。
これからもお見捨てなくよろしゅうお願い申し上げます。
 (o。_。)oペコッ.

お礼日時:2009/01/28 15:44

#1です。



限界があったような感じがしたんですけど・・・

Sub try()
Dim i As Integer
Dim r As Range

Set r = Range("A1")

For i = 3 To 1000 Step 2
Set r = Union(r, Cells(i, 1))
Next

r.Select
End Sub

セルA1からA列を1個飛ばしで選択するとして、500個は出来ましたね。
(Excel2002で検証。Versionの違いにより変わるかも知れませんけど)
    • good
    • 0
この回答へのお礼

n-junさま、ありがとうございました。
文字数でした。

お礼日時:2009/01/27 10:27

67個かは忘れましたが、Unionメソッドで多すぎてエラーになったことありました。

    • good
    • 0
この回答へのお礼

ありがとうございました。
No2でのご回答で1万個ためしました。
途中、ハングアップしたのかとおもいましたが、5分くらいでエラーにならず完了しました。

ありがとうございました。

お礼日時:2009/01/27 10:48

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

このQ&Aを見た人はこんなQ&Aも見ています