Jump to content

Please test this in your language / region


Recommended Posts

  • Moderators

Working well here on Windows 7 x64. I will test on Windows 10 as soon as I get a chance. Awesome work, as always.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

  • Replies 54
  • Created
  • Last Reply

Top Posters In This Topic

7 hours ago, JLogan3o13 said:

Working well here on Windows 7 x64. I will test on Windows 10 as soon as I get a chance. Awesome work, as always.

Thanks for reporting this. It's nice getting it to work, but several improvements can be made to the code. I always set my first task as trying to figure out how to proceed with an idea. I don't care too much about it being all neat as long as it works. Copy, paste and glue it together, after which it's fun to reorganize and improve the code! :D

Link to comment
Share on other sites

Works fine with Windows 10 Pro x64 French

Nice!

Edit : for me, the date format should be 04/10/2016 instead of 04-10-2016, but I see in your code Local $sDelim = '-' ; read from settings ??? [maybe] ... it should be easy for you :)
It works with Local $sDelim = StringRegExp(_WinAPI_GetDateFormat(), "[\D]", 1)[0] on line 183

Edited by jguinch
Link to comment
Share on other sites

Thanks again. A newer (bugfix) version forces a four digit year to always appear in the date control regardless of the locale format, but I'm not ready to post the code yet. It seemed the only sensible thing to do, considering the available range (it's hard to imagine so far into the distant future).

Edited by czardas
Link to comment
Share on other sites

On a more short time scale, I have spent a bit of time on what I consider the key function: GetDateArray(). I think I've somehow managed to support all languages. Unfortunately I can't read them all, so I can't say for certain. I had strange numeric symbols appearing in SciTE during testing. Perhaps incongruities between screen display and locale settings were trying to trick me into reading from right to left on a left to right screen layout. However, now the year always has four digits: so it's a dead give away. Perhaps I misinterpreted what I was seeing, but the returned array always seems to contain the correct number of entries.

I don't intend to clean up the GUI code until all the controls have been added to both tabs. I thought I ought to post the current changes now since some of you have shown interest in this. I changed the delimiter to default. More work needs to be done on output formatting. There are a lot of other program settings to deal with so it that will take more time. Thanks for testing.
 

#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 = 294

    Local $hChild = GUICreate($sTitle, $iWidth, $iHeight, Default + 100, Default + 100); , $iStyle, $iExStyle, $hParent)
    Local $idTab = GUICtrlCreateTab(2, 2, $iWidth -2, $iHeight -32)

    ; standard tab ==>
    GUICtrlCreateTabItem("Standard")

    GUICtrlCreateLabel("Table Dimensions", 14, 35, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Number Of Rows", 14, 59, 94, 18)
    Local $idStdRows = GUICtrlCreateInput("0", 104 +14, 55, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER))
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateLabel("Number Of Columns", 14, 85, 94, 18)
    Local $idStdCols = GUICtrlCreateInput("0", 104 +14, 81, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER))
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateLabel("Table Indices", 14, 113, 120, 20)
    GUICtrlSetColor(-1, 0x008000)

    Local $idIndices = GUICtrlCreateCheckbox(" Enumerate First Column", 14, 135, 160, 20) ; REMEMBER YES, SETTINGS NO

    Local $idStdDec = GUICtrlCreateRadio(" Standard Numbers", 14, 160)
     GUICtrlSetState(-1, $GUI_CHECKED)
    Local $idStdRoman = GUICtrlCreateRadio(" Roman Numerals", $iWidth - 118, 160)

    Local $idPadding = GUICtrlCreateCheckbox(" Leading Zeros", 14, 168 +20, 100, 20) ; REMEMBER YES, SETTINGS NO

    GUICtrlCreateLabel("Begin At", $iWidth - 118, 171 +20, 49, 18)
    Local $idStdStartAt = GUICtrlCreateInput("1", $iWidth - 55 -14, 167 +20, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER))
    GUICtrlSetFont(-1, 10)

    Local $idStdIdxPre = GUICtrlCreateCheckbox(" Include ID Prefix", 14, 201 +16, 100, 20) ; REMEMBER YES, SETTINGS NO

    Local $idStdPrefix = GUICtrlCreateInput("", $iWidth - 118, 202 +14, 99, 20, BitOR($WS_TABSTOP, $ES_LEFT))
    GUICtrlSetFont(-1, 10)

    ; advanced tab ==>
    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 $idAdvDays = GUICtrlCreateCheckbox(" Include Days Of The Week ", 14, 128, 190, 20) ; REMEMBER YES, SETTINGS NO

    Local $idRadio1 = GUICtrlCreateRadio(" Use Short Name", 14, 151)
    Local $idRadio2 = GUICtrlCreateRadio(" Use Long Name", $iWidth - 118, 151)
    GUICtrlSetState(-1, $GUI_CHECKED)
    GUICtrlSetState($idRadio1, $GUI_DISABLE) ; check settings later
    GUICtrlSetState($idRadio2, $GUI_DISABLE) ; check settings later

    Local $idSettings = GUICtrlCreateButton("Options", 14, 179, 66, 20)

    GUICtrlCreateLabel("Add More Columns", 14, 184 +26, 222, 20)
    GUICtrlSetColor(-1, 0x008000)

    GUICtrlCreateLabel("Total Number Of Columns", 14, 184 +23 +26, 129, 18)
    Local $idAdvCols = GUICtrlCreateInput("1", 130 +14, 184 +21 +26, 50, 20, BitOR($WS_TABSTOP, $ES_CENTER, $ES_NUMBER)) ; REMEMBER YES, SETTINGS NO
    GUICtrlSetFont(-1, 10)

    GUICtrlCreateTabItem("") ; end tabitem

    ; continue on normal GUI
    Local $idCancel = GUICtrlCreateButton("Cancel", $iWidth -143, $iHeight -25, 66, 20)
    Local $idOkay = GUICtrlCreateButton("OK", $iWidth -69, $iHeight -25, 66, 20)

    GUISetState(@SW_SHOW)

    ; force a four digit year in the date control
    GUICtrlSendMsg($idDate1, 0x1032, 0, LongYearFormat()) ; what is this magic?
    GUICtrlSendMsg($idDate2, 0x1032, 0, LongYearFormat())
    ; https://www.autoitscript.com/forum/topic/93701-how-to-format-date-time-picker-selected-date/#comment-673255 [Melba23]

    Local $msg2, $bDisable = True, $iMaxFields = 65000, $bStdError = False, $iRows = 0, $iCols = 0, _
    $sMonitorAdv = GUICtrlRead($idDate1) & GUICtrlRead($idDate2) & GUICtrlRead($idAdvCols), $sDate1, $sDate2, $sColsAdv, $iDiff, $bErrorAdv = False, _
    $bStdIndex = True, $bRomanNum = False, $bPrefix = False, $iStart = 1, $bRomanError = False, $aTable[0][0]

    While 1
        $msg2 = GUIGetMsg()
        If $msg2 = $idCancel Or $msg2 = $GUI_EVENT_CLOSE Then ExitLoop

        ; temporary dev code
        If UBound($aTable) Then ReDim $aTable[0][0] ; [remove after full implementation]

        ; control monitoring
        If _GUICtrlTab_GetCurFocus($idTab) = 0 Then ; standard tab

            If BitAND(GUICtrlRead($idIndices), $GUI_CHECKED) == $GUI_CHECKED Then
                If Not $bStdIndex Then
                    GUICtrlSetState($idStdDec, $GUI_ENABLE)
                    GUICtrlSetState($idStdRoman, $GUI_ENABLE)
                    GUICtrlSetState($idStdStartAt, $GUI_ENABLE)

                    If BitAND(GUICtrlRead($idStdRoman), $GUI_CHECKED) <> $GUI_CHECKED Then
                        GUICtrlSetState($idPadding, $GUI_ENABLE)
                        GUICtrlSetState($idStdIdxPre, $GUI_ENABLE)
                        $bRomanNum = False
                    EndIf

                    If Not $bRomanNum And BitAND(GUICtrlRead($idStdIdxPre), $GUI_CHECKED) == $GUI_CHECKED Then
                        GUICtrlSetState($idStdPrefix, $GUI_ENABLE)
                        $bPrefix = True
                    EndIf
                    $bStdIndex = True

                Else
                    If BitAND(GUICtrlRead($idStdRoman), $GUI_CHECKED) <> $GUI_CHECKED Then
                        If $bRomanNum Then
                            GUICtrlSetState($idPadding, $GUI_ENABLE)
                            GUICtrlSetState($idStdIdxPre, $GUI_ENABLE)
                            $bRomanNum = False

                        Else
                            If Not $bPrefix And BitAND(GUICtrlRead($idStdIdxPre), $GUI_CHECKED) == $GUI_CHECKED Then
                                GUICtrlSetState($idStdPrefix, $GUI_ENABLE)
                                $bPrefix = True

                            ElseIf $bPrefix And BitAND(GUICtrlRead($idStdIdxPre), $GUI_CHECKED) <> $GUI_CHECKED Then
                                GUICtrlSetState($idStdPrefix, $GUI_DISABLE)
                                $bPrefix = False
                            EndIf
                        EndIf
                    EndIf
                EndIf

            ElseIf $bStdIndex Then
                GUICtrlSetState($idStdDec, $GUI_DISABLE)
                GUICtrlSetState($idStdRoman, $GUI_DISABLE)
                GUICtrlSetState($idStdStartAt, $GUI_DISABLE)

                If Not $bRomanNum Then
                    GUICtrlSetState($idPadding, $GUI_DISABLE)
                    GUICtrlSetState($idStdIdxPre, $GUI_DISABLE)
                EndIf

                If BitAND(GUICtrlGetState($idStdPrefix), $GUI_ENABLE) == $GUI_ENABLE Then GUICtrlSetState($idStdPrefix, $GUI_DISABLE)
                $bStdIndex = False
            EndIf

            If $bStdIndex Then
                If BitOR(GUICtrlRead($idStdRoman), $GUI_CHECKED) == $GUI_CHECKED Then
                    If Not $bRomanNum Then
                        GUICtrlSetState($idPadding, $GUI_DISABLE)
                        GUICtrlSetState($idStdIdxPre, $GUI_DISABLE)
                        If $bPrefix Then
                            GUICtrlSetState($idStdPrefix, $GUI_DISABLE)
                        EndIf
                        $bRomanNum = True
                        $bPrefix = False
                    EndIf

                Else
                    If BitOR(GUICtrlRead($idStdIdxPre), $GUI_CHECKED) == $GUI_CHECKED Then
                        If Not $bPrefix Then
                            GUICtrlSetState($idStdPrefix, $GUI_ENABLE)
                            $bPrefix = True
                            $bRomanNum = False
                        EndIf
                    EndIf
                EndIf
            EndIf

            ; validate control data
            If ControlGetFocus($hChild) <> "Edit1" And StringRegExp($iRows, '\A0+[1-9]') Then GUICtrlSetData($idStdRows, StringRegExpReplace($iRows, '(\A0+)([1-9])(\d+)*', '$2$3'))
            If ControlGetFocus($hChild) <> "Edit2" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($idStdCols, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3'))
            If ControlGetFocus($hChild) <> "Edit3" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($idStdStartAt, StringRegExpReplace($iStart, '(\A0+)([1-9])(\d+)*', '$2$3'))

            $iRows = GUICtrlRead($idStdRows)
            $iCols = GUICtrlRead($idStdCols)

            If Not $iRows Then
                $iRows = 0
                GUICtrlSetData($idStdRows, $iRows)
                _GUICtrlEdit_SetSel($idStdRows, 0, -1)
            EndIf

            If Not $iCols Then
                $iCols = $bStdIndex ? 1 : 0
                GUICtrlSetData($idStdCols, $iCols)
                _GUICtrlEdit_SetSel($idStdCols, 0, -1)

            ElseIf $bStdIndex And $iCols = 0 Then
                $iCols = 1
                GUICtrlSetData($idStdCols, $iCols)
                If ControlGetFocus($hChild) = "Edit2" Then _GUICtrlEdit_SetSel($idStdCols, 0, -1)
            EndIf

            $iStart = GUICtrlRead($idStdStartAt)
            If Not $iStart Then
                $iStart = $bRomanNum ? 1 : 0
                GUICtrlSetData($idStdStartAt, $iStart)
                _GUICtrlEdit_SetSel($idStdStartAt, 0, -1)

            ElseIf $bStdIndex And $bRomanNum Then
                If $iStart = 0 Then
                    $iStart = 1
                    GUICtrlSetData($idStdStartAt, $iStart)
                    If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($idStdStartAt, 0, -1)

                ElseIf $iStart > 3999 Then
                    $iStart = 3999
                    GUICtrlSetData($idStdStartAt, $iStart)
                    If ControlGetFocus($hChild) = "Edit3" Then _GUICtrlEdit_SetSel($idStdStartAt, 0, -1)
                EndIf
            EndIf

            ; check bounds
            If $bStdIndex And $bRomanNum Then
                If $iStart + $iRows > 4000 Then
                    If Not $bRomanError Then
                        GUICtrlSetBkColor($idStdStartAt, 0xFFA090)
                        If Not $bStdError Then GUICtrlSetBkColor($idStdRows, 0xFFA090)
                        $bRomanError = True
                    EndIf

                ElseIf $bRomanError Then
                    GUICtrlSetBkColor($idStdStartAt, 0xFFFFFF)
                    If Not $bStdError Then GUICtrlSetBkColor($idStdRows, 0xFFFFFF)
                    $bRomanError = False
                EndIf

            ElseIf $bRomanError Then
                GUICtrlSetBkColor($idStdStartAt, 0xFFFFFF)
                If Not $bStdError Then GUICtrlSetBkColor($idStdRows, 0xFFFFFF)
                $bRomanError = False
            EndIf

            If $iRows > $iMaxFields Or $iCols > $iMaxFields Or $iRows * $iCols > $iMaxFields Then
                If Not $bStdError Then
                    GUICtrlSetBkColor($idStdCols, 0xFFA090)
                    If Not $bRomanError Then GUICtrlSetBkColor($idStdRows, 0xFFA090)
                    $bStdError = True
                EndIf

            ElseIf $bStdError Then
                GUICtrlSetBkColor($idStdCols, 0xFFFFFF)
                If Not $bRomanError Then GUICtrlSetBkColor($idStdRows, 0xFFFFFF)
                $bStdError = False
            EndIf ;==> end of control monitoring

            ; run request
            If $msg2 = $idOkay Then
                If $bStdError Or $bRomanError Then
                    MsgBox(262160, "uh-uh!", "Out of Range") ; more detail needed
                    ContinueLoop
                EndIf

                ReDim $aTable[$iRows][$iCols]

                If $bStdIndex And $bRomanNum Then
                    For $i = 0 To $iRows -1
                        $aTable[$i][0] = Roman($iStart + $i)
                    Next

                ElseIf $bStdIndex Then
                    Local $sPrefix = $bPrefix ? GUICtrlRead($idStdPrefix) : ''
                    If BitAND(GUICtrlRead($idPadding), $GUI_CHECKED) == $GUI_CHECKED Then
                        Local $iLen = StringLen($iStart + $iRows -1)
                        For $i = 0 To $iRows -1
                            $aTable[$i][0] = $sPrefix & StringRight('0000000000' & ($iStart + $i), $iLen)
                        Next
                    Else
                        For $i = 0 To $iRows -1
                            $aTable[$i][0] = $sPrefix & ($iStart + $i)
                        Next
                    EndIf
                EndIf

                _ArrayDisplay($aTable)
            EndIf ; [gawd's sake!]

        Else ; advanced tab
            ; control monitoring
            If BitAND(GUICtrlRead($idAdvDays), $GUI_CHECKED) == $GUI_CHECKED Then
                If $bDisable Then
                    GUICtrlSetState($idRadio1, $GUI_ENABLE)
                    GUICtrlSetState($idRadio2, $GUI_ENABLE)
                    $bDisable  = False
                EndIf

            ElseIf Not $bDisable Then
                GUICtrlSetState($idRadio1, $GUI_DISABLE)
                GUICtrlSetState($idRadio2, $GUI_DISABLE)
                $bDisable  = True
            EndIf

            $sDate1 = GUICtrlRead($idDate1)
            $sDate2 = GUICtrlRead($idDate2)
            $sColsAdv = GUICtrlRead($idAdvCols)

            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($idAdvCols, 0xFFA090)
                        $bErrorAdv = True
                    EndIf

                ElseIf $bErrorAdv Then
                    GUICtrlSetBkColor($idAdvCols, 0xFFFFFF)
                    $bErrorAdv = False
                EndIf
                $sMonitorAdv = $sDate1 & $sDate2 & $sColsAdv
            EndIf

            $iCols = GUICtrlRead($idAdvCols)
            If ControlGetFocus($hChild) <> "Edit5" And StringRegExp($iCols, '\A0+[1-9]') Then GUICtrlSetData($idAdvCols, StringRegExpReplace($iCols, '(\A0+)([1-9])(\d+)*', '$2$3'))

            $iCols = GUICtrlRead($idAdvCols)
            If $iCols < 1 Then
                If BitAND(GUICtrlRead($idAdvDays), $GUI_CHECKED) == $GUI_CHECKED And ControlGetFocus($hChild) <> "Edit5" Then
                    GUICtrlSetData($idAdvCols, 2)
                Else
                    GUICtrlSetData($idAdvCols, 1)
                EndIf
                If ControlGetFocus($hChild) = "Edit5" Then _GUICtrlEdit_SetSel($idAdvCols, 0, -1)
            EndIf

            If BitAND(GUICtrlRead($idAdvDays), $GUI_CHECKED) == $GUI_CHECKED Then
                If $iCols < 2 And ControlGetFocus($hChild) <> "Edit5" Then
                    If ControlGetFocus($hChild) = "Button6" Then
                        While _IsPressed('01') ; allow time for checkbox state to change before reading the ($idAdvDays) control
                            Sleep(20)
                        WEnd
                    EndIf

                    If BitAND(GUICtrlRead($idAdvDays), $GUI_CHECKED) == $GUI_CHECKED Then
                        GUICtrlSetData($idAdvCols, 2)
                    Else
                        GUICtrlSetData($idAdvCols, 1)
                    EndIf
                EndIf
            Else
                If $iCols < 1 Then
                    GUICtrlSetData($idAdvCols, 1)
                    If ControlGetFocus($hChild) = "Edit5" Then _GUICtrlEdit_SetSel($idAdvCols, 0, -1)
                EndIf
            EndIf ;==> end of control monitoring

            If $msg2 = $idSettings Then MsgBox(262160, "alpha!", "Not Available")

            If $msg2 = $idOkay Then
                If $bErrorAdv Then
                    MsgBox(262160, "uh-uh!", "Out of Range")
                    ContinueLoop
                EndIf

                Local $sDelim = Default ; read from settings ??? [maybe]
                Local $iName, $sFormat = Default ; read from settings [ini]
                If BitAND(GUICtrlRead($idAdvDays), $GUI_CHECKED) == $GUI_CHECKED Then
                    $iName = (BitAND(GUICtrlRead($idRadio1), $GUI_CHECKED) == $GUI_CHECKED) ? 3 : 2
                Else
                    $iName = -1
                EndIf

                ; $sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1)
                $aTable = GetDateArray($sDate1, $sDate2, $sDelim, $sFormat, $iName)
                If $sColsAdv > 1 Then ReDim $aTable [UBound($aTable)][$sColsAdv]
                _ArrayDisplay($aTable)
            EndIf
        EndIf
    WEnd
    GUIDelete($hChild)
EndFunc ;==> NewTable

Func GetDateArray($sStartDate, $sStopDate, $sDelim = Default, $sFormat = Default, $iDayName = -1)
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3)
    If Not IsArray($aDateSplit) Or UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error?
    ; ConsoleWrite($iID & @LF)

    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

    ; 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)
    $aDateSplit = StringRegExp($sStartDate, '\d+', 3)

    Local $bReadReverse = False ; the following code segment assumes right to left screen reading incongruities
    If StringLen($aDateSplit[2]) = 4 Then ; sometimes dates in the control are displayed in reverse sequence [mainly Middle Eastern locales]
        _ReverseArray($aDateSplit) ; this only seems to effect a small number of regions [further testing is needed]
        $bReadReverse = True
    EndIf

    $sStartDate = StringFormat('%04i' & $sDelim & '%02i' & $sDelim & '%02i', $aDateSplit[0], $aDateSplit[1], $aDateSplit[2])
    $sStopDate  = StringRegExpReplace($sStopDate,  '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)
    $aDateSplit = StringRegExp($sStopDate, '\d+', 3)
    If $bReadReverse Then _ReverseArray($aDateSplit)
    $sStopDate = StringFormat('%04i' & $sDelim & '%02i' & $sDelim & '%02i', $aDateSplit[0], $aDateSplit[1], $aDateSplit[2])

    Local $vReverse = False ; in which order are the dates to be returned?
    If $sStartDate > $sStopDate Then
        $vReverse = $sStartDate
        $sStartDate = $sStopDate
        $sStopDate = $vReverse
    EndIf

    ; internal format = yyyy/mm/dd (or any other delimiter)
    Local $iStartYear = Number(StringRegExp($sStartDate, '\d+', 3)[0]), $iStopYear = Number(StringRegExp($sStopDate, '\d+', 3)[0]), _
    $aTimeLine[(($iStopYear - $iStartYear +1) *366)], $iMonthEnd

    $iCount = 0
    For $iYear = $iStartYear To $iStopYear
        For $iMon = 1 To 12
            Switch $iMon
                Case 1, 3, 5, 7, 8, 10, 12
                    $iMonthEnd = 31

                Case 4, 6, 9, 11
                    $iMonthEnd = 30

                Case Else
                    $iMonthEnd = IsLeapYear($iYear) ? 29 : 28
            EndSwitch

            For $iDay = 1 To $iMonthEnd
                $aTimeLine[$iCount] = StringFormat('%04i' & $sDelim & '%02i' & $sDelim & '%02i', $iYear, $iMon, $iDay)
                If $aTimeLine[$iCount] = $sStopDate Then ExitLoop 3
                $iCount += 1
            Next
        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) ; delete everything before the start date [crude and effective]
            ExitLoop
        EndIf
    Next

    _Predim($aTimeLine, 2) ; add 2nd dimension (the desired output is always 2D, also without day names)

    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 ; get the first 7 day names of the selected period
                If $i = UBound($aTimeLine) Then ExitLoop ; we reached the end of the array
                $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

        Else ; [millennium patch]
            Local $aDayName[7] ; create a temporary array
            For $i = 25 To 31 ; get the last 7 day names returned by the Date UDF functions
                $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

            ; get the difference between 2999/12/25 and the start date
            Local $iDateDiff = DateRange('2999/12/25', StringReplace($aTimeLine[0][0], $sDelim, '/')) -1

            For $i = 0 to 6 ; get the first 7 day names of the selected period
                If $i = UBound($aTimeLine) Then ExitLoop
                $aTimeLine[$i][1] = $aDayName[Mod($iDateDiff + $i, 7)]
            Next
        EndIf

        For $i = 7 To UBound($aTimeLine) -1 ; keep adding more day names
            $aTimeLine[$i][1] = $aTimeLine[Mod($i, 7)][1]
        Next
    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) ; undo YMD date order changes before generating a new regexp pattern
        $sFormat = '$' & $aDateSplit[0][1] & $sDelim & '$' &  $aDateSplit[1][1] & $sDelim & '$' &  $aDateSplit[2][1] ; pattern
    EndIf

    If $bReadReverse Then ; we need to undo all previous formatting changes
        For $i = 0 To UBound($aTimeLine) -1
            $aTimeLine[$i][0] = StringRegExpReplace($aTimeLine[$i][0], '(\d+)(\D)(\d+)(\D)(\d+)', '$5' & $sDelim & '$3' & $sDelim & '$1')
        Next
    EndIf

    For $i = 0 To UBound($aTimeLine) -1 ; [eventually the output should be formatted according to user preferences]
        $aTimeLine[$i][0] = StringRegExpReplace($aTimeLine[$i][0], '(\d+)(\D)(\d+)(\D)(\d+)', $sFormat)
    Next

    If $vReverse Then _ReverseArray($aTimeLine) ; yeah it goes backwards too!
    Return $aTimeLine
EndFunc ;==> GetDateArray

Func DateRange($sDate1, $sDate2) ; (digit) sequence must be yyyy/month/day (any delimiter)
    ; ensure that the first date is prior to the second
    Local $sTemp
    If $sDate1 > $sDate2 Then
        $sTemp = $sDate1
        $sDate1 = $sDate2
        $sDate2 = $sTemp
    EndIf

    ; extract the numbers (only) from each date
    Local $aArray1 = StringRegExp($sDate1, '\d+', 3), $aArray2 = StringRegExp($sDate2, '\d+', 3)

    ; add the days of all the years between the first and final year
    Local $iCount = 0
    For $i = $aArray1[0] +1 To $aArray2[0] -1
        If Not IsLeapYear($i) Then
            $iCount += 365
        Else
            $iCount += 366
        EndIf
    Next

    ; get the remaining days of the first month in the first year
    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

    ; check to see if the first and final years are different
    If $aArray1[0] < $aArray2[0] Then ; different year
        $iCount += $iFirstMonth ; add the remaining days of the first month

        ; add the remainder of the first year
        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

        ; add the days in the final year
        $iCount += $aArray2[2] ; add remaining days in final month
        If $aArray2[1] > 1 Then ; add the days in the months prior
            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

    ; [else] check to see if the first and final month are the same
    ElseIf $aArray1[1] < $aArray2[1] Then ; same year, different month
        $iCount += $iFirstMonth ; add the remaining days of the first month
        For $i = $aArray1[1] +1 to $aArray2[1] -1 ; add the days in the intervening months
            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

    Else ; same month and year
        $iCount = $aArray2[2] - $aArray1[2] +1 ; calculate the days within the month
    EndIf

    Return $iCount
EndFunc ;==> DateRange

Func LongYearFormat() ; convert yy to yyyy
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $sFormat = _WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE)
    $sFormat = StringRegExpReplace($sFormat, '(?i)(\byy\b)', 'yyyy')
    Return $sFormat
EndFunc ;==> LongYearFormat

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 LocaleDateToYMD($sDate, $sDelim = '/') ; year must contain 4 digits
    Local $iID = _WinAPI_GetUserDefaultLCID(), _
    $aDateSplit = StringRegExp(_WinAPI_GetLocaleInfo($iID, $LOCALE_SSHORTDATE), '\w+', 3)

    If Not IsArray($aDateSplit) Or UBound($aDateSplit) <> 3 Then Return SetError(1) ; undetermined error?

    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

    ; 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?

    Local $iCount = 1, $sYMD = ''
    Do ; generate SRE pattern
        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

    $sDate = StringRegExpReplace($sDate, '(\d+)(\D)(\d+)(\D)(\d+)', $sYMD)

    ; test for incongruous right to left screen reading discrepancies
    If Not StringIsDigit(StringLeft($sDate, 4)) Then
        $sDate = StringRegExpReplace($sDate, '(\d+)(\D)(\d+)(\D)(\d+)', '$5' & $sDelim & '$3' & $sDelim & '$1')
    EndIf

    Return $sDate
EndFunc ;==> LocaleDateToYMD

Func Roman($iInt)
    If Not StringIsInt($iInt) Or $iInt > 3999 Or $iInt < 1 Then Return SetError(1, 0, "")
    $iInt = Int($iInt) ; in case the string contains leading zeros

    Local $aNumeral[10][4] = _
    [["","","",""], _
    ["M","C","X","I"], _
    ["MM","CC","XX","II"], _
    ["MMM","CCC","XXX","III"], _
    ["","CD","XL","IV"], _
    ["","D","L","V"], _
    ["","DC","LX","VI"], _
    ["","DCC","LXX","VII"], _
    ["","DCCC","LXXX","VIII"], _
    ["","CM","XC","IX"]]

    Local $iOffset = StringLen($iInt) -4, $sRoman = "", $aDecimal = StringSplit($iInt, "", 2)
    For $i = 0 To UBound($aDecimal) -1
        $sRoman &= $aNumeral[$aDecimal[$i]][$i -$iOffset]
    Next
    Return $sRoman
EndFunc

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Stripped 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

 

Edited by czardas
Demo Fix (not actually a bug)
Link to comment
Share on other sites

U.S. English is good to go.  I've named this project      "Date_Czar_Hard"  because i am witty AF

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

One more update to the code in #46. LocaleDateToYMD() has now also been rewritten. Here, this function is only used to test for 'out of range' table size depending on how many columns you intend to include in the final table (listview). The current limit is set to 65000 fields and is subject to change. You might want to figure this out for yourself and remove the limit for a different purpose. All the ArrayWorkshop functions can be replaced with functions from the Array UDF, but you would have to add some extra lines of code to get it working properly.

I think there's plenty to contemplate here. I learned several new things while trying to piece this jigsaw together: the reverse reading order was a bit baffling. My reasoning may be incorrect, but that's not necessarily relevant. I'm assuming that this now works for every language: right to left reading order (and vice versa) on any modern Windows system, Arabic numerals or other numbering systems. :phew:

Edited by czardas
Link to comment
Share on other sites

Thanks. It's for a program similar to, but much simpler than, Excel. I think many office programs are great, but unnecessarily complicated. Excel and Access are not exactly intuitive and that puts a lot of people off. I also prefer to work with cross-platform compatible formats like csv. Portable software is a good thing to have too. The date range is for accounts, time tables and similar. Once generated, you can delete or duplicate any rows, as and when required. I expect this type of date range feature to already be available in Excel, but I'm not sure how that works.

What I want is to simply cut/paste rows, cols and data in a basic table. I want to be able to do sums using formulas that actually resemble mathematical equations. I also want search features which are as simple to use as those on ebay. I want to store all my records in csv format with one simple program to handle a limited set of basic processes which are not so overwhelming. CSV format is more or less future proof, so it's an obvious choice. Pressing ctrl+c places a csv formatted string on the clipboard. Pasting it generates extra rows if required (without all that nonsense about the selected area containing an incompatible number of entries). You can actually paste into every other row if you select them that way. Also, my version has a much nicer default background. :D

There's a bit more related code here: https://www.autoitscript.com/forum/topic/184606-row-sum-σ-formula-validation/

Edited by czardas
Link to comment
Share on other sites

can you easily make it a function which i can send these selections as parameters and return the array?  I'll do it, but im going to halfass it.

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Providing you use your locale format for the input eg 11/31/2015, you can use GetDateArray($date1, $date2). You can also format the output with an expression like $sFormat (param) = '$5/$3/$1' to get dd/mm/yyyy output ==> GetDateArray($date1, $date2, '/', '$5/$3/$1', 3). Or use '$5$4$3$2$1' - should also work [$1 = yyyy, $2 = delim, $3 = MM, $4 = delim, $5 = dd]. The 5th parameter should be 2, 3 or -1.

What I would like to do would be to return a selected language, instead of the computer's default language. I have an idea how it might be done, but I'm too busy today. After I've implemented this in my project, I'll see what else I can come up with. :)

Edit: Just need to force feed it the wrong information (I guess): http://www.science.co.il/Language/Locale-codes.asp

Edited by czardas
Link to comment
Share on other sites

I have changed the code in post #46 once more. The code is not at all perfect, but getting it working has taken enough time for a single item on the menu. Some of the standard tab controls have a mind of their own (well sort of :think:). It's a bit crazy anyway.

@iamtheky I also did some messing with _DateDayOfWeek(). You can feed the language codes (from the link I posted above) into this function. It seems that only 4 digit codes are supported (on my machine at least). After thinking about your earlier request, It is true that the example in #46 is very specific to my own needs. There are several formats that could be used for input (here it's interpreting the data within a particular control in an unknown locale) and ways in which the return data could be presented. Perhaps you could detail exactly what you want and have a try yourself. I'll get around to it at some point, but this project is consuming much of my time right now. At least you should produce some specs! :)

Return Months and Days in Any Language  - _DateDayOfWeek() modified

#include <WinAPILocale.au3>
#include <Array.au3>

Local $aWeek[7]
For $i = 0 To 6
    $aWeek[$i] = DayOfWeek(1050, $i +1, True)
Next
_ArrayDisplay($aWeek, "Days of the Week")

Local $aMonth[12]
For $i = 0 To 11
    $aMonth[$i] = MonOfYear(1095, $i +1)
Next
_ArrayDisplay($aMonth, BinaryToString('0xC2AF5C5F28E38384295F2FC2AF', 4))

Func DayOfWeek($iLangCID, $iDayNum, $bShortName = False)
    If $bShortName = Default Then $bShortName = False
    $iDayNum = Int($iDayNum)
    If $iDayNum < 1 Or $iDayNum > 7 Then Return SetError(1, 0, "")
    Local $tSYSTEMTIME = DllStructCreate($tagSYSTEMTIME)
    DllStructSetData($tSYSTEMTIME, "Year", 2006) ; 2006 = Sunday 1st Jan
    DllStructSetData($tSYSTEMTIME, "Month", 1)
    DllStructSetData($tSYSTEMTIME, "Day", $iDayNum)
    Return _WinAPI_GetDateFormat($iLangCID, $tSYSTEMTIME, 0, $bShortName ? "ddd" : "dddd")
EndFunc   ;==> DayOfWeek

Func MonOfYear($iLangCID, $iMonNum, $bShortName = False)
    If $bShortName = Default Then $bShortName = False
    $iMonNum = Int($iMonNum)
    If $iMonNum < 1 Or $iMonNum > 12 Then Return SetError(1, 0, "")
    Local $tSYSTEMTIME = DllStructCreate($tagSYSTEMTIME)
    DllStructSetData($tSYSTEMTIME, "Year", 2006) ; 1st month in 2006 = Jan
    DllStructSetData($tSYSTEMTIME, "Month", $iMonNum)
    DllStructSetData($tSYSTEMTIME, "Day", 1)
    Return _WinAPI_GetDateFormat($iLangCID, $tSYSTEMTIME, 0, $bShortName ? "MMM" : "MMMM")
EndFunc   ;==> MonOfYear

After looking into this, I agree with @trancexx, the very first day in history was a Monday (according to Genesis). So you can set the start of time to 2007 if you prefer: read the comments in the original function. (!)

Edited by czardas
Link to comment
Share on other sites

Agreed my feature request was lacking, I head back from Denver tomorrow and will give this my airport time.

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

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

×
×
  • Create New...