Sign in to follow this  
Followers 0
butterfly

About Global Local and For next $z help me tutorial

2 posts in this topic

Hello FellowForumers

I have some questions about this subject and Although I have researched about i have some problems let it sink in proper

Although i have basic understanding of Global and Local I Still have questions to be absolute sure:

#include <Array.au3>

Global $TSAB[20]

While 1
    trading()
    If $TSAB[19] = True Then MsgBox(0,"","Thank you AutoIT Forum ^^ ")
;~  If $TSAB[19] = True then Exit
WEnd

func trading()
    $TSAB[19] = ""
    $TSAB[7] = ""
    while 1
        _ArrayDisplay($TSAB)
        $TSAB[7] = "done"
        _ArrayDisplay($TSAB)
        If $TSAB[7] = "Done" Then $TSAB = ClientDoneCommand()
        _ArrayDisplay($TSAB)
        If $TSAB[19] = True then Return $TSAB
    WEnd
EndFunc

func ClientDoneCommand()
    $TSAB[19] = True
    Return $TSAB
EndFunc

My own example Above gives to me Decent understanding that Global can be called anywhere in the program and that the global variable is sent and called towards other functions and loops as it was just before it got sent or returned

is there anything I have to keep in mind to Prevent any big mess? Am I something missing about this or has anyone some advice?

I will use this global as the soul of my program and store information on where it has been and been and what functions it has visit and what it has been doing etc

Here I move to Local $var

So I got the same script and added some Local var:

#include <Array.au3>

Global $TSAB[20]
local $hugs = ""

While 1
    ConsoleWrite($hugs & "0" & @LF) ;Added line
    $hugs = trading()
    If $TSAB[19] = True Then MsgBox(0,"","Thank you AutoIT Forum ^^ ")
;~     If $TSAB[19] = True then Exit
ConsoleWrite($hugs & "1" & @LF) ;Added line
WEnd

func trading()
    $TSAB[19] = ""
    $TSAB[7] = ""
    local $hugs = "yes"
    while 1
        ConsoleWrite($hugs & "2" & @LF) ;Added line
        _ArrayDisplay($TSAB)
        $TSAB[7] = "done"
        _ArrayDisplay($TSAB)
        If $TSAB[7] = "Done" Then $TSAB = ClientDoneCommand($hugs)
        _ArrayDisplay($TSAB)
        ConsoleWrite($hugs & "4" & @LF) ;Added line
        If $TSAB[19] = True then Return $TSAB
    WEnd
EndFunc

func ClientDoneCommand($hugs)
    $TSAB[19] = True
    ConsoleWrite($hugs & "3" & @LF) ;Added line
    $hugs = "Maybe"
    Return $TSAB
EndFunc

Here I added a few console writes and numbered them the consolewrite output is

0
yes2
yes3
yes4
1
repeat

So the following things I see in my blurry mind as are as follow

at the very start I need to declare Local $hugs = ""  else ;
ConsoleWrite($hugs & "0" & @LF) 

 ;Added line will have variable used before declaration (meaning nothing has been stored ever which I understand)

Now here comes an interesting part to me, about:

    $hugs = trading()
    If $TSAB[19] = True Then MsgBox(0,"","Thank you AutoIT Forum ^^ ")
;~     If $TSAB[19] = True then Exit
ConsoleWrite($hugs & "1" & @LF) ;Added line

here Happens nothing , not even a error (which I expected)

I do not get a consolewrite: 0

it does not output anything

I understand that the functions has not returned the variable of

local $hugs = "yes" or     $hugs = "Maybe"

But I expected an error, why no error?

What Happens with the at line 33

$hugs = "Maybe"

does it get lost? deleted (from the memory ) at the end of the function?

@ line 17?

local $hugs = "yes"

Would it be wise to write there local $hugs = "yes" or is $hugs = "yes" Good enough , does it really matter with managing anything?

and as last I also understand if I would change

that at line 26 that it is not needed the write return $TSAB but just return would be good enough?

because $TSAB is in every function / If / while for next loop avaiable and it will carry over the information stored inside of it?

if i would change it into

Return $hugs

then

ConsoleWrite($hugs & "1" & @LF)  will give me yes1

and even at the very start of the while loop

ConsoleWrite($hugs & "0" & @LF)   will give me yes0 and it was previous just 0

so it seems

anything wrong here? so it seems the local does not get lost at the end of the while loop

then my final questions about for / next

For $z = 0 to 9
    For $x = 0 to 9
        For $y = 0 to 9
        ConsoleWrite($z & $x & $y & @LF)
        next
    next
next
if $z = 9 Then  MsgBox(0,"","1000 ^^ ")
if $x = 9 Then  MsgBox(0,"","x = 9 ^^ ")
if $y = 9 Then  MsgBox(0,"","y = 9 ^^ ")

the Variable $z , $x and $y

are they only used in the for next loop or can they be used outside of it?

my msgboxs do not work here after the next so i guess they end right away in the for next loop

any tips or suggestions are welcome if i am saying anything wrong or retarded here

Cheers Butterfly

Share this post


Link to post
Share on other sites



tl;dr

All you need to know about Global/Local is described in the Help file or in the Wiki.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

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

  • Similar Content

    • InunoTaishou
      By InunoTaishou
      I know on other languages when you try to use a string like this
      Global $sString = "Some String" If ($sString) Then ; ... EndIf The compiler will fail because string cannot be used in an expression where it needs a bool (something along those lines). But I see instances in other languages where using $sString in an expression will work and implicitly use the length of the string (or because there is some value in that variable).
      I'm wondering why AutoIt doesn't do the same. If the $sString is used like in my example (or some other expression where it wants a bool type) implicitly use the length of the string instead of the converting to 0?
    • TheDcoder
      By TheDcoder
      Hello everyone, I discovered a bug yesterday and I posted it at the bug tracker:
      I also made a simple script which can be used to reproduce the bug:
      CreateVariable() ConsoleWrite($sGlobalVariable & @CRLF) Func CreateVariable() Global $sGlobalVariable = "Foobar" EndFunc The bug was closed by @BrewManNH:
      While I partially agree with the above statement, My code was not practical enough... so @mLipok advised me to create a thread on the forums with practical code (Thanks!). That is the point of this thread, I am going to provide the code where I experience this bug/problem .
      I discovered this bug when I was working on one of my projects called "ProxAllium". When the main script finishes execution, Au3Check throws a nasty warning about "variable possibly used before declaration":

      As you can see, the variable is indeed being used after calling the function in which the variable is declared... The warning won't appear if I declare the function ABOVE the variable. As @BrewManNH said, Au3Check reads line by line... I think this should be changed, Au3Check should not throw warnings if the interpreter is able to run the code, at least most of the time anyway!
      So what do you guys think? Is this a valid bug?... and I request those who participate in the discussion not to discuss the code being "poor", that is another thing/thread in itself
      P.S I had already written this once but the forum editor decided to mess up and when I undid (Ctrl + Z) something... This is a poorly written version of that article, I was very frustrated while writing this!
    • ZeroByDevide
      By ZeroByDevide
      so right now i have a small project and i wanted to print this text out every second.
      i have made a random number for the sleep function. but when i want to print out with the while loop it just doesn't work.
      Run("notepad.exe") Sleep(1000) Local $rndSleep = Int (Random(180000,240000,1000)) While $rndSleep <> 0 $rndSleep - 1 If Mod ( $rndSleep, 1000 ) == 0 Then Send("This note will show the sleeptime before closing the tabs, you got " & $rndSleep & " seconds left.") EndIf WEnd plis halp me 
    • czardas
      By czardas
      Test instructions are easy.
      1. Run the following code in post #46
      2. Click the advanced tab
      3. Select a start date and an end date
      4. Put a tick in the checkbox where it says 'Include Days Of The Week'
      5. Click the Okay button
      You should get an array with a column of dates in your local format and a second column with day names in your language. It has a current range limit of just under 89 years but this range can appear anywhere between the years 1601 and 9999. The code is untidy and unfinished, but I would still like to know if it works outside the UK. No extra includes are needed. If it works in China, that would make me happy.
      Latest version in post #46
      https://www.autoitscript.com/forum/topic/184849-please-test-this-in-your-language-region/?do=findComment&comment=1327947
      #include <Array.au3> #include <GUIConstants.au3> #include <GuiEdit.au3> #include <Misc.au3> #include <GuiTab.au3> #include <Date.au3> #include <APILocaleConstants.au3> #include <WinAPILocale.au3> ;#include <ArrayWorkshop.au3> ; required functions are already included in this demo NewTable() Func NewTable(); ($hParent, $idListView, $hListView) ; [missing parent window] Local $sTitle = "New Table", _ $iStyle = BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), _ $iExStyle = BitOR($WS_EX_MDICHILD, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST), _ $iWidth = 250, _ $iHeight = 292 Local $hChild = GUICreate($sTitle, $iWidth, $iHeight, Default + 100, Default + 100); , $iStyle, $iExStyle, $hParent) Local $idTab = GUICtrlCreateTab(2, 2, $iWidth -2, $iHeight -32) GUICtrlCreateTabItem("Standard") GUICtrlCreateLabel("Table Dimensions", 14, 35, 120, 20) GUICtrlSetColor(-1, 0x008000) GUICtrlCreateLabel("Number Of Columns", 14, 60, 94, 18) Local $hStandardCols = GUICtrlCreateInput("0", 104 +14, 55, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER)) GUICtrlSetFont(-1, 10) GUICtrlCreateLabel("Number Of Rows", 14, 83, 90, 18) Local $hStandardRows = GUICtrlCreateInput("0", 104 +14, 81, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER)) GUICtrlSetFont(-1, 10) GUICtrlCreateLabel("Table Indices", 14, 114, 120, 20) GUICtrlSetColor(-1, 0x008000) Local $hIndices = GUICtrlCreateCheckbox(" Enumerate First Column", 14, 137, 160, 20) ; REMEMBER YES, SETTINGS NO Local $hPadding = GUICtrlCreateCheckbox(" Include Leading Zeros", 14, 161, 124, 20) ; REMEMBER YES, SETTINGS NO GUICtrlCreateTabItem("Advanced") GUICtrlCreateLabel("Column 1 = Date Range", 14, 35, 120, 20) GUICtrlSetColor(-1, 0x008000) GUICtrlCreateLabel("Start Date", 14, 35 +20, 100, 20) Local $idDate1 = GUICtrlCreateDate("", 14, 56 +20, 105, 20, $WS_TABSTOP) GUICtrlCreateLabel("End Date", $iWidth - 118, 35 +20, 100, 20) Local $idDate2 = GUICtrlCreateDate("", $iWidth - 118, 56 +20, 105, 20, BitOR($WS_TABSTOP, $DTS_RIGHTALIGN)) GUICtrlCreateLabel("Column 2 = Days Of The Week (Optional)", 14, 108, 220, 20) GUICtrlSetColor(-1, 0x008000) Local $hCheckBox = GUICtrlCreateCheckbox(" Include Days Of The Week ", 14, 128, 190, 20) ; REMEMBER YES, SETTINGS NO Local $hRadio1 = GUICtrlCreateRadio(" Use Short Name", 14, 151) Local $hRadio2 = GUICtrlCreateRadio(" Use Long Name", $iWidth - 118, 151) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetState($hRadio1, $GUI_DISABLE) ; check settings later GUICtrlSetState($hRadio2, $GUI_DISABLE) ; check settings later GUICtrlCreateLabel("Add More Columns", 14, 181, 222, 20) GUICtrlSetColor(-1, 0x008000) GUICtrlCreateLabel("Total Number Of Columns", 14, 182 +23, 129, 18) Local $hColNum = GUICtrlCreateInput("1", 130 +14, 182 +21, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER)) ; REMEMBER YES, SETTINGS NO GUICtrlSetFont(-1, 10) GUICtrlCreateTabItem("") ; end tabitem definition Local $hCancel = GUICtrlCreateButton("Cancel", $iWidth -143, $iHeight -25, 66, 20) Local $hOkay = GUICtrlCreateButton("OK", $iWidth -69, $iHeight -25, 66, 20) GUISetState(@SW_SHOW) Local $msg2, $bDisable = True, $iMaxFields = 65000, $bStandardError = False, $iRows = 0, $iCols = 0, _ $sMonitorAdv = GUICtrlRead($idDate1) & GUICtrlRead($idDate2) & GUICtrlRead($hColNum), $sDate1, $sDate2, $sColsAdv, $iDiff, $bErrorAdv = False While 1 $msg2 = GUIGetMsg() If $msg2 = $hCancel Or $msg2 = $GUI_EVENT_CLOSE Then ExitLoop If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then If $bDisable Then GUICtrlSetState($hRadio1, $GUI_ENABLE) GUICtrlSetState($hRadio2, $GUI_ENABLE) $bDisable = False EndIf ElseIf Not $bDisable Then GUICtrlSetState($hRadio1, $GUI_DISABLE) GUICtrlSetState($hRadio2, $GUI_DISABLE) $bDisable = True EndIf $sDate1 = GUICtrlRead($idDate1) $sDate2 = GUICtrlRead($idDate2) $sColsAdv = GUICtrlRead($hColNum) If $sDate1 & $sDate2 & $sColsAdv <> $sMonitorAdv Then $iDiff = DateRange(LocaleDateToYMD($sDate1), LocaleDateToYMD($sDate2)) ; _DateDiff() is too limited If $iDiff * $sColsAdv > $iMaxFields Then If Not $bErrorAdv Then GUICtrlSetBkColor($hColNum, 0xFFA090) $bErrorAdv = True EndIf ElseIf $bErrorAdv Then GUICtrlSetBkColor($hColNum, 0xFFFFFF) $bErrorAdv = False EndIf $sMonitorAdv = $sDate1 & $sDate2 & $sColsAdv EndIf $iCols = GUICtrlRead($hStandardCols) $iRows = GUICtrlRead($hStandardRows) If Not $iRows Then GUICtrlSetData($hStandardRows, 0) If Not $iCols Then GUICtrlSetData($hStandardCols, 0) If ControlGetFocus($hChild) <> "Edit2" And StringRegExp($iRows, '\A0+[1-9]') Then GUICtrlSetData($hStandardRows, StringRegExpReplace($iRows, '(\A0+)([1-9])(\d+)*', '$2$3')) If ControlGetFocus($hChild) <> "Edit1" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($hStandardCols, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3')) If $iRows > $iMaxFields Or $iCols > $iMaxFields Or GUICtrlRead($hStandardRows) * GUICtrlRead($hStandardCols) > $iMaxFields Then If Not $bStandardError Then GUICtrlSetBkColor($hStandardRows, 0xFFA090) GUICtrlSetBkColor($hStandardCols, 0xFFA090) $bStandardError = True EndIf ElseIf $bStandardError Then GUICtrlSetBkColor($hStandardRows, 0xFFFFFF) GUICtrlSetBkColor($hStandardCols, 0xFFFFFF) $bStandardError = False EndIf $iCols = GUICtrlRead($hColNum) If ControlGetFocus($hChild) <> "Edit3" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($hColNum, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3')) $iCols = GUICtrlRead($hColNum) If $iCols < 1 Then If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED And ControlGetFocus($hChild) <> "Edit3" Then GUICtrlSetData($hColNum, 2) Else GUICtrlSetData($hColNum, 1) EndIf If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($hColNum, 0, -1) EndIf If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then If $iCols < 2 And ControlGetFocus($hChild) <> "Edit3" Then If ControlGetFocus($hChild) = "Button3" Then While _IsPressed('01') Sleep(20) WEnd EndIf If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then GUICtrlSetData($hColNum, 2) Else GUICtrlSetData($hColNum, 1) EndIf EndIf Else If $iCols < 1 Then GUICtrlSetData($hColNum, 1) If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($hColNum, 0, -1) EndIf EndIf If $msg2 = $hOkay Then If $bErrorAdv Then MsgBox(262160, "uh-uh!", "Out of Range") ContinueLoop EndIf Local $sDelim = '-' ; read from settings ??? [maybe] If _GUICtrlTab_GetCurFocus($idTab) = 1 Then Local $iName, $sFormat = Default ; read from settings [ini] If BitAND(GUICtrlRead($hCheckBox), $GUI_CHECKED) == $GUI_CHECKED Then $iName = (BitAND(GUICtrlRead($hRadio1), $GUI_CHECKED) == $GUI_CHECKED) ? 3 : 2 Else $iName = -1 EndIf ; $sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1) GetDateArray(GUICtrlRead($idDate1), GUICtrlRead($idDate2), $sDelim, $sFormat, $iName) ; US [, '$3-$5-$1']) EndIf EndIf WEnd GUIDelete($hChild) EndFunc ;==> NewTable Func LocaleDateToYMD($sDate, $sDelim = '/') Local $iID = _WinAPI_GetUserDefaultLCID(), _ $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3), _ $vTest = True ; [floating variable] If IsArray($aDateSplit) And UBound($aDateSplit) = 3 Then For $i = 0 To 2 ; determine the locale ymd order If StringInStr($aDateSplit[$i], 'y') Then $aDateSplit[$i] = 1 ; year ElseIf StringInStr($aDateSplit[$i], 'm') Then $aDateSplit[$i] = 2 ; month ElseIf StringInStr($aDateSplit[$i], 'd') Then $aDateSplit[$i] = 3 ; day EndIf Next $vTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2] If StringInStr($vTest, '1') And StringInStr($vTest, '2') And StringInStr($vTest, '3') Then $vTest = False ; success EndIf If $vTest Then ; failure with the previous method [both methods work on Win7 in the UK] Local $sLongDate = _WinAPI_GetDateFormat(0, 0, $DATE_LONGDATE) $aDateSplit = StringRegExp($sLongDate, '(*UCP)\w+', 3) If Not IsArray($aDateSplit) And UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error? For $i = 0 To 2 ; determine the locale ymd order If $aDateSplit[$i] = @YEAR Then ; hopefully this method will work for all international regions $aDateSplit[$i] = 1 ; year ElseIf $aDateSplit[$i] = _DateToMonth(@MON, $DMW_LOCALE_LONGNAME) Then $aDateSplit[$i] = 2 ; month Else $aDateSplit[$i] = 3 ; day EndIf Next $vTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2] If Not (StringInStr($vTest, '1') And StringInStr($vTest, '2') And StringInStr($vTest, '3')) Then Return SetError(2) ; undetermined error? EndIf Local $iCount = 1, $sYMD = '' Do For $i = 0 To 2 If $aDateSplit[$i] = $iCount Then $sYMD &= '$'& ($i*2 +1) & ($iCount <> 3 ? $sDelim : '') $iCount += 1 ExitLoop EndIf Next Until $iCount = 4 Return StringRegExpReplace($sDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD) EndFunc Func GetDateArray($sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1) Local $iID = _WinAPI_GetUserDefaultLCID(), _ $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3) If IsArray($aDateSplit) And UBound($aDateSplit) = 3 Then For $i = 0 To 2 ; determine the locale ymd order If StringInStr($aDateSplit[$i], 'y') Then $aDateSplit[$i] = 1 ; year ElseIf StringInStr($aDateSplit[$i], 'm') Then $aDateSplit[$i] = 2 ; month ElseIf StringInStr($aDateSplit[$i], 'd') Then $aDateSplit[$i] = 3 ; day EndIf Next Else ; let's try an alternative method [both methods work on Win7 in the UK] Local $sLongDate = _WinAPI_GetDateFormat(0, 0, $DATE_LONGDATE) $aDateSplit = StringRegExp($sLongDate, '(*UCP)\w+', 3) If Not IsArray($aDateSplit) And UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error? For $i = 0 To 2 ; determine the locale ymd order If $aDateSplit[$i] = @YEAR Then ; hopefully this method will work for all international regions $aDateSplit[$i] = 1 ; year ElseIf $aDateSplit[$i] = _DateToMonth(@MON, $DMW_LOCALE_LONGNAME) Then $aDateSplit[$i] = 2 ; month Else $aDateSplit[$i] = 3 ; day EndIf Next EndIf ; check the array contains numbers 1 to 3 Local $sTest = $aDateSplit[0] & $aDateSplit[1] & $aDateSplit[2] If Not (StringInStr($sTest, '1') And StringInStr($sTest, '2') And StringInStr($sTest, '3')) Then Return SetError(2) ; undetermined error? If $sDelim = Default Then $sDelim = StringRegExp($sStartDate, '\D+', 3)[0] Local $iCount = 1, $sYMD = '' Do For $i = 0 To 2 If $aDateSplit[$i] = $iCount Then $sYMD &= '$'& ($i*2 +1) & ($iCount <> 3 ? $sDelim : '') $iCount += 1 ExitLoop EndIf Next Until $iCount = 4 $sStartDate = StringRegExpReplace($sStartDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD) $sStopDate = StringRegExpReplace($sStopDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD) Local $vReverse = False If $sStartDate > $sStopDate Then $vReverse = $sStartDate $sStartDate = $sStopDate $sStopDate = $vReverse EndIf ; internal format = yyyy/mm/dd Local $iStartYear = Number(StringRegExp($sStartDate, '\d+', 3)[0]), $iStopYear = Number(StringRegExp($sStopDate, '\d+', 3)[0]) Local $aTimeLine[(($iStopYear - $iStartYear +1) *366)] $iCount = 0 For $iYear = $iStartYear To $iStopYear For $iMon = 1 To 12 Switch $iMon Case 1, 3, 5, 7, 8, 10, 12 For $iDay = 1 To 31 ; this section of code can be shortened $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay) If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3 $iCount += 1 Next Case 4, 6, 9, 11 For $iDay = 1 To 30 $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay) If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3 $iCount += 1 Next Case Else For $iDay = 1 To IsLeapYear($iYear) ? 29 : 28 $aTimeLine[$iCount] = $iYear & $sDelim & StringFormat('%02i', $iMon) & $sDelim & StringFormat('%02i', $iDay) If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3 $iCount += 1 Next EndSwitch Next Next ReDim $aTimeLine[$iCount +1] ; get rid of unused elements For $i = 0 To UBound($aTimeLine) -1 If $aTimeLine[$i] = $sStartDate Then _DeleteRegion($aTimeLine, 1, 0, $i) ExitLoop EndIf Next _Predim($aTimeLine, 2) ; add 2nd dimension ; adding a day name column only works for start dates up to christmas day 2999 [millennium bug], is it worth fixing? ==> [FIXED] If $iDayName <> -1 Then ; $iDayName set to -1 because _DateDayOfWeek() format values range from 0 to 3 ReDim $aTimeLine[UBound($aTimeLine)][2] Local $aNextDay, $iDayNum If $sStartDate <= ('2999' & $sDelim & '12' & $sDelim & '25') Then For $i = 0 To 6 If $i = UBound($aTimeLine) Then ExitLoop $aNextDay = StringRegExp($aTimeLine[$i][0], '\d+', 3) $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2])) $aTimeLine[$i][1] = _DateDayOfWeek($iDayNum, $iDayName) Next For $i = 7 To UBound($aTimeLine) -1 $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1] Next Else Local $aDayName[7] For $i = 25 To 31 $aNextDay = StringRegExp('2999/12/' & $i, '\d+', 3) $iDayNum = _DateToDayOfWeek (Number($aNextDay[0]), Number($aNextDay[1]), Number($aNextDay[2])) $aDayName[$i -25] = _DateDayOfWeek($iDayNum, $iDayName) Next Local $iDateDiff = DateRange('2999/12/25', StringReplace($aTimeLine[0][0], $sDelim, '/')) For $i = 0 to 6 If $i = UBound($aTimeLine) Then ExitLoop $aTimeLine[$i][1] = $aDayName[Mod($iDateDiff + $i -1, 7)] Next For $i = 7 To UBound($aTimeLine) -1 $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1] Next EndIf EndIf If $sFormat = Default Then ; [regexp pattern stored in ini or settings] $aDateSplit = StringRegExp($sYMD, '\d', 3) _Predim($aDateSplit, 2) ReDim $aDateSplit[3][2] $aDateSplit[0][1] = 1 $aDateSplit[1][1] = 3 $aDateSplit[2][1] = 5 _ArraySort($aDateSplit) $sFormat = '$' & $aDateSplit[0][1] & $sDelim & '$' & $aDateSplit[1][1] & $sDelim & '$' & $aDateSplit[2][1] EndIf For $i = 0 To UBound($aTimeLine) -1 $aTimeLine[$i][0] = StringRegExpReplace($aTimeLine[$i][0], '(\d+)(\D)(\d+)(\D)(\d+)', $sFormat) Next If $vReverse Then _ReverseArray($aTimeLine) _ArrayDisplay($aTimeLine) Return $aTimeLine EndFunc ;==> GetDateArray Func IsLeapYear($iYear) If Mod($iYear, 4) Then Return False ElseIf Mod($iYear, 100) Then Return True ElseIf Mod($iYear, 400) Then Return False Else Return True EndIf EndFunc ;==> IsLeapYear Func DateRange($sDate1, $sDate2) ; must be yyyy/mm/dd Local $vTemp If $sDate1 > $sDate2 Then $vTemp = $sDate1 $sDate1 = $sDate2 $sDate2 = $vTemp EndIf Local $aArray1 = StringRegExp($sDate1, '\d+', 3), $aArray2 = StringRegExp($sDate2, '\d+', 3) For $i = 0 To 2 $aArray1[$i] = Number($aArray1[$i]) $aArray2[$i] = Number($aArray2[$i]) Next Local $iCount = 0 For $i = $aArray1[0] +1 To $aArray2[0] -1 If Not IsLeapYear($i) Then $iCount += 365 Else $iCount += 366 EndIf Next Local $iFirstMonth = 0 Switch $aArray1[1] Case 1, 3, 5, 7, 8, 10, 12 $iFirstMonth = 32 - $aArray1[2] Case 4, 6, 9, 11 $iFirstMonth = 31 - $aArray1[2] Case Else $iFirstMonth = (IsLeapYear($aArray1[0]) ? 30 : 29) - $aArray1[2] EndSwitch If $aArray1[0] < $aArray2[0] Then $iCount += $iFirstMonth For $i = $aArray1[1] +1 to 12 Switch $i Case 1, 3, 5, 7, 8, 10, 12 $iCount += 31 Case 4, 6, 9, 11 $iCount += 30 Case Else $iCount += (IsLeapYear($aArray1[0]) ? 29 : 28) EndSwitch Next $iCount += $aArray2[2] ; add remaining days in final month If $aArray2[1] > 1 Then For $i = 1 To $aArray2[1] -1 Switch $i Case 1, 3, 5, 7, 8, 10, 12 $iCount += 31 Case 4, 6, 9, 11 $iCount += 30 Case Else $iCount += (IsLeapYear($aArray2[0]) ? 29 : 28) EndSwitch Next EndIf ElseIf $aArray1[1] < $aArray2[1] Then ; same year, different month $iCount += $iFirstMonth For $i = $aArray1[1] +1 to $aArray2[1] -1 Switch $i Case 1, 3, 5, 7, 8, 10, 12 $iCount += 31 Case 4, 6, 9, 11 $iCount += 30 Case Else $iCount += (IsLeapYear($aArray1[0]) ? 29 : 28) EndSwitch Next $iCount += $aArray2[2] Else ; same month and year $iCount = $aArray2[2] - $aArray1[2] +1 EndIf Return $iCount EndFunc ;==> DateRange ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Functions from ArrayWorkshop.au3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #Au3Stripper_Off Func _ReverseArray(ByRef $aArray, $iDimension = 1, $iStart = 0, $iEnd = -1) If Not IsArray($aArray) Or UBound($aArray, 0) > 9 Then Return SetError(1) ; not a valid array Local $aBound = __GetBounds($aArray) If @error Then Return SetError(2) ; array contains zero elements $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension < 1 Or $iDimension > $aBound[0] Then Return SetError(3) ; dimension does not exist $iStart = ($iStart = Default) ? 0 : Int($iStart) If $iStart < 0 Or $iStart > $aBound[$iDimension] - 2 Then Return SetError(4) ; meaningless $iStart value $iEnd = ($iEnd = -1 Or $iEnd = Default) ? $aBound[$iDimension] - 1 : Int($iEnd) If $iEnd <= $iStart Or $iEnd >= $aBound[$iDimension] Then Return SetError(5) ; meaningless $iEnd value If $aBound[0] = 1 Then ___Reverse1D($aArray, $iStart, $iEnd) Else $aBound[$iDimension] = 1 Local $aRegion = ___NewArray($aBound) ; to store extracted regions For $i = 1 To $aBound[0] $aBound[$i] -= 1 Next Local $sIndices = __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]], _ $sTransfer = '$aSource' & $sIndices ; array syntax While $iEnd > $iStart $fnFloodFill($aRegion, $aBound, $iDimension, 0, $iStart, $aArray, $sTransfer) ; extract the current start region $sTransfer = '$aTarget' & $sIndices $fnFloodFill($aArray, $aBound, $iDimension, $iStart, $iEnd, '', $sTransfer) ; overwrite the current start region $sTransfer = '$aSource' & $sIndices $fnFloodFill($aArray, $aBound, $iDimension, $iEnd, 0, $aRegion, $sTransfer) ; overwrite the current end region $iStart += 1 $iEnd -= 1 WEnd EndIf EndFunc ;==>_ReverseArray Func _DeleteRegion(ByRef $aArray, $iDimension = 1, $iSubIndex = 0, $iRange = 1) If Not IsArray($aArray) Then Return SetError(1) Local $aBound = __GetBounds($aArray) ; get the bounds of each dimension If @error Then Return SetError(4) ; $aArray must contain at least one element If $aBound[0] > 9 Then Return SetError(2) ; nine dimension limit $iDimension = ($iDimension = Default) ? 1 : Int($iDimension) If $iDimension > $aBound[0] Or $iDimension < 1 Then Return SetError(3) ; out of bounds dimension $iSubIndex = ($iSubIndex = Default) ? 0 : Int($iSubIndex) If $iSubIndex < 0 Or $iSubIndex > $aBound[$iDimension] - 1 Then Return SetError(5) ; sub-index does not exist in the dimension $iRange = ($iRange = Default) ? 1 : Int($iRange) If $iRange < 1 Then Return SetError(6) ; range must be greater than zero $iRange = ($iSubIndex + $iRange < $aBound[$iDimension]) ? $iRange : $aBound[$iDimension] - $iSubIndex ; corrects for overflow If $iRange = $aBound[$iDimension] Then Return SetError(6) ; deleting the whole region is not currently supported [give reason] $aBound[$iDimension] -= $iRange ; the size of the dimension in the new array If $aBound[0] = 1 Then For $iNext = $iSubIndex To $aBound[$iDimension] - 1 $aArray[$iNext] = $aArray[$iNext + $iRange] Next ReDim $aArray[$aBound[$iDimension]] Return EndIf Local $iMaxIndex = $aBound[$iDimension] - 1 For $i = 1 To $aBound[0] $aBound[$i] -= 1 Next $aBound[$iDimension] = 0 ; set to loop once [one region at a time] Local $iFrom, $sTransfer = '$aTarget' & __HiddenIndices($aBound[0], $iDimension), $fnFloodFill = __FloodFunc()[$aBound[0]] For $iNext = $iSubIndex To $iMaxIndex $iFrom = $iNext + $iRange $fnFloodFill($aArray, $aBound, $iDimension, $iNext, $iFrom, '', $sTransfer) ; overwrite the final [untouched] region Next $aBound[$iDimension] = $iMaxIndex For $i = 1 To $aBound[0] $aBound[$i] += 1 Next __ResetBounds($aArray, $aBound) ; delete remaining indices EndFunc ;==>_DeleteRegion Func _PreDim(ByRef $aArray, $iDimensions, $bPush = False) If Not IsArray($aArray) Then Return SetError(1) $iDimensions = Int($iDimensions) If $iDimensions < 1 Or $iDimensions > 9 Then Return SetError(2) Local $iPreDims = UBound($aArray, 0) ; current number of dimensions If $iPreDims = $iDimensions Then Return ; no change If $iPreDims > 9 Then Return SetError(3) ; too many dimensions Local $aBound = __GetBounds($aArray) ; get the size of each original dimension If @error Then Return SetError(4) ; $aArray must contain at least one element $aBound[0] = $iDimensions ; overwrite this value with the new number of dimensions Local $sTransfer = '[$a[1]][$a[2]][$a[3]][$a[4]][$a[5]][$a[6]][$a[7]][$a[8]][$a[9]]' ; array syntax to be sent to the remote loop region If $bPush Then ; prefix dimensions, or delete from the left Local $iOffset = Abs($iDimensions - $iPreDims) If $iPreDims > $iDimensions Then ; lower dimensions get deleted For $i = 1 To $iDimensions ; shift elements to lower indices $aBound[$i] = $aBound[$i + $iOffset] Next $sTransfer = '$aSource' & StringLeft('[0][0][0][0][0][0][0][0]', $iOffset * 3) & StringLeft($sTransfer, $iDimensions * 7) Else ; lower dimensions are created ReDim $aBound[$iDimensions + 1] ; make space for more dimensions For $i = $iDimensions To $iOffset + 1 Step -1 ; shift elements to higher indices $aBound[$i] = $aBound[$i - $iOffset] Next For $i = 1 To $iOffset ; assign the size of each additional dimension [1][1][1]... etc... $aBound[$i] = 1 Next $sTransfer = '$aSource' & StringMid($sTransfer, 1 + $iOffset * 7, $iPreDims * 7) EndIf Else ; Default behaviour = append dimensions, or delete from the right ReDim $aBound[$iDimensions + 1] ; modify the number of dimensions [according to the new array] For $i = $iPreDims + 1 To $iDimensions ; assign the size of each new dimension ...[1][1][1] etc... $aBound[$i] = 1 Next $sTransfer = '$aSource' & StringLeft($sTransfer, $iPreDims * 7) EndIf ; add or remove dimensions Local $aNewArray = ___NewArray($aBound) For $i = 1 To $iDimensions $aBound[$i] -= 1 ; convert elements to the maximum index value within each dimension Next ; access the remote loop region Local $iSubIndex = 0, $aFloodFill = __FloodFunc() $aFloodFill[$iDimensions]($aNewArray, $aBound, 0, $iSubIndex, '', $aArray, $sTransfer) $aArray = $aNewArray EndFunc ;==>_PreDim Func __GetBounds($aArray, $iHypothetical = 0) Local $iMaxDim = UBound($aArray, 0) Local $aBound[($iHypothetical ? $iHypothetical : $iMaxDim) + 1] ; [or ==> Local $aBound[9]] $aBound[0] = $iMaxDim For $i = 1 To $iMaxDim $aBound[$i] = UBound($aArray, $i) If $aBound[$i] = 0 Then Return SetError(1) Next If $iHypothetical Then For $i = $iMaxDim + 1 To $iHypothetical $aBound[$i] = 1 ; imaginary dimensions Next EndIf Return $aBound EndFunc ;==>__GetBounds Func __HiddenIndices($iBound, $iDimension) Local $sSyntax = '' ; to access elements at their original indices For $i = 1 To $iBound If $i <> $iDimension Then $sSyntax &= '[$a[' & $i & ']]' ; default ==> '$aSource[$iFrom][$a[2]][$a[3]][$a[4]][$a[5]] etc...' Else $sSyntax &= '[$iFrom]' EndIf Next Return $sSyntax EndFunc ;==>__HiddenIndices Func ___NewArray($aBound) Switch $aBound[0] Case 1 Local $aArray[$aBound[1]] Case 2 Local $aArray[$aBound[1]][$aBound[2]] Case 3 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]] Case 4 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]] Case 5 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]] Case 6 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]] Case 7 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]] Case 8 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]] Case 9 Local $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]] EndSwitch Return $aArray EndFunc ;==>___NewArray Func ___Reverse1D(ByRef $aArray, $iStart, $iStop) Local $vTemp While $iStop > $iStart $vTemp = $aArray[$iStart] $aArray[$iStart] = $aArray[$iStop] $aArray[$iStop] = $vTemp $iStart += 1 $iStop -= 1 WEnd EndFunc ;==>___Reverse1D Func __ResetBounds(ByRef $aArray, $aBound) Switch $aBound[0] Case 1 ReDim $aArray[$aBound[1]] Case 2 ReDim $aArray[$aBound[1]][$aBound[2]] Case 3 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]] Case 4 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]] Case 5 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]] Case 6 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]] Case 7 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]] Case 8 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]] Case 9 ReDim $aArray[$aBound[1]][$aBound[2]][$aBound[3]][$aBound[4]][$aBound[5]][$aBound[6]][$aBound[7]][$aBound[8]][$aBound[9]] EndSwitch EndFunc ;==>__ResetBounds Func __FloodFunc() ; [modified for this demo] Local $aFloodFunc = ['', ___Flood1D, ___Flood2D] ; , ___Flood3D, ___Flood4D, ___Flood5D, ___Flood6D, ___Flood7D, ___Flood8D, ___Flood9D] Return $aFloodFunc EndFunc ;==>__FloodFunc Func ___Flood1D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) ; [still experimental] #forceref $iDimension, $iFrom, $aSource ; $iDimension would normally not apply here (special case) Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array] For $a[1] = $iSubIndex To $aBound[1] ; from the start to the bounds of the 1st dimension (special case) ; only one operation is needed in this special case $aTarget[$a[1]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed Next EndFunc ;==>___Flood1D Func ___Flood2D(ByRef $aTarget, $aBound, $iDimension, $iSubIndex, $iFrom, $aSource, $sTransfer) #forceref $iFrom, $aSource ; hidden parameters Local $a[10] = ['', 0, 0, 0, 0, 0, 0, 0, 0, 0] ; loop iteration count [or indices of higher dimensions within the source array] For $a[2] = 0 To $aBound[2] For $a[1] = 0 To $aBound[1] $a[$iDimension] = $iSubIndex ; override the iteration count (fast method) - $a[0] has no influence $aTarget[$a[1]][$a[2]] = Execute($sTransfer) ; hidden parameters may appear in the code being executed Next Next EndFunc ;==>___Flood2D #Au3Stripper_On  
    • PELock
      By PELock
      I'm trying to use #OnAutoItStartRegister to modify the Global variable, but it seems it doesn't work, is that on purpose, that those callback functions cannot modify anything except in their own scope?