VBAのString型の最大文字数について
ツイッターで出したVBAのお題です。
String型はVBAリファレンスでは、「可変長文字列は、最大で約 20 億 (2^31) 文字を格納できます。」と書かれています。
これについて、本当は何文字まではいるのかについての問題です。
お題のツイート
String型はVBAリファレンスでは、
「可変長文字列は、最大で約 20 億 (2^31) 文字を格納できます。」
と書かれています。
「約」ってなんだ、この際はっきりさせようじゃないか。
むしろこれは実際に確かめて回答してもらって良い問題です。
そもそもどうやって確認するか、、、
・
ここには二つの教訓がある。
・書かれていることを妄信してはいけない。
・「約」と書く場合はそれなりの事情がある。
エクセルやVBAに限ったことではないですね。
ツイッターで頂いたリプライから
解説のツイート
しかし、32bitの場合は数億台でエラーになります。(数値ははっきりせず)
「とことんいける」が次いで多いのが頼もしい。
とことん行きたいですよね。
明日時間があれば可能な範囲で説明します。
「最大で約20億(2^31)文字」これを読んでピンきた方は相当にお詳しいひとですね。
この20億(2^31)という数値は、Long型の数値の最大数になります。
ではなぜ、String型の最大文字数がLong型の最大数と関係があるのでしょうか。
文字列を大量に作成する関数には、String関数とSpace関数があります。
関数名の後ろに$をつけると戻り値の型がString型になります。
簡単なところで、Space$関数で検証してみましょう。
以下の検証は64BitのExcelになります。
32bitについては最後に説明します。
?Space(2 ^ 31)
※^は64bitのVBAではLongLongの型文字になるので^の前に空白が必要です。
「オーバーフローしました。」
プロシージャーを書いて1から順に確認してみましょう。
Dim str As String
Dim i As Long
For i = 1 To 31
str = Space$(2 ^ i)
Next
2 ^ 30
これは1073741824
20億の半分でもエラーになってしまいました。
これはSpace関数の制限です。
2 ^ 30 -1
ここまでがSpace関数の限界になっています。
これはString関数も同じです。
そこで、Space$(2 ^ 30 -1)を&でつなげてみましょう。
str = Space$(2 ^ 30 -1) & Space$(2 ^ 30 -1)
これはエラーになります。
確認には処理時間がかかるので目星をつけて、
2 ^ 31
この少し下の数値から確認してみましょう。
Dim str As String
Dim i As Long
For i = 20 To 1 Step -1
str = Space(2 ^ 30 - 1) & Space(2 ^ 30 - i)
Debug.Print Len(str)
Next
2147483635
ここが限界です。
「最大で約20億(2^31)文字」でしたが、
2^31=2147483648
Longの最大数は、
2^31-1=2147483647
これよりも、もう少しだけ小さい数値になっています。
確認するにはVarPtr関数とStrPtr関数を使います。
実際の文字列があるアドレスの直前には4バイトの文字列長部分があり、文字列の直後には2バイトの終端があります。
https://excel-ubara.com/excelvba4/EXCEL_VBA_422.html
つまりString型の最大文字数は、
Long型の最大数、
2^31-1=2147483647
ここから終端の2バイトを引いた、
2147483645
これがString型の最大文字数になります。
以上が64bitの場合のString型の最大文字数です。
32bitの制限でメモリは4GB(アプリは2GB)が限界となります。
Excelの他にもChromeやらその他のソフトでメモリが使われています。
メモリを超えるサイズの文字列は作れません。
つまり残っているメモリ次第という事になります。
Excel以外に色々なアプリが沢山動いていればもっと少なく、3億文字くらいでもエラーになります。
PC環境、実行のたびにも違った限界値になります。
32bitの場合は、2億文字くらいが限界と考えておいた方が良いでしょう。
Excelを64bitにするならメモリはちゃんと積みましょうね。
解説は以上です。
正解としては、
「まだまだ、とことんいける」
これ以外はある意味どれも正解で良いでしょう。
気分としては、とことん行きたかったですけどね(笑)
同じテーマ「ツイッター出題回答 」の記事
Variantの数値型と文字列型の比較
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。