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
xmlObj.cls
Option Explicit Dim xmlObj As Object Dim xmlAttr As Object Dim xmlNode As Object Dim xmlString As String Private Sub Class_Initialize() Set xmlObj = CreateObject("MSXML2.DOMDocument") xmlObj.async = False xmlObj.setProperty "SelectionLanguage", "XPath" xmlObj.appendChild xmlObj.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'") End Sub Private Sub Class_Terminate() Set xmlObj = Nothing End Sub Public Sub XMLin(ByVal data As Variant) If TypeName(data) = "String" Then Call FileLoad(data) ElseIf TypeName(data) = "Dictionary" Then Call judgeTypeName(data) Else Call Die("XMLinメソッドは、String型またはDictionary型のみを取ることができます" & vbCrLf & _ "引数の型:" & TypeName(data)) End If End Sub Public Sub XMLout(ByVal FilePath As String) xmlObj.Save FilePath End Sub Public Function XPath(ByVal strXPath As String) 'xmlの文字列をロードする xmlObj.loadXML xmlString Set XPath = xmlObj.documentElement.selectNodes(strXPath) End Function Private Sub FileLoad(ByVal FilePath As Variant) Dim FH As Object Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") xmlString = "" If Not FSO.FileExists(FilePath) Then Call Die("FileLoadメソッド:ファイルは存在しません" & vbCrLf & "FilePath:" & FilePath) Set FH = FSO.OPenTextFile(FilePath, 1) Do While Not FH.AtEndOfStream xmlString = xmlString & FH.ReadLine Loop FH.Close Set FH = Nothing Set FSO = Nothing End Sub Private Sub judgeTypeName(ByRef data As Variant) Dim counter As Long Dim key As Variant 'キーに属性を含んでいる場合を高所して先に属性の登録を行う Call AddAttributeNode(data) For Each key In data counter = counter + 1 If AddXmlNode(key) Then GoTo NextForLoop If TypeName(key) = "Dictionary" Then Call judgeTypeName(key) If counter = data.Count Then _ Set xmlNode = xmlNode.parentNode ElseIf TypeName(data(key)) = "Collection" Then Call judgeTypeName(data(key)) ElseIf TypeName(data(key)) = "Dictionary" Then Call judgeTypeName(data(key)) If counter = data.Count Then _ Set xmlNode = xmlNode.parentNode ElseIf TypeName(data(key)) = "String" Then Call AddChildText(data(key)) Else Call Die("judgeTypeNameメソッドエラー:") Debug.Print "" End If NextForLoop: Next End Sub Private Sub AddChildText(ByVal ChildText As String) '子要素にテキストを追加 Set xmlNode = xmlNode.appendChild(xmlObj.createTextNode(ChildText)) Set xmlNode = xmlNode.parentNode Set xmlNode = xmlNode.parentNode End Sub Private Sub AddAttributeNode(ByRef data As Variant) Dim key As Variant '子要素をぶら下げた後に属性処理をすると意図したところと違うところに属性がつくので '最初にキーを走査して属性を探しあれば親要素に属性を追加する For Each key In data If TypeName(key) <> "String" Then GoTo NextForEach If key = "@" Then Call Die("AddAttributeNodeメソッドエラー:属性名がありません") ElseIf Left(key, 1) = "@" Then Set xmlAttr = xmlNode.Attributes.setNamedItem(xmlObj.createAttribute(Mid(key, 2, Len(key)))) xmlAttr.nodeValue = data(key) End If NextForEach: Next End Sub Private Function AddXmlNode(ByRef key As Variant) If TypeName(key) <> "String" Then Exit Function ElseIf key = "" Then Exit Function End If 'キーを処理する If xmlNode Is Nothing Then 'Nothingの時は初なのでルートとして指定 Set xmlNode = xmlObj.appendChild(xmlObj.CreateElement(key)) Else '親要素以外の処理 If Left(key, 1) <> "@" Then '@で始まらない時は、子要素として登録。 False(0)を返す Set xmlNode = xmlNode.appendChild(xmlObj.CreateElement(key)) AddXmlNode = 0 Else '@で始まる時は、True(1)を返す AddXmlNode = 1 End If End If End Function Private Sub Die(ByVal msg As String) MsgBox "下記理由により終了します" & vbCrLf & _ msg End End Sub
Logger
Option Explicit Dim data() As String Dim DataCellObj As Object Dim DataSheetObj As Object Dim x As Long Dim y As Long Dim DelColumn As Long Dim FlagTransposeError As Boolean 'Setter/Getter Public Property Let DeleteColumn(ByVal Num As Long) DelColumn = Num End Property Public Property Get DeleteColumn() As Long DeleteColumn = DelColumn End Property Private Sub Class_Initialize() '初期化 x = -1 y = -1 End Sub Public Sub BorderLine(Optional ByVal Sht As Worksheet, Optional ByVal Cell As String, _ Optional ByVal LineStyle As Integer = xlContinuous, _ Optional Weight As Integer = xlThin, _ Optional ColorIndex As Integer = xlAutomatic) Dim BaseRow As Long Dim BaseCol As Long Dim RangeObj As Object If Not Sht Is Nothing Then Set DataSheetObj = Sht If DataCellObj Is Nothing Then Call Die("Sheetobjが設定されていません") If Cell <> "" Then Set DataCellObj = DataSheetObj.Range(Cell) If DataCellObj Is Nothing Then Call Die("開始のセル情報がありません") '初期値のままだと出力できないので終了する If y < 0 Then Exit Sub BaseRow = DataCellObj.Row BaseCol = DataCellObj.Column Set RangeObj = DataSheetObj.Range(DataSheetObj.Cells(BaseRow, BaseCol), DataSheetObj.Cells(BaseRow + y, BaseCol + x)) RangeObj.Borders(xlEdgeLeft).LineStyle = LineStyle RangeObj.Borders(xlEdgeLeft).Weight = Weight RangeObj.Borders(xlEdgeLeft).ColorIndex = ColorIndex RangeObj.Borders(xlEdgeTop).LineStyle = LineStyle RangeObj.Borders(xlEdgeTop).Weight = Weight RangeObj.Borders(xlEdgeTop).ColorIndex = ColorIndex RangeObj.Borders(xlEdgeBottom).LineStyle = LineStyle RangeObj.Borders(xlEdgeBottom).Weight = Weight RangeObj.Borders(xlEdgeBottom).ColorIndex = ColorIndex RangeObj.Borders(xlEdgeRight).LineStyle = LineStyle RangeObj.Borders(xlEdgeRight).Weight = Weight RangeObj.Borders(xlEdgeRight).ColorIndex = ColorIndex If 0 < x Then RangeObj.Borders(xlInsideVertical).LineStyle = LineStyle RangeObj.Borders(xlInsideVertical).Weight = Weight RangeObj.Borders(xlInsideVertical).ColorIndex = ColorIndex End If If 0 < y Then RangeObj.Borders(xlInsideHorizontal).LineStyle = LineStyle RangeObj.Borders(xlInsideHorizontal).Weight = Weight RangeObj.Borders(xlInsideHorizontal).ColorIndex = ColorIndex End If End Sub Public Function Count() If x = -1 And y = -1 Then Count = 0 Else '要素数を返す Count = UBound(data, 2) + 1 End If End Function Public Function Item(ByVal a As Long, ByVal B As Long, Optional ByVal Str As Variant) '引数なし If IsMissing(Str) Then Item = data(a, B) '引数あり Else data(a, B) = Str End If End Function Public Function Join(ByVal Ele02 As Long, ByVal delimiter As String) Dim i As Long Dim temp As String For i = 0 To UBound(data, 1) temp = temp & data(i, Ele02) & IIf(i = UBound(data, 1), "", delimiter) Next Join = temp End Function Public Function Last() '最終要素を返す Last = UBound(data, 2) End Function Private Function TransposeData() Dim S As Long Dim t As Long Dim TPData() As String ReDim TPData(y, x) For S = 0 To y For t = 0 To x TPData(S, t) = data(t, S) Next Next TransposeData = TPData End Function Public Function Value() As String() '2次元配列自体を返す Value = data() End Function Public Sub Add(ByRef list As Variant) Dim i As Long '1次元の要素数が確定していない時、要素数の調査をおこなう If x = -1 Then If TypeName(list) = "Variant()" Or TypeName(list) = "String()" Then x = UBound(list) Else x = 0 End If End If '要素数の再定義 y = y + 1 ReDim Preserve data(x, y) If TypeName(list) = "Variant()" Or TypeName(list) = "String()" Then For i = 0 To x '要素数が足りないときは、空文字を指定 On Error Resume Next data(i, y) = list(i) 'Transpose関数は255文字を越えたデータを受け取るとエラーとなるので判定する If 255 < Len(list(i)) Then FlagTransposeError = True On Error GoTo 0 Next Else data(x, y) = list 'Transpose関数は255文字を越えたデータを受け取るとエラーとなるので判定する If 255 < Len(list) Then FlagTransposeError = True End If End Sub Public Sub Clear() '初期化 Erase data DelColumn = -1 x = -1 y = -1 FlagTransposeError = False End Sub Private Sub Die(ByVal msg As String) MsgBox "下記理由により終了します" & vbCrLf & msg End End Sub Public Function Output(ByVal Sht As Worksheet, ByVal Cell As String, Optional ByVal KeyIndexNumber As Long = -1) Dim BaseRow As Long Dim BaseCol As Long 'JuuFukuチェック用の引数が指定されていたらチェックする If -1 < KeyIndexNumber Then Call OverLapCheck(KeyIndexNumber) End If BaseRow = Sht.Range(Cell).Row BaseCol = Sht.Range(Cell).Column 'DelColumnが1以上でセットされている時該当列をクリアする If 0 < DelColumn Then Sht.Range(Sht.Cells(BaseRow, BaseCol), Sht.Cells(65536, BaseCol + DelColumn)).ClearContents End If '初期値のままだと出力できないので終了する If y < 0 Then Exit Function If FlagTransposeError Then Sht.Range(Sht.Cells(BaseRow, BaseCol), Sht.Cells(BaseRow + y, BaseCol + x)) = TransposeData() Else Sht.Range(Sht.Cells(BaseRow, BaseCol), Sht.Cells(BaseRow + y, BaseCol + x)) = WorksheetFunction.Transpose(data) End If Set DataCellObj = Sht.Range(Cell) Set DataSheetObj = Sht Set Output = Me End Function Public Sub Sort(Optional ByVal Element As Variant) Dim i As Long '■引数エラーチェック If VarType(Element) = vbError Then '引数が設定されていないと VarTypeでErrorとなるのでチェックする '引数が設定されていない時は、最初の要素についてSortする Element = Array(0) ElseIf IsNumeric(Element) Then '数字の時、整数値か確認。0以上か確認。 If CLng(Element) <> Element Or Element < 0 Then Call Die("Sort関数の引数には、0以上の整数を指定してください") Else Element = Array(CLng(Element)) End If ElseIf Not IsArray(Element) Then Call Die("Sortメソッドの引数は、配列を指定してください") End If '引数がセットされていた時、それらはすべて整数で要素数の範囲内かどうかチェックする For i = UBound(Element) To 0 Step -1 Call BubbleSort(Element(i)) Next End Sub Private Sub BubbleSort(ByVal Element As Long) Dim ChangeData As String Dim DataA As String Dim DataB As String Dim FlagChange As String Dim i As Long Dim ii As Long 'データがない時ソートができないので終了する If Count = 0 Then Exit Sub Do FlagChange = False For i = 0 To UBound(data, 2) - 1 DataA = data(Element, i) DataB = data(Element, i + 1) If DataB < DataA Then FlagChange = True For ii = 0 To UBound(data, 1) ChangeData = data(ii, i) data(ii, i) = data(ii, i + 1) data(ii, i + 1) = ChangeData Next End If Next If FlagChange = False Then Exit Do Loop End Sub Private Sub OverLapCheck(ByVal KeyIndexNumber As Long) Dim HashOverLap As Object Dim key As String Dim i As Long Dim ii As Long Dim temp() As String '** Objectの生成 ** Set HashOverLap = CreateObject("Scripting.Dictionary") 'そもそも二次元配列が空の時はループを抜ける If y = -1 Then Exit Sub y = -1 'JuuFukuCheckする For i = 0 To UBound(data, 2) key = data(KeyIndexNumber, i) If Not HashOverLap.Exists(key) Then HashOverLap.Add key, "" y = y + 1 ReDim Preserve temp(UBound(data, 1), y) For ii = 0 To UBound(data, 1) temp(ii, y) = data(ii, i) Next End If Next 'Temp内は重複がチェックされたもの。 'Dataの内容を書き換える ReDim data(UBound(temp, 1), UBound(temp, 2)) data = temp Set HashOverLap = Nothing End Sub
2017年11月4日土曜日
scanf で charを受け取る
char以外の文字を受け取りその後charを受け取る場合
以下のように書くと期待しない動きになる
scanfは、3回登場するが、入力は10とaの2回
最初の変数に10が代入。
改行はストリームに残っているので、char変数にaに代入される。
その後、改めて入力したaがchar変数bに代入される。
一度入力した後にcharに代入する場合、改行を毎回捨てる必要がある
①getchar()で読み捨てる
②書式文字列に半角スペースを先頭につけ、最初の改行を読み捨てる
③書式文字列に代入不可(*)を指定して読み飛ばす
以下のように書くと期待しない動きになる
#includeint main() { int n; char a; char b; scanf("%d", &n); scanf("%c", &a); scanf("%c", &b); return 0; }
scanfは、3回登場するが、入力は10とaの2回
10 a
最初の変数に10が代入。
改行はストリームに残っているので、char変数にaに代入される。
その後、改めて入力したaがchar変数bに代入される。
一度入力した後にcharに代入する場合、改行を毎回捨てる必要がある
①getchar()で読み捨てる
#includeint main() { int n; char a; char b; scanf("%d", &n); (void)getchar(); scanf("%c", &a); (void)getchar(); scanf("%c", &b); return 0; }
②書式文字列に半角スペースを先頭につけ、最初の改行を読み捨てる
#includeint main() { int n; char a; char b; scanf("%d", &n); scanf(" %c", &a); scanf(" %c", &b); return 0; }
③書式文字列に代入不可(*)を指定して読み飛ばす
#includeint main() { int n; char a; char b; scanf("%d", &n); scanf("%*c%c", &a); scanf("%*c%c", &b); return 0; }
2017年10月22日日曜日
NULL
NULLは void型 で値は0
NULLをintに変換すれば0と一緒
0を(void*)として変換すればNULLと一緒
NULLをintに変換すれば0と一緒
#includeint main(){ if((int)NULL == 0){ printf("0です\n"); }else{ printf("0じゃないです\n"); } return 0; }
0を(void*)として変換すればNULLと一緒
#includeint main(){ if(NULL == (void*)0){ printf("0です\n"); }else{ printf("0じゃないです\n"); } return 0; }
2017年8月13日日曜日
typescriptコンパイル結果
案件でTypeScriptが使えなかった時に備え何が何に変換されるかメモ
■class
.ts
.js
■コンストラクタ
.ts
.js
■インスタンス変数(public)
.ts
.js
■インスタンス変数(private)
コンパイラ時チェックのみ
■Getter/Setter
.ts
.js
■staticメソッド、変数
.ts
.js
■class
.ts
class animal { }
.js
var animal = (function () { // コンストラクタ function animal() { } return animal; }());
■コンストラクタ
.ts
class animal { constructor() { alert("const"); } }
.js
var animal = (function () { // コンストラクタ function animal() { alert("const"); } return animal; }());
■インスタンス変数(public)
.ts
class animal { name: string = "default"; }
.js
var animal = (function () { function animal() { this.name = "default"; } return animal; }());
■インスタンス変数(private)
コンパイラ時チェックのみ
■Getter/Setter
.ts
class animal { _name: string = "default"; get name() { return this._name; } set name(value: string) { this._name = value; } }
.js
var animal = (function () { function animal() { this._name = "default"; } Object.defineProperty(animal.prototype, "name", { get: function () { return this._name; }, set: function (value) { this._name = value; }, enumerable: true, configurable: true }); return animal; }());
■staticメソッド、変数
.ts
class animal { static count: number = 0; static Print(): void { alert(animal.count); } }
.js
var animal = (function () { function animal() { } animal.Print = function () { alert(animal.count); }; animal.count = 0; return animal; }());
2017年5月31日水曜日
C++メモ
■コンストラクタ/デストラクタ
Sample.h
Sample.cpp
main.cpp
■インスタンス変数/メソッド
Sample.h
Sample.cpp
main.cpp
Sample.h
#pragma once class Sample { public: Sample(); Sample(int num); ~Sample(); };
Sample.cpp
#include "Sample.h" #includeSample::Sample() { printf("コンストラクタ\n"); } Sample::Sample(int num) { printf("コンストラクタ引数:%d\n", num); } Sample::~Sample() { printf("デストラクタ\n"); }
main.cpp
#include "stdio.h" #include "Sample.h" int main() { Sample s1; Sample s2(10); //他の言語寄りに記載するなら下記かな //Sample s1 = Sample(); //Sample s2 = Sample(10); return 0; }
■インスタンス変数/メソッド
Sample.h
#pragma once class Sample { public: Sample(int num1, int num2); void Sum(); private: int _num1; int _num2; };
Sample.cpp
#include "Sample.h" #includeSample::Sample(int num1, int num2) { this->_num1 = num1; this->_num2 = num2; } void Sample::Sum() { printf("%d\n", this->_num1 + this->_num2); }
main.cpp
#include "stdio.h" #include "stdio.h" #include "Sample.h" int main() { Sample s(10, 20); s.Sum(); return 0; }
2017年5月13日土曜日
C# 型生成コスト比較
諸事情により比較と結果をのっけておく。
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Diagnostics; namespace ConsoleApplication9 { class Program { private static readonly int Counter = 1000000; static void Main(string[] args) { Console.WriteLine("■WriteOnly"); TimeSpan t1 = Program.HashTableData(false); Log log = new Log(t1); log.Output("HashTable"); TimeSpan t2 = Program.DictionaryData(false); log.Output("Dictionary", t2); TimeSpan t3 = Program.StructData(false); log.Output("Struct", t3); TimeSpan t4 = Program.ClassData(false); log.Output("Class", t4); Console.WriteLine("■Write/Read"); TimeSpan t5 = Program.HashTableData(true); log = new Log(t5); log.Output("HashTable"); TimeSpan t6 = Program.DictionaryData(true); log.Output("Dictionary", t6); TimeSpan t7 = Program.StructData(true); log.Output("Struct", t7); TimeSpan t8 = Program.ClassData(true); log.Output("Class", t8); } static TimeSpan HashTableData(bool flag) { Stopwatch sw = Stopwatch.StartNew(); List<hashtable> data = new List<hashtable>(); foreach (int num in Enumerable.Range(1, Counter)) { Hashtable ht = new Hashtable(); ht["a"] = "a"; ht["b"] = "b"; ht["c"] = "c"; ht["d"] = "d"; ht["e"] = "e"; data.Add(ht); } if (flag) { foreach (var d in data) { string val1 = (string)d["a"]; string val2 = (string)d["b"]; string val3 = (string)d["c"]; string val4 = (string)d["d"]; string val5 = (string)d["e"]; } } return sw.Elapsed; } static TimeSpan DictionaryData(bool flag) { Stopwatch sw = Stopwatch.StartNew(); List<Dictionary<string, string>> data = new List<Dictionary<string, string>>(); foreach (int num in Enumerable.Range(1, Counter)) { Dictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("a", "a"); dic.Add("b", "b"); dic.Add("c", "c"); dic.Add("d", "d"); dic.Add("e", "e"); data.Add(dic); } if (flag) { foreach (var d in data) { string val1 = d["a"]; string val2 = d["b"]; string val3 = d["c"]; string val4 = d["d"]; string val5 = d["e"]; } } return sw.Elapsed; } static TimeSpan StructData(bool flag) { Stopwatch sw = Stopwatch.StartNew(); List<structdatatype> data = new List<structdatatype>(); foreach (int num in Enumerable.Range(1, Counter)) { structDataType d = new structDataType(); d.a = "a"; d.b = "b"; d.c = "c"; d.d = "d"; d.e = "e"; data.Add(d); } if (flag) { foreach (var d in data) { string val1 = d.a; string val2 = d.b; string val3 = d.c; string val4 = d.d; string val5 = d.e; } } return sw.Elapsed; } static TimeSpan ClassData(bool flag) { Stopwatch sw = Stopwatch.StartNew(); List<hoge> data = new List<hoge>(); foreach (int num in Enumerable.Range(1, Counter)) { hoge g = new hoge(); g.a = "a"; g.b = "b"; g.c = "c"; g.d = "d"; g.e = "e"; data.Add(g); } if (flag) { foreach (var d in data) { string val1 = d.a; string val2 = d.b; string val3 = d.c; string val4 = d.d; string val5 = d.e; } } return sw.Elapsed; } private struct structDataType { public string a; public string b; public string c; public string d; public string e; } } class hoge { public string a; public string b; public string c; public string d; public string e; } class Log { public Log(TimeSpan baseTime) { this.BaseTime = baseTime; } private TimeSpan BaseTime { get; set; } public void Output(string Name) { string ret = string.Format("{0, -10}{1}", Name, this.BaseTime); Console.WriteLine(ret); } public void Output(string Name, TimeSpan time) { string ret = string.Format("{0, -10}{1}({2:F1}%)", Name, time, time.TotalMilliseconds / this.BaseTime.TotalMilliseconds * 100); Console.WriteLine(ret); } } }
■WriteOnly HashTable 00:00:01.1076920 Dictionary00:00:01.2820160(115.7%) Struct 00:00:00.0399449(3.6%) Class 00:00:00.2202693(19.9%) ■Write/Read HashTable 00:00:01.4136740 Dictionary00:00:01.5449535(109.3%) Struct 00:00:00.0694128(4.9%) Class 00:00:00.2186330(15.5%)
2017年2月18日土曜日
登録:
投稿 (Atom)