Now, I have successfully display the time in "HH:mm" format, but I will need to change it to decimals. For example, the hours is 2.30 meaning 2 hours and 30 minutes, but I need it to be 2.5 meaning 2.5 hours. Please help. Below is my code:
Local NumberVar HoursDiff;
Local NumberVar MinutesDiff;
Local NumberVar SecondsDiff;
Local StringVar strOut;
SecondsDiff := DateDiff('s',{Invoicing.TimeFrom},{Invoicing.TimeTo});
HoursDiff:= SecondsDiff \ (60 * 60);
SecondsDiff := SecondsDiff MOD (60 * 60);
MinutesDiff:= SecondsDiff \ 60;
strOut := strOut & CStr(HoursDiff,0)& '.' & CStr(MinutesDiff,'00');
strOut
Try the following formula, I think it will work for you
timeVar time_value := CTime("2:30");//Time in HH:mm format
stringVar timeString := ToText(time_value);
numberVar time_in_min := ToNumber(Split(timeString,":")[1])*60 + ToNumber(Split(timeString,":")[2]) ;
time_in_min/60;
Convert this returned string value to time format using "time(strout)", then right click on formula field then select format filed option, it will opens a format editor in this select "date and time" tab. Then click on "customize" tab it will opens a custom style window.
in custom style window select time from order field in "Datetime" tab. then click on time tab and select which format you want.
Related
I have a date field on which my inventory item was bought. Then I have a lifespan field in months eg 240. Now I am trying to calculate the end of the item's lifespan date but I get an error:
numbervar myVariable := ({TABLE.LIFESPAN} * 30);
dateadd("d", myVariable,{#date})
I get the following error: "Date must be between year 1 and 9999"
As soon as I change the variable to: numbervar myVariable := {TABLE.LIFESPAN};
it works without any errors. Also if I change the dateadd formula to dateadd("d", 7200,{#date}) it works.
The format of the field TABLE.LIFESPAN is decimal(9,2) but none of the value has decimals, eg it will be 240.00
I have also tried
numbervar myVariable := Round({TABLE.LIFESPAN} * 30);
I suspect it has something to do with the decimals.
Help will be greatly appreciated.
you will receive this value once your ({TABLE.LIFESPAN} * 40) causes the year to be greater than 9999. So if {#date} were today's date then {TABLE.LIFESPAN} could not be higher than 73955 or so. I would create a formula for ({TABLE.LIFESPAN} *40) and drop it on the canvas and see what that value is on all records and see if you have an unusually high number somewhere.
I want to print all the days of a given month in Crystal Report. This is what my Crystal Report looks like:
So on and so forth.
What I have done is, I created a table with dates, when the user pick a month through the date-timepicker my program will insert all the days of the picked month to the table.
Although it can be attempted at SQL level also (as suggested by #aMazing), if you want to do it at Crystal Report level only, you can adapt from the following basic idea to accomplish rows with dates having no records.
Create three formula fields in report design, namely First_Dates, Mid_Dates, Last_Dates and set their values in formula editor as under:
First_Dates
WhilePrintingRecords;
numberVar TotalDays := Day ({Sale_Date_Field}) - 1;
numberVar i;
stringVar DayList := "";
for i := 1 to TotalDays step 1 do
DayList := DayList & ToText(i, 0) & " 0.00 0.00" & Chr(13);
DayList;
Mid_Dates
WhilePrintingRecords;
numberVar FromDay := Day({Sale_Date_Field}) + 1;
numberVar To_Day := Day(Next({Sale_Date_Field})) - 1;
numberVar i;
stringVar DayList := "";
for i := FromDay to To_Day step 1 do
DayList := DayList & ToText(i, 0) & " 0.00 0.00" & Chr(13);
DayList;
Last_Dates
WhilePrintingRecords;
numberVar NextDay := Day ({Sale_Date_Field}) + 1;
numberVar i;
numberVar MonthDays := 30;
if (Month ({Sale_Date_Field}) in [1,3,5,7,8,10,12]) then
MonthDays := 31
else if (Month ({Sale_Date_Field}) in [4,6,9,11]) then
MonthDays := 30
else if (Month ({Sale_Date_Field}) = 2
and Remainder(Year({Sale_Date_Field}), 4) = 0) then
MonthDays := 29
else
MonthDays := 28;
stringVar DayList := "";
for i := NextDay to MonthDays step 1 do
DayList := DayList & ToText(i, 0) & " 0.00 0.00" & Chr(13);
DayList;
Now place these formula fields in your report as under:
First_Dates in Report Header Section
Mid_Dates in Details b Section
Last_Dates in Report Footer Section
Now enable Can Grow option for each of them in the Format Field on the Common tab.
Enable Suppress Blank Section option for Detail b Section in Section Expert.
Format the fields and DayList accordingly.
For multiple months the report can be grouped by Months and First_Dates, Last_Dates formulas can be placed in the Group Header and Footer respectively.
This solution will not work with Cross-Tab format.
When using LastFullWeek i get the last Sunday - Saturday week, but for my reports i want the last Monday - Sunday week.
Is there any simple way to get this behaviour, or do I have to write my own function for it (which isn't that hard, but unconvenient for such a common date span.)
custom function:
//LastFullWeekEx
Function (DateVar date, Optional NumberVar firstDayOfWeek := crSunday)
(date - DayOfWeek(date, firstDayOfWeek)) - 6 TO (date - DayOfWeek(date, firstDayOfWeek))
usage:
// use with non-volatile DataDate and Sunday
{TABLE.DATE} IN LastFullWeekEx(DataDate)
// use with non-volatile DataDate and Monday
{TABLE.DATE} IN LastFullWeekEx(DataDate, crMonday)
testing:
// should return True
( Minimum(LastFullWeek) = Minimum(LastFullWeekEx(DataDate, crSunday)) ) AND
( Maximum(LastFullWeek) = Maximum(LastFullWeekEx(DataDate, crSunday)) )
Instead of using
{DATE} in LastFullWeek
use the form
{DATE}-1 in LastFullWeek
The code, if no better answer comes along, for others who find this question through the search engine:
{DATE} >= currentdate - dayofweek(currentdate, crMonday) - 6 AND
{DATE} < currentdate - dayofweek(currentdate, crMonday) + 1
You have no other choice than to use a custom formule as Crystal Reports uses fixed week settings (US). So a week is Sunday to Saturday and DayOfWeek starts with Sunday (value/index 1).
Add +1 to LastFullWeek min and max:
DateVar Start := Minimum(LastFullWeek)+1; //Monday
DateVar End := Maximum(LastFullWeek)+1; //Sunday
Edit: Since LastFullWeek always takes Sunday as the first day of the week, we need to check if the current day is Sunday. If so, we need to subtract a week:
// Check if the current day is Sunday
IF (DAYOFWEEK(CurrentDate) = 1)
THEN (
Start := Start - 7;
End := End - 7
);
Example: Date range to string
StringVar LastWeekRange := ToText(Start) + " - " + ToText(End);
LastWeekRange;
Return example: "MM/DD/YYYY - MM/DD/YYYY"
Example: Selecting all dates within date range
{datefield} >= Start and {datefield} <= End;
I am using Crystal Reports XI R2.
My table has transaction data by date. I have a group set up by day and a summary to give a count of transactions for each day. I also have a running total set to give a year to date count for each day. Of course it resets on a change in year.
My goal is to be able to find the difference between the YTD count yesterday and the same for the same date last year.
Edit: I've misstated the goal. It isn't to be able to find the difference for just yesterday, but for each day in a range of days.
Create these two formula fields:
//{#LastYearToDate}
If {table.dateField} IN LastYearYTD Then
1
Else
0
//{#ThisYearToDate}
If {table.dateField} IN YearToDate Then
1
Else
0
Insert a summary on each field in the ReportFooter section.
I finally got this nailed down. There is likely a cleaner way of doing this, but....
I converted the dates (started as text yyyy-mm-dd) into text mm/dd/yyyy format:
stringvar yyyyear := {table.dateField}[1 to 4];
stringvar mmonth := {table.dateField}[6 to 7];;
stringvar dday := {table.dateField}[9 to 10];
mmonth + "/" + dday + "/" + yyyyear
Grouped by this field and inserted a count summary into the group header. Created a separate field for the mm/dd portion of each date:
{#textDate}[1 to 5]
Added a flag to see if the date in the current group header matched the previous:
if previous({#mm/dd}) = {#mm/dd}
then 1
else 0
Used a shared variable to store the YTD totals for each year (2 formulas):
shared numbervar totalsCurentYear;
if {#prevDateFlag} = 1 then
totalsCurrentYear := totalsCurrentYear + Sum ({#transactionCount}, {#textDate});
totalsCurrentYear
|
shared numbervar totalsLastYear;
if {#prevDateFlag} = 1 then
totalsLastYear := totalsLastYear + Sum ({#transactionCount}, {#textDate});
totalsLastYear
Put both of these into the group footer (suppressed) and added a field to do the subtraction into the group header.
I am trying to format a date to look like this 2011-09-19
If I do the following :
leaveDate = "09/19/11"
FormatTime, fileDate, leaveDate, yyyy-MM-dd
MsgBox, %fileDate%
It will just pick up the current date and time because my input date format is invalid. How can I take this 09/19/11 and turn it into this 2011-09-19?
I have read the docs, and I can't find a function to do this. Am I just overlooking it?
Your date needs to be supplied in YYYYMMDDHH24MISS format. If your date format is consistent and all years are after 2000 then the following code using SubStr() to split up the date should work:
leaveDate := "09/19/11"
year := "20" . SubStr(leaveDate, 8, 2)
month := SubStr(leaveDate, 2, 2)
date := SubStr(leaveDate, 5, 2)
formattedTime := year . month . date
FormatTime, fileDate, %formattedTime%, yyyy-MM-dd
MsgBox, %fileDate%
At the bottom of the documentation page for FormatTime a link is given to a forum topic giving the code for a function titled DateParse. This function will take a date in pretty much any format and return a YYYYMMDDHH24MISS formatted string that can be used instead of SubStr() generated string.
The example given is:
DateParse("2:35 PM, 27 November 2007")