Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions all.sas
Original file line number Diff line number Diff line change
Expand Up @@ -1215,8 +1215,9 @@ or %index(&pgm,/tests/testteardown)
%mend mf_getuser;
/**
@file
@brief Retrieves a value from a dataset. If no filter supplied, then first
record is used.
@brief Retrieves a value from a dataset. Returned value is fetched from the
'fetchobs=' record (row 1 by default), after applying the optional filter.

@details Be sure to <code>%quote()</code> your where clause. Example usage:

%put %mf_getvalue(sashelp.class,name,filter=%quote(age=15));
Expand All @@ -1231,24 +1232,43 @@ or %index(&pgm,/tests/testteardown)
@param [in] libds dataset to query
@param [in] variable the variable which contains the value to return.
@param [in] filter= (1) contents of where clause
@param [in] fetchobs= (1) observation to fetch. NB: Filter applies first.

@version 9.2
@author Allan Bowe
**/

%macro mf_getvalue(libds,variable,filter=1
%macro mf_getvalue(libds,variable,filter=1,fetchobs=1
)/*/STORE SOURCE*/;
%if %mf_getattrn(&libds,NLOBS)>0 %then %do;
%local dsid rc &variable;
%let dsid=%sysfunc(open(&libds(where=(&filter))));
%local dsid;

%let dsid=%sysfunc(open(&libds(where=(&filter))));
%if (&dsid) %then %do;
%local rc &variable;
%syscall set(dsid);
%let rc = %sysfunc(fetch(&dsid));
%let rc = %sysfunc(fetchobs(&dsid,&fetchobs));
%if (&rc ne 0) %then %do;
%put NOTE: Problem reading obs &fetchobs from &libds..;
%put %sysfunc(sysmsg());
/* Coerce an rc value of -1 (read past end of data) to a 4
that, in SAS condition code terms, represents the sysmsg
w@rning it generates. */
%if &rc eq -1 %then %let rc = 4;
/* And update SYSCC if the &rc value is higher */
%let syscc = %sysfunc(max(&syscc,&rc));
%end;
%let rc = %sysfunc(close(&dsid));

%trim(&&&variable)

%end;
%mend mf_getvalue;/**
%else %do;
%put %sysfunc(sysmsg());
%let syscc = %sysfunc(max(&syscc,%sysfunc(sysrc())));
%end;

%mend mf_getvalue;
/**
@file
@brief Returns number of variables in a dataset
@details Useful to identify those renagade datasets that have no columns!
Expand Down
35 changes: 27 additions & 8 deletions base/mf_getvalue.sas
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/**
@file
@brief Retrieves a value from a dataset. If no filter supplied, then first
record is used.
@brief Retrieves a value from a dataset. Returned value is fetched from the
'fetchobs=' record (row 1 by default), after applying the optional filter.

@details Be sure to <code>%quote()</code> your where clause. Example usage:

%put %mf_getvalue(sashelp.class,name,filter=%quote(age=15));
Expand All @@ -16,21 +17,39 @@
@param [in] libds dataset to query
@param [in] variable the variable which contains the value to return.
@param [in] filter= (1) contents of where clause
@param [in] fetchobs= (1) observation to fetch. NB: Filter applies first.

@version 9.2
@author Allan Bowe
**/

%macro mf_getvalue(libds,variable,filter=1
%macro mf_getvalue(libds,variable,filter=1,fetchobs=1
)/*/STORE SOURCE*/;
%if %mf_getattrn(&libds,NLOBS)>0 %then %do;
%local dsid rc &variable;
%let dsid=%sysfunc(open(&libds(where=(&filter))));
%local dsid;

%let dsid=%sysfunc(open(&libds(where=(&filter))));
%if (&dsid) %then %do;
%local rc &variable;
%syscall set(dsid);
%let rc = %sysfunc(fetch(&dsid));
%let rc = %sysfunc(fetchobs(&dsid,&fetchobs));
%if (&rc ne 0) %then %do;
%put NOTE: Problem reading obs &fetchobs from &libds..;
%put %sysfunc(sysmsg());
/* Coerce an rc value of -1 (read past end of data) to a 4
that, in SAS condition code terms, represents the sysmsg
w@rning it generates. */
%if &rc eq -1 %then %let rc = 4;
/* And update SYSCC if the &rc value is higher */
%let syscc = %sysfunc(max(&syscc,&rc));
%end;
%let rc = %sysfunc(close(&dsid));

%trim(&&&variable)

%end;
%mend mf_getvalue;
%else %do;
%put %sysfunc(sysmsg());
%let syscc = %sysfunc(max(&syscc,%sysfunc(sysrc())));
%end;

%mend mf_getvalue;
91 changes: 91 additions & 0 deletions tests/base/mf_getvalue.test.sas
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
@file
@brief Testing mf_getvalue macro

<h4> SAS Macros </h4>
@li mf_getvalue.sas
@li mp_assert.sas
@li mp_assertscope.sas

**/

data work.test_data;
do i = 1 to 10;
output;
end;
stop;
run;

/* - Test 1 -
Get value from default first observation.
No filter.
*/
%mp_assertscope(SNAPSHOT)
%let test_value=%mf_getvalue(work.test_data,i);
%mp_assertscope(COMPARE,ignorelist=test_value)

%mp_assert(
iftrue=(&test_value=1 and &syscc eq 0),
desc=Basic test fetching value from default first obs,
outds=work.test_results
)

/* - Test 2 -
Get value from 10th observation.
No filter.
*/
%let test_value=%mf_getvalue(work.test_data,i,fetchobs=10);
%mp_assert(
iftrue=(&test_value=10 and &syscc eq 0),
desc=Test fetching value from specifically the 10th row,
outds=work.test_results
)

/* - Test 3 -
Get value from default first observation.
With filter.
*/
%let test_value=%mf_getvalue(work.test_data,i,filter=(i>4));
%mp_assert(
iftrue=(&test_value=5 and &syscc eq 0),
desc=Test fetching value from default row of filtered data,
outds=work.test_results
)

/* - Test 4 -
Get value from specified observation.
With filter.
*/
%let test_value=%mf_getvalue(work.test_data,i,filter=(i>4),fetchobs=5);
%mp_assert(
iftrue=(&test_value=9 and &syscc eq 0),
desc=Test fetching value from 5th row of filtered data,
outds=work.test_results
)

/* - Test 5 -
Get value from default observation.
Filter removes all rows. This simulates providing an empty dataset
or specifying an observation number beyond the set returned by the filter.
*/
%let test_value=%mf_getvalue(work.test_data,i,filter=(i>10));
%mp_assert(
iftrue=(&test_value=%str() and &syscc eq 4),
desc=Test fetching value from 1st row of empty (filtered) data,
outds=work.test_results
)

%let syscc = 0; /* Reset w@rning To ensure confidence in next test */

/* - Test 6 -
Get value from default observation.
Dataset does not exist.
*/
%let test_value=%mf_getvalue(work.test_data_x,i);
%mp_assert(
iftrue=(&test_value=%str() and &syscc gt 0),
desc=Test fetching value from 1st row of non-existent data,
outds=work.test_results
)

%let syscc = 0; /* To reset expected error and allow test job to exit clean. */
Loading