PhilHibbs Posted March 16, 2010 Share Posted March 16, 2010 It's difficult to narrow this down to an example that you can run, so sorry about that, I'll try to break it down further if the problem isn't obvious from this. Here are the lines that are failing: MsgBox(0,"Boxes","UBound="&UBound($Boxes)&@CRLF&"ProjNum="&$ProjNum&@CRLF&"UBound="&UBound($Boxes[$ProjNum])) GUICtrlSetState( $Boxes[$ProjNum][1], $GUI_CHECKED ) The message box says this: The script then fails with this error: C:\dev\AutoIt\DSLaunch\DSLaunch2.au3 (397) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.: Line 397 is the GUICtrlSetState call. So, $Boxes has 1 element, $Boxes[0] has 4 elements, but $Boxes[0][1] is causing a failure. I don't understand. Link to comment Share on other sites More sharing options...
jchd Posted March 16, 2010 Share Posted March 16, 2010 When you're at a loss, use the last resort magic wand: expandcollapse popupLocal $x[2] = [1.234, True] Local $boxes[1][4] = [['abc', 75, $x, default]] ConsoleWrite(_VarDump($boxes) & @LF) Func _VarDump(ByRef $vVar, $sIndent = '') Select Case IsDllStruct($vVar) Return 'Struct(' & DllStructGetSize($vVar) & ') = ' & Hex($vVar) Case IsArray($vVar) Local $iSubscripts = UBound($vVar, 0) Local $sDims = 'Array' $iSubscripts -= 1 For $i = 0 To $iSubscripts $sDims &= '[' & UBound($vVar, $i + 1) & ']' Next Return $sDims & @CRLF & _VarDumpArray($vVar, $sIndent) Case IsBinary($vVar) Return 'Binary(' & BinaryLen($vVar) & ')' Case IsBool($vVar) Return 'Boolean(' & $vVar & ')' Case IsFloat($vVar) Return 'Float(' & $vVar & ')' Case IsHWnd($vVar) Return 'HWnd(' & $vVar & ')' Case IsInt($vVar) Return 'Integer(' & $vVar & ')' Case IsKeyword($vVar) Return 'Keyword(' & $vVar & ')' Case IsPtr($vVar) Return 'Pointer(' & $vVar & ')' Case IsObj($vVar) Return 'Object(' & ObjName($vVar) & ')' Case IsString($vVar) Return 'String(' & StringLen($vVar) & ") '" & $vVar & "'" Case Else Return 'Unknown(' & $vVar & ')' EndSelect EndFunc Func _VarDumpArray(ByRef $aArray, $sIndent = '') Local $sDump Local $sArrayFetch, $sArrayRead, $bDone Local $iSubscripts = UBound($aArray, 0) Local $aUBounds[$iSubscripts] Local $aCounts[$iSubscripts] $iSubscripts -= 1 For $i = 0 To $iSubscripts $aUBounds[$i] = UBound($aArray, $i + 1) - 1 $aCounts[$i] = 0 Next $sIndent &= @TAB While 1 $bDone = True $sArrayFetch = '' For $i = 0 To $iSubscripts $sArrayFetch &= '[' & $aCounts[$i] & ']' If $aCounts[$i] < $aUBounds[$i] Then $bDone = False Next $sArrayRead = Execute('$aArray' & $sArrayFetch) If @error Then ExitLoop Else $sDump &= $sIndent & $sArrayFetch & ' => ' & _VarDump($sArrayRead, $sIndent) If Not $bDone Then $sDump &= @CRLF Else Return $sDump EndIf EndIf For $i = $iSubscripts To 0 Step -1 $aCounts[$i] += 1 If $aCounts[$i] > $aUBounds[$i] Then $aCounts[$i] = 0 Else ExitLoop EndIf Next WEnd EndFunc This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
BrettF Posted March 16, 2010 Share Posted March 16, 2010 (edited) PhilHibbs,If you have ever done some more advanced maths you will probably have done something with matrices. For most arrays (1D and 2D) you can visualize them in much the same way.For example:Lets create $array[5] = [1, 2, 3, 4, 5] ; 1 row, 5 colsWhich can be displayed like a matrix as:$array = [1 2 3 4 5] If we create a 2D array-$array[2][5] = [[1,2,3,4,5],[6,7,8,9,0]]; 2 rows, 5 colsWe get this (I split it up so it had a hope of displaying correctly. It probably didn't though):$array = | 1 2 3 4 5 || 6 7 8 9 0 |If you think of it that way, whats the issue?You've created a 1 dimension array, but you're trying to get the value of a 2D array... I do believe the issue is with your UBound statement though. Probably the reverse of what I just said... 1D instead of 2D, but in ubound you just need to tell it the var name... Edited March 16, 2010 by BrettF Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version! Link to comment Share on other sites More sharing options...
PhilHibbs Posted March 16, 2010 Author Share Posted March 16, 2010 (edited) Neat, but I still don't understand: ConsoleWrite(_VarDump($ProjNum) & @LF) ConsoleWrite(_VarDump($boxes) & @LF) GUICtrlSetState( $Boxes[$ProjNum][1], $GUI_CHECKED ) >Running:(3.3.6.0):C:\Program Files\AutoIt3\autoit3.exe "C:\dev\AutoIt\DSLaunch\DSLaunch2.au3" Integer(0) Array[1] [0] => Array[4] [0] => Integer(31) [1] => Integer(32) [2] => Integer(33) [3] => Integer(34) C:\dev\AutoIt\DSLaunch\DSLaunch2.au3 (398) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.: GUICtrlSetState( $Boxes[$ProjNum][1], $GUI_CHECKED ) GUICtrlSetState( ^ ERROR @BrettF: The array should be 2-dimensional, although it was built dynamically and not explicitly dimensioned. Does an array have to be explicitly dimensioned as 2-dimensional in order for the [][] syntax to work? Edited March 16, 2010 by PhilHibbs Link to comment Share on other sites More sharing options...
jchd Posted March 16, 2010 Share Posted March 16, 2010 (edited) What do you mean by "not explicitely dimensionned" ?Yes, of course, you have to explicitely give as many dimensions ([n] pairs) as you whish to your array. How could AutoIt (or any language) read your mind? Edited March 16, 2010 by jchd This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
BrettF Posted March 16, 2010 Share Posted March 16, 2010 (edited) What do you mean by "not explicitely dimensionned" ? Yes, of course, you have to explicitely give as many dimensions ([n] pairs) as you whish to your array. How could AutoIt (or any language) read your mind? If you're switching between using 2 and 1 dimensions on the same array then your code is pointless and you make it hard for yourself... Use one or two dimensions and not both. AutoIt can know the number of dimensions in an array Ubound($array,0), but doing this way is pretty pointless. Edited March 16, 2010 by BrettF Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version! Link to comment Share on other sites More sharing options...
PhilHibbs Posted March 16, 2010 Author Share Posted March 16, 2010 What do you mean by "not explicitely dimensionned" ? Yes, of course, you have to explicitely give as many dimensions ([n] pairs) as you whish to your array. How could AutoIt (or any language) read your mind? By being dynamically typed? So, how would you address an element of the nested array in the following example from the help file: $$Array[0]=1 $Array[1]=true $Array[2]="Text" $Array[3]=$AnotherArray It seems that the syntax $Array[3][0] is not valid in this case, which is the problem that I am having. Perhaps _ArrayAdd needs to handle adding an array to a multi-dimensional array differently. Bingo, that's it, _ArrayAdd doesn't do multi-dimensional arrays at all. Link to comment Share on other sites More sharing options...
PhilHibbs Posted March 16, 2010 Author Share Posted March 16, 2010 OK, I've solved my problem - I initially DIM the array to be [1][4], and I will live with the fact that there will always be an empty, dummy zeroth entry in the array. I use this variant of _ArrayAdd, and all my loops run from 1 to UBound($array) instead of from 0, and when I delete entries I always stop before the last dummy entry is gone. _ArrayDelete already handles 2-dimensional arrays. Func MyArrayAdd2(ByRef $avArray, $avValue) If Not IsArray($avArray) Then Return SetError(1, 0, -1) If UBound($avArray, 0) <> 2 Then Return SetError(2, 0, -1) Local $iUBound1 = UBound($avArray) Local $iUBound2 = UBound($avValue) ReDim $avArray[$iUBound1 + 1][$iUBound2] For $i = 0 To $iUBound2 - 1 $avArray[$iUBound1][$i] = $avValue[$i] Next Return $iUBound1 EndFunc ;==>_ArrayAdd Link to comment Share on other sites More sharing options...
jchd Posted March 16, 2010 Share Posted March 16, 2010 By being dynamically typed? So, how would you address an element of the nested array in the following example from the help file: This are possibilities: Local $x[2] = [1.234, True] Local $boxes[1][4] = [['abc', 75, $x, default]] ConsoleWrite(_VarDump($boxes) & @LF) ; "array in array" isn't a very good idea ; ; using an intermediate variable Local $y = $boxes[0][2] ConsoleWrite($y[0] & @LF) ; another way: using a function ConsoleWrite(_ArrayInArrayRead($boxes[0][2], 0) & @LF) Func _ArrayInArrayRead(ByRef $ar, $idx) Return $ar[$idx] + 456.90466 EndFunc This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
PhilHibbs Posted March 16, 2010 Author Share Posted March 16, 2010 Func MyArrayAdd2(ByRef $avArray, $avValue) Local $iUBound1 = UBound($avArray) Local $iUBound2 = UBound($avValue) If UBound($avArray, 0) <> 2 Then Dim $TempArray[1][$iUBound2] $avArray = $TempArray $iUBound1 = 0 Else ReDim $avArray[$iUBound1 + 1][$iUBound2] EndIf For $i = 0 To $iUBound2 - 1 $avArray[$iUBound1][$i] = $avValue[$i] Next Return $iUBound1 EndFunc This is my latest 2-dimensional _ArrayAdd variant, it now handles an empty array. This in concert with _ArrayDelete can now be used to dynamically build a 2-dimensional array from scratch, or remove all existing elements from an array and re-populate it from nothing. Standard loops from 0 to UBound($array)-1 will work in all cases. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now