wonderer Posted October 22, 2007 Share Posted October 22, 2007 (edited) So I had a piece of code that was giving the dreaded error: "Array variable has incorrect number of subscripts or subscript dimension range exceeded" I read the forums searching for the answer...found many answers, just not the one I needed. I spent several hours fiddling and wondered what could be going on. Frustrating! Mystifying. If it were a complex script this might be expected...but it all seemed so simple....Finally I found the answer, and I want to share it...I would call what I found a bug, but perhaps it is simply a lack of fastidious programming on my part. What do you think?#include <Array.au3> #include <file.au3> $logfile="c:\logfile" $datfile="c:\datfile" Dim $alist[50000] Dim $foundfiles[300] If _FileReadToArray ( $logfile, $foundfiles ) Then ;define some variables ;ReDim $foundfiles[300] EndIf If Not _FileReadToArray($datfile, $alist) Then MsgBox(4096,"Error", " Error reading alist to Array error:" & @error) Exit EndIf For $x = 1 to 10 ; scan the last 10 records. $ID = $alist[$alist[0]-8*$x] ;records are in 8 line chunks, read backwards through the chunks If _ArraySearch ( $foundfiles, $ID, 1 ) == -1 Then ;record not found in array $foundfiles[0] += 1 ;increment the number of elements in the array $foundfiles[$foundfiles[0]] = $ID ;add to array FileWrite ($logfile, $ID & @CRLF) Else ;the ID was already added. EndIf Next This is a stripped down version that should illustrate the issue.logfile contains a list of ID numbers that were found by the program. They are saved as they are found, and when the program is run, the logfile is loaded into memory so we can be sure we are not re-adding ones we've found before.datfile contains records. We are exracting the ID from each record and saving it. There are 8 lines per record, ID is the first line.The script would load all the elements from logfile easily. The For - Next loop was itself within a loop that would monitor for changes in datfile periodically (by scanning the last 10 records). When new records were found, it would grab those ID's. But I would get "the error" after getting 1 or 2 new records. The line: $foundfiles[$foundfiles[0]] = $ID ;add to arraywas the source of the error. I tried:Global $foundfiles[300] and other simple things that didn't help. Finally I realized that despite my declaration of: Dim $foundfiles[300] or Global $foundfiles[300]the _FileReadToArray was returning an array containing only the number of elements it read from $logfile. I added the ReDim command (that is commented out):ReDim $foundfiles[300]and viola...it worked. So, is this a bug in the way the array is being passed to and from _FileReadToArray (UDF)? Perhaps an error in the StringSplit function at the heart of the UDF? Or do I in fact deserve a slap on the back of my hand? Edited October 22, 2007 by wonderer Link to comment Share on other sites More sharing options...
GEOSoft Posted October 22, 2007 Share Posted October 22, 2007 (edited) #include <Array.au3> #include <file.au3> $logfile="c:\logfile" $datfile="c:\datfile" ;Dim $alist[50000];<<<<<<< Removed and replaced with following $aList = "" ;Dim $foundfiles[300];<<<<<<<< Removed and replaced with following $FoundFiles = "" If _FileReadToArray ( $logfile, $foundfiles ) Then ;define some variables ;ReDim $foundfiles[300] EndIf If Not _FileReadToArray($datfile, $alist) Then MsgBox(4096,"Error", " Error reading alist to Array error:" & @error) Exit EndIf For $x = 1 to 10; scan the last 10 records. $ID = $alist[$alist[0]-8*$x];records are in 8 line chunks, read backwards through the chunks If _ArraySearch ( $foundfiles, $ID, 1 ) == -1 Then;record not found in array $foundfiles[0] += 1 ;increment the number of elements in the array $foundfiles[$foundfiles[0]] = $ID ;add to array FileWrite ($logfile, $ID & @CRLF) Else ;the ID was already added. EndIf Next If _FileReadToArray() is the only function you are using from File.au3 Then you might want to try this modified version. It does not require that you pre-declare the array at all Func _FileReadToArray($sFilePath) Local $hFile $hFile = FileOpen($sFilePath, 0) If $hFile = -1 Then SetError(1) Return 0 EndIf $aArray = StringSplit( StringStripCR( FileRead($hFile, FileGetSize($sFilePath))), @LF) FileClose($hFile) Return $aArray EndFunc Edit: I should have showed how to call the function $foundFiles = _FileReadToArray($logfile) Edited October 22, 2007 by GEOSoft George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 22, 2007 Share Posted October 22, 2007 (edited) ;... Finally I realized that despite my declaration of: Dim $foundfiles[300] or Global $foundfiles[300] the _FileReadToArray was returning an array containing only the number of elements it read from $logfile. I added the ReDim command (that is commented out): ReDim $foundfiles[300] and viola...it worked. So, is this a bug in the way the array is being passed to and from _FileReadToArray (UDF)? Perhaps an error in the StringSplit function at the heart of the UDF? Or do I in fact deserve a slap on the back of my hand? You get the slap. _FileReadToArray() did exactly what it was supposed to do, completely replaced the specified array with a new one of the file's lines. The variable name needed to be declared before hand, but didn't even have to be declared as an array. Nothing about the variable, including its type or length, are preserved. That is normal for AutoIt's variables, they are not "strongly typed" as might be expected from dealing with other languages. P.S. The modified function posted by GeoSoft will do the same (replace the old Type/Size/Content of the variable the return is saved to). Edited October 22, 2007 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
wonderer Posted October 22, 2007 Author Share Posted October 22, 2007 You get the slap. Thanks...i needed that!P.S. The modified function posted by GeoSoft will do the same (replace the old Type/Size/Content of the variable the return is saved to).I figured as much. It would be nice if it were more explicit in the documentation that this was the behavior. Perhaps it does exist and I haven't studied the documentation thoroughly enough. Anyhow, hope this discussion will help someone else...perhaps I'll post a tutorial at some point on the various ways to elicit / repair this error. 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