[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『VBAのワークシート関数について』(マリオ)
VBAのワークシート関数で、65536を越えた配列要素を取り扱うと、結果がおかしくなります(下記test1〜test5参照)。 Worksheet関数(VBA)で取り扱える 配列の上限は、65536までみたいです。
★Worksheet関数(VBA)で、気を付けるべき点が他にあれば、ご教授願います。
下記URLでも、同じようなことが掲載されています。 http://excel-ubara.com/excelvba4/EXCEL226.html
'****************************************************************************************** Option Explicit Sub test1() Const x As Long = 65536 '★★★
'---------------------------------------------------------- 'xが、1〜65536では問題ない → A列=「1」,B列=「2」,C列=「3」 'xが、65537で、次のようになる。→ A列=「1」,B列=「1」,C列=「1」 '(セルに表示される値がおかしいが、エラーにはならない。) '----------------------------------------------------------
Dim sh As Worksheet, i As Long, j As Long, k As Long ReDim Data(1 To 3, 1 To 1) As Variant Set sh = Sheets("Sheet1")
For j = 1 To x k = k + 1 ReDim Preserve Data(1 To 3, 1 To k) For i = 1 To 3 Data(i, k) = i Next i Next j
sh.UsedRange.Clear sh.Range(sh.Cells(1, 1), sh.Cells(x, 3)) = _ WorksheetFunction.Transpose(Data) '★ End Sub
Sub test2() Const x As Long = 65536 '★★★
'---------------------------------------------------------- 'xが、1〜65536では問題ない(次行参照) '3 '65536 '****************** '65536 '3
'---------------------------------------------------------- 'xが、65537で Debugの結果がおかしくなる。 'また、エラー(インデックスが有効範囲にありません)になる。 '3 '65537(問題ない) '****************** '3(Debugの結果がおかしい。65537にならない。) '(エラーとなるDebugの結果が返ってこない) '----------------------------------------------------------
Dim sh As Worksheet, i As Long, j As Long, k As Long ReDim Data(1 To 3, 1 To 1) As Variant Set sh = Sheets("Sheet1")
For j = 1 To x k = k + 1 ReDim Preserve Data(1 To 3, 1 To k) For i = 1 To 3 Data(i, k) = i Next i Next j
Debug.Print UBound(Data, 1) Debug.Print UBound(Data, 2) Debug.Print "******************" ReDim Data2(1 To UBound(Data, 2), 1 To 3) Data2 = WorksheetFunction.Transpose(Data) '★ Debug.Print UBound(Data2, 1) '★ Debug.Print UBound(Data2, 2) '★ Debug.Print vbCrLf End Sub
Sub test3() Const x As Long = 65536 '★★★
'---------------------------------------------------------- 'xが、1〜65536では問題ない(次行参照) '65536 '3 '****************** '3 '65536
'---------------------------------------------------------- 'xが、65537で Debugの結果がおかしくなる。エラーにはならない。 '65537(問題ない) '3 '****************** '3 '1(Debugの結果がおかしい。65537にならない。) '----------------------------------------------------------
Dim sh As Worksheet, i As Long, j As Long, k As Long ReDim Data(1 To x, 1 To 3) As Variant Set sh = Sheets("Sheet1")
For j = 1 To x For i = 1 To 3 Data(j, i) = i Next i Next j
Debug.Print UBound(Data, 1) Debug.Print UBound(Data, 2) Debug.Print "******************" ReDim Data2(1 To 3, 1 To UBound(Data, 1)) Data2 = WorksheetFunction.Transpose(Data) '★ Debug.Print UBound(Data2, 1) Debug.Print UBound(Data2, 2) '★ Debug.Print vbCrLf End Sub
Sub test4() Const x As Long = 65536 '★★★
'---------------------------------------------------------- 'xが、1〜65536では問題ない 'Debugの結果:「65536」
'---------------------------------------------------------- 'xが、65537だと、Debugの結果がおかしい。 'Debugの結果:「1」 '----------------------------------------------------------
Dim sh As Worksheet, i As Long, Data2 As Long ReDim Data(1 To x) As Variant Set sh = Sheets("Sheet1")
For i = 1 To x Data(i) = 1 Next i
Data2 = WorksheetFunction.Sum(Data) '★ Debug.Print Data2 End Sub
Sub test5() Const x As Long = 65537 '★★★ '---------------------------------------------------------- 'xが、65536では問題ない '9 '-5
'---------------------------------------------------------- 'xが、65537だと、Debugの結果がおかしい。 '-5 '-5 '----------------------------------------------------------
Dim sh As Worksheet, i As Long, Data2 As Long, Data3 As Long ReDim Data(1 To x) As Variant Set sh = Sheets("Sheet1")
Data(1) = -5 Data(2) = 9 For i = 3 To x Data(i) = 1 Next i
Data2 = WorksheetFunction.Max(Data) '★ Data3 = WorksheetFunction.Min(Data) '★ Debug.Print Data2 '★ Debug.Print Data3 '★ End Sub
< 使用 Excel:Excel2013、使用 OS:Windows 8.1 >
きっと、そうだと思います。 たとえば TRANSPOSE関数は 65536 すらカバーしていないと思いますね。 しかも、項目数が多ければ多いほど、限界が小さくなる 不思議な現象ですね)
Sub Test() Dim w As Variant
w = WorksheetFunction.Transpose(Range("A1:A100000")) MsgBox UBound(w, 1)
w = WorksheetFunction.Transpose(Range("A1:A1000000")) MsgBox UBound(w, 1)
End Sub
(β) 2016/03/27(日) 16:55
To βさん
65536まで、カバーしてませんか?
Sub Test6() Dim w As Variant w = WorksheetFunction.Transpose(Range("A1:A65536")) MsgBox UBound(w, 1)'ちゃんとした結果「65536」が返る。
w = WorksheetFunction.Transpose(Range("A1:A65537")) MsgBox UBound(w, 1)'「65537」を返してほしいのに、結果が「1」になる。 End Sub (マリオ) 2016/03/27(日) 17:07
衝突
配列に対するTranspose Methodには制限(2^16)があり, それを超えると2^16分を下方から差し引いた要素数の配列になるはず。
[[20141026141028]] 『必要な行データだけを配列へ格納』(やっぱり初歩) >>
[[20121004235255]] 『配列について』(MAKO) >>BOT
(seiya) 2016/03/27(日) 17:16
To seiyaさん
あぁ、そうだったんですか! 勉強になります。
To マリオさん
65536 (2^16)以上の項目数で、100000 とか 1000000 で試してみてくださいね。
(β) 2016/03/27(日) 17:28
To seiya さん
>配列を使用して確実な結果を期待するなら、配列に対してのTranspose関数の使用は極力避けた方が無難でしょう。 >vbaの Transpose method には制限があります。 >配列に255を超える長さの文字列が存在したり、 >配列のどの次元でも要素数(Index数)が65536(2^16)を超えると機能しません。
情報ありがとうございます。 255を超える文字を、配列に格納して、transposeするとエラーになっちゃうんですね。 (マリオ) 2016/03/28(月) 11:40
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.