BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
mbell88
Fluorite | Level 6

Hello Experts!

 

I am new to SAS Stored Processes and having some difficulty getting the HTML pages to display after the first prompt. I am attempting to create a SAS stored Process based on dynamic prompts that users will specify and be prompted an additional prompt based on the value of the first one. For simplicity, I am switching to a SASHELP dataset to better show what I am trying to get accomplished.

 

Data: sashelp.CARS

 

Stored Process Flow

Prompt1 (dynamic) ---> Prompt2 (dynamic, dependent on prompt1) ---> Report

 

Prompt1: A list of distinct 'Types' of vehicles that exist in the data (this step works!). The user selects this value and will move to a new page with prompt2.

 

Prompt2: A list of distinct 'Makes' of vehicles for the specific 'Type' of vehicle specified from the previous screen (this does NOT work!).Getting authorization issue. Note: I am seeing that the value from the first prompt is used and actually creates the table that would be used for the second prompt. Not sure if this is an HTML issue of something else. I have very little knowledge of HTML.

 

Report: Can't get prompt2 to display so I am not able to validate if this will work properly.

 

Error when executed in SAS SP Web Application

 

ERROR: Insufficient authorization to access /opt/sas/sas94m3/SASApp/config/Lev2/SASApp/_webout.dat.

 

%macro main;

	%global reqtype _namevalue cred type make;

	filename pwfile "/data/dev/mebell/pw_enc.txt";

	data _NULL_;
		infile pwfile obs=1 length=l;
		input @;
		input @1 line $varying1024. l; 
		call symput('cred',substr(line,1,l));
	run;

	%macro first;

		%stpbegin;

			%let _namevalue=%str(_default_entry=firstout.html);

			filename firstout "&_stpwork/firstout.html";

			/* 1. Get List of Distinct Vehicle Types to Pick */
			proc sql;
				create table work.vehicle_types as
				select distinct type
				from sashelp.cars
				order by 1;
			quit;
			run;

			/* 2. Select Vehicle Type */
			data _NULL_;
				set work.vehicle_types end=eof;
				file firstout;
				if _n_ = 1 then do;
					thissrv = "&_URL";
					thispgm = "&_PROGRAM";

					put '<br>';
					put '<h1> List of Vehicle Types </h1>';

					put '<FORM ACTION="'  thissrv +(-1) '" method=get>';

					put '<input type="hidden" name="_program" value="'
					  thispgm +(-1) '">';
					put '<input type="hidden" name=reqtype value="print">';

					put '<br>';
					put '<b>Select Vehicle Type: </b>';
					put '<select name="type">';
				end;

				if type ne '' then do;
					put '<OPTION VALUE="' type '">' type;
				end;

				if eof then do;
					put '</select>';
					put '<br><br>';
					put '<input type="submit" value="Submit Request">';
					put '</form>';
				end;
			run;

		%stpend;
	%mend first;

	%macro second;

		%stpbegin;

			/* 3. Get List of Vehicle Make for the Selected Vehicle Type */
			%put Vehicle Type previously selected was: &type.;

			proc sql;
				create table work.vehicle_makes as
				select distinct make
				from sashelp.cars
				where type = "&type."
				order by 1;
			quit;
			run;

				/* 4. Select Service Template */
			data _NULL_;
				set work.vehicle_makes end=eof;
				file _webout encoding='utf-8';
				if _n_ = 1 then do;
					thissrv = "&_URL";
					thispgm = "&_PROGRAM";

					put '<br>';
					put '<h1> List of Vehicle Makes for &type. Vehicles </h1>';

					put '<FORM ACTION="&_URL" method=get target="_blank">';

					put '<input type="hidden" name="_program" value="'
					  thispgm +(-1) '">';

					put '<br>';
					put '<b>Select Vehicle Make: </b>';
					put '<select name="make">';
				end;

				if make ne '' then do;
					put '<OPTION VALUE="' make '">' make;

				end;

				if eof then do;
					put '</select>';
					put '<br><br>';
					put '<input type="submit" value="Submit Request">';
					put '</form>';
				end;
			run;

		%stpend;
	%mend second;

	%macro report;

		%stpbegin;

			%let _namevalue=%str(_default_entry=main.html); 
		
			/* 5. Pull Service Template Definition */
			proc sql;
				create table work.all_vehicles as
				select *
				from sashelp.cars
				where type = "&type." and make = "&make.";
			quit;
			run;
				
			/* 6. Display Report for Definition */
			title 'List of Vehicles';

			proc print data = work.all_vehicles;
			run;

		%stpend;
	%mend report;


%if "&reqtype" = "print2" %then %do;
    %report;
%end;

%if "&reqtype" = "print" %then %do;
    %second;
%end;
%else %do;
    %first;
%end;

%mend main;


%main;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Vince_SAS
Rhodochrosite | Level 12

What @FredrikE said about removing the extra STPBEGIN/END calls is correct, but it's a lot more complicated than that.

 

Try this slightly reworked version of your code to see if it gives you the result that you need.

 

%global MAKE
        TYPE
        REQTYPE;

%macro first_prompt;

%* 1. Get list of distinct vehicle types;

proc sql;
  create table work.vehicle_types as
  select distinct type
  from sashelp.cars
  order by type;
quit;

%* 2. Create the first prompt;

data _null_;
set work.vehicle_types end=eof;
file _webout encoding='utf-8';
if (_n_ eq 1) then do;
  thissrv = "&_URL";
  thispgm = "&_PROGRAM";
  put '<br>';
  put '<h1> List of Vehicle Types </h1>';
  put '<form action="'  thissrv +(-1) '" method="get">';

  put '<input type="hidden" name="_program" value="'
      thispgm +(-1) '">';
  put '<input type="hidden" name=reqtype value="print">';

  put '<br>';
  put '<b>Select Vehicle Type: </b>';
  put '<select name="type">';
end;

if type ne '' then do;
  put '<option value="' type '">' type;
end;

if (eof) then do;
  put '</select>';
  put '<br><br>';
  put '<input type="submit" value="Submit Request">';
  put '</form>';
end;
run;

%mend first_prompt;

%macro second_prompt;

%* 3. Get list of vehicle make for the selected vehicle type;

%put Vehicle Type previously selected was: &TYPE;

proc sql;
  create table work.vehicle_makes as
  select distinct make
  from sashelp.cars
  where (type eq "&TYPE")
  order by make;
quit;

%* 4. Create the second prompt;

data _NULL_;
set work.vehicle_makes end=eof;

file _webout encoding='utf-8';

if _n_ = 1 then do;
  thissrv = "&_URL";
  thispgm = "&_PROGRAM";

  put '<br>';
  put "<h1> List of Vehicle Makes for &TYPE Vehicles </h1>";

  put '<form action="' thissrv +(-1) '" method="get" target="_blank">';

  put '<input type="hidden" name="_program" value="'
      thispgm +(-1) '">';
  put '<input type="hidden" name="reqtype" value="print2">';
  put '<input type="hidden" name="type" value="' "&TYPE" '">';

  put '<br>';
  put '<b>Select Vehicle Make: </b>';
  put '<select name="make">';
end;

if make ne '' then do;
  put '<option value="' make '">' make;
end;

if eof then do;
	put '</select>';
	put '<br><br>';
	put '<input type="submit" value="Submit Request">';
	put '</form>';
end;
run;

%mend second_prompt;

%macro report;

%stpbegin;

%* 5. Create the report based on prompt selections;

title 'List of Vehicles Based on Prompt Selections';

proc sql;
  select *
  from sashelp.cars
  where (type eq "&TYPE") and (make eq "&MAKE");
quit;
				
%stpend;

%mend report;

%if (&REQTYPE eq ) %then %do;
  %FIRST_PROMPT
%end;
%if (&REQTYPE eq print) %then %do;
  %SECOND_PROMPT
%end;
%if (&REQTYPE eq print2) %then %do;
  %REPORT
%end;

 

Vince DelGobbo

SAS R&D

 

View solution in original post

5 REPLIES 5
Vince_SAS
Rhodochrosite | Level 12

This message:

 

ERROR: Insufficient authorization to access /opt/sas/sas94m3/SASApp/config/Lev2/SASApp/_webout.dat.

 

Indicates that the _WEBOUT FILEREF isn't assigned, and SAS is attempting to write to a file in the server startup directory.

 

Check the stored process definition and make sure that "Stream" is specified for the "Result capabilities" property.

 

Vince DelGobbo

SAS R&D

mbell88
Fluorite | Level 6

Hi Vince - Thank you for the reply and suggestion. I left the code the same and checked the box for the 'stream' option. Now the first prompt output will not display, whereas it did before. See the log below. It stated the &_STPWORK macro variable is not assigned. I removed that variable from the filename and get the same result. Any thoughts what causes the first output to not write to the file?

 

No Code change with 'Stream' option

 

WARNING: Apparent symbolic reference _STPWORK not resolved.

NOTE: Table WORK.VEHICLE_TYPES created, with 6 rows and 1 columns.
NOTE: PROCEDURE SQL used (Total process time): real time 0.08 seconds cpu time 0.04 seconds

 

ERROR: Physical file does not exist, /opt/sas/sas94m3/SASApp/config/Lev2/SASApp/&_stpwork/firstout.html.

 

 

 

Removed Macro Variable &_STPWORK

NOTE: Table WORK.VEHICLE_TYPES created, with 6 rows and 1 columns.                                                                                          
NOTE: PROCEDURE SQL used (Total process time): real time 0.02 seconds cpu time 0.00 seconds

 

ERROR: Insufficient authorization to access /opt/sas/sas94m3/SASApp/config/Lev2/SASApp/firstout.html.

Vince_SAS
Rhodochrosite | Level 12

What @FredrikE said about removing the extra STPBEGIN/END calls is correct, but it's a lot more complicated than that.

 

Try this slightly reworked version of your code to see if it gives you the result that you need.

 

%global MAKE
        TYPE
        REQTYPE;

%macro first_prompt;

%* 1. Get list of distinct vehicle types;

proc sql;
  create table work.vehicle_types as
  select distinct type
  from sashelp.cars
  order by type;
quit;

%* 2. Create the first prompt;

data _null_;
set work.vehicle_types end=eof;
file _webout encoding='utf-8';
if (_n_ eq 1) then do;
  thissrv = "&_URL";
  thispgm = "&_PROGRAM";
  put '<br>';
  put '<h1> List of Vehicle Types </h1>';
  put '<form action="'  thissrv +(-1) '" method="get">';

  put '<input type="hidden" name="_program" value="'
      thispgm +(-1) '">';
  put '<input type="hidden" name=reqtype value="print">';

  put '<br>';
  put '<b>Select Vehicle Type: </b>';
  put '<select name="type">';
end;

if type ne '' then do;
  put '<option value="' type '">' type;
end;

if (eof) then do;
  put '</select>';
  put '<br><br>';
  put '<input type="submit" value="Submit Request">';
  put '</form>';
end;
run;

%mend first_prompt;

%macro second_prompt;

%* 3. Get list of vehicle make for the selected vehicle type;

%put Vehicle Type previously selected was: &TYPE;

proc sql;
  create table work.vehicle_makes as
  select distinct make
  from sashelp.cars
  where (type eq "&TYPE")
  order by make;
quit;

%* 4. Create the second prompt;

data _NULL_;
set work.vehicle_makes end=eof;

file _webout encoding='utf-8';

if _n_ = 1 then do;
  thissrv = "&_URL";
  thispgm = "&_PROGRAM";

  put '<br>';
  put "<h1> List of Vehicle Makes for &TYPE Vehicles </h1>";

  put '<form action="' thissrv +(-1) '" method="get" target="_blank">';

  put '<input type="hidden" name="_program" value="'
      thispgm +(-1) '">';
  put '<input type="hidden" name="reqtype" value="print2">';
  put '<input type="hidden" name="type" value="' "&TYPE" '">';

  put '<br>';
  put '<b>Select Vehicle Make: </b>';
  put '<select name="make">';
end;

if make ne '' then do;
  put '<option value="' make '">' make;
end;

if eof then do;
	put '</select>';
	put '<br><br>';
	put '<input type="submit" value="Submit Request">';
	put '</form>';
end;
run;

%mend second_prompt;

%macro report;

%stpbegin;

%* 5. Create the report based on prompt selections;

title 'List of Vehicles Based on Prompt Selections';

proc sql;
  select *
  from sashelp.cars
  where (type eq "&TYPE") and (make eq "&MAKE");
quit;
				
%stpend;

%mend report;

%if (&REQTYPE eq ) %then %do;
  %FIRST_PROMPT
%end;
%if (&REQTYPE eq print) %then %do;
  %SECOND_PROMPT
%end;
%if (&REQTYPE eq print2) %then %do;
  %REPORT
%end;

 

Vince DelGobbo

SAS R&D

 

FredrikE
Rhodochrosite | Level 12

Hi!

You should not use "file _webout" inside the %stpbegin/end macros.

Instead only use the macros when printing result with for example proc print or proc report, like you have in the %report macro 🙂

Remove the ones you have in %first and %second.

//Fredrik

 

mbell88
Fluorite | Level 6

Fredrik - Thank you for this info. With this along with Vince's suggested code change I have the stored procedure working now. The cascading prompts are working as expected with a dependency on the previous prompt.

 

Much appreciated, Thank you!

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 1253 views
  • 6 likes
  • 3 in conversation