Jump to content

_GUICtrlMonthCal select different days


 Share

Recommended Posts

HI,

I need help for select different days in control _GUICtrlMonthCal_Create.
I select multiples days using $style=$MCS_MULTISELECT.

Exemple the days of select: 01, 05 and 09/07/2020.

How to do this?

#include <GUIConstantsEx.au3>
#include <GuiMonthCal.au3>
#include <WindowsConstants.au3>

Global $g_idMemo

Example()

Func Example()
    Local $idMonthCal

    ; Create GUI
    GUICreate("Month Calendar Set Sel Count", 400, 300)
    $idMonthCal = GUICtrlCreateMonthCal("", 4, 4, -1, -1, BitOR($WS_BORDER, $MCS_MULTISELECT))

    ; Create memo control
    $g_idMemo = GUICtrlCreateEdit("", 4, 168, 392, 128, 0)
    GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New")
    GUISetState(@SW_SHOW)

    ; Get/Set maximum selection count
    _GUICtrlMonthCal_SetMaxSelCount($idMonthCal, 31)
    MemoWrite("Maximum selction count: " & _GUICtrlMonthCal_GetMaxSelCount($idMonthCal))

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>Example

; Write message to memo
Func MemoWrite($sMessage)
    GUICtrlSetData($g_idMemo, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite

 

Link to comment
Share on other sites

As per MSDN :

 

MCS_MULTISELECT
The month calendar enables the user to select a range of dates within the control. By default, the maximum range is one week. You can change the maximum range that can be selected by using the MCM_SETMAXSELCOUNT message.
Link to comment
Share on other sites

After more thoughts, there could be an easy way to perform what you want to do.  I suggest that you create a List Control beside the calendar and each time you select a new date (with the mouse), it would be automatically added to the list.  With 2 buttons (Go and Clear) and a context menu to delete a single entry, you would have a complete solution without creating you own calendar control. 

Link to comment
Share on other sites

I have been playing with this example for about a week, off and on. 

May this example help someone.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
#include <Array.au3>
; https://www.autoitscript.com/forum/topic/203556-_guictrlmonthcal-select-different-days/?do=findComment&comment=1462072

Global $g_idMemo
Global $iFrmt = "other"  ; Format MM/DD/YYYY ; or ;
;Global $iFrmt = "au"     ; Format DD/MM/YYYY ;

Example()


Func Example()
    Local $idMonthCal

    GUICreate("Select Dates", 250, 340, -1, 20, BitOR($WS_SIZEBOX, $WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU))

    Local $idMonthCal = GUICtrlCreateMonthCal("", 10, 10, 230, 160, $WS_BORDER)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetTip(-1, "Left mouse click on date to select")

    $g_idMemo = GUICtrlCreateEdit("", 10, 180, 230, 110)
    GUICtrlSetFont(-1, 9, 400, 0, "Courier New")
    GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, "Drag bottom edge of the GUI window is possible")

    Local $idButSort = GUICtrlCreateButton("Sort (Asc/Desc)", 10, 295, 100, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, 'Toggle ascending and descending date sort order.')

    Local $idButUniq = GUICtrlCreateButton("Unique", 120, 295, 50, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, 'Remove duplicate dates.')

    Local $idButParse = GUICtrlCreateButton("Parse", 180, 295, 50, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, "Change a range of dates (if present) to a list of dates" & @CRLF & _
            'eg. "12/08/202014/08/2020" or "12/08/2020 14/08/2020" or "14/08/2020:12/08/2020" or "12/08/2020 to 14/08/2020"  will return:-' & @CRLF & _
            '12/08/2020' & @CRLF & _
            '13/08/2020' & @CRLF & _
            '14/08/2020')

    Local $idButFormat = GUICtrlCreateButton("MM/DD/YYYY", 10, 318, 100, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, 'Toggle date format between "DD/MM/YYYY" and "MM/DD/YYYY"')
    GUISetState(@SW_SHOW)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $idMonthCal
                ;GUICtrlSetData($g_idMemo, GUICtrlRead($idMonthCal) & @CRLF, 1)
                GUICtrlSetData($g_idMemo, StringRegExpReplace(GUICtrlRead($idMonthCal), "(\d{4})/(\d{2})/(\d{2})", ($iFrmt = "au" ? "$3/$2/$1" : "$2/$3/$1") & @CRLF), 1) ; YYYY/MM/DD to (DD/MM/YYYY or MM/DD/YYYY)
            Case $idButSort
                _Parse() ; Default parameter is "1" to sort.  And, will change a range of dates (if present) to a list of dates.
            Case $idButUniq
                _Unique()
            Case $idButParse
                _Parse(0) ; Parameter "0" will not sort, but will change a range of dates (if present) to a list of dates.
            Case $idButFormat
                GUICtrlSetData($idButFormat, ($iFrmt = "au" ? "MM/DD/YYYY" : "DD/MM/YYYY"))
                $iFrmt = ($iFrmt = "au" ? "other" : "au")
                GUICtrlSetData($g_idMemo, StringRegExpReplace(GUICtrlRead($g_idMemo), "(\d{2})/(\d{2})/(\d{4})", "$2/$1/$3"), "")
        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>Example

; Any two dates on the same line separated by any character(s) that are not a digit or a "/",
; will be replaced with a sequencial range of dates between the two dates.
; eg. "12/08/202014/08/2020" or "12/08/2020 15/08/2020" or "15/08/2020:12/08/2020" or "12/08/2020 to 15/08/2020"  will return:-
; 12/08/2020
; 13/08/2020
; 14/08/2020
; 15/08/2020
Func _Parse($iSort = 1)
    Local $Y, $M, $D, $iStart, $iEnd, $iStep = 1, $iIndex = 0
    Local $aRet[1000][2]

    Local Static $iDesc = 1
    If $iSort Then $iDesc = Not $iDesc  ; Toggle ascending and descending date sort order.

    Local $a = StringRegExp(GUICtrlRead($g_idMemo), "[\d\V]+", 3)
    For $j = 0 To UBound($a) - 1
        $aTemp = StringRegExp($a[$j], "[^\D]{2,4}", 3)  ; Note: "[^\D]{2,4}" is faster than "\d{2,4}"
        If UBound($aTemp) = 6 Then

            ; Expand date range to date list. In 2D array, 1st column is sorting date,"y/m/d". 2nd column is formatted date, either "d/m/y" or "m/d/y"."
            $iStart = _DateToDayValue($aTemp[2], ($iFrmt = "au" ? $aTemp[1] : $aTemp[0]), ($iFrmt = "au" ? $aTemp[0] : $aTemp[1]))
            If @error Then ContinueLoop (Abs(MsgBox(16, "Error", "Error iInvalid range start date", 4))) ; Check valid date.

            $iEnd = _DateToDayValue($aTemp[2], ($iFrmt = "au" ? $aTemp[4] : $aTemp[3]), ($iFrmt = "au" ? $aTemp[3] : $aTemp[4]))
            If @error Then ContinueLoop (Abs(MsgBox(16, "Error", "Error invalid range end date", 4))) ; Check valid date.

            If $iStart > $iEnd Then $iStep = -1
            For $i = $iStart To $iEnd Step $iStep
                _DayValueToDate($i, $Y, $M, $D)
                $aRet[$iIndex][0] = $Y & "/" & $M & "/" & $D
                $aRet[$iIndex][1] = ($iFrmt = "au" ? $D & "/" & $M : $M & "/" & $D) & "/" & $Y
                $iIndex += 1
            Next

        Else
            If _DateIsValid($aTemp[2] & "/" & ($iFrmt = "au" ? $aTemp[1] & "/" & $aTemp[0] : $aTemp[0] & "/" & $aTemp[1])) = 0 Then _ ; Check valid date.
                    ContinueLoop (Abs(MsgBox(16, "Error", "Invalid date: " & $a[$j], 4))) ; Check valid date.
            $a[$j] = StringRegExpReplace($a[$j], "([^\d/\v]+)", "")
            $aRet[$iIndex][0] = StringRegExpReplace($a[$j], "(\d{2})/(\d{2})/(\d{4})", ($iFrmt = "au" ? "$3/$2/$1" : "$3/$1/$2")) ; DD/MM/YYYY to YYYY/MM/DD for sorting on YYYY/MM/DD.
            $aRet[$iIndex][1] = $a[$j]
            $iIndex += 1
        EndIf
    Next
    ReDim $aRet[$iIndex][2]
    If $iSort Then _ArraySort($aRet, $iDesc)
    _ArrayColDelete($aRet, 0)
    GUICtrlSetData($g_idMemo, _ArrayToString($aRet, @CRLF) & @CRLF)
EndFunc   ;==>_Parse

Func _Unique()
    Local $a = StringRegExp(GUICtrlRead($g_idMemo), "[\d/]+", 3)
    $aU = _ArrayUnique($a)
    _ArrayDelete($aU, 0)
    GUICtrlSetData($g_idMemo, _ArrayToString($aU, @CRLF) & @CRLF)
EndFunc   ;==>_Unique

 

Edited by Malkey
Added date validity checks. And, added if two dates on the same line have no characters separating them, then these dates are also treated as the two end points of a sequencial range of dates.
Link to comment
Share on other sites

  • 4 weeks later...
On 8/14/2020 at 6:14 AM, Malkey said:

I have been playing with this example for about a week, off and on. 

May this example help someone.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
#include <Array.au3>
; https://www.autoitscript.com/forum/topic/203556-_guictrlmonthcal-select-different-days/?do=findComment&comment=1462072

Global $g_idMemo
Global $iFrmt = "other"  ; Format MM/DD/YYYY ; or ;
;Global $iFrmt = "au"     ; Format DD/MM/YYYY ;

Example()


Func Example()
    Local $idMonthCal

    GUICreate("Select Dates", 250, 340, -1, 20, BitOR($WS_SIZEBOX, $WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU))

    Local $idMonthCal = GUICtrlCreateMonthCal("", 10, 10, 230, 160, $WS_BORDER)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetTip(-1, "Left mouse click on date to select")

    $g_idMemo = GUICtrlCreateEdit("", 10, 180, 230, 110)
    GUICtrlSetFont(-1, 9, 400, 0, "Courier New")
    GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, "Drag bottom edge of the GUI window is possible")

    Local $idButSort = GUICtrlCreateButton("Sort (Asc/Desc)", 10, 295, 100, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, 'Toggle ascending and descending date sort order.')

    Local $idButUniq = GUICtrlCreateButton("Unique", 120, 295, 50, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, 'Remove duplicate dates.')

    Local $idButParse = GUICtrlCreateButton("Parse", 180, 295, 50, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, "Change a range of dates (if present) to a list of dates" & @CRLF & _
            'eg. "12/08/202014/08/2020" or "12/08/2020 14/08/2020" or "14/08/2020:12/08/2020" or "12/08/2020 to 14/08/2020"  will return:-' & @CRLF & _
            '12/08/2020' & @CRLF & _
            '13/08/2020' & @CRLF & _
            '14/08/2020')

    Local $idButFormat = GUICtrlCreateButton("MM/DD/YYYY", 10, 318, 100, 20)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKBOTTOM + $GUI_DOCKLEFT)
    GUICtrlSetTip(-1, 'Toggle date format between "DD/MM/YYYY" and "MM/DD/YYYY"')
    GUISetState(@SW_SHOW)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $idMonthCal
                ;GUICtrlSetData($g_idMemo, GUICtrlRead($idMonthCal) & @CRLF, 1)
                GUICtrlSetData($g_idMemo, StringRegExpReplace(GUICtrlRead($idMonthCal), "(\d{4})/(\d{2})/(\d{2})", ($iFrmt = "au" ? "$3/$2/$1" : "$2/$3/$1") & @CRLF), 1) ; YYYY/MM/DD to (DD/MM/YYYY or MM/DD/YYYY)
            Case $idButSort
                _Parse() ; Default parameter is "1" to sort.  And, will change a range of dates (if present) to a list of dates.
            Case $idButUniq
                _Unique()
            Case $idButParse
                _Parse(0) ; Parameter "0" will not sort, but will change a range of dates (if present) to a list of dates.
            Case $idButFormat
                GUICtrlSetData($idButFormat, ($iFrmt = "au" ? "MM/DD/YYYY" : "DD/MM/YYYY"))
                $iFrmt = ($iFrmt = "au" ? "other" : "au")
                GUICtrlSetData($g_idMemo, StringRegExpReplace(GUICtrlRead($g_idMemo), "(\d{2})/(\d{2})/(\d{4})", "$2/$1/$3"), "")
        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>Example

; Any two dates on the same line separated by any character(s) that are not a digit or a "/",
; will be replaced with a sequencial range of dates between the two dates.
; eg. "12/08/202014/08/2020" or "12/08/2020 15/08/2020" or "15/08/2020:12/08/2020" or "12/08/2020 to 15/08/2020"  will return:-
; 12/08/2020
; 13/08/2020
; 14/08/2020
; 15/08/2020
Func _Parse($iSort = 1)
    Local $Y, $M, $D, $iStart, $iEnd, $iStep = 1, $iIndex = 0
    Local $aRet[1000][2]

    Local Static $iDesc = 1
    If $iSort Then $iDesc = Not $iDesc  ; Toggle ascending and descending date sort order.

    Local $a = StringRegExp(GUICtrlRead($g_idMemo), "[\d\V]+", 3)
    For $j = 0 To UBound($a) - 1
        $aTemp = StringRegExp($a[$j], "[^\D]{2,4}", 3)  ; Note: "[^\D]{2,4}" is faster than "\d{2,4}"
        If UBound($aTemp) = 6 Then

            ; Expand date range to date list. In 2D array, 1st column is sorting date,"y/m/d". 2nd column is formatted date, either "d/m/y" or "m/d/y"."
            $iStart = _DateToDayValue($aTemp[2], ($iFrmt = "au" ? $aTemp[1] : $aTemp[0]), ($iFrmt = "au" ? $aTemp[0] : $aTemp[1]))
            If @error Then ContinueLoop (Abs(MsgBox(16, "Error", "Error iInvalid range start date", 4))) ; Check valid date.

            $iEnd = _DateToDayValue($aTemp[2], ($iFrmt = "au" ? $aTemp[4] : $aTemp[3]), ($iFrmt = "au" ? $aTemp[3] : $aTemp[4]))
            If @error Then ContinueLoop (Abs(MsgBox(16, "Error", "Error invalid range end date", 4))) ; Check valid date.

            If $iStart > $iEnd Then $iStep = -1
            For $i = $iStart To $iEnd Step $iStep
                _DayValueToDate($i, $Y, $M, $D)
                $aRet[$iIndex][0] = $Y & "/" & $M & "/" & $D
                $aRet[$iIndex][1] = ($iFrmt = "au" ? $D & "/" & $M : $M & "/" & $D) & "/" & $Y
                $iIndex += 1
            Next

        Else
            If _DateIsValid($aTemp[2] & "/" & ($iFrmt = "au" ? $aTemp[1] & "/" & $aTemp[0] : $aTemp[0] & "/" & $aTemp[1])) = 0 Then _ ; Check valid date.
                    ContinueLoop (Abs(MsgBox(16, "Error", "Invalid date: " & $a[$j], 4))) ; Check valid date.
            $a[$j] = StringRegExpReplace($a[$j], "([^\d/\v]+)", "")
            $aRet[$iIndex][0] = StringRegExpReplace($a[$j], "(\d{2})/(\d{2})/(\d{4})", ($iFrmt = "au" ? "$3/$2/$1" : "$3/$1/$2")) ; DD/MM/YYYY to YYYY/MM/DD for sorting on YYYY/MM/DD.
            $aRet[$iIndex][1] = $a[$j]
            $iIndex += 1
        EndIf
    Next
    ReDim $aRet[$iIndex][2]
    If $iSort Then _ArraySort($aRet, $iDesc)
    _ArrayColDelete($aRet, 0)
    GUICtrlSetData($g_idMemo, _ArrayToString($aRet, @CRLF) & @CRLF)
EndFunc   ;==>_Parse

Func _Unique()
    Local $a = StringRegExp(GUICtrlRead($g_idMemo), "[\d/]+", 3)
    $aU = _ArrayUnique($a)
    _ArrayDelete($aU, 0)
    GUICtrlSetData($g_idMemo, _ArrayToString($aU, @CRLF) & @CRLF)
EndFunc   ;==>_Unique

 

Tks... Perfect!

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...