VBA技術解説
LSetとユーザー定義型のコピー(100桁の足し算)

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
公開日:2020-07-09 最終更新日:2020-12-19

LSetとユーザー定義型のコピー(100桁の足し算)


数の単位に「無量大数」というものがあります。
その桁数は10^68(10^88とする場合もあるよう)です。
VBAでこの無量大数の足し算をするにはどうしたら良いでしょうか。


方法としては、VBAで計算できる桁数にちぎって足し上げていけば良いでしょう。
ここではサンプルとして、100桁の数値を1桁ずつ足し上げていくVBAを紹介します。
そして、このサンプルVBAの中で、
RSetステートメント
LSetステートメント
Typeステートメント
LSetでユーザー定義型のコピー
これらを使用しています。

数値データ型の数値範囲

データ型 名称 格納できる範囲
Integer 整数型 -32,768 ~ 32,767
Long 長整数型 -2,147,483,648 ~ 2,147,483,647
LongLong 64ビット符号付き数値 -9223372036854775808 ~ 9223372036854775807
※64ビットプラットフォームのみで有効な宣言型
Single 単精度浮動小数点数型 -3.402823E38 ~ -1.401298E-45(負の値)
1.401298E-45 ~ 3.402823E38(正の値)
Double 倍精度浮動小数点数型 -1.79769313486232E308 ~ -4.94065645841247E-324(負の値)
4.94065645841247E-324 ~ 1.79769313486232E308(正の値)
Currency 通貨型 -922,337,203,685,477.5808 ~ 922,337,203,685,477.00
Decimal 10進数データ型 スケールが0 (小数部がない) の場合の利用可能な最大値は、 +/-79,228,162,514,264,337,593,543,950,335 になります。
小数点以下の桁数が28の場合、最大値は +/-ない場合、最小値0以外の値は、 +/-0.0000000000000000000000000001 です。

いずれにしても、整数値として正確に表すことのできる桁数は100桁には遠く及びません。

100桁数値の足し算VBA

Option Explicit

Const MaxDigits As Long = 100 '入力の最大桁数

Type tpA
  tpA1 As String * MaxDigits
End Type

Type tpB
  tpB1(1 To MaxDigits) As String * 1
End Type

'大きな文字列数値の足し算
Function AddBigNumber(ByVal arg1 As String, _
           ByVal arg2 As String) As String
  'LSetで構造体から構造体の配列にコピー
  Dim b1 As tpB, b2 As tpB
  LSet b1 = Str2Type(arg1)
  LSet b2 = Str2Type(arg2)
  
  '一桁ずつ足し上げていく
  Dim i As Long, tmp As String
  Dim ans(MaxDigits) As String 'インデックス0は桁上がり用
  For i = MaxDigits To 1 Step -1
    If Trim(b1.tpB1(i) & b2.tpB1(i)) = "" Then Exit For
    tmp = Str2Num(ans(i)) _
      + Str2Num(b1.tpB1(i)) + Str2Num(b2.tpB1(i))
    ans(i) = Right$(tmp, 1)
    ans(i - 1) = IIf(Len(tmp) = 1, "", Left$(tmp, 1))
  Next
  
  AddBigNumber = Join(ans, "")
End Function

'文字列を構造体に入れて返す
Function Str2Type(ByVal str As String) As tpA
  RSet Str2Type.tpA1 = str
End Function

'文字列の数値化:スペースを0にする
Function Str2Num(ByVal str As String) As Long
  Str2Num = IIf(IsNumeric(str), str, 0)
End Function

100桁数値の足し算VBAの使い方と結果

Sub sample()
  Dim a1 As String, a2 As String
  a1 = "9999999999987654321098765432109876543210987654321098765432109876543210"
  a2 = "123456789012345678901234567890123456789012345678901234567890"
  Debug.Print AddBigNumber(a1, a2)
  
  a1 = "1"
  a2 = "99999999999999999999999999999999999999999999999999"
  Debug.Print AddBigNumber(a1, a2)
  
  a1 = "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
  a2 = "8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888"
  Debug.Print AddBigNumber(a1, a2)
End Sub

イミディエイト ウィンドウに、
10000000000111111111111111111111111111111111111111111111111111111111100
100000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110

100桁数値の足し算VBAの解説

RSet ステートメント

文字列変数内の文字列を右揃えにします。

RSet 文字列変数 = 文字列

RSetは文字列変数の残りの文字を半角スペースに置き換えます。
文字列が文字列変数よりも長い場合、 RSetは左端から文字列変数の長さの文字だけを文字列変数に格納します。

LSet ステートメント

文字列変数内で文字列を左揃えにします。

RSet 文字列変数 = 文字列

LSetは文字列変数の残りの文字を半角スペースに置き換えます。
文字列が文字列変数よりも長い場合、 LSetは左端から文字列変数の長さの文字だけを文字列変数に格納します。

Type ステートメント

Typeステートメントは、ユーザー定義型の宣言です。

ユーザー定義型は、名前の通りユーザーが定義できるデータ型になります。
普通の変数は、1つの値しか入れられませんが、
ユーザー定義型は、複数の異なるデータ型を入れる事が出来ます。
プログラミング言語での一般的な呼び方としては、構造体とも呼ばれます。

Typeステートメントの詳細は以下を参照してください。
第110回.ユーザー定義型・構造体(Type)|VBA入門
・Typeステートメントの構文 ・ユーザー定義型の使い方 ・ユーザー定義型の使用例 ・ユーザー定義型の制限 ・最後に

ユーザー定義型変数のコピー:TypeとLSet

LSet ユーザー定義型変数1 = ユーザー定義型変数2

ユーザー定義型の変数を別の変数にコピーする場合、要素に指定されているデータ型は考慮されず、一方の変数のバイナリ データがもう一方の変数のメモリ領域にコピーされます。

MicrosoftのVBAリファレンスには、
LSet を使用してユーザー定義型の変数を別のユーザー定義型の変数にコピーすることはお勧めしません。
特定のデータ型用に予約されているスペースに別のデータ型のデータをコピーした場合、予期しない結果になることがあります。
このように書かれています。
今回は、これを承知の上でのサンプルVBAです。
以下は、桁数を少なくして見やすくした場合の例です。

Type tpA
  tpA1 As String * 5
End Type

Type tpB
  tpB1(4) As String * 1
End Type

Sub sample()
  Dim a As tpA
  Dim b As tpB
  RSet a.tpA1 = "123"
  LSet b = a
  Stop
End Sub

RSet a.tpA1 = "123"
a.tpA1に右寄せで"123"と入ります。

LSet b = a
5文字がString * 1の配列に入ります。

VBA マクロ 100桁数値 足し算 Type Lset RSet


上記VBAの参考ページ

第45回.VBA関数(Format)|VBA入門
・Format関数 ・日付/時刻表示書式指定文字 ・数値表示書式指定文字 ・文字列表示書式指定文字 ・Format関数の使用例 ・※セルに出力する場合 ・最後に
第106回.Functionプロシージャー|VBA入門
プログラム(マクロVBA)内で特定の処理を実行し値を返すプロシージャーです。これはつまり、Functionプロシージャーで独自の関数をつくれるということです。Subプロシージャーとの違いは、値を返すか返さないかの違いです。
第110回.ユーザー定義型・構造体(Type)|VBA入門
・Typeステートメントの構文 ・ユーザー定義型の使い方 ・ユーザー定義型の使用例 ・ユーザー定義型の制限 ・最後に
第113回.配列に関連する関数|VBA入門
・LBound関数とUBound 関数 ・Array関数 ・IsArray 関数 ・Join関数 ・Filter関数 ・Eraseステートメント
第133回.引数の数を可変にできるパラメーター配列(ParamArray)|VBA入門
・引数の構文 ・名前付き引数について ・ParamArrayキーワード(パラメーター配列)とは ・ParamArrayキーワード(パラメーター配列)の使用例 ・サイト内の関連ページ

Left関数 , LeftB関数
・Left関数 ・LeftB関数 ・Left$関数、LeftB$関数 ・Left関数の使用例
Right関数 , RightB関数
・Right関数 ・RightB関数 ・Right$関数、RightB$関数 ・Right関数の使用例
IsNumeric関数|VBA関数
・IsNumeric関数 ・IsNumeric関数の使用例 ・Is○○関数一覧
IIf関数|VBA関数
・IIf関数 ・IIf関数の注意点 ・IIf関数の使用例



同じテーマ「マクロVBA技術解説」の記事

列幅・行高をDPI取得しピクセルで指定する
VBAでWMIの使い方について
アクティブシート以外のWindowを設定できるWorksheetView
LSetとユーザー定義型のコピー(100桁の足し算)
省略可能なVariant引数の参照不可をラップ関数で利用
ブックのいろいろな開き方(GetObject,参照設定,アドイン)
入力規則への貼り付けを禁止する
Select Caseでの短絡評価(ショートサーキット)の使い方
RangeオブジェクトのFor EachとAreasについて
画像が行列削除についてこない場合の対処
新関数SORTBYをVBAで利用するラップ関数を作成


新着記事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コードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。


このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ