Help using Base SAS procedures

read catalog

Accepted Solution Solved
Reply
Valued Guide
Posts: 858
Accepted Solution

read catalog

I am trying to open and view the code that is stored within a catalog.  I've been researching this all day and am at my wits end.  First I realized I needed to open an older version of SAS, I've tried proc catalog:

proc catalog catalog=formats.formats;
contents;
run;

 

but that information provides very little.  Also not very valuable:

proc format /*fmtlib*/ library=formats.formats
cntlout=test;
run;

 

I have read about cport and cimport as well but I'm not sure what to do with that information.  I would like to open the file stored within the catalog formats, name = PORT.  Any help is appreciated. 


Accepted Solutions
Solution
‎03-16-2017 02:39 PM
Valued Guide
Posts: 505

Re: read catalog

Not sure this is what you are looking fo

/* T005670 Creating format source code from a format catalog -- John Groenfeld

inspired by
https://goo.gl/a25zs7
https://communities.sas.com/t5/SAS-Procedures/read-catalog/m-p/341691

HAVE A COMPILED FORMAT
======================

Contents of Catalog WORK.FORMATS

 #    Name       Type
--------------------------
 1    CITY       FORMATC

WANT
====
value  $city
       'BR1' = 'Birmingham UK'
       'BR2' = 'Plymouth UK'
       'BR3' = 'York UK'
       'US1' = 'Denver USA'
       'US2' = 'Miami USA'
       other = 'INCORRECT CODE'
;
run;quit;

WORKING CODE

      %utl_getfmt(outfile=d:/txt/city.txt,myfile=myformats,mytype=C,myfmt=CITY);


FULL SOLUTION
=============

proc datasets lib=work kill;
run;quit;

%symdel outfile myfmt myfile mytype / nowarn; * just in case;

* create and compile format $city;
proc format lib=work;
value  $city
       'BR1'   = 'Birmingham UK'
       'BR2'   = 'Plymouth UK'
       'BR3'   = 'York UK'
       'US1'   = 'Denver USA'
       'US2'   = 'Miami USA'
       other   = 'INCORRECT CODE'
;
run;quit;

proc format library=work cntlout=myformats;
run;quit;

%let pgm=utl_mkefmtsas;

/* this macro generates SAS program to re-create a user-defined format */
/* utiltity to delete sas code if you are rerunning */
%macro utl_fkil ( utlfkil ) / des="delete an external file";
    %local urc;
    %let urc = %sysfunc(filename(fname,%quote(&utlfkil)));
    %if &urc = 0 and %sysfunc(fexist(&fname)) %then
        %let urc = %sysfunc(fdelete(&fname));
    %let urc = %sysfunc(filename(fname,''));
  run;
%mend utl_fkil

;

/* create the format code */
%macro utl_getfmt(outfile=,myfmt=,myfile=,mytype=) ;

 /* This work is based on John Groenfeld macro in SAS-L         */
 /* Program will fail if format type is other than P C I N or J */
 /* I have tried to cover all kinds of format but I am no sure  */

 %put %sysfunc(ifc(%sysevalf(%superq(outfile)=,boolean),**** Please Provide output fileref for sas format code ****,));
 %put %sysfunc(ifc(%sysevalf(%superq(myfile )=,boolean),**** Please Provide an input format control dataset    ****,));
 %put %sysfunc(ifc(%sysevalf(%superq(mytype )=,boolean),**** Please Provide antype of format P C I N J only    ****,));
 %put %sysfunc(ifc(%sysevalf(%superq(myfmt  )=,boolean),**** Please Provide format name                        ****,));

 %let res= %eval
 (
     %sysfunc(ifc(%sysevalf(%superq(outfile)=,boolean),1,0))
   + %sysfunc(ifc(%sysevalf(%superq(myfile )=,boolean),1,0))
   + %sysfunc(ifc(%sysevalf(%superq(mytype )=,boolean),1,0))
   + %sysfunc(ifc(%sysevalf(%superq(myfmt  )=,boolean),1,0))
 );

 %if &res = 0 %then %do;

  /*
   /* tetcases without macro
   %let outfile  =outf;
   %let myfile   =fmt001;
   %let mytype   =P;
   %let myfmt    =SALARY;
  */

  data _null_ ;
      file "&outfile" mod ;
      set &myfile (where=(fmtname="&myfmt" and type="&mytype")) end=dne;
      /* global stuff */
      if   index(upcase(start),'*OTHER*' ) then start = compress(start,'*') ;
      if   index(upcase(end),  '*OTHER*' ) then end   = compress(start,'*') ;
      select (type);
          when ('P') do;
                       if _n_=1 then put  "picture " "&myfmt" ;
                       link other;
                       link quotelabel;
                       link noquotestart;
                       if upcase(start) ne 'OTHER' then do;
                          put '(mult=' mult best12. ;
                          if not missing(prefix)  then do ;
                            prefix=cats('"',prefix,'"');
                            put 'prefix=' prefix ;
                          end ;
                          if not missing(fill)  then do ;
                            fill=cats('"',fill,'"');
                            put 'fill=' fill;
                          end ;
                          put ')' ;
                       end;
          end;
          when ('C') do;
                       if _n_=1 then put  "value "  "$&myfmt";
                       link other;
                       link quotelabel;
                       link quotestart;
          end;
          when ('I') do;
                       if _n_=1 then put  "invalue " "&myfmt" ;
                       link other;
                       link noquotelabel;
                       link quotestart;
          end;
          when ('N') do;
                       if _n_=1 then put  "value "  "&myfmt" ;
                       link other;
                       link quotelabel;
                       link noquotestart;
          end;
          when ('J') do;
                       if _n_=1 then put  "invalue " "$&myfmt";
                       link other;
                       link quotelabel;
                       link quotestart;
          end;
      end;
      if dne then put ';';
      return;

      other:
        if   index(upcase(start),'*OTHER*' ) then start = compress(start,'*') ;
        if   index(upcase(end),  '*OTHER*' ) then end   = compress(start,'*') ;
      return;

      noquotestart:
        if start ne end then put start ' - ' end '= ' label;
        else put start '= ' label;
      return;

      quotestart:
        if upcase(start) ne 'OTHER'  then start = cats('"',start,'"');
        if upcase(end)   ne 'OTHER'  then end   = cats('"',end,  '"');
        if start ne end then put start ' - ' end '= ' label;
        else put start '= ' label;
      return;

      quotelabel:
        if hlo=:'LF' then label = cats('[',label,']') ;
        else              label = cats('"',label, '"');
      return;

      /* documentation purposes only */
      noquotelabel:
        label=label;
      return;
  run ;
 %end;
%mend utl_getfmt;

proc catalog cat=work.formats;
contents;
run;quit;

View solution in original post


All Replies
Super User
Posts: 10,490

Re: read catalog

WHY is the cntlout dataset "not very valuable"? Please be very specific as there is everything about a format that you need to know in there though some of the values may take awhile to get used to interpretting, espcially indicator for such things a "other" or "_same_" and the multilabel and custom date formats.

 

Or are you looking for information about something other than formats that may be in that catalog?

Valued Guide
Posts: 858

Re: read catalog

I'm looking for the formats that are in there, something that I can duplicate in my own proc format. 

 

What I'm getting in cntout is fmtname, start end label min max etc.  I don't know what to do with any of that information. 

 

I opened an older version of SAS, ran the code and am viewing the fields that the format runs on.   This is what I was looking for, but it seems odd to me that it isn't easier to run some feature of proc catalog and get the macros that are stored within. 

Solution
‎03-16-2017 02:39 PM
Valued Guide
Posts: 505

Re: read catalog

Not sure this is what you are looking fo

/* T005670 Creating format source code from a format catalog -- John Groenfeld

inspired by
https://goo.gl/a25zs7
https://communities.sas.com/t5/SAS-Procedures/read-catalog/m-p/341691

HAVE A COMPILED FORMAT
======================

Contents of Catalog WORK.FORMATS

 #    Name       Type
--------------------------
 1    CITY       FORMATC

WANT
====
value  $city
       'BR1' = 'Birmingham UK'
       'BR2' = 'Plymouth UK'
       'BR3' = 'York UK'
       'US1' = 'Denver USA'
       'US2' = 'Miami USA'
       other = 'INCORRECT CODE'
;
run;quit;

WORKING CODE

      %utl_getfmt(outfile=d:/txt/city.txt,myfile=myformats,mytype=C,myfmt=CITY);


FULL SOLUTION
=============

proc datasets lib=work kill;
run;quit;

%symdel outfile myfmt myfile mytype / nowarn; * just in case;

* create and compile format $city;
proc format lib=work;
value  $city
       'BR1'   = 'Birmingham UK'
       'BR2'   = 'Plymouth UK'
       'BR3'   = 'York UK'
       'US1'   = 'Denver USA'
       'US2'   = 'Miami USA'
       other   = 'INCORRECT CODE'
;
run;quit;

proc format library=work cntlout=myformats;
run;quit;

%let pgm=utl_mkefmtsas;

/* this macro generates SAS program to re-create a user-defined format */
/* utiltity to delete sas code if you are rerunning */
%macro utl_fkil ( utlfkil ) / des="delete an external file";
    %local urc;
    %let urc = %sysfunc(filename(fname,%quote(&utlfkil)));
    %if &urc = 0 and %sysfunc(fexist(&fname)) %then
        %let urc = %sysfunc(fdelete(&fname));
    %let urc = %sysfunc(filename(fname,''));
  run;
%mend utl_fkil

;

/* create the format code */
%macro utl_getfmt(outfile=,myfmt=,myfile=,mytype=) ;

 /* This work is based on John Groenfeld macro in SAS-L         */
 /* Program will fail if format type is other than P C I N or J */
 /* I have tried to cover all kinds of format but I am no sure  */

 %put %sysfunc(ifc(%sysevalf(%superq(outfile)=,boolean),**** Please Provide output fileref for sas format code ****,));
 %put %sysfunc(ifc(%sysevalf(%superq(myfile )=,boolean),**** Please Provide an input format control dataset    ****,));
 %put %sysfunc(ifc(%sysevalf(%superq(mytype )=,boolean),**** Please Provide antype of format P C I N J only    ****,));
 %put %sysfunc(ifc(%sysevalf(%superq(myfmt  )=,boolean),**** Please Provide format name                        ****,));

 %let res= %eval
 (
     %sysfunc(ifc(%sysevalf(%superq(outfile)=,boolean),1,0))
   + %sysfunc(ifc(%sysevalf(%superq(myfile )=,boolean),1,0))
   + %sysfunc(ifc(%sysevalf(%superq(mytype )=,boolean),1,0))
   + %sysfunc(ifc(%sysevalf(%superq(myfmt  )=,boolean),1,0))
 );

 %if &res = 0 %then %do;

  /*
   /* tetcases without macro
   %let outfile  =outf;
   %let myfile   =fmt001;
   %let mytype   =P;
   %let myfmt    =SALARY;
  */

  data _null_ ;
      file "&outfile" mod ;
      set &myfile (where=(fmtname="&myfmt" and type="&mytype")) end=dne;
      /* global stuff */
      if   index(upcase(start),'*OTHER*' ) then start = compress(start,'*') ;
      if   index(upcase(end),  '*OTHER*' ) then end   = compress(start,'*') ;
      select (type);
          when ('P') do;
                       if _n_=1 then put  "picture " "&myfmt" ;
                       link other;
                       link quotelabel;
                       link noquotestart;
                       if upcase(start) ne 'OTHER' then do;
                          put '(mult=' mult best12. ;
                          if not missing(prefix)  then do ;
                            prefix=cats('"',prefix,'"');
                            put 'prefix=' prefix ;
                          end ;
                          if not missing(fill)  then do ;
                            fill=cats('"',fill,'"');
                            put 'fill=' fill;
                          end ;
                          put ')' ;
                       end;
          end;
          when ('C') do;
                       if _n_=1 then put  "value "  "$&myfmt";
                       link other;
                       link quotelabel;
                       link quotestart;
          end;
          when ('I') do;
                       if _n_=1 then put  "invalue " "&myfmt" ;
                       link other;
                       link noquotelabel;
                       link quotestart;
          end;
          when ('N') do;
                       if _n_=1 then put  "value "  "&myfmt" ;
                       link other;
                       link quotelabel;
                       link noquotestart;
          end;
          when ('J') do;
                       if _n_=1 then put  "invalue " "$&myfmt";
                       link other;
                       link quotelabel;
                       link quotestart;
          end;
      end;
      if dne then put ';';
      return;

      other:
        if   index(upcase(start),'*OTHER*' ) then start = compress(start,'*') ;
        if   index(upcase(end),  '*OTHER*' ) then end   = compress(start,'*') ;
      return;

      noquotestart:
        if start ne end then put start ' - ' end '= ' label;
        else put start '= ' label;
      return;

      quotestart:
        if upcase(start) ne 'OTHER'  then start = cats('"',start,'"');
        if upcase(end)   ne 'OTHER'  then end   = cats('"',end,  '"');
        if start ne end then put start ' - ' end '= ' label;
        else put start '= ' label;
      return;

      quotelabel:
        if hlo=:'LF' then label = cats('[',label,']') ;
        else              label = cats('"',label, '"');
      return;

      /* documentation purposes only */
      noquotelabel:
        label=label;
      return;
  run ;
 %end;
%mend utl_getfmt;

proc catalog cat=work.formats;
contents;
run;quit;

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 3 replies
  • 230 views
  • 0 likes
  • 3 in conversation