Jump to content

While loop exit when not intended?


Recommended Posts

Hello,

Using the following code I'm simply trying to search a file every five minutes for a certain string, and then when found just insert a value into an array, indexed by $k. It works fine except for some reason only the "first" value INPUTS[1][1] is input into the array...the While loop continues as intended however the subsequent values INPUTS[1][2], INPUTS[1][3], etc...are not printed in the console. It's like the loop exits after the first search of the file but it shouldn't as I have it written (or so I thought...). Any ideas as to why the $k value doesn't increment are appreciated.

Dim $INPUTS[100][18]
$KEY = "ABCDEF"

$source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0)
$source3 = FileOpen("C:\SegFiles\Automate\HISTORY.txt", 9)  

$i = 1
$k = 1  

While 1
    
 If (StringRight(@MIN, 1) = 0) Or (StringRight(@MIN, 1) = 5) Then  ;if current minute ends in 0 or 5
     
    if $source then
        
     $chars = FileReadLine($source)     
      If @error = -1 Then $k += 1  ;increment after file has been searched every 5 minutes
     $result = StringInStr($chars, $KEY)
 
     if $result > 0 Then
     $EXAMPLE = StringMid($chars, 18, 7)
    
      if $k < 17 Then $INPUTS[$i][$k] = $EXAMPLE
      if $k < 17 Then ConsoleWrite($INPUTS[$i][$k])
     EndIf        
    
    Endif

 EndIf    ;@MIN is 0 OR 5...
 
Wend
Link to comment
Share on other sites

OK I have a better idea of what is happening but I'm unsure how to solve it. The loop is running during the entire minute, thus populating the array values completely but incorrectly...I can control that with a variable (to run once per 5 minutes) but what I want is to run the script once each 5 minutes and add a value to the array each "5 minute run", thus after 85 minutes (17 * 5) the array will have all 17 values in it...is it possible to pass variable values between scripts??

Link to comment
Share on other sites

Just add a sleep(60000). Thus pauseing script after it runs the If Then statement;

Dim $INPUTS[100][18]
$KEY = "ABCDEF"

$source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0)
$source3 = FileOpen("C:\SegFiles\Automate\HISTORY.txt", 9)  

$i = 1
$k = 1  

While 1
    
 If (StringRight(@MIN, 1) = 0) Or (StringRight(@MIN, 1) = 5) Then  ;if current minute ends in 0 or 5
     
    if $source then
        
     $chars = FileReadLine($source)     
      If @error = -1 Then $k += 1  ;increment after file has been searched every 5 minutes
     $result = StringInStr($chars, $KEY)
 
     if $result > 0 Then
     $EXAMPLE = StringMid($chars, 18, 7)
    
      if $k < 17 Then $INPUTS[$i][$k] = $EXAMPLE
      if $k < 17 Then ConsoleWrite($INPUTS[$i][$k])
     EndIf        
     Sleep(60000)
    Endif

 EndIf    ;@MIN is 0 OR 5...
 
Wend

Or with a Sleep(1000) <- 1 second:

If (StringRight(@MIN, 1) + @SEC = 0) Or (StringRight(@MIN, 1) + @SEC = 5) Then
Edited by rogue5099
Link to comment
Share on other sites

I don't fully understand what the heck you're doing, but I know I would structure it more like this:

$Key = "ABCDEF"

While 1
    $Timer = TimerInit() ;Start a timer
    Do 
        Sleep(1000)
        Tooltip("Checking File In: "&Round(((1000*60*5)-TimerDiff($Timer))/1000,2)&" seconds",0,0)
    Until TimerDiff($Timer) >= 1000*60*5 ;5 Minutes
    CheckFile()
WEnd

Func CheckFile()
    $Source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0)
    ;Code to check the file for whatever you need
    ;Code to update array
    FileClose($Source)
Endfunc

If you explained more clearly what you were doing with the file, I could help more.

Edited by Paulie
Link to comment
Share on other sites

Thanks for the responses. I'll play around with the suggestions. Basically I'm trying to do this:

1. Every 5 minutes check a .txt file for a certain string of characters ($KEY)

2. When the desired characters are found then strip out a numerical value from that line in the .txt file

3. Store the stripped value into an array, starting with the first array position

4. Populate the array every 5 minutes until it is "full", with array[1] - array[17] having stored values. Thus it would take a total of 85 minutes to populate the array fully, with 1 value every 5 minutes...

Hope that clears it up a bit.

Link to comment
Share on other sites

Paulie,

I like that method using the Function(), elegant and less coding. I am, however, unsure how to force the Timer to "reset"...as you have written it seems to stop after 5 minutes and the Do/Until loop is no longer executed. I've not worked with timers in AutoIT before, could you explain how to "reset" the timer/Do/Until loop until the required number of 5 minute repititions has elapsed?? Thank you.

Link to comment
Share on other sites

Hello,

For testing purposes I've setup the While/Wend loop to run every second, calling the function each time. I should be seeing the output in the console spit out each second...however I see only the first array values and nothing else. The consolewrite within the While loop (not the function) doesn't print at all, it seems the While loop runs only once and no more...why???

$i = 1
$k = 1  

While 1
Sleep(1000)  
$k += 1
CheckFile() 
ConsoleWrite($k)
Wend

Func CheckFile()
    $source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0)
    
    While 1
    If @error = -1 Then ExitLoop    
        $chars = FileReadLine($source)
    $result = StringInStr($chars, $KEY)
      if $result > 0 Then
      $EXAMPLE = StringMid($chars, 18, 7)
        if $k < 17 Then $INPUTS[$i][$k] = $EXAMPLE
        if $k < 17 Then 
        ConsoleWrite($k & " " & $INPUTS[$i][$k] & @CRLF)      
        EndIf
         EndIf  
    Wend
        FileClose($source)
    
Endfunc
Edited by Burgs
Link to comment
Share on other sites

Paulie,

I like that method using the Function(), elegant and less coding. I am, however, unsure how to force the Timer to "reset"...as you have written it seems to stop after 5 minutes and the Do/Until loop is no longer executed. I've not worked with timers in AutoIT before, could you explain how to "reset" the timer/Do/Until loop until the required number of 5 minute repititions has elapsed?? Thank you.

The timer is "reset" when the $Timer variable is reassigned with TimerInit() when the While...Wend loop repeats.

Thanks for the responses. I'll play around with the suggestions. Basically I'm trying to do this:

1. Every 5 minutes check a .txt file for a certain string of characters ($KEY)

2. When the desired characters are found then strip out a numerical value from that line in the .txt file

3. Store the stripped value into an array, starting with the first array position

4. Populate the array every 5 minutes until it is "full", with array[1] - array[17] having stored values. Thus it would take a total of 85 minutes to populate the array fully, with 1 value every 5 minutes...

Hope that clears it up a bit.

As you have written it, Step 2 is decently complex. Perhaps you could provide up an example of the References.txt file you are reading from, and the numbers you are trying to pull.

Maybe adding this will make it a little better?

$Key = "ABCDEF"
$K = 0

Dim $Inputs[2][18]
While $K < 17; Check 17 times
    $Timer = TimerInit() ;Start/Restart a timer
    Do
        Sleep(1000)
        Tooltip("Checking File In: "&Round(((1000*60*5)-TimerDiff($Timer))/1000,2)&" seconds",0,0)
    Until TimerDiff($Timer) >= 1000*60*5 ;5 Minutes
    $K+=1
    CheckFile($K)
WEnd

Func CheckFile($Increment)
    $Source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0) ;make sure the file is updated.
        ;Code to pull out the values from the text file goes here
            $Value = "foo_"&$Increment 
        ;== 
    $Inputs[1][$Increment] = $Value
    ConsoleWrite(@CRLF&"$Inputs[1]["&$Increment&"] = "&$Value)
    FileClose($Source)
Endfunc
Link to comment
Share on other sites

Thanks for the reply. I think you have the idea as the code you posted seems to have the desired effect. When I place my code into the function to "strip out" the required text from the file it seems to cause my continuous problems with the While/Wend loop no longer functioning. I use FileReadLine and StringInStr to "look" for the info I'd like to strip out, so my function is as so:

Func CheckFile($Increment)
    $Source = FileOpen("C:\SegFiles\Automate\Referencpe.txt", 0)  ;make sure the file is updated.
        ;Code to pull out the values from the text file goes here
While 1
 If @error = -1 Then ExitLoop  ;***DOES THIS CAUSE PROBLEMS WITH THE "CALLIN" WHILE/WEND LOOP?  
 $chars = FileReadLine($source)  ;READ EACH LINE IN THE $SOURCE FILE...
 $result = StringInStr($chars, $KEY)  ;FIND THE LINE WITH THE "KEY" TEXT...
   if $result > 0 Then  ;FOUND THE LINE WITH THE "KEY" TEXT...
   $EXAMPLE = StringMid($chars, 18, 7)  ;STRIP OUT THE DESIRED TEXT FROM THAT LINE...
    if $k < 17 Then $INPUTS[$i][$k] = $EXAMPLE  ;PLACE THE STRIPPED TEXT INTO THE ARRAY
   EndIf    
Wend    
            $Value = "foo_"&$Increment 

        ;== 
    $Inputs[1][$Increment] = $Value
    ConsoleWrite(@CRLF&"$Inputs[1]["&$Increment&"] = "&$Value)
    FileClose($Source)
Endfunc

My code finds the desired text to rip out without difficulty however as stated before how do I incorporate it without it messing with my loop? No matter how I modify my script I seem to always be "killing" the While/Wend loop so there is no more than 1 iteration...? Thanks again.

Link to comment
Share on other sites

Hello,

This is driving me crazy. Can somebody please explain why the code below only inputs the value(s) to the first array position only (INPUTS[1])?? Everything else works as it should, such as:

1. The script runs correctly every 5 seconds

2. The value for $K is incremented by 1 correctly each run

3. The correct desired text to search for is properly found

However the "_ArrayInsert($INPUTS, $K, $EXAMPLE)" is only inputing to array position $INPUTS[1], instead of the desired $INPUTS[1], $INPUTS[2], $INPUTS[3], $INPUTS[4]...etc as dictated by the value of $K...It's as if the script stops searching after the desired text is found the first time, however I would think a "new" search should be initiated every time the timer is reset (every 5 seconds), thus forcing the next array position to be used to output to. Any help appreciated.

Dim $INPUTS[18]
$KEY = "ABCDE"

$source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0)

$k = 1  

While $K < 17  ;Check 17 times

    $Timer = TimerInit()  ;Start/Restart a timer
     Do
    
        Tooltip("Checking File In: "&Round(((1000*1*5)-TimerDiff($Timer))/1000,2)&" seconds",0,0)   

    
 if $source Then
     
     $chars = FileReadLine($source)     

     $result = StringInStr($chars, $KEY)
 
     if $result > 0 Then
     $EXAMPLE = StringMid($chars, 18, 7)    
     _ArrayInsert($INPUTS, $K, $EXAMPLE)
     EndIf   

 EndIf   
 
     Until TimerDiff($Timer) >= 1000*1*5  ;5 seconds    
     ConsoleWrite($K)
     _ArrayDisplay($INPUTS, "$INPUTS")
     $K+=1      

Wend
Link to comment
Share on other sites

It works if you move the Until line to before the file read functions like this:

#include <array.au3>
Dim $INPUTS[18]
$KEY = "ABCDE"

$source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0)
$k = 1

While $k < 17 ;Check 17 times

    $Timer = TimerInit() ;Start/Restart a timer
    Do

        ToolTip("Checking File In: " & Round(((1000 * 1 * 5) - TimerDiff($Timer)) / 1000, 2) & " seconds", 0, 0)

    Until TimerDiff($Timer) >= 1000 * 1 * 5 ;5 seconds

    If $source Then

        $chars = FileReadLine($source)
        ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $chars = ' & $chars & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

        $result = StringInStr($chars, $KEY)

        If $result > 0 Then
            $EXAMPLE = StringMid($chars, 18, 7)
            _ArrayInsert($INPUTS, $k, $EXAMPLE)
        EndIf

    EndIf

    ConsoleWrite($k)
    _ArrayDisplay($INPUTS, "$INPUTS")
    $k += 1

WEnd

You were reading the whole file every time and storing it in the Inputs array, now it will only read one line at a time every 5 seconds.

Edited by BrewManNH

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Thanks for your reply, but that's not exactly what I wish to do. The code you posted seems to cycle through 17 lines of the $source file and then post the "found" text to it's line position in the array...

What I'm trying to do is cycle through the entire file (it's 31 lines) to find the desired text, but do it 17 times (every 5 seconds) until all array positions $INPUTS[1] - $INPUTS[17] are "filled" with values. Thus the first run should output the desired text to $INPUTS[1], 5 seconds later it should run again and output the desired text to $INPUTS[2]...and so on until after 85 seconds (17 * 5) have elapsed and $INPUTS[17] has a value...

Link to comment
Share on other sites

Does the text in the file keep changing?

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Yes the text in the $source file changes, which is the reason for continuous (5 second, 5 minute, 5 hour, whatever) updates...to create a "history" type array file. I'm only using 5 second intervals right now for testing, I can change that if/when the code logic performs as needed.

Link to comment
Share on other sites

Sorry, I misunderstood what you were trying to acheive. How about trying this attempt and see if it works as intended.

#include <array.au3>
Dim $INPUTS[18]
Global $File
$KEY = "ABCDE"
$source = FileOpen("C:\SegFiles\Automate\Reference.txt", 0)
$k = 1
$Timer = TimerInit() ;Start/Restart a timer
While $k < 17 ;Check 17 times
    If TimerDiff($Timer) >= 5000 Then
        While 1
            If $source Then
                $chars = FileReadLine($source)
                If @error = -1 Then ExitLoop
                $result = StringInStr($chars, $KEY)
                If $result > 0 Then
                    $EXAMPLE = StringMid($chars, 18, 7)
                    $INPUTS[$k] = $EXAMPLE
                EndIf
            EndIf
        WEnd
        ConsoleWrite($k)
        _ArrayDisplay($INPUTS, "$INPUTS")
        $k += 1
        $Timer = TimerInit()
        FileClose($source)
        $source = FileOpen("Reference.txt", 0)
    Else
        ToolTip("Checking File In: " & Round(((1000 * 1 * 5) - TimerDiff($Timer)) / 1000, 2) & " seconds", 0, 0)
    EndIf
WEnd

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Yes, very clever...that seems to be more what I was shooting for. Thank you. My code was very similar however I didn't realize it was necessary to call both the FileOpen and the Timer commands a second time...seems a bit strange to have to do that. Thanks again very much!

Link to comment
Share on other sites

If you have read the whole file, at least with my tests, it wouldn't read from the beginning again unless I closed it and reopened it. You could also do it by using FileReadLine($Source, <line number>) and just reset it back to lin 1 when you've read the whole file.

The TimerInit has to be reset everytime your TimerDiff gets past 5 seconds unless your check is increased by 5000 ms every time. Resetting makes it a lot easier to code.

By the way, _ArrayInsert will add lines to the array making it larger everytime you insert a new line, so your Inputs array would have 36 elements in it by the end of the loops. I didn't think that was what you were shooting for so I recoded that part as well.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...