VBAにおける変数のメモリアドレスについて
VBA開発においてメモリアドレスを気にすることはほとんど無いと思います。
気になる場合があるとしたら、
・String変数の処理が遅い
・Variant変数の処理が遅い
・ByRef,ByValの違い
・WindowsAPI使用時
このような場合に多少は気になる事があるくらいではないでしょうか。
普段はほとんど気にすることもないVBAでのメモリアドレスですが、一度くらいは確認しておくことも今後の学習の役に立つのではないでしょうか。
言うまでもありませんが、メモリアドレスの数値は、たまたまその時に出力された数値になります。
メモリアドレスを取得する関数とメモリコピーのWindowsAPI
・文字列が入っている(長さ0の文字列("")も含む)の場合は、文字列情報のメモリアドレス値を返します。
(ByVal Destination As Any, ByVal Source As Any, ByVal Length As LongPtr)
メモリアドレスを確認するために使用した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検索して動作確認したものになります。
出力するためのアドレス数値の編集については、
今回の検証の都合で作成したものであり、一般的なメモリダンプ形式とは全く別のものです。
dumpMemory
これを使って、メモリアドレスをイミディエイト ウインドウに出力しています。
何かの折に使うかもしれないと思い入れておいただけのものになります。
文字列型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)になっています。
実際の文字列のあるアドレスの直前には、文字列長のバイト数(Unicodeなので半角も2バイト)が入っています。
直後は終端として0x00(&H00)があります。
上の結果と、下の図を見比べて確認してみてください。
String型変数のアドレスには、実際に文字列が置かれているメモリのアドレスが入っています。
実際に文字列が置かれているメモリアドレスの直前には、文字列長部分があります。
実際に文字列が入っているメモリアドレスを取得する関数が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
変数のアドレスに直接数値が入っています。
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
変数のアドレスに直接数値が入っています。
単精度浮動小数点数型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
さらにいろいろな型が想定されています。
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
メモリアドレスの数値がきれいに順番に並んでいることが確認できます。
ただし、その配列の順番については気をつけて確認してください。
この順番は、配列を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
ワークシート
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)が入れ替わるという事になります。
この構造は、どのようなオブジェクトでも同じです。
変数宣言時はアドレスが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入門
- ホーム
- マクロVBA応用編
- マクロVBA技術解説
- VBAにおける変数のメモリアドレスについて
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。