VBA技術解説
VBAにおける変数のメモリアドレスについて

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
公開日:2019-11-08 最終更新日:2021-02-02

VBAにおける変数のメモリアドレスについて


VBA開発においてメモリアドレスを気にすることはほとんど無いと思います。
気になる場合があるとしたら、
・String変数の処理が遅い
・Variant変数の処理が遅い
・ByRef,ByValの違い
・WindowsAPI使用時
このような場合に多少は気になる事があるくらいではないでしょうか。


メモリアドレスについては、ほとんどの場合多分こんな感じだろうという程度の認識で問題ありませんし、困ることもほとんどないでしょう。
普段はほとんど気にすることもないVBAでのメモリアドレスですが、一度くらいは確認しておくことも今後の学習の役に立つのではないでしょうか。

以下の検証は、Windows10+Excel2019(64bit)で行ったものになります。
言うまでもありませんが、メモリアドレスの数値は、たまたまその時に出力された数値になります。

メモリアドレスを取得する関数とメモリコピーのWindowsAPI

VarPtr関数
変数のメモリアドレスを返します。
ObjPtr関数
オブジェクトのメモリアドレスを返します。
StrPtr関数
実際の文字列が入っているメモリアドレスを返します。

・値0の文字列(vbNullString、初期状態)の場合は、0を返します。
・文字列が入っている(長さ0の文字列("")も含む)の場合は、文字列情報のメモリアドレス値を返します。

この実際の文字列が入っているメモリアドレスは、変数の文字列を変更する度に別のメモリアドレスが割り当てられます。
RtlMoveMemory WindowsAPI
ソースメモリブロックの内容を宛先メモリブロックにコピーします。

Declare PtrSafe Sub RtlMoveMemory Lib "kernel32.dll" _
(ByVal Destination As Any, ByVal Source As Any, ByVal Length As LongPtr)


Call RtlMoveMemory(Destination, Sourcer, Length)

Destination
コピー先のメモリブロックへのポインタ。
Sourcer
コピー元のソースメモリブロックへのポインタ。
Length
コピー元からコピー先にコピーするバイト数。

メモリアドレスを確認するために使用したVBA

Option Explicit

Declare PtrSafe Sub RtlMoveMemory Lib "kernel32.dll" _
  (ByVal Destination As Any, ByVal Source As Any, ByVal Length As LongPtr)

Function dumpMemory(ByVal addr As LongPtr, _
          ByVal size As Long, _
          Optional ByVal opt As String) As LongPtr
  If addr <= 0 Or size <= 0 Then
    Debug.Print addr & " :"
    Exit Function
  End If
  
  ReDim bData(1 To size) As Byte
  Call RtlMoveMemory(VarPtr(bData(1)), addr, size)
  
  Dim i As Long
  Dim pStr As String, tStr As String
  Dim hVal As String, dVal As LongPtr, bVal As String
  pStr = addr & " :"
  For i = 1 To size
    hVal = Right("0" & Hex$(bData(i)), 2)
    pStr = pStr & " " & hVal
    bVal = hex2bin(hVal) & bVal
    If size <= 8 Then dVal = dVal + hex2dec(hVal, i)
  Next i
  Select Case LCase(opt)
    Case "str"
      tStr = bData
      pStr = pStr & " ⇒ " & CStr(bData)
    Case "dec"
      pStr = pStr & " ⇒ " & dVal
    Case "bin"
      pStr = pStr & " ⇒ " & bVal
  End Select
  Debug.Print pStr
  dumpMemory = dVal
End Function

Function hex2dec(hVal As String, Optional ByVal pos As LongPtr = 0) As LongPtr
  hex2dec = CLngPtr("&H" & hVal) * (256 ^ (pos - 1))
End Function

Function hex2bin(hVal As String) As String
  Dim dVal As LongPtr
  dVal = CLng("&H" & hVal)
  Dim power2 As LongPtr: power2 = 1
  Do Until dVal < power2
    If (dVal And power2) <> 0 Then
      hex2bin = "1" & hex2bin
    Else
      hex2bin = "0" & hex2bin
    End If
    power2 = power2 * 2
  Loop
  hex2bin = Right("00000000" & hex2bin, 8)
End Function

API(RtlMoveMemory)の使い方については、WEBに多数出ています。
筆者も普段のVBAで使う事はありませんので、改めてWEB検索して動作確認したものになります。
出力するためのアドレス数値の編集については、
今回の検証の都合で作成したものであり、一般的なメモリダンプ形式とは全く別のものです。

これ以降の検証VBAでは、
dumpMemory
これを使って、メモリアドレスをイミディエイト ウインドウに出力しています。

Functionとしてメモリアドレスの内容を戻していますが、以下の検証では使用していません。
何かの折に使うかもしれないと思い入れておいただけのものになります。

文字列型Stringのメモリアドレス

Sub dumpString()
  Dim v As String
  Debug.Print "VarPtr : " & VarPtr(v)
  Debug.Print "StrPtr : " & StrPtr(v)
  Call dumpMemory(VarPtr(v), 8, "dec")
  v = "1あA"
  Debug.Print "Let : " & v
  Debug.Print "VarPtr : " & VarPtr(v)
  Debug.Print "StrPtr : " & StrPtr(v)
  Call dumpMemory(VarPtr(v), 8, "dec")
  Call dumpMemory(StrPtr(v) - 4, 4, "dec") '文字列長は-4位置
  Call dumpMemory(StrPtr(v), LenB(v), "str") '実際の文字列
  Call dumpMemory(StrPtr(v) + LenB(v), 2) '終端2バイト
  v = "1あA"
  Debug.Print "Let : " & v
  Debug.Print "VarPtr : " & VarPtr(v)
  Debug.Print "StrPtr : " & StrPtr(v)
  Call dumpMemory(VarPtr(v), 8, "dec")
  Call dumpMemory(StrPtr(v) - 4, 4, "dec") '文字列長は-4位置
  Call dumpMemory(StrPtr(v), LenB(v), "str") '実際の文字列
  Call dumpMemory(StrPtr(v) + LenB(v), 2) '終端2バイト
End Sub

実行結果は、イミディエイト ウインドウに、以下のように出力されます。

VarPtr : 2550268246000
StrPtr : 0
2550268246000 : 00 00 00 00 00 00 00 00 ⇒ 0
Let : 1あA
VarPtr : 2550268246000
StrPtr : 2550343459896
2550268246000 : 38 E4 50 CC 51 02 00 00 ⇒ 2550343459896
2550343459892 : 06 00 00 00 ⇒ 6
2550343459896 : 31 00 42 30 41 00 ⇒ 1あA
2550343459902 : 00 00
Let : 1あA
VarPtr : 2550268246000
StrPtr : 2550347482728
2550268246000 : 68 46 8E CC 51 02 00 00 ⇒ 2550347482728
2550347482724 : 06 00 00 00 ⇒ 6
2550347482728 : 31 00 42 30 41 00 ⇒ 1あA
2550347482734 : 00 00

String変数宣言時には、変数は値0の文字列(vbNullString)になっています。
空文字列の扱い方と処理速度について("";とvbNullString)
・String型変数のメモリ配置と取得する関数 ・空文字列について ・String変数に空文字列を入れる ・セルに空文字列を入れる ・Stringが空文字列か判定 ・InputBox関数の戻り値が空文字列判定 ・空文字列の処理方法による速度比較
変数のアドレス(VerPtr)のメモリには実際の文字列のあるアドレスが入っています。
実際の文字列のあるアドレスの直前には、文字列長のバイト数(Unicodeなので半角も2バイト)が入っています。
直後は終端として0x00(&H00)があります。
上の結果と、下の図を見比べて確認してみてください。

String型変数のメモリアドレス
String型変数のメモリアドレスに直接文字が入っているわけではありません。
String型変数のアドレスには、実際に文字列が置かれているメモリのアドレスが入っています。
実際に文字列が置かれているメモリアドレスの直前には、文字列長部分があります。

VBA マクロ String vbNullstring メモリ

変数のメモリアドレスを取得する関数がVarPtr関数
実際に文字列が入っているメモリアドレスを取得する関数がStrPtr関数です。

Integer, Long, Single, Double, Dateのメモリアドレス

正数型Integerのメモリアドレス

Sub dumpInteger()
  Dim v As Integer
  Debug.Print "VarPtr : " & VarPtr(v)
  v = 1234: Debug.Print "Let : " & v
  Call dumpMemory(VarPtr(v), LenB(v), "dec") '2バイト
End Sub

VarPtr : 2550268246000
Let : 1234
2550268246000 : D2 04 ⇒ 1234

変数のアドレスに直接数値が入っています。

VBAの
bVal = hex2bin(hVal) & bVal
この部分をみてもらうと分かるのですが、順番が逆になります。
D2 04
→04 D2 ・・・ 16進
→00000100 11010010 ・・・ 2進
→4*256+210=1234 ・・・ 10進

長整数型Longのメモリアドレス

Sub dumpLong()
  Dim v As Long
  Debug.Print "VarPtr : " & VarPtr(v)
  v = 12345678: Debug.Print "Let : " & v
  Call dumpMemory(VarPtr(v), LenB(v), "dec") '4バイト
End Sub

VarPtr : 2550268246000
Let : 12345678
2550268246000 : 4E 61 BC 00 ⇒ 12345678

変数のアドレスに直接数値が入っています。

16進→10進は、Integerと同様です。

単精度浮動小数点数型Singleのメモリアドレス

Sub dumpSingle()
  Dim v As Single
  Debug.Print "VarPtr : " & VarPtr(v)
  v = 0.15625: Debug.Print "Let : " & v
  Call dumpMemory(VarPtr(v), LenB(v), "bin") '符号1+指数8+仮数23
End Sub

VarPtr : 2340742441072
Let : 0.15625
2340742441072 : 00 00 20 3E ⇒ 00111110001000000000000000000000

変数のアドレスに直接数値が入っています。
浮動小数点数の2進数は難しいので、見た目では正しいか分かりませんし、自力変換も書いてられません。
ですが、ビットを見る限り、ちゃんと単精度浮動小数点数として入っているようです。
上の結果は、浮動小数点数に出ている画像のビットと一致しています。
浮動小数点数:符号1+指数8+仮数2

倍精度浮動小数点数型Doubleのメモリアドレス

Sub dumpDouble()
  Dim v As Double
  Debug.Print "VarPtr : " & VarPtr(v)
  v = 1234.5678: Debug.Print "Let : " & v
  Call dumpMemory(VarPtr(v), LenB(v), "bin") '符号1+指数11+仮数52
End Sub

VarPtr : 2550268246000
Let : 1234.5678
2550268246000 : AD FA 5C 6D 45 4A 93 40 ⇒ 0100000010010011010010100100010101101101010111001111101010101101

変数のアドレスに倍精度浮動小数点数として数値が入っています。
倍精度浮動小数点数:符号1+指数11+仮数52

日付Dateのメモリアドレス

Sub dumpDate()
  Dim v As Date
  Debug.Print "VarPtr : " & VarPtr(v)
  v = 1234.5678: Debug.Print "Let : " & v
  Call dumpMemory(VarPtr(v), LenB(v)) '8バイト
End Sub

VarPtr : 2550268246000
Let : 1903/05/18 13:37:38
2550268246000 : AD FA 5C 6D 45 4A 93 40

上のDoubleと比較すると、同じ状態で入っていることが分かります。
つまり、Date型はDouble型と同じだという事が解ります。
日付は、整数部が日、小数部が時分秒

Variantのメモリアドレス

Sub dumpVariant()
  Dim v
  Debug.Print "VarPtr : " & VarPtr(v)
  
  Debug.Print "文字列"
  v = "2いB": Debug.Print "Let : " & v
  Debug.Print "StrPtr : " & StrPtr(v)
  Call dumpMemory(VarPtr(v), 8, "dec") 'データ型
  Call dumpMemory(VarPtr(v) + 8, 8, "dec") 'StrPtrのアドレスがここ
  Call dumpMemory(StrPtr(v), LenB(v), "str") '実際の文字列
  Call dumpMemory(StrPtr(v) + LenB(v), 2) '終端2バイト
  
  Debug.Print "長整数"
  v = CLng(12345678): Debug.Print "Let : " & v
  Debug.Print "StrPtr : " & StrPtr(v)
  Call dumpMemory(VarPtr(v), 8, "dec") 'データ型
  Call dumpMemory(VarPtr(v) + 8, 4, "dec") '実際の数値
  Call dumpMemory(StrPtr(v), LenB(v), "str") '数値が文字列で
  
  Debug.Print "倍精度小数点"
  v = CDbl(1234.5678): Debug.Print "Let : " & v
  Debug.Print "StrPtr : " & StrPtr(v)
  Call dumpMemory(VarPtr(v), 8, "dec") 'データ型
  Call dumpMemory(VarPtr(v) + 8, 8, "bin") '実際の数値
  Call dumpMemory(StrPtr(v), LenB(v), "str") '数値が文字列で
End Sub

VarPtr : 2550268245984
文字列
Let : 2いB
StrPtr : 2550346748760
2550268245984 : 08 00 00 00 00 00 00 00 ⇒ 8
2550268245992 : 58 13 83 CC 51 02 00 00 ⇒ 2550346748760
2550346748760 : 32 00 44 30 42 00 ⇒ 2いB
2550346748766 : 00 00
長整数
Let : 12345678
StrPtr : 2550270415048
2550268245984 : 03 00 00 00 00 00 00 00 ⇒ 3
2550268245992 : 4E 61 BC 00 ⇒ 12345678
2550270414664 : 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 ⇒ 12345678
倍精度小数点
Let : 1234.5678
StrPtr : 2550346750488
2550268245984 : 05 00 00 00 00 00 00 00 ⇒ 5
2550268245992 : AD FA 5C 6D 45 4A 93 40 ⇒ 0100000010010011010010100100010101101101010111001111101010101101
2550270414616 : 31 00 32 00 33 00 34 00 2E 00 35 00 36 00 37 00 38 00 ⇒ 1234.5678

Variantなのでもっと多くのデータ型がありますが、ここでは代表的なString, Long, Doubleで確認しています。
この結果を見ると、変数のアドレス位置にはデータ型を区別する数値が入っています。。
Integer:2
Long:3
Single:4
Double5
Currency:6
Date:7
String:8
Object:9
Boolean:11
Byte:17
さらにいろいろな型が想定されています。
Twitterで情報をもらいました。
詳しくは、C++のVariant.VariantType Enumこちらの列挙の数値になります。

Variant/Stringは、String型と同じように入っています。
注目すべきは数値の時でしょう。
StrPtrで取得されるメモリアドレスには、文字列として数値が格納されているようです。
この文字列は、VBAではCStr関数で変換したり、変数をイミディエイト等で表示した時の文字列と同様のようです。
実際にここの値がどのようなときに使われるかは不明ですが、Variant変数がかなり色々な事をしているという事だけは分かります。

配列のメモリアドレス

1次元配列のメモリアドレス

Sub dumpArray()
  Dim v(2) As Long
  v(0) = 1: v(1) = 2: v(2) = 3
  Debug.Print "VarPtr(0) : " & VarPtr(v(0))
  Debug.Print "VarPtr(1) : " & VarPtr(v(1))
  Debug.Print "VarPtr(2) : " & VarPtr(v(2))
  Call dumpMemory(VarPtr(v(0)), LenB(v(0)), "dec")
  Call dumpMemory(VarPtr(v(1)), LenB(v(1)), "dec")
  Call dumpMemory(VarPtr(v(2)), LenB(v(2)), "dec")
End Sub

VarPtr(0) : 2550347791088
VarPtr(1) : 2550347791092
VarPtr(2) : 2550347791096
2550347791088 : 01 00 00 00 ⇒ 1
2550347791092 : 02 00 00 00 ⇒ 2
2550347791096 : 03 00 00 00 ⇒ 3

メモリアドレスの数値がきれいに順番に並んでいることが確認できます。

2次元配列のメモリアドレス

Sub dumpArray2()
  Dim v(1 To 3, 1 To 3) As Long
  Dim i As Long, j As Long
  For j = 1 To 3
    For i = 1 To 3
      v(i, j) = i & j
    Next
  Next
  
  For j = 1 To 3
    For i = 1 To 3
      Debug.Print "VarPtr(" & i & "," & j & ") : " & VarPtr(v(i, j))
    Next
  Next
  
  For j = 1 To 3
    For i = 1 To 3
      Call dumpMemory(VarPtr(v(i, j)), LenB(v(i, j)), "dec")
    Next
  Next
  
  Dim t
  For Each t In v
    Debug.Print t
  Next
End Sub

VarPtr(1,1) : 1949978142528
VarPtr(2,1) : 1949978142532
VarPtr(3,1) : 1949978142536
VarPtr(1,2) : 1949978142540
VarPtr(2,2) : 1949978142544
VarPtr(3,2) : 1949978142548
VarPtr(1,3) : 1949978142552
VarPtr(2,3) : 1949978142556
VarPtr(3,3) : 1949978142560
1949978142528 : 0B 00 00 00 ⇒ 11
1949978142532 : 15 00 00 00 ⇒ 21
1949978142536 : 1F 00 00 00 ⇒ 31
1949978142540 : 0C 00 00 00 ⇒ 12
1949978142544 : 16 00 00 00 ⇒ 22
1949978142548 : 20 00 00 00 ⇒ 32
1949978142552 : 0D 00 00 00 ⇒ 13
1949978142556 : 17 00 00 00 ⇒ 23
1949978142560 : 21 00 00 00 ⇒ 33
11
21
31
12
22
32
13
23
33

メモリアドレスの数値がきれいに順番に並んでいることが確認できます。
ただし、その配列の順番については気をつけて確認してください。

上位の1次元目(つまり縦・行)が先に推移している点は押さえておいてください。
この順番は、配列をFor Eachで処理した時の順番になります。
これは、RangeをFor Eachで回した場合に横(列)が先に推移することと大きく違う点でもあります。


ここでは分かりやすくLong型を使用しましたが、他の型でも同じです。
他の型、例えばStringの場合は、先のStringと同様に実際の文字列の値があるアドレスが入っています。
配列がメモリ上で連続で配置されていることは、配列を扱う上で必ず知っておいてください。

オブジェクトのメモリアドレス

Sub dumpObject()
  Debug.Print "ワークシート"
  Dim v1 As Worksheet
  Debug.Print "VarPtr : " & VarPtr(v1)
  Debug.Print "ObjPtr : " & ObjPtr(v1)
  Call dumpMemory(VarPtr(v1), 8, "dec") 'ObjPtrのアドレス
  Call dumpMemory(ObjPtr(v1), 8, "dec") 'オブジェクトのアドレス
  Set v1 = Worksheets(1): Debug.Print "Set : " & TypeName(v1)
  Debug.Print "ObjPtr : " & ObjPtr(v1)
  Call dumpMemory(VarPtr(v1), 8, "dec") 'ObjPtrのアドレス
  Call dumpMemory(ObjPtr(v1), 8, "dec") 'オブジェクトのアドレス
  
  Debug.Print "クラス"
  Dim v2 As Class1
  Debug.Print "VarPtr : " & VarPtr(v2)
  Debug.Print "ObjPtr : " & ObjPtr(v2)
  Set v2 = New Class1: Debug.Print "Set : " & TypeName(v2)
  Debug.Print "ObjPtr : " & ObjPtr(v2)
  Call dumpMemory(VarPtr(v2), 8, "dec") 'ObjPtrのアドレス
  Call dumpMemory(ObjPtr(v2), 8, "dec") 'オブジェクトのアドレス
  
  Debug.Print "コレクション"
  Dim v3 As Collection
  Debug.Print "VarPtr : " & VarPtr(v3)
  Debug.Print "ObjPtr : " & ObjPtr(v3)
  Set v3 = New Collection: Debug.Print "Set : " & TypeName(v3)
  Debug.Print "ObjPtr : " & ObjPtr(v3)
  Call dumpMemory(VarPtr(v3), 8, "dec") 'ObjPtrのアドレス
  Call dumpMemory(ObjPtr(v3), 8, "dec") 'オブジェクトのアドレス
  
  Debug.Print "ファイルシステムオブジェクト"
  Dim v4 As Object
  Debug.Print "VarPtr : " & VarPtr(v4)
  Debug.Print "ObjPtr : " & ObjPtr(v4)
  Set v4 = CreateObject("Scripting.FileSystemObject"): Debug.Print "Set : " & TypeName(v4)
  Debug.Print "ObjPtr : " & ObjPtr(v4)
  Call dumpMemory(VarPtr(v4), 8, "dec") 'ObjPtrのアドレス
  Call dumpMemory(ObjPtr(v4), 8, "dec") 'オブジェクトのアドレス
End Sub
※32bitExcelでは、4バイトに変更してください。

ワークシート
VarPtr : 2550268246000
ObjPtr : 0
2550268246000 : 00 00 00 00 00 00 00 00 ⇒ 0
0 :
Set : Worksheet
ObjPtr : 2550270003104
2550268246000 : A0 07 F0 C7 51 02 00 00 ⇒ 2550270003104
2550270003104 : 90 D5 CE C7 51 02 00 00 ⇒ 2550267827600
クラス
VarPtr : 2550268245920
ObjPtr : 0
Set : Class1
ObjPtr : 2550269495504
2550268245920 : D0 48 E8 C7 51 02 00 00 ⇒ 2550269495504
2550269495504 : 48 21 34 CC 51 02 00 00 ⇒ 2550341574984
コレクション
VarPtr : 2550268245912
ObjPtr : 0
Set : Collection
ObjPtr : 2549906117584
2550268245912 : D0 93 3F B2 51 02 00 00 ⇒ 2549906117584
2549906117584 : D8 F7 40 AE FB 7F 00 00 ⇒ 140718937012184
ファイルシステムオブジェクト
VarPtr : 2550268245904
ObjPtr : 0
Set : FileSystemObject
ObjPtr : 2550027026544
2550268245904 : 70 80 74 B9 51 02 00 00 ⇒ 2550027026544
2550027026544 : 90 21 94 EF FB 7F 00 00 ⇒ 140720032981392

VarPtrのなかにはObjPtrのアドレスが入っていて、ObjPtrのなかにオブジェクトのアドレスが入っています。
単純な言い方をすれば、オブジェクト変数にはオブジェクトのメモリアドレスが入っているということです。
オブジェクト変数にSetステートメントでオブジェクトを入れ直した場合、
オブジェクト変数(VarPtr)はそのままで、変数の中に入っているアドレス(ObjPtr)が入れ替わるという事になります。
この構造は、どのようなオブジェクトでも同じです。

VBA マクロ オブジェクト変数 メモリ

確認することとしては、
変数宣言時はアドレスが0、つまり、まだオブジェクトへの参照は存在していないという事です。
実際にオブジェクトをいれた時点やNewした時点で、初めてそのオブジェクトのメモリアドレスが入ります。

そして、これは推測になりますが、
VBAProject内のクラスとそれ以外では、使われるメモリアドレスが完全に違っているようです。
・Worksheet、自作クラスClass1
・Collection、FileSystemObject
これらでメモリアドレスがかなり違う場所であることが分かります。

ByRef,ByValのメモリアドレス

参照渡し:ByRef

Sub dumpByRef()
  Dim i As Long
  i = 123
  Debug.Print "元 : " & VarPtr(i)
  Call dumpByRef_sub(i)
End Sub
Sub dumpByRef_sub(ByRef i As Long)
  Debug.Print "先 : " & VarPtr(i)
End Sub

元 : 2550268246000
先 : 2550268246000

参照渡し(ByRef)では、同じ変数を参照していることが分かります。

値渡し:ByVal

Sub dumpByVal()
  Dim i As Long
  i = 123
  Debug.Print "元 : " & VarPtr(i)
  Call dumpByVal_sub(i)
End Sub
Sub dumpByVal_sub(ByVal i As Long)
  Debug.Print "先 : " & VarPtr(i)
End Sub

元 : 2550268246000
先 : 2550268245968

値渡し(Byval)では、アドレスが違う事が解ります。
変数の値を、いったん別の仮の変数に入れているという事になります。

参照渡し:仮引数がVariantのByRef

Sub dumpByRefVariant()
  Dim i As Long, j As Long
  i = 123: j = 123
  Debug.Print "元i : " & VarPtr(i)
  Debug.Print "元j : " & VarPtr(j)
  Call dumpByRefVariant_sub(i, j)
End Sub
Sub dumpByRefVariant_sub(ByRef i As Long, ByRef j As Variant)
  Debug.Print "先i : " & VarPtr(i)
  Debug.Print "先j : " & VarPtr(j)
End Sub

元i : 2550268246000
元j : 2550268245992
先i : 2550268246000
先j : 2550268245944

参照渡し(ByRef)であっても、受け側の仮変数がVariant型の場合は、いったん別の仮の変数が作成されます。
プロシージャーが終了して呼び出し元に戻るときに、元の変数に値が入れ直されるという事です。
※仮変数がVariant以外で型が違う場合はコンパイルエラーになります。、



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

ユーザー定義型の制限とクラスとの使い分け
シングルクォートの削除とコピー(PrefixCharacter)
空文字列の扱い方と処理速度について(""とvbNullString)
VBAにおける変数のメモリアドレスについて
Evaluateメソッド(文字列の数式を実行します)
Rangeオブジェクトの論理演算(差集合と排他的論理和)
VBAで写真の撮影日時や音楽動画の長さを取得する
VBAでWindowsMediaPlayerを使い動画再生する
VBAでWEBカメラ操作する
VBAで電光掲示板を作成
ユーザーに絶対に停止させたくない場合の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」をお願いいたします。
本文下部へ