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

The FORMAT Procedure docs for "Using a Function to Format Values" show an example of a function that computes the formatted values for a custom format. 

 

My question is that when the function contains a PUT statement, nothing appears in the Log window.  Where do the puts end up ?

 

 

 

ods html file='quirky.html';

proc fcmp outlib=work.functions.smd;
   function qfmt(date) $;
      put date;  /************* DOES NOT GET LOGGED **************/
      return ("foobar");
/*      length qnum $4;*/
/*      qnum=put(date,yyq4.);*/
/*      if substr(qnum,3,1)='Q'*/
/*         then return(substr(qnum,3,2));*/
/*      else return(qnum);*/
   endsub;
run;

/* Make the function available to SAS. */
options cmplib=(work.functions);

/* Create a format using the function created by the FCMP procedure. */
proc format; value qfmt other=[qfmt()]; run;

/* Use the format in a SAS program.  */
data djia2009;
input closeDate date7. close;
datalines;
01jan09 800.86
02feb09 7062.93
02mar09 7608.92
01apr09 8168.12
01may09 8500.33
01jun09 8447.00
01jul09 9171.61
03aug09 9496.28
01sep09 9712.28
01oct09 9712.73
02nov09 10344.84
02dec09 10428.05
;

proc print data=djia2009;
format closedate qfmt. close dollar9.;
run;

ods html close;

 

 

 

Log

 

 

 

6132  ;
6133
6134  proc print data=djia2009;
6135  format closedate qfmt. close dollar9.;
6136  run;

NOTE: There were 12 observations read from the data set WORK.DJIA2009.
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.06 seconds
      cpu time            0.03 seconds


6137

 

 

 

Output

foobar.png

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Didn't you try it? 

data test;
  y=qfmt(1111);
  z=put(2222,qfmt.);
run;

It wrote it to the listing output when I tried it.

2366  filename list2 temp;
2367  filename log2 temp;
2368  options nosource nonotes;
2376  data _null_;
2377  put 'listing';
2378  do until(eof1);
2379    infile list2 end=eof1;
2380    input;
2381    put _infile_;
2382  end;
2383  put 'log';
2384  do until(eof2);
2385    infile log2 end=eof2;
2386    input;
2387    put _infile_;
2388  end;
2389  stop;
2390  run;

NOTE: The infile LIST2 is:
      Filename=C:\Users\ABERNA~1\AppData\Local\Temp\1\SAS Temporary Files\_TD13900_AMRL20L6F1E4992_\#LN00747,
      RECFM=V,LRECL=32767,File Size (bytes)=136,
      Last Modified=17Apr2020:18:29:06,
      Create Time=17Apr2020:18:29:06

NOTE: The infile LOG2 is:
      Filename=C:\Users\ABERNA~1\AppData\Local\Temp\1\SAS Temporary Files\_TD13900_AMRL20L6F1E4992_\#LN00748,
      RECFM=V,LRECL=32767,File Size (bytes)=6,
      Last Modified=17Apr2020:18:29:06,
      Create Time=17Apr2020:18:29:06

listing
                                                                                            16:21 Thursday, April 16, 2020  99

2222
log
1111
NOTE: 3 records were read from the infile LIST2.
      The minimum record length was 0.
      The maximum record length was 126.
NOTE: 1 record was read from the infile LOG2.
      The minimum record length was 4.
      The maximum record length was 4.
NOTE: DATA statement used (Total process time):
      real time           0.02 seconds
      cpu time            0.01 seconds

Apparently PROC PRINT calls it many times per observation.

proc print data=sashelp.class(obs=1);
  format age qfmt.;
run;
                                                                                            16:21 Thursday, April 16, 2020 104

Obs     Name     Sex     Age      Height    Weight

  1    Alfred     M     foobar      69       112.5

                                                                                            16:21 Thursday, April 16, 2020 105

14
14
14
14

View solution in original post

7 REPLIES 7
ballardw
Super User

If you are attempting to test this in the Proc print then create a second variable with the raw date value and use a more typcial format for display.

 

For debugging in the data step

data djia2009;
input closeDate date7. close;
put "Date7 format" +1 closedate= date7. +1 "Custom format" +1 closedate= qfmt.;
datalines;
01jan09 800.86
02feb09 7062.93
02mar09 7608.92
01apr09 8168.12
01may09 8500.33
;

Tis the nature of functions that they return values, not create print style output.

novinosrin
Tourmaline | Level 20

My guess is since Proc FCMP uses the SAS language compiler to create user-defined functions. The compiler subsystem generates machine language code for the computer on which SAS is running. This guess leads me to put my bet of something akin to stored compiled macro. Plus the fact FCMP offers interaction with macro language by using the macro function %SYSFUNC and the macro statement %SYSCALL could have made the design overriding  execution of PUT as null?

 

PS I am all ears to sit corrected and learn the proper mechanism besides the fun guess

 

 

Tom
Super User Tom
Super User

Didn't you try it? 

data test;
  y=qfmt(1111);
  z=put(2222,qfmt.);
run;

It wrote it to the listing output when I tried it.

2366  filename list2 temp;
2367  filename log2 temp;
2368  options nosource nonotes;
2376  data _null_;
2377  put 'listing';
2378  do until(eof1);
2379    infile list2 end=eof1;
2380    input;
2381    put _infile_;
2382  end;
2383  put 'log';
2384  do until(eof2);
2385    infile log2 end=eof2;
2386    input;
2387    put _infile_;
2388  end;
2389  stop;
2390  run;

NOTE: The infile LIST2 is:
      Filename=C:\Users\ABERNA~1\AppData\Local\Temp\1\SAS Temporary Files\_TD13900_AMRL20L6F1E4992_\#LN00747,
      RECFM=V,LRECL=32767,File Size (bytes)=136,
      Last Modified=17Apr2020:18:29:06,
      Create Time=17Apr2020:18:29:06

NOTE: The infile LOG2 is:
      Filename=C:\Users\ABERNA~1\AppData\Local\Temp\1\SAS Temporary Files\_TD13900_AMRL20L6F1E4992_\#LN00748,
      RECFM=V,LRECL=32767,File Size (bytes)=6,
      Last Modified=17Apr2020:18:29:06,
      Create Time=17Apr2020:18:29:06

listing
                                                                                            16:21 Thursday, April 16, 2020  99

2222
log
1111
NOTE: 3 records were read from the infile LIST2.
      The minimum record length was 0.
      The maximum record length was 126.
NOTE: 1 record was read from the infile LOG2.
      The minimum record length was 4.
      The maximum record length was 4.
NOTE: DATA statement used (Total process time):
      real time           0.02 seconds
      cpu time            0.01 seconds

Apparently PROC PRINT calls it many times per observation.

proc print data=sashelp.class(obs=1);
  format age qfmt.;
run;
                                                                                            16:21 Thursday, April 16, 2020 104

Obs     Name     Sex     Age      Height    Weight

  1    Alfred     M     foobar      69       112.5

                                                                                            16:21 Thursday, April 16, 2020 105

14
14
14
14
RichardDeVen
Barite | Level 11

@Tom. Good catch. I hadn't thought to look in the OUTPUT window, and there it was. Peculiar, because ODS LISTING was closed. I am using the PUT in the function as a way to observe what a PROC is doing in concert with ODS when a styling setting to apply is obtained via .... style-attr=format.

ChrisNZ
Tourmaline | Level 20

You guys are cleverer than me it seems.

I can't get that result. Using SAS UE, the RESULTS tab remains stubbornly empty (except for the proc print output if I add that).

What's the missing link? See my attempt below.

proc fcmp outlib=work.functions.smd;
   function qfmt(date) $;
      put '=>' date;  /************* DOES NOT GET LOGGED **************/
      return ("foobar");
/*      length qnum $4;*/
/*      qnum=put(date,yyq4.);*/
/*      if substr(qnum,3,1)='Q'*/
/*         then return(substr(qnum,3,2));*/
/*      else return(qnum);*/
   endsub;
run;

/* Make the function available to SAS. */
options cmplib=(work.functions);

/* Create a format using the function created by the FCMP procedure. */
proc format; value qfmt other=[qfmt()]; run;


/****** WHAT AM I DOING WRONG HERE? START ********/

filename list2 temp;
filename log2 temp;

ods listing;

data test;
  y=qfmt(1111);
  z=put(2222,qfmt.);
run;

proc print data=sashelp.class(obs=1);
  format age qfmt.;
run;

ods listing close;

/****** WHAT AM I DOING WRONG HERE? END ********/


data _null_;
  put 'listing';
  do until(eof1);
    infile list2 end=eof1;
    input;
    put _infile_;
  end;
  put 'log';
  do until(eof2);
    infile log2 end=eof2;
    input;
    put _infile_;
  end;
  stop;
run;

 

 

 

 

 

Tom
Super User Tom
Super User

You left out the PROC PRINTTO step to redirect the PRINT destination to your temporary file.

Not sure where UE points the default print output.

ChrisNZ
Tourmaline | Level 20

@Tom This indeed works. Any idea why the redirected (printto) output is:

 

=> 2222
Obs    Name     Sex     Age      Height    Weight

  1    Joyce     F     foobar     51.3      50.5 
=> 11
=> 11
=> 11
=> 11

but the non-redirected output (in the listing window) is:

=> 2222
Obs    Name     Sex     Age      Height    Weight

=> 11
  1    Joyce     F     foobar     51.3      50.5 
=> 11

=> 11

Why should they be any different?

Interesting how proc print calls the format several times per obs.

 

 

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 7 replies
  • 837 views
  • 0 likes
  • 5 in conversation