Option Explicit Private Indent As Integer Private Prefix As String Private FH As Object Private FlagNotime As Boolean Private FlagDebugPrint As Boolean Private Declare Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long) Sub DebugPrint(ByVal VarName As Variant, Optional ByVal Filename As String = "Debug.txt", _ Optional ByVal TypeNameFlag As Boolean = False, Optional ByVal IndentCount As Integer = 4, _ Optional NotimeFlag As Boolean = False, Optional DebugPrintFlag As Boolean = False) '必須: 'VarName: データ構造を知りたい変数名を指定 'オプション: 'Indentcount: 配列、コレクション、Dictionaryなどネストして表示されるデータの全角スペースの数 'TypeNameFlag:全ての型を表示したい時にTrue '---------------------------------------------------------------------------------------------- '再帰呼出で、トップの時⇒追記状態でファイルオープンしておく If Indent = 0 Then FlagNotime = NotimeFlag FlagDebugPrint = DebugPrintFlag If Not FlagDebugPrint Then Call FileOpen(Filename) End If Dim i As Long Dim key As Variant If TypeName(VarName) = "Byte" Or TypeName(VarName) = "Integer" Or _ TypeName(VarName) = "Long" Or TypeName(VarName) = "String" Or _ TypeName(VarName) = "Single" Or TypeName(VarName) = "Double" Or _ TypeName(VarName) = "Currency" Or TypeName(VarName) = "Date" Or _ TypeName(VarName) = "Boolean" Or TypeName(VarName) = "Boolean" Then Call Output(TypeName(VarName), IndentCount, TypeNameFlag, VarName) ElseIf TypeName(VarName) = "Empty" Or TypeName(VarName) = "Null" Or _ TypeName(VarName) = "Nothing" Or TypeName(VarName) = "Unknown" Then Call Output(TypeName(VarName), IndentCount, TypeNameFlag) ElseIf 0 < InStr(TypeName(VarName), "()") Then '2次元配列まで対応!3次元以上はNG! Dim temp As Integer, Dimension As Integer On Error Resume Next temp = UBound(VarName, 3) If Err.Number = 0 Then MsgBox "配列は3次元配列以上は未対応です" End End If Err.Clear temp = UBound(VarName, 2) Dimension = IIf(Err.Number = 0, 2, 1) On Error GoTo 0 Call Output(TypeName(VarName), IndentCount, TypeNameFlag) '1次元配列か2次元配列かで処理を分岐 Indent = Indent + 1 If Dimension = 1 Then '1次元配列の処理 For i = 0 To UBound(VarName) Prefix = "(" & i & "): " Call DebugPrint(VarName(i), IndentCount, TypeNameFlag) Next ElseIf Dimension = 2 Then '2次元配列の処理 Dim ii As Long For i = 0 To UBound(VarName, 1) For ii = 0 To UBound(VarName, 2) Prefix = "(" & i & "," & ii & "): " Call DebugPrint(VarName(i, ii), IndentCount, TypeNameFlag) Next Next End If Indent = Indent - 1 ElseIf TypeName(VarName) = "Collection" Then Call Output(TypeName(VarName), IndentCount, TypeNameFlag) Indent = Indent + 1 For i = 1 To VarName.Count Prefix = i & ":" Call DebugPrint(VarName.Item(i), IndentCount, TypeNameFlag) Next Indent = Indent - 1 ElseIf TypeName(VarName) = "Dictionary" Then Call Output(TypeName(VarName), IndentCount, TypeNameFlag) Indent = Indent + 1 For Each key In VarName Prefix = "[" & TypeName(key) & "]" & key & " => " Call DebugPrint(VarName.Item(key), IndentCount, TypeNameFlag) Next Indent = Indent - 1 End If '再帰呼出で、トップの時⇒追記状態でファイルオープンしておく If Indent = 0 And Not FlagDebugPrint Then Call FileClose End Sub Sub Output(ByVal TypeVarName As String, ByVal IndentCount As Integer, ByVal TypeNameFlag As Boolean, Optional ByVal VarName As Variant = "") If IndentCount < 0 Then IndentCount = 0 Dim OutPutData As String If TypeNameFlag Then OutPutData = String(Indent * IndentCount, " ") & Prefix & "[" & TypeVarName & "]" & VarName & vbCrLf If FlagDebugPrint Then Debug.Print Replace(OutPutData, vbCrLf, "") '改行ははずす Else FH.Write OutPutData End If Else If 0 < InStrRev(Prefix, "]") Then Prefix = Right(Prefix, Len(Prefix) - InStrRev(Prefix, "]")) End If If 0 < InStr(TypeVarName, "()") Or TypeVarName = "Collection" Or TypeVarName = "Dictionary" Then OutPutData = String(Indent * IndentCount, " ") & Prefix & "[" & TypeVarName & "]" & VarName & vbCrLf If FlagDebugPrint Then Debug.Print Replace(OutPutData, vbCrLf, "") '改行ははずす Else FH.Write OutPutData End If Else OutPutData = String(Indent * IndentCount, " ") & Prefix & VarName & vbCrLf If FlagDebugPrint Then Debug.Print Replace(OutPutData, vbCrLf, "") '改行ははずす Else FH.Write OutPutData End If End If End If Prefix = "" End Sub Private Sub FileOpen(ByVal Filename As String) '.txtが省略されていたら追加する If 0 = InStr(Filename, ".txt") Then Filename = Filename & ".txt" Dim FSO As Object, FilePath As String Set FSO = CreateObject("Scripting.FileSystemObject") If FlagNotime Then FilePath = ThisWorkbook.Path & "\" & Filename Set FH = FSO.OPenTextFile(FilePath, 2, True) Else FilePath = ThisWorkbook.Path & "\(" & Replace(Time, ":", "") & ")" & Filename Set FH = FSO.OPenTextFile(FilePath, 8, True) End If Set FSO = Nothing End Sub Private Sub FileClose() FH.Close Set FH = Nothing Sleep (1000) '同名ファイルに出力されるのを避けるため、1秒時間をおいている End Sub '■SampleCode Private Sub SampleCode1() 'Dummyデータ Dim varString As String: varString = "文字列" Dim varInteger As Integer: varInteger = 3 Dim varLong As Long: varLong = 3 Dim varDouble As Double: varDouble = 3.5 Dim varBoolean As Boolean: varBoolean = True '■配列データの出力を行います Dim varArray(2) As Variant varArray(0) = varString varArray(1) = varInteger varArray(2) = varBoolean '※引数にデータ構造を見たい変数名を指定します '実行Excelファイルと同階層に (時間)Debug.txt として出力されます Call DebugPrint(varArray) '----------------------------- '[Variant()] ' (0): 文字列 ' (1): 3 ' (2): True '----------------------------- End Sub Private Sub SampleCode2() 'Dummyデータ Dim varString As String: varString = "文字列" Dim varInteger As Integer: varInteger = 3 Dim varLong As Long: varLong = 3 Dim varDouble As Double: varDouble = 3.5 Dim varBoolean As Boolean: varBoolean = True Dim varArray(2) As Variant varArray(0) = varString varArray(1) = varInteger varArray(2) = varBoolean '■Dictionaryの出力を行います Dim varDic As Object Set varDic = CreateObject("Scripting.Dictionary") varDic.Add "配列1", varArray varDic.Add "配列2", Array("a", "b", "c") '※引数にデータ構造を見たい変数名を指定します '実行Excelファイルと同階層に (時間)Debug.txt として出力されます Call DebugPrint(varDic) '----------------------------- '※ファイルの出力結果 '[Dictionary] '配列1 => [Variant()] ' (0): 文字列 ' (1): 3 ' (2): True '配列2 => [Variant()] ' (0): a ' (1): b ' (2): c '----------------------------- '対応している変数形式は 'String/Integer/Long/Single/Double/Currency/Date/Boolean/Byte/Variant '上記を用いた、Collection/Dictionary/配列(2次元配列まで) End Sub Private Sub SampleCode3() 'Dummyデータ Dim varString As String: varString = "文字列" Dim varInteger As Integer: varInteger = 3 Dim varLong As Long: varLong = 3 Dim varDouble As Double: varDouble = 3.5 Dim varBoolean As Boolean: varBoolean = True Dim varArray(2) As Variant varArray(0) = varString varArray(1) = varInteger varArray(2) = varBoolean Dim varDic As Object Set varDic = CreateObject("Scripting.Dictionary") varDic.Add "配列1", varArray varDic.Add "配列2", Array("a", "b", "c") 'Q And A '■複数出力したとき、何の変数を出力したものか判断がつきにくい! ' なんとかしてほしい ' ⇒Filenameオプションにファイル名を指定してください Call DebugPrint(varArray, Filename:="Array.txt") Call DebugPrint(varDic, Filename:="Dictionary") '拡張子は書かなくても自動的.txtになります End Sub Private Sub SampleCode4() 'Dummyデータ Dim varString As String: varString = "文字列" Dim varInteger As Integer: varInteger = 3 Dim varLong As Long: varLong = 3 Dim varDouble As Double: varDouble = 3.5 Dim varBoolean As Boolean: varBoolean = True Dim varArray(2) As Variant varArray(0) = varString varArray(1) = varInteger varArray(2) = varBoolean Dim varDic As Object Set varDic = CreateObject("Scripting.Dictionary") varDic.Add "配列1", varArray varDic.Add "配列2", Array("a", "b", "c") 'Q And A '■複数出力なんてしません!なのでファイル名に時間をつけて複数出力するのはやめてくれますか? ' 何度も何度も消すのがめんどくさい。ゴミ箱がひどいことになる・・・ ' ⇒NotimeFlagオプションをTrueにしてください Call DebugPrint(varDic, Filename:="上書きテスト") Call DebugPrint(varDic, Filename:="上書きテスト") '通常だと(時間)上書きテスト.txt が時間ごとに作られる Call DebugPrint(varDic, Filename:="上書きテスト", NotimeFlag:=True) Call DebugPrint(varDic, Filename:="上書きテスト", NotimeFlag:=True) Call DebugPrint(varDic, Filename:="上書きテスト", NotimeFlag:=True) '上書きテスト.txt が一つだけ作られる(一番最後に実行したものだけが残る) End Sub Private Sub SampleCode5() 'Dummyデータ Dim varString As String: varString = "文字列" Dim varInteger As Integer: varInteger = 3 Dim varLong As Long: varLong = 3 Dim varDouble As Double: varDouble = 3.5 Dim varBoolean As Boolean: varBoolean = True Dim varArray(2) As Variant varArray(0) = varString varArray(1) = varInteger varArray(2) = varBoolean Dim varDic As Object Set varDic = CreateObject("Scripting.Dictionary") varDic.Add "配列1", varArray varDic.Add "配列2", Array("a", "b", "c") 'Q And A '■配列/Collection/Dictionaryでインデントされて出力 ' されますが、あの幅が好みじゃない・・・。 ' ⇒IndentCountオプションを指定してください Call DebugPrint(varDic, IndentCount:=5) '----------------------------- '※ファイルの出力結果 '[Dictionary] ' 配列1 => [Variant()] ' (0): 文字列 ' (1): 3 ' (2): True ' 配列2 => [Variant()] ' (0): a ' (1): b ' (2): c '----------------------------- End Sub Private Sub SampleCode6() 'Dummyデータ Dim varString As String: varString = "文字列" Dim varInteger As Integer: varInteger = 3 Dim varLong As Long: varLong = 3 Dim varDouble As Double: varDouble = 3.5 Dim varBoolean As Boolean: varBoolean = True Dim varArray(2) As Variant varArray(0) = varString varArray(1) = varInteger varArray(2) = varBoolean Dim varDic As Object Set varDic = CreateObject("Scripting.Dictionary") varDic.Add "配列1", varArray varDic.Add "配列2", Array("a", "b", "c") 'Q And A '■データの型式を全てみたいです ' ⇒TypeNameFlagオプションをTrueにしてください Call DebugPrint(varDic, TypeNameFlag:=True) '----------------------------- '※ファイルの出力結果 '[Dictionary] '[String] 配列1 >= [Variant()] ' (0): [String]文字列 ' (1): [Integer]3 ' (2): [Boolean]True '[String] 配列2 >= [Variant()] ' (0): [String]a ' (1): [String]b ' (2): [String]c '----------------------------- End Sub Private Sub SampleCode7() 'Dummyデータ Dim varString As String: varString = "文字列" Dim varInteger As Integer: varInteger = 3 Dim varLong As Long: varLong = 3 Dim varDouble As Double: varDouble = 3.5 Dim varBoolean As Boolean: varBoolean = True Dim varArray(2) As Variant varArray(0) = varString varArray(1) = varInteger varArray(2) = varBoolean Dim varDic As Object Set varDic = CreateObject("Scripting.Dictionary") varDic.Add "配列1", varArray varDic.Add "配列2", Array("a", "b", "c") 'Q And A '■ファイルじゃなくイミディエイトウィンドウにだしてよ ' ⇒DebugPrintFlagをTrueにしてください Call DebugPrint(varDic, DebugPrintFlag:=True) End Sub
Translate
2017年12月19日火曜日
DebugModule.bas
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿