How to select a date in a sysmonth Control in autohotkey - autohotkey

i'm trying to select a date in a monthcal with the sendmessage cmd from AHK. Unfortunately, this is not working and i don't know where is my mistake or my misunderstanding. Anyone could help ? Here's what i already try.
ConvertNormalDateToSystemTime(YYYYMMDD)
; this return a SystemTime format date from a normal date
{
YYYYMMDD.=000000
YYYYMMDDHHMISS:=YYYYMMDD
VarSetCapacity(SystemTime, 16, 0) ; This struct consists of 8 UShorts (i.e. 8*2=16).
Int := SubStr(YYYYMMDDHHMISS, 1, 4) ; YYYY (year)
NumPut(Int, SystemTime, 0, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 5, 2) ; MM (month of year, 1-12)
NumPut(Int, SystemTime, 2, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 7, 2) ; DD (day of month)
NumPut(Int, SystemTime, 6, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 9, 2) ; HH (hour in 24-hour time)
NumPut(Int, SystemTime, 8, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 11, 2) ; MI (minute)
NumPut(Int, SystemTime, 10, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 13, 2) ; SS (second)
NumPut(Int, SystemTime, 12, "UShort")
return % &SystemTime
}
MCM_FIRST:= 0x1000
MCM_SETCURSEL:= MCM_FIRST + 2
MyDate:= 20211115
WinActivate ahk_class AutoHotkeyGUI, ExempleCalendrier.ahk
dateASelectionnerDansCalendrier := ConvertNormalDateToSystemTime(20211115)
try
{
SendMessage MCM_SETCURSEL , , &dateASelectionnerDansCalendrier, SysMonthCal321, ahk_class AutoHotkeyGUI ; THIRD TRIAL
MsgBox % ErrorLevel
}
catch e
{
MsgBox % ErrorLevel
}
An other strange thing is that i always get the MCM_SETCURSEL message back in MyReturn variable. I already try to compile the script and run it as admin. I know that there is no multiselected option on my monthcal. Someone on Discord suggest me that MCM_SETCURSEL lparam was pointing to a systemtime. So how could i send my date to my monthcal ? Should i convert my actual date into a systemTime in an other way ? (speaking as a noob)
Thanks for any help !

Related

Output dates based on an array

Need Help. I have an associative array which has the days of the week. I know very little about arrays. Each day has a 1 or 0 in the array below. I am trying to output dates and use them to generate tasks. I'm sure can this be done easily, but I lack the experience.
I want to output only dates which have 1's as shown in the array below.
The first task is due in 4 days.
I need to view dates up to 3 days ahead, so if today is Tuesday, and start is on Friday, then the Friday task date won't appear until Wednesday.
Today := A_now
WeekDays_Array := {Sun: 0, Mon: 0, Tue: 1, Wed: 0, Thu: 1, Fri: 1, Sat: 0}
I am pretty sure this is most of it. The suggestion to use the array above made the most sense.
The script uses Wkday (which is A_Now) as the start day but I think that can be changed by substituting it for a specific start day
PastDue := []
DueBy := []
;~ Weekday_Array := {Sunday: 0, Monday: 0, Tuesday: 1, Wednesday: 0, Thursday: 1, Friday: 1, Saturday: 0}
Weekday_Array := [1,1,1,1,1,1,1] ;Represents Sun-Saturday
AssignTask:
FormatTime, WkDay, MyTime, WDay
For i, value in Weekday_Array{
DueDate =
if (i > WkDay && Value = 1){
x++
DueDate += (x), days
FormatTime, DueDate, % DueDate, MM/dd/yy
DueBy.InsertAt(i,DueDate)
}
if (i = WkDay && Value = 1){
FormatTime, DueDate, % A_Now, MM/dd/yy
DueBy.InsertAt(i,DueDate)
}
if (i < WkDay && Value = 1){
y--
Pastdate =
PastDate += (y) , days
NewDate := PastDate
NewDate += 7, days
FormatTime, PastDate, % PastDate, MM/dd/yy
FormatTime, NewDate, % NewDate, MM/dd/yy
PastDue.InsertAt(i,PastDate)
DueBy.insertAt(i,NewDate)
}
}
For i, PastDue in PastDue
PastDueDates .= PastDue "`n"
Sort, PastDueDates
PastDueDates := "Past due dates so far this week `n`n" PastDueDates
MsgBox, 0x1000,, % PastDueDates
For i, DueDate in DueBy
DueDates .= DueDate "`n"
Sort, DueDates
DueDates := "All upcoming due dates based criteria `n`n" DueDates
MsgBox, 0x1000,, % DueDates
sort, DueDates
FormatTime, xDay1, % A_Now, MM/dd/yy
xDay2 += 1, days
FormatTime, xDay2, % xDay2, MM/dd/yy
xDay3 += 2, days
FormatTime, xDay3, % xDay3, MM/dd/yy
For i, DueDate in DueBy{
if (DueDate = xDay1 || DueDate = xDay2 || DueDate = xDay3)
XDays .= DueDate "`n"
}
xDays := "Only view the next 3 days from today `n`n" xDays
MsgBox, 0x1000,, % xDays
;~ return
*esc::
ExitApp
return

Add to date or time in AutoHotkey

I was looking for an inbuild ahk function that allows the user to add days, months, years or even time to an existing day thus converting it correctly to a new month if the day count reaches 32. I didn't find anything, so I came up with this little solution:
; returns an array [year, month, day, hour, minute, second]
DateTimeAdd(v_a_now,yearPlus=0,monthPlus=0,dayPlus=0,hrPlus=0,minPlus=0,secPlus=0) {
daysInMonth := { 1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31 }
; Parse data from an A_NOW type format
; If you pass your custom "A_NOW" format remember that numbers < 10 are expected to have a leading 0
day := SubStr(v_a_now,7,2) + dayPlus
month := SubStr(v_a_now,5,2) + monthPlus
year := SubStr(v_a_now,1,4) + yearPlus
hours := SubStr(v_a_now,9,2) + hrPlus
minutes := SubStr(v_a_now,11,2) + minPlus
seconds := SubStr(v_a_now,13,2) + secPlus
; Start formatting
if(seconds >= 60) {
tadd := seconds / 60
seconds -= Floor(tadd) * 60
minutes += Floor(tadd)
}
if(minutes >= 60) {
tadd := minutes / 60
minutes -= Floor(tadd) * 60
hours += Floor(tadd)
}
if(hours >= 24) {
tadd := hours / 24
hours -= Floor(tadd) * 24
day += Floor(tadd)
}
; We have to format the month first in order to be able to format the days later on
if(month >= 13) {
tadd := month / 12
month -= Floor(tadd) * 12
year += Floor(tadd)
}
; Assmuning the number of days is an absurd number like 23424 we need to go through each month and subtract the max. amount of days from that month
cond := true
while(cond) {
; Get the number of max. days in this current month (sadly no loop years included :< )
max_days_in_this_month := daysInMonth[month]
; If the number of days i.e. 42 is great than 31 for example in January
if(day > max_days_in_this_month) {
; Subtract max. allowed days in month from day
day -= max_days_in_this_month
; New Year?
if(month == 12) {
month := 1
year++
} else {
month++
}
} else {
cond := false
}
}
; Add leading zero to numbers
return_array := [year, month, day, hours, minutes, seconds]
i := 2
while(i != return_array.MaxIndex()+1) {
thisIteration := return_array[i]
if(thisIteration <= 9) {
return_array[i] := "0" thisIteration
}
i++
}
; Done formatting
; For testing
;~ msg := return_array[1] "/" return_array[2] "/" return_array[3] " " return_array[4] ":" return_array[5] ":" return_array[6]
;~ msgbox % msg
return return_array
}
Sadly this function does not take loop years into aspect. Do you guys know any better alternatives?
Check out EnvAdd at https://autohotkey.com/docs/commands/EnvAdd.htm
EnvAdd, Var, Value, TimeUnits
equivalent to
Var += Value, TimeUnits
EnvAdd sets a date variable Var (in YYYYMMDDHH24MISS format) to the sum of itself plus the given date value Value using the timeunits parameter.
Example:
newDate := %A_Now% ; or whatever your starting date is
EnvAdd, newDate, 20, days
NewDate += 11, days
MsgBox, %newDate% ; The answer will be the date 31 days from now.

Converting VBS to web form

I need to create a web form that -- 1. checks if a serial number is correct. I have the script that does this in VBScript and I am trying to incorporate that into a form. It is a simple algorithm as shown below (the licence format is 9999-999999):
Dim strID
Dim ColCSum3
Dim ChkVal
Dim InitVal
strID = InputBox("Please enter the the serial number to verify", "Verify serial")
If strID = "" Then wscript.Quit
If mid(strID, 5, 1) <> "-" Or Len(strID) <> 11 Then MsgBox "Invalid number format...", 16, "Input error": wscript.Quit
InitVal = CLng(Left(strID, 1))
ChkVal = CLng(Mid(strID, 2, 3))
ColCSum3 = (2 * CLng(Mid(strID, 6, 1)) + _
7 * CLng(Mid(strID, 7, 1)) + _
6 * CLng(Mid(strID, 8, 1)) + _
3 * CLng(Mid(strID, 9, 1)) + _
5 * CLng(Mid(strID, 10, 1)) + _
4 * CLng(Mid(strID, 11, 1))) * 3
If 11 * InitVal + ColCSum3 + 3 = ChkVal Then
MsgBox strID & " is a valid serial number..", 64, "Validated"
Else
MsgBox strID & " is not a valid serial number", 48, "Invalid"
End If
and 2. Once this works, would the key inputed by the user be able to get stored into a database somewhere so that it does not get used again? So I guess the form would also have to check against this field of the database.
The main site is in WordPress but I could set this up as a standalone page if need be. Maybe there is a good WP form plugin that is capable of doing this?
Many thanks.

Converting numbers to MM:SS format in Cross-tab

I'm trying to convert a value in Cross-tab of Crystal report into a MM:SS format. I used the following steps: Right-click summary > Format Field > Display String > x+2
WhilePrintingRecords;
NumberVar curr := CurrentFieldValue;
NumberVar mins := Truncate(curr / 60);
NumberVar secs := Remainder(curr, 60);
ToText(mins, 0, "") & ":" & ToText(secs, 0, "")
The results are ok when the secs is not 0. Example: `4:30'
But, I am having problems when secs is 0, the result is (for 4 minutes): 4:0
I would like to have the output as 4:00, with the seconds display as always a 2 digit number.
Thank you for all your help
You my ElapsedTime function in conditional-formatting expression.
I used this instead, and it worked :)
NumberVar curr := CurrentFieldValue;
NumberVar mins := Truncate(curr / 60);
NumberVar secs := Remainder(curr, 60);
ToText(mins, 0, "") & ":" & ToText(secs, '00')

Which days are work days in a given date range

Is there a built in function that will tell me which days are work days? this is what i mean,
If I were to choose today's date (6/14/2011), it will give me any inspection numbers clocked out today. This lead time includes weekends. So if I had a customer start a project on the 10th (Friday) and finish it today; it would show it took about five days, instead of three.
I believe there used to be a function to do this a long long time ago, but I believe that function has since been removed. I believe that you should be able to use something like the following which calculates the business days between two dates:
DateDiff ("d", {Orders.OrderDate}, {Orders.ShipDate}) -
DateDiff ("ww", {Orders.OrderDate}, {Orders.ShipDate}, crSaturday) -
DateDiff ("ww", {Orders.OrderDate}, {Orders.ShipDate}, crSunday)
This gets the total days difference and subtracts the saturdays and sundays from the total. Note this does not include holidays. For that you'd need to maintain them in your own User Function Library and include them in the calculation.
Hope this helps.
This is the solution i came up with. Pretty much if it is anything over 7 days i know how many days to subtract. if it is under 7 days i can still figure out if it spanned the weekend. Crystal reports has a function DayOfWeek that returns a number for the day i.e. Sunday = 1, Monday = 2, etc. If the finish time day number is less than the start time number we know it passed the weekend. and we can subtract 2.
timeDiff is startdate - finishdate.
if({#timeDiff} >= 35) then
{#timeDiff} - 10
else if({#timeDiff} >= 28) then
{#timeDiff} - 8
else if({#timeDiff} >= 21) then
{#timeDiff} - 6
else if({#timeDiff} >= 14) then
{#timeDiff} - 4
else if({#timeDiff} >= 7) then
{#timeDiff} - 2
else if(DayOfWeek({Command.Finishdate}) < DayOfWeek({Command.Startdate})) then
{#timeDiff} - 2
else
{#timeDiff}
I have a more in depth explanation on my website. the link is here
Here is a monster solution that also takes public holidays into account:
// WorkingDays
// Count the number of working days between a start and an end date.
//
// startDate - first date in the interval
// endDate - last date in the interval
// countStartAndEnd - if true 1 feb to 2 feb will count as 2 days
// if false 1 feb to 2 feb will count as 1 day
// given both of them are working days
Function (dateVar startDate, dateVar endDate, optional booleanVar countStartAndEnd := False)
local NumberVar Weeks;
local NumberVar Days;
local NumberVar Hol;
// 5 days for every week (whole or partial)
Weeks := (Truncate (endDate - dayofWeek(endDate) + 1 - (startDate - dayofWeek (startDate) + 1)) /7 ) * 5;
// Number of days in partial weeks (can be positive or negative)
Days := DayOfWeek(endDate) - DayOfWeek(startDate) + 1 +
(if DayOfWeek(startDate) = crSunday then -1 else 0) +
(if DayOfWeek(endDate) = crSaturday then -1 else 0);
// Count number of public holidays in the period
local NumberVar iYear;
local NumberVar i;
for iYear := Year(startDate) to Year(endDate) do (
Local DateVar Array Holidays := getHolidays(iYear);
for i := 1 to uBound(Holidays) do (
local NumberVar hMonth := Month(Holidays[i]);
local NumberVar hDay := Day(Holidays[i]);
local DateVar hDate := cDate(iYear, hMonth, hDay);
if DayOfWeek(hDate) in crMonday to crFriday and
hDate in startDate to endDate then Hol := Hol+1;
);
);
// Return number of working days
Weeks + Days - Hol - toNumber(not countStartAndEnd);
Code above modified from solution found at KenHamady.
The following function is called by the previous function and returns all public holidays:
// getHolidays
// Returns an array with all public holidays for a given year
// These are Swedish holidays. Modify as needed.
Function (Numbervar yyyy)
Datevar Array holidays;
local Datevar holiday;
local Datevar easterSunday := getEasterSunday(yyyy);
// New Years Day
// 1 jan
holiday:=Date(yyyy, 1, 1);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Epiphany
// 6 jan
holiday:=Date(yyyy, 1, 6);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Good Friday
// 2 days before easter sunday
holiday:=cDate(DateAdd("d", -2, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Holy Saturday
// 1 day before easter sunday
holiday:=cDate(DateAdd("d", -1, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Easter Sunday
// The first Sunday following the first ecclesiastical full moon that occurs on or after the day of the vernal equinox
holiday:=cDate(DateAdd("d", -2, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Easter Monday
// 1 day after easter sunday
holiday:=cDate(DateAdd("d", 1, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Labour day
// 1 may
holiday:=Date(yyyy, 5, 1);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Ascension
// 39 days after easter sunday
holiday:=cDate(DateAdd("d", 39, easterSunday));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// National day
// 6 june
holiday:=Date(yyyy, 6, 6);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Midsummer's eve
// The friday in the interval 19 june - 25 june
holiday:=cDate(DateAdd("d", 1-dayOfWeek(Date(yyyy, 6, 25), crFriday), Date(yyyy, 6, 25)));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// All saints' day
// The saturday in the interval 31 october - 6 november
holiday:=cDate(DateAdd("d", 1-dayOfWeek(Date(yyyy, 11, 6), crSaturday), Date(yyyy, 11, 6)));
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Christmas eve
// 24 december
holiday:=Date(yyyy, 12, 24);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// Chritmas day
// 25 december
holiday:=Date(yyyy, 12, 25);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// St. Stephen's Day
// 26 december
holiday:=Date(yyyy, 12, 26);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
// New year's eve
// 31 december
holiday:=Date(yyyy, 12, 31);
Redim Preserve holidays[Ubound(holidays)+1];
holidays[Ubound(holidays)]:=holiday;
holidays;
Code above based on the custom function in this post by craig.
The holiday function need to be able to get the date for easter sunday for a given year:
// getEasterSunday
// Returnes a dateVar of the easter sunday for a given year
//
// Based upon formula from http://aa.usno.navy.mil/faq/docs/easter.php
Function (numberVar yyyy)
local numberVar c := int(yyyy / 100);
local numberVar n := yyyy - 19 * int(yyyy / 19);
local numberVar k := int((c-17)/25);
local numberVar i := c - int(c/4) - int((c-k)/3) + 19*n + 15;
i := i - 30 * int(i/30);
i := i - int(i/28) * ( 1 - int(i/28) * int(29/(i+1)) * int((21-n)/11));
local numberVar j := yyyy + int(yyyy/4) + i + 2 - c + int(c/4);
j := j - 7 * int(j/7);
local numberVar l := i - j;
local numberVar m := 3 + int((l+40)/44);
local numberVar d := l + 28 - 31 * int(m/4);
cDate(yyyy, m , d);
Easter sunday calculation formula from United States Naval Observatory.