[[20160327164200]] 『VBAのワークシート関数について』(マリオ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『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.