;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfArrayCompare (arrA, arrB, strFilename) arrErr = ArrDimension (7) hdlFW = 0 If strFilename != "" intEMLast = ErrorMode (@OFF) LastError () hdlFW = FileOpen (strFilename, "WRITE") intLastError = LastError () ErrorMode (intEMLast) If intLastError > 0 ArrInitialize (arrErr, "") arrErr[0] = 6 arrErr[1] = intLastError Return arrErr ; Cannot create file. EndIf EndIf ; Valid array? ArrInitialize (arrErr, "") blnInvalidA = !ArrInfo (arrA, -1) blnInvalidB = !ArrInfo (arrB, -1) arrErr[1] = blnInvalidA | blnInvalidB << 1 If arrErr[1] arrErr[0] = 1 arrErr[2] = blnInvalidA arrErr[3] = blnInvalidB If hdlFW GoSub WriteFileHeader GoSub WriteFileLine GoSub WriteFileFooterAndClose EndIf Return arrErr ; Further comparing not possible. EndIf If hdlFW Then GoSub WriteFileHeader ; Same dimension? ArrInitialize (arrErr, "") intDimsA = ArrInfo (arrA, 0) intDimsB = ArrInfo (arrB, 0) arrErr[1] = (intDimsA > intDimsB) | (intDimsA < intDimsB) << 1 If arrErr[1] arrErr[0] = 2 arrErr[2] = intDimsA arrErr[3] = intDimsB If hdlFW GoSub WriteFileLine GoSub WriteFileFooterAndClose EndIf Return arrErr ; Further comparing not possible. EndIf ; Empty arrays? At this point the question could be also: Are they both dim-0 arrays? ArrInitialize (arrErr, "") intElemsA = ArrInfo (arrA, 6) intElemsB = ArrInfo (arrB, 6) If (intElemsA == 0) && (intElemsB == 0) arrErr[0] = 3 ; arrA and arrB have no elements. If hdlFW GoSub WriteFileLine GoSub WriteFileFooterAndClose EndIf Return arrErr ; Further comparing not possible. EndIf ; If we reach here, then both arrays have the same dimension and the same number of elements. ; Now compare element VarType and value. intErrCount = 0 strIndexFill = StrFill (",0", 2 * (5 - intDimsA)) arrD = ArrDimension (6) arrE = ArrDimension (6) For intD = 1 To 5 arrE[intD] = Max (ArrInfo (arrA, intD) - 1, 0) Next ; Compare elements. For intD1 = 0 To arrE[1] arrD[1] = intD1 For intD2 = 0 To arrE[2] arrD[2] = intD2 For intD3 = 0 To arrE[3] arrD[3] = intD3 For intD4 = 0 To arrE[4] arrD[4] = intD4 For intD5 = 0 To arrE[5] arrD[5] = intD5 strIdx = "" For intD = 1 To intDimsA strIdx = ItemInsert (arrD[intD], -1, strIdx, ",") Next blnNEQVarType = VarType (arrA [%strIdx%]) != VarType (arrB [%strIdx%]) blnNEQValue = arrA [%strIdx%] != arrB [%strIdx%] If blnNEQVarType || blnNEQValue intErrCount = intErrCount + blnNEQVarType + blnNEQValue ; Count each difference. arrErr[0] = 4 arrErr[1] = blnNEQVarType | blnNEQValue << 1 arrErr[2] = strIdx : strIndexFill arrErr[3] = VarType (arrA [%strIdx%]) arrErr[4] = VarType (arrB [%strIdx%]) arrErr[5] = arrA [%strIdx%] arrErr[6] = arrB [%strIdx%] If hdlFW Then GoSub WriteFileLine Else Return arrErr EndIf Next Next Next Next Next If hdlFW Then GoSub WriteFileFooterAndClose ArrInitialize (arrErr, "") arrErr[0] = 0 arrErr[1] = 0 If intErrCount arrErr[0] = 5 arrErr[1] = intErrCount EndIf Return arrErr ; from udfArrayCompare. ;.......................................................................................................................................... :WriteFileHeader arrArrInfo = ArrDimension (8) arrArrInfo[0] = "ArrInfo;-1;{0};Validity of the array. 1=@TRUE valid, 0=@FALSE invalid." arrArrInfo[1] = "ArrInfo;0;{1};Number of dimensions in the array." arrArrInfo[2] = "ArrInfo;1;{2};Number of elements in dimension 1." arrArrInfo[3] = "ArrInfo;2;{3};Number of elements in dimension 2." arrArrInfo[4] = "ArrInfo;3;{4};Number of elements in dimension 3." arrArrInfo[5] = "ArrInfo;4;{5};Number of elements in dimension 4." arrArrInfo[6] = "ArrInfo;5;{6};Number of elements in dimension 5." arrArrInfo[7] = "ArrInfo;6;{7};Number of elements in the entire array." strBOM = "" ; BOM (EF BB BF) for Unicode UTF-8. FileWrite (hdlFW, strBOM : '<?xml version="1.0" encoding="utf-8" standalone="yes"?>') ; XML declaration line with leading BOM (EF BB BF). FileWrite (hdlFW, "<ARRAY_COMPARE>") ; Open node "ARRAY_COMPARE". FileWrite (hdlFW, "<ARRINFO_A><![CDATA[") ; Open node "ARRINFO_A". If arrErr[0] == 1 && arrErr[2] == 1 FileWrite (hdlFW, StrReplace (arrArrInfo[0], "{0}", 0)) Else FileWrite (hdlFW, StrReplace (arrArrInfo[0], "{0}", 1)) For intI = 1 To 7 FileWrite (hdlFW, StrReplace (arrArrInfo[intI], "{" : intI : "}", ArrInfo (arrA, intI - 1))) Next EndIf FileWrite (hdlFW, "]]></ARRINFO_A>") ; Close node "ARRINFO_A". FileWrite (hdlFW, "<ARRINFO_B><![CDATA[") ; Open node "ARRINFO_B". If arrErr[0] == 1 && arrErr[3] == 1 FileWrite (hdlFW, StrReplace (arrArrInfo[0], "{0}", 0)) Else FileWrite (hdlFW, StrReplace (arrArrInfo[0], "{0}", 1)) For intI = 1 To 7 FileWrite (hdlFW, StrReplace (arrArrInfo[intI], "{" : intI : "}", ArrInfo (arrB, intI - 1))) Next EndIf FileWrite (hdlFW, "]]></ARRINFO_B>") ; Close node "ARRINFO_B". FileWrite (hdlFW, "<COMPARE_RESULT><![CDATA[") ; Open node "COMPARE_DATA". Drop (arrArrInfo) Return ; from GoSub WriteFileHeader. ;.......................................................................................................................................... :WriteFileLine strOut = "" For intI = 0 To 6 strOut = strOut : ";" : arrErr[intI] Next strOut = ChrStringToUnicode ("" : StrSub (strOut, 2, -1)) intPrevCodePage = ChrSetCodepage (65001) FileWrite (hdlFW, strOut) ChrSetCodepage (intPrevCodePage) Return ; from GoSub WriteFileLine. ;.......................................................................................................................................... :WriteFileFooterAndClose FileWrite (hdlFW, "]]></COMPARE_RESULT>") ; Close node "ERRORDATA". FileWrite (hdlFW, "</ARRAY_COMPARE>") ; Close node "ARRAY_COMPARE". hdlFW = FileClose (hdlFW) Return ; from GoSub WriteFileFooterAndClose. ;.......................................................................................................................................... ; This function "udfArrayCompare" compares two Winbatch arrays. ; ; Parameter: ; arrA .......... First array. ; arrB .......... Second array. ; strFilename ... Optional filename for writing out error data to XML file when comparing array elements. ; ; If the optional filename is left blank, then the function returns at the first encountered error. ; ; Return value: ; A dim-1 array of 7 elements. This error array is filled with data in relation to the error context. ; If the option "output to file" is used, then a XML file is created, which contains a list of all mismatched elements. ; ; Return codes stored in error array: ; ; E[0] Code = 1 ... Array is not valid. ; E[1] Subcode = 1 ... Array A is not valid. ; E[1] Subcode = 2 ... Array B is not valid. ; E[1] Subcode = 3 ... Both arrays A and B are not valid. ; ; E[0] Code = 2 ... Array dimensions are different. ; E[1] Subcode = 1 ... Array A has more dimensions than array B. ; E[1] Subcode = 2 ... Array B has more dimensions than array A. ; E[2] Dimensions A ........ Number of dimensions in array A. ; E[3] Dimensions B ........ Number of dimensions in array B. ; ; E[0] Code = 3 ... Both arrays A and B have no elements. ; ; E[0] Code = 4 ... Array element mismatch. ; E[1] Subcode = 1 ... VarType mismatch ; E[1] Subcode = 2 ... Value mismatch. ; E[1] Subcode = 3 ... Both VarType and Value mismatch. ; E[2] Index ........ Element index in format "0,0,0,0,0". ; E[3] VarType A ........ VarType of element in array A. ; E[4] VarType B ........ VarType of element in array B. ; E[5] Value A ........ Value of element in array A. ; E[6] Value B ........ Value of element in array B. ; ; E[0] Code = 5 ... Only set when option "output to file" is used. ; E[1] Error count ........ Number of errors count. ; ; E[0] Code = 6 ... Report file creation failed. ; E[1] Subcode = 1 ... WinBatch error code. ; ; ; Detlev Dalitz.20110123. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfArrayFromList (strList, strDelimiter) If strList == "" Then Return ArrDimension (0) ; Return dim-0 array with no element. If strDelimiter == "" Then Return ArrayFromStr (strList) ; Return dim-1 array with one character per array element. arrD = ArrDimension (6) ArrInitialize (arrD, "") arrE = ArrDimension (6) ArrInitialize (arrE, 0) arrE [0] = Min (5, StrLen (strDelimiter)) arrD [1] = StrSub (strDelimiter, 1, 1) arrE [1] = ItemCount (strList, arrD [1]) strItem = ItemExtract (1, strList, arrD [1]) For intI = 2 To arrE [0] arrD [intI] = StrSub (strDelimiter, intI, 1) arrE [IntI] = ItemCount (strItem, arrD [intI]) strItem = ItemExtract (1, strItem, arrD [intI]) Next arrArray = ArrDimension (arrE[1], arrE[2], arrE[3], arrE[4], arrE[5]) Switch arrE [0] Case 1 For intD1 = 1 To arrE [1] arrArray [intD1 - 1] = ItemExtract (intD1, strList, arrD [1]) Next Break Case 2 For intD1 = 1 To arrE [1] strItem1 = ItemExtract (intD1, strList, arrD [1]) For intD2 = 1 To arrE [2] arrArray [intD1 - 1, intD2 - 1] = ItemExtract (intD2, strItem1, arrD [2]) Next Next Break Case 3 For intD1 = 1 To arrE [1] strItem1 = ItemExtract (intD1, strList, arrD [1]) For intD2 = 1 To arrE [2] strItem2 = ItemExtract (intD2, strItem1, arrD [2]) For intD3 = 1 To arrE [3] arrArray [intD1 - 1, intD2 - 1, intD3 - 1] = ItemExtract (intD3, strItem2, arrD [3]) Next Next Next Break Case 4 For intD1 = 1 To arrE [1] strItem1 = ItemExtract (intD1, strList, arrD [1]) For intD2 = 1 To arrE [2] strItem2 = ItemExtract (intD2, strItem1, arrD [2]) For intD3 = 1 To arrE [3] strItem3 = ItemExtract (intD3, strItem2, arrD [3]) For intD4 = 1 To arrE [4] arrArray [intD1 - 1, intD2 - 1, intD3 - 1, intD4 - 1] = ItemExtract (intD4, strItem3, arrD [4]) Next Next Next Next Break Case 5 For intD1 = 1 To arrE [1] strItem1 = ItemExtract (intD1, strList, arrD [1]) For intD2 = 1 To arrE [2] strItem2 = ItemExtract (intD2, strItem1, arrD [2]) For intD3 = 1 To arrE [3] strItem3 = ItemExtract (intD3, strItem2, arrD [3]) For intD4 = 1 To arrE [4] strItem4 = ItemExtract (intD4, strItem3, arrD [4]) For intD5 = 1 To arrE [5] arrArray [intD1 - 1, intD2 - 1, intD3 - 1, intD4 - 1, intD5 - 1] = ItemExtract (intD5, strItem4, arrD [5]) Next Next Next Next Next Break EndSwitch Return arrArray ;.......................................................................................................................................... ; This UDF "udfArrayFromList" returns a dim-1 .. dim-5 array, whose array elements are filled ; by iterative separating the given input string into chunks of substrings. ; ; The input string is a serialized string list representation of a dim-1 .. dim-5 array. ; The elements are delimited by 1 .. 5 delimiter string characters accordingly to their array dimension. ; ; If the given strList is empty, then the function returns a dim-0 array with no element. ; ; If the given strDelimiter is empty, then the function returns a dim-1 array with each element filled ; with one character of the given strList, which has been splitted into separate chars. ; ; Syntax: ; arr:Array = udfArrayFromList (str:String, str:Delimiter) ; ; Detlev Dalitz.20030225.20090520.20110123. ;.......................................................................................................................................... ; ; Example 1: ; ; ; Create dim-2 array. ; ; One Element = "o". ; ; Dim2 = 2 x Element = "o+o" ; Delim "+". ; ; Dim1 = 3 x Dim1 = "o+o=o+o=o+o" ; Delim "=". ; ; ; ; | 0 1 ; ; --+------ ; ; 0 | a b ; ; 1 | c d ; ; 2 | e f ; ; intElementsShouldBe = 3 * 2 ; 6. ; ; strList = "o+o=o+o=o+o" ; strDelimiter = "=+" ; Dimensions 1-2. ; ; intElementsAre = StrLen (StrClean (strList, strDelimiter, "", @TRUE, 1)) ; 6. ; ; arrA = udfArrayFromList (strList, strDelimiter) ; ; arrB = ArrDimension (8) ; arrB[0] = ArrInfo (arrA, -1) ; Validity of the array. 1=@TRUE valid, 0=@FALSE invalid. ; arrB[1] = ArrInfo (arrA, 0) ; Number of dimensions in the array. ; arrB[2] = ArrInfo (arrA, 1) ; Number of elements in dimension 1. ; arrB[3] = ArrInfo (arrA, 2) ; Number of elements in dimension 2. ; arrB[4] = ArrInfo (arrA, 3) ; Number of elements in dimension 3. ; arrB[5] = ArrInfo (arrA, 4) ; Number of elements in dimension 4. ; arrB[6] = ArrInfo (arrA, 5) ; Number of elements in dimension 5. ; arrB[7] = ArrInfo (arrA, 6) ; Number of elements in the entire array. ; ; strListInfo = udfArrayToList (arrB, "|") ; 1|2|3|2|0|0|0|6. ; ;.......................................................................................................................................... ; ; Example 2: ; ; ; Create dim-5 array. ; ; One Element = "o". ; ; Dim5 = 2 x Element = "o+o" ; Delim "+". ; ; Dim4 = 4 x Dim5 = "o+o=o+o=o+o=o+o" ; Delim "=". ; ; Dim3 = 3 x Dim4 = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "/". ; ; Dim2 = 2 x Dim3 = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "|". ; ; Dim1 = 2 x Dim2 = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o@o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "@". ; ; intElementsShouldBe = 2 * 2 * 3 * 4 * 2 ; 96. ; ; strList = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o@o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; strDelimiter = "@|/=+" ; Dimensions 1-2-3-4-5. ; ; intElementsAre = StrLen (StrClean (strList, strDelimiter, "", @TRUE, 1)) ; 96. ; ; arrA = udfArrayFromList (strList, strDelimiter) ; ; arrB = ArrDimension (8) ; arrB[0] = ArrInfo (arrA, -1) ; Validity of the array. 1=@TRUE valid, 0=@FALSE invalid. ; arrB[1] = ArrInfo (arrA, 0) ; Number of dimensions in the array. ; arrB[2] = ArrInfo (arrA, 1) ; Number of elements in dimension 1. ; arrB[3] = ArrInfo (arrA, 2) ; Number of elements in dimension 2. ; arrB[4] = ArrInfo (arrA, 3) ; Number of elements in dimension 3. ; arrB[5] = ArrInfo (arrA, 4) ; Number of elements in dimension 4. ; arrB[6] = ArrInfo (arrA, 5) ; Number of elements in dimension 5. ; arrB[7] = ArrInfo (arrA, 6) ; Number of elements in the entire array. ; ; strListInfo = udfArrayToList (arrB, "|") ; 1|5|2|2|3|4|2|96. ; ;.......................................................................................................................................... ; ; Previous code for ArrayFromString functionality (from version 20090520): ; ; If strDelimiter == "" ; strDelim = Num2Char (7) ; Surrogate char. ; intSizeBB = StrLen (strList) << 1 ; hdlBB = BinaryAlloc (intSizeBB) ; BinaryPokeStrW (hdlBB, 0, strList) ; BinaryReplace (hdlBB, "", strDelim, @TRUE) ; arrArray = Arrayize (BinaryPeekStr (hdlBB, 0, intSizeBB - 1), strDelim) ; hdlBB = BinaryFree (hdlBB) ; Return arrArray ; Return dim1 array with each element containing one char. ; EndIf ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;---------------------------------------------------------------------------------------------------------------------- #DefineFunction udfArrayToList (arrArray, strDelimiter) If !ArrInfo (arrArray, -1) Then Return "" ; No array. If !ArrInfo (arrArray, 6) Then Return "" ; No elements. arrE = ArrDimension (6) arrE [0] = ArrInfo (arrArray, 0) For intI = 1 To 5 arrE [intI] = Max (0, ArrInfo (arrArray, intI) - 1) Next arrD = ArrDimension (6) ArrInitialize (arrD, "") intLen = Min (arrE [0], StrLen (strDelimiter)) For intI = 1 To intLen arrD [intI] = StrSub (strDelimiter, intI, 1) Next Switch arrE [0] Case 1 strItemList1 = "" For intD1 = 0 To arrE [1] If !!VarType (arrArray [intD1]) strItemList1 = strItemList1 : arrD [1] : arrArray [intD1] Else strItemList1 = strItemList1 : arrD [1] EndIf Next If arrD [1] != "" Then strItemList1 = StrSub (strItemList1, 2, -1) Break Case 2 strItemList1 = "" For intD1 = 0 To arrE [1] strItemList2 = "" For intD2 = 0 To arrE [2] If !!VarType (arrArray [intD1, intD2]) strItemList2 = strItemList2 : arrD [2] : arrArray [intD1, intD2] Else strItemList2 = strItemList2 : arrD [2] EndIf Next If arrD [2] != "" Then strItemList2 = StrSub (strItemList2, 2, -1) strItemList1 = strItemList1 : arrD [1] : strItemList2 Next If arrD [1] != "" Then strItemList1 = StrSub (strItemList1, 2, -1) Break Case 3 strItemList1 = "" For intD1 = 0 To arrE [1] strItemList2 = "" For intD2 = 0 To arrE [2] strItemList3 = "" For intD3 = 0 To arrE [3] If !!VarType (arrArray [intD1, intD2, intD3]) strItemList3 = strItemList3 : arrD [3] : arrArray [intD1, intD2, intD3] Else strItemList3 = strItemList3 : arrD [3] EndIf Next If arrD [3] != "" Then strItemList3 = StrSub (strItemList3, 2, -1) strItemList2 = strItemList2 : arrD [2] : strItemList3 Next If arrD [2] != "" Then strItemList2 = StrSub (strItemList2, 2, -1) strItemList1 = strItemList1 : arrD [1] : strItemList2 Next If arrD [1] != "" Then strItemList1 = StrSub (strItemList1, 2, -1) Break Case 4 strItemList1 = "" For intD1 = 0 To arrE [1] strItemList2 = "" For intD2 = 0 To arrE [2] strItemList3 = "" For intD3 = 0 To arrE [3] strItemList4 = "" For intD4 = 0 To arrE [4] If !!VarType (arrArray [intD1, intD2, intD3, intD4]) strItemList4 = strItemList4 : arrD [4] : arrArray [intD1, intD2, intD3, intD4] Else strItemList4 = strItemList4 : arrD [4] EndIf Next If arrD [4] != "" Then strItemList4 = StrSub (strItemList4, 2, -1) strItemList3 = strItemList3 : arrD [3] : strItemList4 Next If arrD [3] != "" Then strItemList3 = StrSub (strItemList3, 2, -1) strItemList2 = strItemList2 : arrD [2] : strItemList3 Next If arrD [2] != "" Then strItemList2 = StrSub (strItemList2, 2, -1) strItemList1 = strItemList1 : arrD [1] : strItemList2 Next If arrD [1] != "" Then strItemList1 = StrSub (strItemList1, 2, -1) Break Case 5 strItemList1 = "" For intD1 = 0 To arrE [1] strItemList2 = "" For intD2 = 0 To arrE [2] strItemList3 = "" For intD3 = 0 To arrE [3] strItemList4 = "" For intD4 = 0 To arrE [4] strItemList5 = "" For intD5 = 0 To arrE [5] If !!VarType (arrArray [intD1, intD2, intD3, intD4, intD5]) strItemList5 = strItemList5 : arrD [5] : arrArray [intD1, intD2, intD3, intD4, intD5] Else strItemList5 = strItemList5 : arrD [5] EndIf Next If arrD [5] != "" Then strItemList5 = StrSub (strItemList5, 2, -1) strItemList4 = strItemList4 : arrD [4] : strItemList5 Next If arrD [4] != "" Then strItemList4 = StrSub (strItemList4, 2, -1) strItemList3 = strItemList3 : arrD [3] : strItemList4 Next If arrD [3] != "" Then strItemList3 = StrSub (strItemList3, 2, -1) strItemList2 = strItemList2 : arrD [2] : strItemList3 Next If arrD [2] != "" Then strItemList2 = StrSub (strItemList2, 2, -1) strItemList1 = strItemList1 : arrD [1] : strItemList2 Next If arrD [1] != "" Then strItemList1 = StrSub (strItemList1, 2, -1) Break EndSwitch Return strItemList1 ;---------------------------------------------------------------------------------------------------------------------- ; This UDF "udfArrayToList" converts a given array into a serialized itemlist ; with each item separated by the delimiter character accordingly to the current dimension. ; ; Example: strMyItemList = udfArrayToList (arrMyArray, @TAB) ; Creates an itemlist from array. ; ; Note: ; This UDF supports dim-1 to dim-5 array. ; An array element which is not initialized has a Vartype=0 (undefined). ; Therefore an empty item will be appended to target itemlist. ; ; Detlev Dalitz.20020718.20090519.20110923. ;---------------------------------------------------------------------------------------------------------------------- #EndFunction ;---------------------------------------------------------------------------------------------------------------------- ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfArrayUnloadToFile (arrArray, strFilename) If !ArrInfo (arrArray, -1) Then Return 0 ; No array. If !ArrInfo (arrArray, 6) Then Return 0 ; No elements. arrArrInfo = ArrDimension (8) arrArrInfo[0] = "ArrInfo;-1;{0};Validity of the array. 1=@TRUE valid, 0=@FALSE invalid." arrArrInfo[1] = "ArrInfo;0;{1};Number of dimensions in the array." arrArrInfo[2] = "ArrInfo;1;{2};Number of elements in dimension 1." arrArrInfo[3] = "ArrInfo;2;{3};Number of elements in dimension 2." arrArrInfo[4] = "ArrInfo;3;{4};Number of elements in dimension 3." arrArrInfo[5] = "ArrInfo;4;{5};Number of elements in dimension 4." arrArrInfo[6] = "ArrInfo;5;{6};Number of elements in dimension 5." arrArrInfo[7] = "ArrInfo;6;{7};Number of elements in the entire array." intDims = ArrInfo (arrArray, 0) strIndexFill = StrFill (",0", 2 * (5 - intDims)) arrD = ArrDimension (6) arrE = ArrDimension (6) For intD = 1 To 5 arrE[intD] = Max (ArrInfo (arrArray, intD) - 1, 0) Next hdlFW = FileOpen (strFilename, "WRITE") strBOM = "" ; BOM (EF BB BF) for Unicode UTF-8. FileWrite (hdlFW, strBOM : '<?xml version="1.0" encoding="utf-8" standalone="yes"?>') ; XML declaration line with leading BOM (EF BB BF). FileWrite (hdlFW, "<ARRAY>") ; Open node "ARRAY". FileWrite (hdlFW, "<ARRINFO><![CDATA[") ; Open node "ARRINFO". ; Write data. For intI = 0 To 7 FileWrite (hdlFW, StrReplace (arrArrInfo[intI], "{" : intI : "}", ArrInfo (arrArray, intI - 1))) Next FileWrite (hdlFW, "]]></ARRINFO>") ; Close node "ARRINFO". FileWrite (hdlFW, "<ARRDATA><![CDATA[") ; Open node "ARRDATA". ; Write data. For intD1 = 0 To arrE[1] arrD[1] = intD1 For intD2 = 0 To arrE[2] arrD[2] = intD2 For intD3 = 0 To arrE[3] arrD[3] = intD3 For intD4 = 0 To arrE[4] arrD[4] = intD4 For intD5 = 0 To arrE[5] arrD[5] = intD5 strIdx = "" For intD = 1 To intDims strIdx = ItemInsert (arrD[intD], -1, strIdx, ",") Next strArrIndex = strIdx : strIndexFill intVarType = VarType (arrArray [%strIdx%]) If intVarType strOut = ChrStringToUnicode ("" : arrArray [%strIdx%]) intPrevCodePage = ChrSetCodepage (65001) FileWrite (hdlFW, strArrIndex : ";" : intVarType : ";" : strOut) ChrSetCodepage (intPrevCodePage) Else FileWrite (hdlFW, strArrIndex : ";" : intVarType : ";") EndIf Next Next Next Next Next FileWrite (hdlFW, "]]></ARRDATA>") ; Close node "ARRDATA". FileWrite (hdlFW, "</ARRAY>") ; Close node "ARRAY". hdlFW = FileClose (hdlFW) Return FileSizeEx (strFilename) ;.......................................................................................................................................... ; This function "udfArrayUnloadToFile" creates a specific array definition textfile (xml) from array, ; which can be used to load data back into an array by function "udfArrayLoadFromFile". ; ; Detlev Dalitz.20010731.20020828.20030222.20090528.20100122.20100125.20110123. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfArrayLoadFromFile (strFilename) intResult = 0 If !FileSizeEx (strFilename) Then Goto CANCEL IntControl (65, 4096 * 256, 0, 0, 0) ; Enlarge fileread buffer for speedy access. arrArrInfo = ArrDimension (8) arrArrInfo[0] = "ArrInfo;-1;" arrArrInfo[1] = "ArrInfo;0;" arrArrInfo[2] = "ArrInfo;1;" arrArrInfo[3] = "ArrInfo;2;" arrArrInfo[4] = "ArrInfo;3;" arrArrInfo[5] = "ArrInfo;4;" arrArrInfo[6] = "ArrInfo;5;" arrArrInfo[7] = "ArrInfo;6;" hdlFR = FileOpen (strFilename, "READ") If !hdlFR Then Goto CANCEL While @TRUE strLine = FileRead (hdlFR) strLine = StrTrim (strLine) If strLine == "*EOF*" Then Goto CANCEL If strLine == "<ARRINFO><![CDATA[" Then Break EndWhile ; Read header. While @TRUE strLine = FileRead (hdlFR) strLine = StrTrim (strLine) If strLine == "*EOF*" Then Goto CANCEL If strLine == "]]></ARRINFO>" Then Break If strLine == "" Then Continue If 1 == StrIndex (strLine, arrArrInfo[0], 1, @FWDSCAN) arrArrInfo[0] = ItemExtract (3, strLine, ";") ElseIf 1 == StrIndex (strLine, arrArrInfo[1], 1, @FWDSCAN) arrArrInfo[1] = ItemExtract (3, strLine, ";") ElseIf 1 == StrIndex (strLine, arrArrInfo[2], 1, @FWDSCAN) arrArrInfo[2] = ItemExtract (3, strLine, ";") ElseIf 1 == StrIndex (strLine, arrArrInfo[3], 1, @FWDSCAN) arrArrInfo[3] = ItemExtract (3, strLine, ";") ElseIf 1 == StrIndex (strLine, arrArrInfo[4], 1, @FWDSCAN) arrArrInfo[4] = ItemExtract (3, strLine, ";") ElseIf 1 == StrIndex (strLine, arrArrInfo[5], 1, @FWDSCAN) arrArrInfo[5] = ItemExtract (3, strLine, ";") ElseIf 1 == StrIndex (strLine, arrArrInfo[6], 1, @FWDSCAN) arrArrInfo[6] = ItemExtract (3, strLine, ";") ElseIf 1 == StrIndex (strLine, arrArrInfo[7], 1, @FWDSCAN) arrArrInfo[7] = ItemExtract (3, strLine, ";") EndIf EndWhile While @TRUE strLine = FileRead (hdlFR) strLine = StrTrim (strLine) If strLine == "*EOF*" Then Goto CANCEL If strLine == "<ARRDATA><![CDATA[" Then Break EndWhile ; Declare Array. arrArray = ArrDimension (arrArrInfo[2], arrArrInfo[3], arrArrInfo[4], arrArrInfo[5], arrArrInfo[6]) intDimNext = ArrInfo (arrArray, 0) + 1 ; Read data. While @TRUE strLine = FileRead (hdlFR) strLine = StrTrim (strLine) If strLine == "*EOF*" Then Goto CANCEL If strLine == "]]></ARRDATA>" Then Break If strLine == "" Then Continue strArrIndex = ItemExtract (1, strLine, ";") intLen1 = StrLen (strArrIndex) intArrVarType = Int (ItemExtract (2, strLine, ";")) intLen2 = StrLen (intArrVarType) strArrData = StrSub (strLine, intLen1 + intLen2 + 3, -1) For intD = 5 To intDimNext By -1 strArrIndex = ItemRemove (intD, strArrIndex, ",") Next Switch intArrVarType Case 2 ; VARTYPE_STRING intPrevCodePage = ChrSetCodepage (65001) strUnicode = ChrStringToUnicode (strArrData) ChrSetCodepage (intPrevCodePage) arrArray [%strArrIndex%] = ChrUnicodeToString (strUnicode) Break Case 32 ; VARTYPE_FLOATNUM arrArray [%strArrIndex%] = 1.0 * strArrData Break ; Case 64 ; VARTYPE_BINARY ; Case 128 ; VARTYPE_LPWSTR or "Unicode" ; Case 256 ; VARTYPE_ARRAY ; Case 512 ; VARTYPE_VARIANT ; Case 1024 ; VARTYPE_COMOBJECT ; Case 0 ; VARTYPE_UNDEFINED ; Case -1 ; VARTYPE_RESWORD ; Break Case intArrVarType If intArrVarType & 1 Then arrArray [%strArrIndex%] = 1 * strArrData ; 1=VARTYPE_INT; 65=VARTYPE_INT|VARTYPE_BINARY, 17=VARTYPE_INT|VARTYPE_OLEOBJECT, 5=VARTYPE_INT|VARTYPE_FILE, 1537=VARTYPE_INT|VARTYPE_VARIANT|VARTYPE_COMOBJECT Break EndSwitch EndWhile intResult = 1 :CANCEL If IsDefined (hdlFR) Then hdlFR = FileClose (hdlFR) If !intResult Then Return ArrDimension (0) Return arrArray ;.......................................................................................................................................... ; This function ""udfArrayLoadFromFile" creates an array from a specific array definition textfile (xml), ; which has been created previously by function "udfArrayUnloadToFile" resp. by other method. ; ; Detlev Dalitz.20010731.20020828.20030222.20090528.20100122.20100125.20110123. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ; Test. strMsgTitle = "Demo: udfArrayFromList / udfArrayToList / udfArrayUnloadToFile / udfArrayLoadFromFile / udfArrayCompare" strDirScript = DirScript () strFilenameA = strDirScript : "ARRAY.A.txt.xml" strFilenameB = strDirScript : "ARRAY.B.txt.xml" strFileCompareResult = strDirScript : "ARRAY.Compare.txt.xml" ;---- ; ; Create dim-2 array. ; ; One Element = "o". ; ; Dim2 = 2 x Element = "o+o" ; Delim "+". ; ; Dim1 = 3 x Dim1 = "o+o=o+o=o+o" ; Delim "=". ; ; Elements = 3*2 = 6. ; ; strList = "ä+ö=ü+ß=é+è" ; strDelimiter = "=+" ; Dimensions 1-2. ; arrA = udfArrayFromList (strList, strDelimiter) ;---- ; ; Create dim-5 array. ; ; One Element = "o". ; ; Dim5 = 2 x Element = "o+o" ; Delim "+". ; ; Dim4 = 4 x Dim5 = "o+o=o+o=o+o=o+o" ; Delim "=". ; ; Dim3 = 3 x Dim4 = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "/". ; ; Dim2 = 2 x Dim3 = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "|". ; ; Dim1 = 2 x Dim2 = "o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o@o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" ; Delim "@". ; ; Elements = 2*2*3*4*2 = 96. ;---- strList = "ä+ö=ü+ß=é+è=Ò+Ó/Ä+Ö=Ü+©=É+È=Ý+ÿ/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o@o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o|o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o/o+o=o+o=o+o=o+o" strDelimiter = "@|/=+" ; Dimensions 1-2-3-4-5. arrA = udfArrayFromList (strList, strDelimiter) ; Unload array A to xml file. intResult = udfArrayUnloadToFile (arrA, strFilenameA) ; Load array B from xml file. arrB = udfArrayLoadFromFile (strFilenameA) ; Unload array B to xml file. intResult = udfArrayUnloadToFile (arrB, strFilenameB) ; Compare xml files. intResult = FileCompare (strFilenameA, strFilenameB) ; Should be 0 ==> Files content are identical. If !!intResult Then Pause ("Error", "Files are different.") ; Test 1. ; Compare array A and B. No report file. arrResult = udfArrayCompare (arrA, arrB, "") ; No report file. strMsgTitle = "udfArrayCompare - Test 1" strMsgText = "Error Code.Subcode = " : arrResult[0] : "." : arrResult[1] If !!arrResult[0] Then Pause (strMsgTitle, strMsgText) Else Pause (strMsgTitle, "No Error.") ; Test 2. ; Compare array A and B. No report file. ; Change array B to get some error result. arrB[0, 0, 0, 0, 0] = @PI arrResult = udfArrayCompare (arrA, arrB, "") ; No report file. strMsgTitle = "udfArrayCompare - Test 2" strMsgText = "Error Code.Subcode = " : arrResult[0] : "." : arrResult[1] ; "4.3". strMsgText = strMsgText : @LF : @LF : "Index = " : arrResult[2] ; "0,0,0,0,0". strMsgText = strMsgText : @LF : @LF : "Vartype = " : arrResult[3] : " | " : arrResult[4] ; "2 | 32". strMsgText = strMsgText : @LF : @LF : "Value = " : arrResult[5] : " | " : arrResult[6] ; "ä | 3.14159265". If !!arrResult[0] Then Pause (strMsgTitle, strMsgText) Else Pause (strMsgTitle, "No Error.") ; Test 3. ; Compare array A and B. Create report file. ; Change array B to get some error result. arrB[0, 0, 0, 0, 0] = @PI arrB[0, 0, 0, 1, 0] = "Test" arrB[0, 0, 1, 0, 0] = 221 arrB[0, 0, 1, 1, 0] = ObjectType ("BOOL", @TRUE) arrResult = udfArrayCompare (arrA, arrB, strFileCompareResult) strMsgTitle = "udfArrayCompare - Test 3" strMsgText = "Error Code.Subcode = " : arrResult[0] : "." : arrResult[1] ; "5.7". ==> Report file, 7 errors. If !!arrResult[0] Then Pause (strMsgTitle, strMsgText) Else Pause (strMsgTitle, "No Error.") ; Report file. ; 4;3;0,0,0,0,0;2;32;ä;3.14159265 ==> two errors: VarType and Value. ; 4;2;0,0,0,1,0;2;2;ü;Test ==> one error : Value. ; 4;3;0,0,1,0,0;2;1;Ä;221 ==> two errors: VarType and Value. ; 4;3;0,0,1,1,0;2;512;Ü;-1 ==> two errors: VarType and Value. ; Display Result. blnResult = RunShell (strFilenameA, "", "", @ZOOMED, @NOWAIT) TimeDelay (4) blnResult = RunShell (strFilenameB, "", "", @ZOOMED, @NOWAIT) TimeDelay (4) blnResult = RunShell (strFileCompareResult, "", "", @ZOOMED, @NOWAIT) TimeDelay (4) blnResult = ShellExecute (strFileCompareResult, "", "", @ZOOMED, "") :CANCEL Exit