Sign in to follow this  
Followers 0
leomoon

Error: Subscript used with non-Array variable

8 posts in this topic

Ok so I wrote a little script that will read an INI file and search startup folder to see if that name exists and if it does, it will delete it. But I keep getting the error msg: Subscript used with non-Array variable. Can somebody please tell me what I'm doing wrong?

Script:

#include <File.au3>
#include <Array.au3>

$configFile = "startup.ini"

_qtStartupCleanup()

Func _qtStartupCleanup()
    ;ini Read
    $startupCleaner = IniReadSection($configFile, "Startup Cleanup")
    If @error Then
        Sleep(500)
    Else
        For $startupCleanerCr = 1 To $startupCleaner[0][0]
            If $startupCleaner[$startupCleanerCr][1] = 1 Then
                $SearchFor = $startupCleaner[$startupCleanerCr][0]
                _startupFileList($SearchFor)
            EndIf
        Next
    EndIf
EndFunc

Func _startupFileList($startupFile)
    ;StartupDir
    $startupFileList = _FileListToArray(@StartupDir, "*", 1)
    If @error = 1 Then
        ;Do nothing
    EndIf
    ;Search for string
    For $i = 1 To $startupFileList[0]
        If $i > $startupFileList[0] Then ExitLoop
        If StringInStr($startupFileList[$i], $startupFile) Then
            FileDelete(@StartupDir&'\'&$startupFileList[$i])
            _ArrayDelete($startupFileList, $i)
            $i -= 1
            $startupFileList[0] -= 1
        EndIf
    Next
EndFunc

INI:

[Startup Cleanup]
dellDock=1
java=1

Thanks.

Share this post


Link to post
Share on other sites



Run this example and then look at your search loop:

$n = 20
For $i=0 To $n
 $n = 1 ;should make it stop right?
 ConsoleWrite($i & @CRLF)
Next

A for loop only evaluates it's parameters when it's called, so deleting an array index like this will cause it to fail.

You could flip the loop around. Start at the highest index, then search to 1, or store the indexes you want to delete and then delete them when your loop has finished. (from highest to lowest to avoid the indexes shifting)

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Hi leomoon !

simply after your _ArrayDelete ( $startupFileList, $i ) you must set $startupFileList[0]=UBound ( $startupFileList ) -1 Posted Image

#include <File.au3>
#include <Array.au3>

$configFile = "startup.ini"

_qtStartupCleanup()

Func _qtStartupCleanup()
    $startupCleaner = IniReadSection ( $configFile, "Startup Cleanup" )
    If Not @error Then
        For $startupCleanerCr = 1 To $startupCleaner[0][0]
            If $startupCleaner[$startupCleanerCr][1] = 1 Then
                $SearchFor = $startupCleaner[$startupCleanerCr][0]
                _startupFileList($SearchFor)
            EndIf
        Next
    EndIf
EndFunc

Func _startupFileList ( $startupFile )
    $startupFileList = _FileListToArray ( @StartupDir, "*", 1 )
    If Not @error  Then
        For $i = 1 To $startupFileList[0]
            If StringInStr ( $startupFileList[$i], $startupFile ) Then
                FileDelete ( @StartupDir & '\' & $startupFileList[$i] )
                _ArrayDelete ( $startupFileList, $i )
                $startupFileList[0]=UBound ( $startupFileList )-1
            EndIf
        Next
    EndIf 
EndFunc
Edited by wakillon

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

Tnx a lot for all the replies. Both ways work. The second way I understand. I rewrote the whole thing in a way that doesn't require deleting arrays. So here is final code for people who might have the same problem:

#include <File.au3>
#include <Array.au3>

$configFile = "startup.ini"

$startupCleaner = IniReadSection($configFile, "Startup Cleanup")
If @error Then
    Sleep(500)
Else
    For $startupCleanerCr = 1 To $startupCleaner[0][0]
        If $startupCleaner[$startupCleanerCr][1] = 1 Then
            $SearchFor = $startupCleaner[$startupCleanerCr][0]

            ;StartupDir Search
            $startupFiles=_FileListToArray(@StartupDir, "*", 1)
            If @Error=1 Then
                Sleep(100)
            EndIf
            ;~ _ArrayDisplay($startupFiles, '')
            For $i = 1 To $startupFiles[0]
                If StringInStr($startupFiles[$i], $SearchFor) Then
                    FileDelete(@StartupDir&'\'&$startupFiles[$i])
                EndIf
            Next

        EndIf
    Next
EndIf

Share this post


Link to post
Share on other sites

Tnx a lot for all the replies. Both ways work.

Actually the second way is the same as your first one and will not work because of the way For loops work. I'll demonstrate it here:

#include<array.au3>
Local $sSearch = "match" ;searchstring

;first method (search in reversed order)
MsgBox(0,"Test","Starting method 1")
Local $aValues[10] = [9,1,2,3,"match",5,6,7,8,9] ;set up an array with one match to the searchstring
For $i = $aValues[0] To 1 Step -1 ;the array counts down this way
    If StringInStr ( $aValues[$i], $sSearch ) Then
        FileDelete ( @StartupDir & '\' & $aValues[$i] )
        _ArrayDelete ( $aValues, $i )
    EndIf
Next
_ArrayDisplay($aValues) ;show the adjusted array

;second method (update $aValues[0])
MsgBox(0,"Test","Starting method 2")
Local $aValues[10] = [9,2,3,"match",5,6,7,8,9]
For $i = 1 To $aValues[0]
    If StringInStr ( $aValues[$i], $sSearch ) Then
        FileDelete ( @StartupDir & '\' & $aValues[$i] )
        _ArrayDelete ( $aValues, $i )
        $aValues[0]=UBound ( $aValues )-1
    EndIf
Next
_ArrayDisplay($aValues) ;show the adjusted array (won't happen, trust me)

Your adjusted script looks pretty good, but I see a few potential improvements for it:

1. If _FileListToArray returns @error (with any value, you're only checking for 1) you might as well call Exitloop, or Exit. It's not going to work for the rest of the script anyways

2. Are you sure you want to use StringInStr for your comparison? it might produce false positives.

3. Call _FileListToArray once and update that array like you tried before. You don't even have to delete any values if you replace StringInStr, with "="

Share this post


Link to post
Share on other sites

You are right !

But i find a solution Posted Image

#include<array.au3>
Local $sSearch = "match" 

Local $aValues[10] = [9,1,2,"match",4,5,6,7,8,9 ]
_ArrayDisplay($aValues)
For $i = 1 To $aValues[0]
    If StringInStr ( $aValues[$i], $sSearch ) Then
        FileDelete ( @StartupDir & '\' & $aValues[$i] )
        _ArrayDelete ( $aValues, $i )
        $aValues[0]=UBound ( $aValues )-1
    EndIf
    If $i = $aValues[0] Then ExitLoop
Next
_ArrayDisplay($aValues)

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0