DBASE Command Line to Replace a Year in Date Field - date

I am working in a software program called PastPerfect that has a "command window" where it says you can use dbase commands to do global updates to the program's dbf files.
THE PROBLEM: a user accidentally entered the wrong year, "1901", in a date field across multitudes of records and it needs to be replaced/fixed with the year "2001".
I have tried:
REPLACE YEAR(catdate) WITH 2001 FOR YEAR(catdate)=1901
and it keeps telling me it is an Invalid Command
Can somebody give me the correct dbase/foxpro syntax to replace all the years that are 1901 with 2001?

The syntax for the REPLACE command is.
REPLACE FieldName WITH Value FOR BooleanExpression
If CATDATE is a date field (no time), then
REPLACE catdate WITH DATE(2001, MONTH(catdate), DAY(catdate)) FOR YEAR(catdate) = 1901
If CATDATE is a date time field, then
REPLACE catdate WITH DATETIME(2001, MONTH(catdate), DAY(catdate), HOUR(catdate), MINUTE(catdate), SEC(catdate)) FOR YEAR(catdate) = 1901

Related

Sending automated email from SAS with attachments that changes name

I have files that should be send out every week. These files changes names e.g. "filename_1" next week it will be "filename_2".
But it only takes the filename that I manually wrote which is filename_1. Is there a way to say that it should take the latest file with this name everyweek,instead of me doing it manually every week?
This is my code for the email (I manually wrote the filename):
filename outbox email from="test#test.dk" to="test#test.dk"
type='text/html' subject='test' attach=("F:\filename_1.png" ct='png')
ods html body=outbox rs=none style=Htmlblue;run; ods html close;
The SAS macro facility will help you solve this very problem. If your filenames always have a consistent pattern, you can assign a macro variable to automatically change it for you. For simplicity's sake, let's say your filename always ends with today's date. You can assign a macro variable to hold this value.
%let filename = filename_&sysdate9..png;
This will resolve to filename_14DEC2020.png. You can confirm it with %put &filename.
If your file is sent out weekly and increments in a pattern, some quick math will help us figure out the correct suffix. Let's set a base week to start. We can count the number of weeks from this base week to identify the suffix. In this case, let's say it's today: December 14th, 2020. intck() can count the number of weeks from then until today. Our logic is:
suffix = (Number of weeks from Dec. 14th 2020 to Today) + 1.
In data step language, this is:
suffix = intck('week', '14DEC2020'd, today() ) + 1;
Translated to SAS macro language:
%let suffix = %sysevalf(%sysfunc(intck(week, %sysfunc(inputn(14DEC2020, date9.)), %sysfunc(today()) )) + 1);
%let filename = filename_&suffix..png;
Because we're pulling from data step functions, we need to enclose nearly everything in %sysfunc() to call them. This is one of the functions available that connect the SAS macro facility with the data step language.
Note that we also cannot use date literals directly in the SAS macro facility. We must use inputn() or putn() to convert a human-readable date into a SAS date format.
Simply call this macro variable within your code and it will resolve automatically (except within single quotes).
filename outbox email
from="test#test.dk" to="test#test.dk"
type='text/html'
subject='test'
attach=("F:\&filename" ct='png')
;

Postgresql invalid input syntax with windows CSV files

For some reason Postgresql wont read my CSV files in the form:
2017-10-20T21:20:00,124.502,CAM[CR][LF]
2017-10-20T21:21:00,124.765,CAM[CR][LF]
(thats an ISO compliant timestamp right?) into a table defined as:
CREATE TABLE ext_bsrn.spa_temp (
spadate TIMESTAMP WITHOUT TIME ZONE,
spa_azimuth NUMERIC,
station_id CHAR(3) )
WITH (oids = false);
It returns this error:
ERROR: invalid input syntax for type timestamp: "?2015-01-01T00:00:00"
CONTEXT: COPY spa_temp, line 1, column spadate: "?2015-01-01T00:00:00"
I don't understand why the '?' is shown inside the quotes in the error message, there's no characters before 2015 in my file (checked it in Notepad++ with noprint characters shown.)
I tried both windows (CRLF) and unix (LF) line ends, but neither makes any difference.
I also tried seperate date & time columns but then it just throws a similar error re the date field. "invalid input syntax for type date"
Does line 1 mean the first line or the second line (if there is a Line 0)?

How to format input for SAS's MONYY format

I currently have a dataset with dates in the format "FY15 FEB". In attempting to format this variable for use with SAS's times and dates, I've done the following:
data temp;
set pre_temp;
yr = substr(fiscal,3,2);
month = substr(fiscal,6,length(fiscal));
mmmyy = month||yr;
input mmmyy MONYY5.;
datalines;
run;
So, I have the strings representing the year and corresponding month. However, running this code gives me the error "The informat $MONYY was not found or could not be loaded." Doing some background on this error tells me that it has something to do with passing the informat a value with the wrong type; what should I alter in order to get the correct output?
*Edit: I see on the SAS support page for formats that "MONYYw. expects a SAS date value as input;" given this, how do I go from strings to a different date format before this one?
When you see a $, it means character value. In this case, you're feeding SAS a character value and giving it a numeric format. SAS inserts the $ for you, but there is no such format in existence.
I'm going to ignore the datalines statement, because I'm not sure why it's there (though I do notice there is no set statement). You might have an easier time just changing your program to:
data temp;
yr = substr(fiscal,3,2);
month = substr(fiscal,6,length(fiscal));
pre_mmmyy = strip(month)||strip(yr);
mmmyy=input(pre_mmmyy,MONYY5.);
run;
you can also remove the "length(fiscal))" from the substring function. The 3rd argument to the substring function is optional, and will go to the end of the string by default.

Get tomorrow's date in MS Word insert field

I'm trying to insert date field in MS Word that will display tomorrow's date we one opens the document.
I can insert Today's date {DATE \# "dd/MM/yyyy"}, can we insert tomorrow's date using modified formula?
Thanks
Without VBA, the calculation is possible, but not straightforward, because the Word field language has very limited support for date-related operations.
Originally I thought Word would auto-update the DATE when you open or close/re-open the document, but further experiments suggest that even the second suggestion in here will not do that.
In the specific case described (add 1 day), you should be able to use the following field coding:
{QUOTE {SET xxx { DATE }}{SET yyy {xxx \#YYYY}}{SET mmm {xxx \#M}}{SET xxx1 {={xxx \#YYYYMMDD}+1 \#0000'-'00'-'00}}{=13-{xxx1 \#M} \#"'{xxx1}';'{=mmm-11 \#'{=yyy+1}-01-01';'{yyy}-{=mmm+1 \#00'-01'}'"}'"} \#DD/MM/YYYY}
All the {} must be the special field code brace pairs that you can insert on Windows Word using ctrl-F9, and (typically) on Mac Word using cmd-F9 or fn-cmd-F9, depending on your keyboard setup. You can change the format at the end ("\#DD/MM/YYYY" ) as required.
However, that set of field codes probably will not be updated automatically by Word when you open the document, so the user would need to select the field codes and press F9.
I originally thought Word would update the date on open and/or close/re-open using the following coding, but I now believe I was wrong. The one thing it does achieve on recent versions of Windows Word is to present the Date field in a "bubble" with an option to update the field:
{DATE \#"'{QUOTE {SET xxx { DATE }}{SET yyy {xxx \#YYYY}}{SET mmm {xxx \#M}}{SET xxx1 {={xxx \#YYYYMMDD}+1 \#0000'-'00'-'00}}{=13-{xxx1 \#M} \#"'{xxx1}';'{=mmm-11 \#'{=yyy+1}-01-01';'{yyy}-{=mmm+1 \#00'-01'}'"}'"} \#DD/MM/YYYY}'"}
Here is some pseudocode for the algorithm:
Set xxx to the date.
Set yyy to the 4-digit year
Set mmm to the month
Set xxx1 to the date but with the day number incremented by 1. e.g., for 2016-12-31, that would be a string, "2106-12-32"
This is the tricky bit:
Try to extract the month from that date using { xxx1 \#M }. If the date is valid, { xxx1 \#M } will return a valid month number, i.e. in the range 1 to 12. If the date is not valid, { xxx1 \#M } will return xxx1, e.g. "2106-12-32", which the { = } field will treat as a calculation, i.e. "year-(a maximum of 12+32=44)", so it is always going to return a number larger than 12.
If xxx1 is a valid date then
result=xxx1
Else 'xxx1 is not a valid date so...
If mmm (the original month) is 12 then
result = "(yyy+1)-01-01"
Else
result = "yyy-(mmm+1)-01"
End If
End If
Apply the date format you want to "result".
NB, this also relies on the assumption that Word always correctly recognises the month and day when you specify a date in the format "YYYY-MM-DD", regardless of the locale, in other words that "2016-04-01" is always recognised as 01 April 2016, never as 04 January 2016. If anyone can provide a counter-example, then the assumption is wrong, the field coding will need to change, and will probably need to be locale-dependent.

Comparing Dates With User Input

I have found a statement that compares two dates to see if one is greater than another:
If Format(Date, "m/d/yyyy") > #1/1/2000# Then MsgBox "Okay"
That's basically saying if today is later than January 1st, 2000 then pop up a message box.
This is fine if I am putting the date in the code (i.e., 1/1/2000), but I would like to get a date from the user during run-time and can't figure out how to incorporate that into the statement above.
If I provide a TextBox for the user to enter a date, I have surrounded the text with the # symbol:
If MyDate > "#" & Text1.Text & "#" then
That does not work. I've tried converting the text to Double, Integer, and Long. I have no idea how to use the enclosing # symbols with user input.
Thanks in advance for your help.
Use CDate(Text1.Text) to convert a string to a date. In reality you will want to do some checking to make sure that the value entered is a valid date, something along the lines of:
Dim myDate As Date
If IsDate(Text1.Text) Then
MyDate = CDate(Text1.Text)
Else
'Indicate the error to the user
End If
The # characters are "date quotes", if you will - they serve the same purpose for date literals as " does to delimit a string literal. You can't just concatenate # to a value to make it into a date.