Recent Activity
Hi,
I am trying to capture the status of jobs and their exit code into a Table.
I'm saving the log in a folder using proc printto and then reading the log into a dataset for finding required values.
I'm using sas program step in my SAS Studio Flows for execution.
When there is no error in the flow, my code executes successfully and I'm able to capture the details.
However, when I add an error in the flow, to test whether the details are being captured or not, I get errors.
Logfile is not being read by the program and no value for ERROR_CODE and ERROR are being saved.
How can I ensure that the logfile is read? I added a delay of 15sec and 60sec but its still unable to read log.
Code:
data _null_;
call sleep(60,1);
run;
options symbolgen mprint mlogic;
%macro m_upd_job_status(m_full_name=, m_job_name=,m_startdt=,m_end_dt=);
FILENAME REFFILE FILESRVC FOLDERPATH='/Project/Test/LOGS' FILENAME="&m_full_name..txt";
%let Job_status=Completed;
%let ERROR_CODE= ;
%let ERROR_DESC= ;
data test;
infile REFFILE truncover;
input log_line $400.;
I=index((log_line), 'SYSCC=');
run;
data _null_;
infile REFFILE truncover;
input log_line $400.;
if index((log_line), 'SYSCC=') =1 then call symputx('ERROR_CODE', STRIP(SUBSTR(log_line,8)));
if index((log_line), 'ERROR ') > 0 or index((log_line), 'ERROR:') > 0 then call symputx('ERROR_DESC', STRIP(log_line));
run;
%if %sysevalf(%superq(ERROR_CODE) > 0) %then %do;
%let Job_status = Failed;
%end;
%put &ERROR_CODE.;
%put &ERROR_DESC.;
%put &Job_status.;
proc sql;
update LIB.AUDIT_TBL SET STATUS="&Job_status."
where JOB_NAME = "&jobnm.";
update LIB.AUDIT_TBL SET EXIT_CODE=&ERROR_CODE.
where JOB_NAME = "&jobnm.";
update LIB.AUDIT_TBL SET START_DTTM="&logdt."dt
where JOB_NAME = "&jobnm.";
update LIB.AUDIT_TBL SET END_DTTM="&endt."dt
where JOB_NAME = "&jobnm.";
quit;
%mend m_upd_job_status;
%m_upd_job_status(m_full_name=&full_job. ,m_job_name=&jobnm.,m_startdt=&logdt.,m_end_dt=&endt.);
Log:
2032 data _null_;
2033 call sleep(60,1);
2034 run;
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
2035 options symbolgen mprint mlogic;
2036
2037 %macro m_upd_job_status(m_full_name=, m_job_name=,m_startdt=,m_end_dt=);
2038 FILENAME REFFILE FILESRVC FOLDERPATH='/Project/Test/LOGS' FILENAME="&m_full_name..txt";
2039
2040 %let Job_status=Completed;
2041 %let ERROR_CODE= ;
2042 %let ERROR_DESC= ;
2043
2044 data test;
2045 infile REFFILE truncover;
2046 input log_line $400.;
2047 I=index((log_line), 'SYSCC=');
2048 run;
2049
2050 data _null_;
2051 infile REFFILE truncover;
2052 input log_line $400.;
2053 if index((log_line), 'SYSCC=') =1 then call symputx('ERROR_CODE', STRIP(SUBSTR(log_line,8)));
2054 if index((log_line), 'ERROR ') > 0 or index((log_line), 'ERROR:') > 0 then call symputx('ERROR_DESC', STRIP(log_line));
2055 run;
2056
2057 %if %sysevalf(%superq(ERROR_CODE) > 0) %then %do;
2058 %let Job_status = Failed;
2059 %end;
2060
2061 %put &ERROR_CODE.;
2062 %put &ERROR_DESC.;
2063 %put &Job_status.;
2064
2065 proc sql;
2066 update LIB.AUDIT_TBL SET STATUS="&Job_status."
2067 where JOB_NAME = "&jobnm.";
2068 update LIB.AUDIT_TBL SET EXIT_CODE=&ERROR_CODE.
2069 where JOB_NAME = "&jobnm.";
2070 update LIB.AUDIT_TBL SET START_DTTM="&logdt."dt
2071 where JOB_NAME = "&jobnm.";
2072 update LIB.AUDIT_TBL SET END_DTTM="&endt."dt
2073 where JOB_NAME = "&jobnm.";
2074 quit;
2075 %mend m_upd_job_status;
2076
2077 %m_upd_job_status(m_full_name=&full_job. ,m_job_name=&jobnm.,m_startdt=&logdt.,m_end_dt=&endt.);
MLOGIC(M_UPD_JOB_STATUS): Beginning execution.
SYMBOLGEN: Macro variable FULL_JOB resolves to 027_JOB1_02MAY2025:19:18:54
SYMBOLGEN: Macro variable JOBNM resolves to 027_JOB1
SYMBOLGEN: Macro variable LOGDT resolves to 02MAY2025:19:18:54
SYMBOLGEN: Macro variable ENDT resolves to 02MAY2025:19:18:55
MLOGIC(M_UPD_JOB_STATUS): Parameter M_FULL_NAME has value 027_JOB1_02MAY2025:19:18:54
MLOGIC(M_UPD_JOB_STATUS): Parameter M_JOB_NAME has value 027_JOB1
MLOGIC(M_UPD_JOB_STATUS): Parameter M_STARTDT has value 02MAY2025:19:18:54
MLOGIC(M_UPD_JOB_STATUS): Parameter M_END_DT has value 02MAY2025:19:18:55
SYMBOLGEN: Macro variable M_FULL_NAME resolves to 027_JOB1_02MAY2025:19:18:54
MPRINT(M_UPD_JOB_STATUS): FILENAME REFFILE FILESRVC FOLDERPATH='/Project/Test/LOGS'
FILENAME="027_JOB1_02MAY2025:19:18:54.txt";
MLOGIC(M_UPD_JOB_STATUS): %LET (variable name is JOB_STATUS)
MLOGIC(M_UPD_JOB_STATUS): %LET (variable name is ERROR_CODE)
MLOGIC(M_UPD_JOB_STATUS): %LET (variable name is ERROR_DESC)
MPRINT(M_UPD_JOB_STATUS): data test;
MPRINT(M_UPD_JOB_STATUS): infile REFFILE truncover;
MPRINT(M_UPD_JOB_STATUS): input log_line $400.;
MPRINT(M_UPD_JOB_STATUS): I=index((log_line), 'SYSCC=');
MPRINT(M_UPD_JOB_STATUS): run;
NOTE: The data set WORK.TEST has 0 observations and 2 variables.
WARNING: Data set WORK.TEST was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds
MPRINT(M_UPD_JOB_STATUS): data _null_;
MPRINT(M_UPD_JOB_STATUS): infile REFFILE truncover;
MPRINT(M_UPD_JOB_STATUS): input log_line $400.;
MPRINT(M_UPD_JOB_STATUS): if index((log_line), 'SYSCC=') =1 then call symputx('ERROR_CODE', STRIP(SUBSTR(log_line,8)));
MPRINT(M_UPD_JOB_STATUS): if index((log_line), 'ERROR ') > 0 or index((log_line), 'ERROR:') > 0 then call symputx('ERROR_DESC',
STRIP(log_line));
MPRINT(M_UPD_JOB_STATUS): run;
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
MLOGIC(M_UPD_JOB_STATUS): %IF condition %sysevalf(%superq(ERROR_CODE) > 0) is FALSE
MLOGIC(M_UPD_JOB_STATUS): %PUT &ERROR_CODE.
SYMBOLGEN: Macro variable ERROR_CODE resolves to
MLOGIC(M_UPD_JOB_STATUS): %PUT &ERROR_DESC.
SYMBOLGEN: Macro variable ERROR_DESC resolves to
MLOGIC(M_UPD_JOB_STATUS): %PUT &Job_status.
SYMBOLGEN: Macro variable JOB_STATUS resolves to Completed
Completed
MPRINT(M_UPD_JOB_STATUS): proc sql;
NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements.
SYMBOLGEN: Macro variable JOB_STATUS resolves to Completed
SYMBOLGEN: Macro variable JOBNM resolves to 027_JOB1
MPRINT(M_UPD_JOB_STATUS): update LIB.AUDIT_TBL SET STATUS="Completed" where JOB_NAME = "027_JOB1";
ORACLE_379: Prepared: on connection 4
SELECT * FROM LIB.AUDIT_TBL
ORACLE_380: Prepared: on connection 4
update LIB.AUDIT_TBL set LIB.AUDIT_TBL."STATUS" = 'Completed' where LIB.AUDIT_TBL."JOB_NAME" =
'027_JOB1'
NOTE: Statement not executed due to NOEXEC option.
SYMBOLGEN: Macro variable ERROR_CODE resolves to
SYMBOLGEN: Macro variable JOBNM resolves to 027_JOB1
NOTE 137-205: Line generated by the invoked macro "M_UPD_JOB_STATUS".
2077 proc sql; update LIB.AUDIT_TBL SET STATUS="&Job_status." where JOB_NAME = "&jobnm."; update
2077 ! LIB.AUDIT_TBL SET EXIT_CODE=&ERROR_CODE. where JOB_NAME = "&jobnm."; update LIB.AUDIT_TBL SET
--------
22
ERROR 22-322: Syntax error, expecting one of the following: (, ',', WHERE.
MPRINT(M_UPD_JOB_STATUS): update LIB.AUDIT_TBL SET EXIT_CODE= where JOB_NAME = "027_JOB1" ;
SYMBOLGEN: Macro variable LOGDT resolves to 02MAY2025:19:18:54
SYMBOLGEN: Macro variable JOBNM resolves to 027_JOB1
MPRINT(M_UPD_JOB_STATUS): update LIB.AUDIT_TBL SET START_DTTM="02MAY2025:19:18:54"dt where JOB_NAME =
"027_JOB1";
ORACLE_381: Prepared: on connection 4
SELECT * FROM LIB.AUDIT_TBL
ORACLE_382: Prepared: on connection 4
update LIB.AUDIT_TBL set LIB.AUDIT_TBL."START_DTTM" = TO_DATE('
02MAY2025:19:18:54','DDMONYYYY:HH24:MI:SS','NLS_DATE_LANGUAGE=American') where LIB.AUDIT_TBL."JOB_NAME" =
'027_JOB1'
NOTE: Statement not executed due to NOEXEC option.
SYMBOLGEN: Macro variable ENDT resolves to 02MAY2025:19:18:55
SYMBOLGEN: Macro variable JOBNM resolves to 027_JOB1
MPRINT(M_UPD_JOB_STATUS): update LIB.AUDIT_TBL SET END_DTTM="02MAY2025:19:18:55"dt where JOB_NAME =
"027_JOB1";
ORACLE_383: Prepared: on connection 4
SELECT * FROM LIB.AUDIT_TBL
ORACLE_384: Prepared: on connection 4
update LIB.AUDIT_TBL set LIB.AUDIT_TBL."END_DTTM" = TO_DATE('
02MAY2025:19:18:55','DDMONYYYY:HH24:MI:SS','NLS_DATE_LANGUAGE=American') where LIB.AUDIT_TBL."JOB_NAME" =
'027_JOB1'
NOTE: Statement not executed due to NOEXEC option.
MPRINT(M_UPD_JOB_STATUS): quit;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SQL used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
MLOGIC(M_UPD_JOB_STATUS): Ending execution.
... View more

0
1
I would like the lines below for c1= to c4= to go on for 14 columns. That means col5 is col14 and I should have c1= to c14=.
Could someone please share a macro to do this loop?:
data a; set tran; const=0; c1=log((sum(of col1-col1)+const)/(sum(of col2-col5)+const)); c2=log((sum(of col1-col2)+const)/(sum(of col3-col5)+const)); c3=log((sum(of col1-col3)+const)/(sum(of col4-col5)+const)); c4=log((sum(of col1-col4)+const)/(sum(of col5-col5)+const)); run;
... View more

0
1
If my table has 1Million records, I want to:
1) sort by largest to smallest by price
2) take the first 100K and call it 'group 1'.....then the next 100K and call it 'group 2' and so on
How can I do it?
proc sort would sort the data
but I am not sure how can I label the records based on the a group of x records.
As an example, I have attached a list of 30 records, and grouped them in 3 creating 10 groups(attached excel)
... View more

0
2
Hi,
DISCLAIMER: This might be a very niche problem peculiar to trying to mapping New Zealand territory with the GeoRegion object in SAS Viya 3.5 and Visual Analytics 8.5.2. The Map Service in use is OpenStreetMap. All data shown in screenshots are dummy data created just for illustration.
Quick Summary We are trying to create a VA report with the GeoRegion object to map our business data to each of the regions defined by the shape files supplied by Statistics New Zealand (Stats NZ Geographic Data Service).
What We Need We are looking for a way to instruct the VA GeoRegion map object to centre itself on the 180-degree line of longitude, and not the zero-degrees line of longitude, so that all of the territory of New Zealand appears together when the report opens. We would need to do this for all of our reports, not just as a one-off.
More Detailed Bits
New Zealand consists of four main islands, North Island, South Island, Stewart Island and The Chatham Islands.
The problem that we have seems to be due to The Chatham Islands being located on the other side of the 180-degree line of longitude, separate from the remainder of New Zealand, as shown in the screenshot below where the red vertical line is an approximation of the 180-degree line of longitude.
The result of this positioning is that, when we need to represent business data across all of New Zealand territory (including the Chatham Islands), the GeoRegion map opens to show the entire world map, with The Chatham Islands completely separated from the rest of the mapped instance New Zealand, as shown in the screenshot below.
We know that by simply filtering out the regions that make up The Chatham Islands our report opens nicely zoomed in to just the main body of New Zealand territory. However, our users must include The Chatham Islands in their reports, so filtering their data out is not an option.
We believe that this separation is happening because the GeoRegion map object draws the land masses in a left-to-right pattern from West 180-degrees (on the far left) to East 180-degrees (on the far right) and thus zero-degrees in the middle of the map.
We have tried several different projections offered by Statistics New Zealand to drive our Geographic Data Provider used for this report, but all of them, so far adopt this same layout (the example report above is using EPSG:4326).
I think that New Zealand may be the only country that has close-by territory (800kms in the case of The Chathams), but where territory is separated by the 180-degree line of longitude, but I am optimistic that someone out there has seen this problem and resolved it.
Any bright ideas out there, ironically, in the rest of the world ?😃
Many thanks,
Downunder Dave Wellington
... View more

0
0
I am Learning the proc template. I tried to create a box plot with sashelp.cars. I've got to make it 80% of what I am thinking , I am stuck at the last 20 % to finish. Looking for help. My code creates graph correctly but stuck at creating the legend. Present graph only show the group legends text in legends, but 1. I want to add the number of to the legends text to display the counts. like (SUV-Asia (N= 25)). I tried creating the macro variable for counts and attach to the group., but it messing up my graph. 2. Is it possible to to diplay all the Asia related in one column, USA in another column, and Europe in another columns in Legends Here is my cars code *create data;
proc sql;
create table car_subjects as
select distinct
cats(Make, "-", Model) as USUBJID length=50,
Type as CarType length=15,
Origin as Region length=15,
Horsepower,
Weight,
MPG_City,
MPG_Highway,
MSRP
from sashelp.cars
where Make is not null and Model is not null;
quit;
*get Count to display in legend;
proc sql;
create table car_counts as
select CarType, Region, count(*) as N
from car_subjects
group by CarType, Region;
quit;
* Add count to dataset;
proc sort data=car_subjects;
by CarType Region;
run;
proc sort data=car_counts;
by CarType Region;
run;
/* Step 4: Merge and build final dummy dataset */
*try with few groups first;
data dummy_cars_final ( where = (region in ('USA' 'Asia' 'Europe') and cartype in ('SUV' 'Sedan' 'Truck')));
merge car_subjects(in=a) car_counts;
by CarType Region;
if a;
/* Derived variables */
region_type = catx("-", CarType, Region);
Score = round(40 + ranuni(0)*60, 0.1);
PowerIndex = round((Horsepower * 0.6 + Weight * 0.0005), 0.1);
EcoScore = round((MPG_City * 0.4 + MPG_Highway * 0.6), 0.1);
length LuxuryLevel $10;
if MSRP > 50000 then LuxuryLevel = "High";
else if MSRP > 30000 then LuxuryLevel = "Medium";
else LuxuryLevel = "Low";
drop Horsepower Weight MPG_City MPG_Highway MSRP;
run;
proc template;
define statgraph boxplot_template;
begingraph;
discreteattrmap name="comboMap" / ignorecase=true;
value "SUV-Asia" / fillattrs=(color=orange);
value "SUV-Europe" / fillattrs=(color=orange) ;
value "SUV-USA" / fillattrs=(color=orange) ;
value "Sedan-Asia" / fillattrs=(color=magenta) ;
value "Sedan-Europe" / fillattrs=(color=orange);
value "Sedan-USA" / fillattrs=(color=magenta);
value "Truck-Asia" / fillattrs=(color=grey) ;
value "Truck-USA" / fillattrs=(color=grey);
enddiscreteattrmap;
discreteattrvar attrvar=patgroup var=region_type attrmap='comboMap';
layout lattice / rows=2 columns=1 columndatarange=union ROWWEIGHTS=(.75 .25) ;
layout overlay /
xaxisopts=(label="Region" labelattrs=(size=12pt weight=bold)
tickvalueattrs=(size=12pt weight=bold))
yaxisopts=(offsetmin=0.05 offsetmax=0.05 label="Rating Score"
linearopts=(tickvaluesequence=(start=0 end=100 increment=10)));
boxplot x=region y=score /
name='BoxLegend'
group=patgroup
groupdisplay=cluster
boxwidth=0.6 clusterwidth=0.5
display=( median mean caps fillpattern )
medianattrs=(pattern=1);
endlayout;
discretelegend 'BoxLegend' /
border=false
valueattrs=(size=8pt weight = bold)
across=3 location=inside valign=top ;
endlayout;
endgraph;
end;
run;
proc template;
define style styles.mypatterns;
parent=styles.listing;
style GraphData1 from GraphData1 / fillpattern="R1" ;
style GraphData2 from GraphData2 / fillpattern="X1" ;
style GraphData3 from GraphData3 / fillpattern="E" ;
style GraphData4 from GraphData4 / fillpattern="R1" ;
style GraphData5 from GraphData5 / fillpattern="X1" ;
style GraphData6 from GraphData6 / fillpattern="E" ;
style GraphData7 from GraphData7 / fillpattern="R1" ;
style GraphData8 from GraphData8 / fillpattern="X1" ;
style GraphData9 from GraphData9/ fillpattern="E" ;
end;
run;
options orientation=landscape;
ods rtf file="boxplot_grouped.rtf" style=mypatterns;
ods graphics / reset width=8.5in height=5.5in border=off;
proc sgrender data=Dummy_cars_final template=boxplot_template;
run;
ods rtf close; Thank you.
... View more

0
22
Unanswered topics
These topics from the past 30 days have no replies. Can you help?