メインコンテンツへスキップ
プログラミング_VBA_ヘッダー_s

[プログラミング: ExcelVBA] Transpose関数で入れ替えられる要素数を検証してみた

    すけっちょ ・3・

     お疲れ様です (  'ω')ノ

     VBAでは、2次元配列の中身を行方向、列方向の入れ替えをするときにTranspose関数が便利です。

     Transpose関数は、セルをコピーして貼り付けする際に使用する
    ”行/列の入れ替え (T)” をVBAで行うための関数です。

    xl_行列の入れ替え

     この関数はシート上に出力するときだけでなく、2次元配列に対しても有効です。
     しかし、このTranspose関数については明記されていない制限があるようで、ハッキリと”○行×○列に対して有効”とか”2次元配列の要素数が○個までは入れ替えができる”とは記述が無いようです。

     そこで、独自にどれぐらいまで使えるのかを検証してみました。

    < 検証環境 >

    OS環境

    Excel環境


    < 検証用のコード >

    Sub WF_Transpose_test()
    '===== 変数宣言 =======================================================
     Dim i As Long, j As Long
     Dim varSample As Variant
     Dim lngAryYCnt As Long, lngAryXCnt As Long
     Dim lngAryCnt As Long
    '====================================================================
     
     '----- 配列の要素数を指定
     lngAryYCnt = 100                       '行の要素数を指定
     lngAryXCnt = 290800                    '列の要素数を指定
     lngAryCnt = lngAryYCnt * lngAryXCnt    '要素数の合計
     
     '----- 配列を再宣言
     ReDim varSample(1 To lngAryYCnt, 1 To lngAryXCnt)
     
     '----- 試す
     On Error GoTo ErrLine
     varAft = WorksheetFunction.Transpose(varSample)
     
    ErrLine:
     If Err.Number = 0 Then
       Debug.Print _
          "要素数:" & Format(lngAryCnt, "#,##0") _
          & Format(lngAryYCnt, "(#,##0") & "*" & Format(lngAryXCnt, "#,##0)") _
          & vbTab & "正常終了"
     Else
       Debug.Print _
          "要素数:" & Format(lngAryCnt, "#,##0") _
          & Format(lngAryYCnt, "(#,##0") & "*" & Format(lngAryXCnt, "#,##0)") _
          & vbTab & Err.Number & vbTab & Err.Description
     
       Err.Clear
     End If
    End Sub
    

     簡単に上記の説明をすると、lngAryYCnt に配列の行にあたる要素数を指定し、lngAryXCnt に列にあたる要素数を指定します。
     配列に入れる値の大きさによって結果のバラツキが出ないように配列の各要素の中には何も代入していません。
     そして、そのままコードを実行するとイミディエイトウィンドウに配列の要素数合計(行要素数×列要素数)と”正常終了” または エラー番号とエラーメッセージが出力されます。

    < 実行結果 >

     実行結果は、以下の通りです。

    要素数:27,000,000(1,000*27,000) 正常終了
    要素数:28,000,000(1,000*28,000) 正常終了
    要素数:29,000,000(1,000*29,000) 正常終了
    要素数:30,000,000(1,000*30,000) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,000,000(1,000*29,000) 正常終了
    要素数:30,000,000(1,000*30,000) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,500,000(1,000*29,500) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,800,000(1,000*29,800) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,300,000(1,000*29,300) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,000,000(1,000*29,000) 正常終了
    要素数:29,200,000(1,000*29,200) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,100,000(1,000*29,100) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,050,000(1,000*29,050) 正常終了
    要素数:29,080,000(1,000*29,080) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,070,000(1,000*29,070) 正常終了
    要素数:29,075,000(1,000*29,075) 正常終了
    要素数:29,078,000(1,000*29,078) 正常終了
    要素数:29,079,000(1,000*29,079) 正常終了
    要素数:29,080,000(1,000*29,080) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,079,500(100*290,795) 正常終了
    要素数:29,079,800(100*290,798) 正常終了
    要素数:29,079,900(100*290,799) 正常終了
    要素数:29,080,000(100*290,800) 正常終了
    要素数:29,080,000(1,000*29,080) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,080,000(1,000*29,080) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,080,000(29,080*1,000) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,080,000(290,800*100) 1004 WorksheetFunction クラスの Transpose プロパティを取得できません。
    要素数:29,080,000(100*290,800) 正常終了

     厳密にエラーになるか、ならないかの閾値となる要素数を1つずつ探したわけではありません。
     ただ、結果としては行×列の要素数が 29,080,000個となるあたりでエラーが発生しています。

     しかし、出力された結果を上から見ていくと 要素数:29,080,000個 でも
    行1,000 × 列:29,080 の場合と 行:100 × 列:290,800 の場合ではエラーが発生するかどうかが違うようです。
     さらに 行:100 × 列290,800 ではエラーになりませんでしたが、
    行:290,800 × 列:100 ではエラーになっています。

     因みに下がコード実行中のエラーになる直前のタスクマネージャーです。

    xl_行列の入れ替え_task

     一時的にではありますが、Excelのプロセスでメモリが2,504MB使用されています。
     Excelファイルを開いているだけだと60数MBだったので、2,400MB前後もコードの実行に使用されているようでした。

     あと、画像は残していませんでしたが、上で記した実行結果の前に2,3度テストをしていましたが、エラーが発生した要素数を一旦ファイルを閉じてから再度実行した時にエラーが発生せずに正常終了したこともありました。

     そのことを踏まえ、タスクマネージャで使用されているメモリを見ていると要素数〇個までTranspose関数で入れ替えができるというよりメモリ使用量との兼ね合いなのではないかと思われます。

     また、この検証では配列の各要素には値を代入していません。ですので、各要素の値はEmptyのままになっています。
     このTranspose関数では、使用しているPCの性能やExcelが64bit版でも入れ替えできる要素数の上限が変わってきそうです。

    < 結論 >

    ・PCの性能やその時の使用メモリによる
    ・配列内にどれぐらいの情報量(値)があるかで変わる
    ・Excelが64bit版だとExcelで使用できるメモリ容量が変わるので、そこでも変わると思われる


     最後まで、記事を読んでいただきありがとうございました!

     宜しければ ”スキ” をしてもらえると僕のモチベーションが上がり、また次の記事につなげることができます。

     どうぞよろしくお願いします!

     
     
     
    Excel, Access, VBAが好きです。 MySQL/MariaDB, SQLServerも使っていました。 VBAを中心に仕事で使える知識や技術を記事にまとめています。 良かったら是非見て下さい!

    あなたへのおすすめ