I want to make a simple timer for processes that I run with a Macro. I'm using SetTempVar to record the start and end times, and a simple query to calculate the elapsed time.
The macro is:
Then the query is simply:
SELECT [tempvars]![ProcessStart] AS Start, [TempVars]![ProcessEnd] AS [End], DateDiff("s",[start],[end]) AS Seconds;
But the output is strange:
The 2 fields from SetTempVar display in some strange font. However, the elapsed time of 84 seconds is correct.
How can I display the start and end times correctly?
I can reproduce this. It's an odd issue.
The TempVar gets interpreted as a string, though it contains a date. The binary date data gets interpreted as UTF-16 characters, displaying random characters (often Chinese since there are many Chinese characters in UTF-16).
I'd consider this a bug in Access. Queries should correctly determine variable type, and that's apparently somehow going wrong.
To display the date value, use either Format or CDate.
If you're interested in a time difference, I recommend formatting it as Long Time:
SELECT Format([tempvars]![ProcessStart], "Long Time") AS Start, Format([TempVars]![ProcessEnd], "Long Time") AS [End], DateDiff("s",[start],[end]) AS Seconds;
Related
My table field is date/time and formatted like this:
mm/dd/yyyy hh:nn:ss
I want the user to see this (with the space appearing between date and time
__/__/__ __:__:__
I want an input mask that demands:
Either 1 or 2 digits for the month
Either 1 or 2 digits for the dat
All 4 digits for the year
SHOWS the space but just jumps over it for the user
Either 1 or 2 digits for each of Hours, Minutes and Seconds
Further, when setting up a DB, is it just smarter to have two separate fields for Date and Time. A collegue encouraged me to break them out ... seems sensible?
00/00/0000##00:00:00
See the outcome in the image
Controlled user input is not an easy task in Access, as it is optimised for the opposite: To be tolerant and accept many input sequences for date and time.
For the cases where controlled input is mandatory, I've written two articles including full code (too much to post here) and demo, that may give you some ideas:
Entering ISO formatted date with input mask and full validation in Microsoft Access
Current code at VBA.DateEntry.
and
Entering 24-hour time with input mask and full validation in Microsoft Access.
Current code at VBA.TimeEntry.
I have an SSIS package that runs each morning to pull the previous days file from an FTP server. I am using the code below to create the file name using the previous date. Everything works great with this except when today's date is the first day of the month. for example, if ran today (3/1/2021) this returns name_of_file_20210328.xml.gz, however yesterday's date is 2/28/2021 not 3. How do i update this to say if today's date is beginning of month return mm - 1?
"name_of_file_" + (DT_STR,4,1252)(DATEPART("yyyy",GETDATE())) + (LEN((DT_STR,2,1252)(DATEPART("MM",GETDATE()))) == 2 ? (DT_STR,2,1252)(DATEPART("MM",GETDATE())) : "0" + (DT_STR,2,1252)(DATEPART("MM",GETDATE()))) + (LEN((DT_STR,2,1252)(DATEPART("dd",DATEADD( "day",-1, GETDATE())))) == 2 ? (DT_STR,2,1252)(DATEPART("dd",DATEADD( "day",-1, GETDATE()))) : "0" + (DT_STR,2,1252)(DATEPART("dd",DATEADD( "day",-1, GETDATE())))) +
".xml.gz"
Create a variable, Yesterday of type DateTime. Specify that it uses an expression and use the following expression. This provides a consistent reference point you can test against and if you disable the expression, allows you to specify a date for boundary/special case checking (like a leap year 2020-03-01)
DATEADD("DAY", -1, #[System::StartTime])
The next steps, especially if you're starting out, is to build the date parts in separate variables. It doesn't cost any extra to use lots of variables in your package and makes troubleshooting so much easier.
Add a new variable, YearString of type String.
(DT_WSTR, 4)datepart("YYYY", #[User::Yesterday])
That was easy.
Now we need to deal with create a zero, left padded string. Right now, your expression looks like it's trying to determine if day or month has 2 digits. I have a cleaner expression.
We're going to convert the day/month to a string and then prepend a zero to it. For Jan-Sep, we'll end up with a 2 character expression, Oct-Dec, we'll have a three character expression e.g. 011. For Day, similar bit where it's 01-09 or 010-031. We will then take the last two characters from the string. For the two character strings, it's a no-operation and for the three character variant, it gets us what we want.
Add Variable MonthString, as type string, to your package
RIGHT("0" + (DT_WSTR, 2)datepart("MONTH", #[User::Yesterday]), 2)
Add Variable DayString, as type string, to your package
RIGHT("0" + (DT_WSTR, 2)datepart("DAY", #[User::Yesterday]), 2)
Take a moment and look at your Variable collection. You can see that you have all the building blocks needed to properly construct your YYYYMMDD string. If something is wrong, it's small enough snippet to play with it. If not, break it up into smaller Variables.
Now that we have defined #Yesterday and then built YearString, MonthString and DayString off of Yesterday, all we have to do is bring it all together with the concatenation + operator
Back to the Variable well, creating #CurrentFileName of type string
"name_of_file_" + #[User::YearString] + #[User::MonthString] + #[User::DayString] + ".xml.gz"
Results in a value of name_of_file_20210216.xml.gz
Not addressed in this answer but things you should think about
What happens when the job doesn't run at all today (server fails horrifically, the data source is down, etc)? To pick up and process 2 days ago file, you would need to edit this package, run it through whatever change review process is applicable, deploy to prod, run it and then go back to the process yesterday file package.
That's not fun to type much less consider. You certainly aren't going to change the server time to trick the expression into being yesterday.
I am an advocate for passing the run date to the package (mechanism depends on how you deploy/run packages). In that situation, it's been my experience that it's a far easier bureaucracy fight to change the calling parameter (because no "code" has changed) than to get an emergency code change run through.
I am working on a time system that require manual input of the coming and going times. (not my system) I am building a dashboard for this system that will show average time on site and more. Because it requires a manually entered coming and going time, mistakes can happen. If someone checks in at 18:00hours but forgets to clock out, the system automatically leaves the clock out time at 0:00:00 hours.
When calculating my averages, if the above occurs, then it calculates the average time spent on site and adds in a -18:00 hours. This obviously breaks the whole calculation. Is there a way to have the query ignore any negatives to avoid this?
SELECT id, TIMEDIFF(`booking_time_out`, `booking_time`) AS 'Time_Spent'
FROM `table_name`
The negative result criteria is a result of the 0:00:00 booking out time so append the exclusion of that row in the where criteria like:
where booking_time_out != '0:00:00'
You seem to want a case expression:
select id,
case when timediff(`booking_time_out`, `booking_time`) < 0
then 0
else timediff(`booking_time_out`, `booking_time`)
end as time_spent
from tablename
Side note: do not surround identifiers with single quotes (as in as 'Time_spent'). In standard SQL, single quotes stand for literal strings. On the other hand, you usually do not need to quote an identifier (unless its name is really badly chosen) - and if you need to, the quoting character of MySQL is backticks.
I created a MS Access database for tracking some items at work. Users enter data which is then aggregated in queries (using count or sum) to calculate the actual value for each area, joined using UNION, then compared to goals for that area. I attempted to enter an IIF statement to conditionally calculate the percentage of [Act]/[Goal], leaving it zero if [Act] is blank or 1 if [Act] is greater than [Goal] so there is nothing over 100%. The issue is that it works most of the time, but other times fails with no obvious logic error or reason why that I can figure out.
Sometimes it can't tell that [Act] > [Goal] even though looking at it, it's obvious. The numbers are all integers, nothing crazy or formatting differences. The formula in [Met] is what I hope to achieve. I added the [TEST] field to trace back where it might not be working, which shows Access just isn't always returning the correct answer to [Act] > [Goal].
My Query:
What comes out (just the broken part):
As you can see, it works correctly for most rows, but then thinks 149 is less than 52, and 128 is less than 3. Because of this, it generates [Met] values over 100%.
Has anyone had this happen before or have any suggestions? I have tried using refresh, clicking in the cell to hit enter, everything I can think of.
I think that although your columns are Ints, they are being converted to strings in the variables (or at least one of the variables) Goal and Met.
If you look at the data, you'll see that if you compare them the results of Test are correct for a string comparison.
E.g. "3" > "128" (Because the first character has a higher char value).
In your query, try surrounding the variables with Val() when you are comparing them, as follows:
IIf(IsNull([Act]),0,IIf(Val([Act])>Val([Goal]),1,Round([Act]/[Goal],2)))
This is specifically for MS-Access Web Databases (requires Sharepoint hosting) which has many limitations compared to their client counterparts, like no VBA, instead you get form macros and data macros to manage data.
I've run into a weird bug on one of my applications. I have a query used to check stock levels against a "minimum stock level" also saved in the table. The query is pretty intense and there are over 4,000 records now to check against. These querys normally take about 75s. So I have made a little label that gets updated every time the form is loaded showing the time and date the query was last run, and the duration in seconds it took. (so users can see how fresh the data is and decide if it needs to be run again)
Now, the weird thing is it works fine in my Access client, but when I sync my changes to the server and try it in a web browser I get a "type mismatch" error. A small table is used to store the start and end times whenever the query is run, that's how I get the timestamp data. These fields are in a "Date/Time" format, obviously. But it seems the problem here is changing the date format to a string format so it can be put in a label on the form. The Access client seems perfectly capable of doing this, while the web client stumbles and falls.
My problem is, how do I change data in a date/time format to a string format in a Web database? I can't figure out how to do this. The tools are so limited. I may have to end up answering my own question here but I'm posting this for others just in case.
To return a value from a data macro as string, you have to format the internal date/time format as a string. In Access an internal date/time value is a double number with the integer part as number of days since 1900, and the “decimal” time part is a fraction of 24 hours. Unfortunately if you simply wrap the date/time in the str$() function we had for 20+ years, then you get something JUST like if you type this into the debug window:
? cdbl(now())
41955.5478587963
The solution is to simply pull out each part. And “nice” is while in few cases a data macro will cast the data type, it does in this case and thus the STR$() command is not required.
The expression you thus can use is this:
Month([d]) & "/" & Day([d]) & " Time = " & Hour([d]) & ":" & Minute([d])
So say to pluck out the VERY LAST start time column from say a invoice table, since we don’t have a dmax(), then we simply sort the table in the order we want and pull out the first row.
Our data macro will thus look like:
Note how in above I simply typed in the SQL and SET the order on the date/time column. I want the MOST recent invoice start date and time. For those new to SQL, then I suggest you build a query in the query builder and specify a query in above lookup feature, since many are not "comfortable" typing in free hand SQL as I did above.
Now, in your browser side (UI) macro, you can use this code:
The above returns a formatted string that you can stuff into a text box, or as per above code change the caption of a label.
Unfortunately with silly problems like this, it becomes a path-of-least resistance thing.
Since my intended result was simply to get "a timedatestamp from a table to show up on a form (so users could see when a query was last run)", this became redesigning my form in Access to be a text field instead of a label. Text fields can be adjusted to accept "Time/Date" formats, so this is exactly what I did, it now pulls the timestamp data directly from the last record of the table and requires no extra formatting to appear in the web browser. I redesigned the text field to appear and function more like a label, and my desired function was achieved.
However, since my question specifically asks, "how do you change a time/date format into a string format in a Web db?", I will leave it here in case someone actually does solve it.