Blois Posted August 7, 2020 Share Posted August 7, 2020 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 More sharing options...
Nine Posted August 7, 2020 Share Posted August 7, 2020 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. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Nine Posted August 8, 2020 Share Posted August 8, 2020 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. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Malkey Posted August 14, 2020 Share Posted August 14, 2020 (edited) I have been playing with this example for about a week, off and on. May this example help someone. expandcollapse popup#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 August 17, 2020 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. dmob and Blois 1 1 Link to comment Share on other sites More sharing options...
Blois Posted September 9, 2020 Author Share Posted September 9, 2020 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. expandcollapse popup#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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now