;------------------------------------------------------------------------------------------------------------------------------------------ #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 ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #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 ;------------------------------------------------------------------------------------------------------------------------------------------ ; Test. strMsgTitle = "Demo: udfArrayUnloadToFile / udfArrayLoadFromFile / udfArrayFromList" strDirScript = DirScript () strFilenameA = strDirScript : "ARRAY.A.xml" strFilenameB = strDirScript : "ARRAY.B.xml" ; 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) intResult = udfArrayUnloadToFile (arrB, strFilenameB) ; Display Result. strFilename = ShortCutDir ("Local Settings", 0, 1) : "Temp\Demo.udfArrayFromList.txt" hdlWinId = "" If udfArrayUnloadToFile (arrB, strFilename) hdlWinId = WinItemProcId (RunShell (strFilename, "", "", @ZOOMED, @GETPROCID), 0, 0) blnResult = FileDelete (strFilename) EndIf intDims = ArrInfo (arrB, 0) ; Number of dimensions in the array. intElements = ArrInfo (arrB, 6) ; Number of elements in the entire array. strMsgText = "strList = " : strList : @LF strMsgText = strMsgText : "strDelimiter = " : strDelimiter : @LF strMsgText = strMsgText : "intDims = " : intDims : @LF strMsgText = strMsgText : "intElements = " : intElements : @LF IntControl (63, 300, 300, 700, 700) ; Sets coordinates for AskFileText, AskItemList and AskTextBox windows. IntControl (28, 1, 0, 0, 0) ; Selects system font used in list boxes. p1=1=fixed pitch font. AskItemlist (strMsgTitle, strMsgText, @LF, @UNSORTED, @SINGLE) :CANCEL If IsDefined (hdlWinId) Then If hdlWinId != "" Then If WinExist (hdlWinId) Then WinClose (hdlWinId) Exit