SAS Macro in macro - how change the process?









up vote
1
down vote

favorite












You wrote that I shouldn't set %macro in %macro. so please help in my process.
Genesis: I have one table where is stock all SAS processes which starting day by day - but various of report should be run various day - according to field "Nr_week_day". If today is contained in this field - I put this process to general_stock table to run.
Below is my code with comment - what I'm trying to get.
Generally - this code works, but it with macro in macro. maybe you have better idea what can work it.
This process is related with my another "questions":
SAS include dynamic path
SAS Macro in macro



 data CONTROL_FILES_BASE;
input Priority : 2.
ACTIVE: 1.
PROCES_NAME: $10.
Nr_week_day: $10.

; cards;
1 1 TEST_01 (1,3,6)
2 1 TEST_02 0
3 1 TEST_03 (4,5)
;

Data Kalendariusz;
infile cards dlm=',' dsd;
input ref_date: date9.
Nr_day_of_month
Nr_week_day
Number_date;
Format ref_date DDMMYY10.;
cards;
01NOV2018, 1, 4, 20181101
02NOV2018, 2, 5, 20181102
03NOV2018, 3, 6, 20181103
04NOV2018, 4, 7, 20181104
05NOV2018, 5, 1, 20181105
06NOV2018, 6, 2, 20181106
07NOV2018, 7, 3, 20181107
08NOV2018, 8, 4, 20181108
09NOV2018, 9, 5, 20181109
10NOV2018, 10, 6, 20181110
11NOV2018, 11, 7, 20181111
12NOV2018, 12, 1, 20181112
13NOV2018, 13, 2, 20181113
14NOV2018, 14, 3, 20181114
15NOV2018, 15, 4, 20181115
16NOV2018, 16, 5, 20181116
17NOV2018, 17, 6, 20181117
18NOV2018, 18, 7, 20181118
19NOV2018, 19, 1, 20181119
20NOV2018, 20, 2, 20181120
21NOV2018, 21, 3, 20181121
22NOV2018, 22, 4, 20181122
23NOV2018, 23, 5, 20181123
24NOV2018, 24, 6, 20181124
25NOV2018, 25, 7, 20181125
26NOV2018, 26, 1, 20181126
27NOV2018, 27, 2, 20181127
28NOV2018, 28, 3, 20181128
29NOV2018, 29, 4, 20181129
30NOV2018, 30, 5, 20181130
;

/*COMMENT: I TAKE TODAY IN VARIABLE*/
%LET EXTRACT_DATE_DT = date();

/*COMMENT: I CREATE EMPTY TABLE TO STOCK OF PROCESS*/
Proc sql;
Create table GENERAL_STOCK as
Select
*
FROM WORK.CONTROL_FILES_BASE
WHERE ACTIVE = 2
;quit;

/*START MAIN MACRO*/
%macro GENERATE_STOCK();

/*COMMENT: I check how many processes should be generated.*/
PROC SQL noprint;
Select
count(*) into :i
From work.CONTROL_FILES_BASE
WHERE Nr_week_day <> '0'
;quit;
%PUT &i;

/*COMMENT: I separated process which should be check*/
Proc sql;
Create table STOCK_2 as
Select
monotonic() as ROW_ID,
*
FROM work.CONTROL_FILES_BASE
WHERE Nr_week_day ne '0'
;quit;

/*MAIN LOOP - I take field NR_WEEK_DAY and will check that this number of day is today - row by row*/
%do ITER = 1 %To &i;

Proc sql;
Select
Nr_week_day into :SET_VAR
from STOCK_2
WHERE ROW_ID = &ITER
;quit;
%PUT &SET_VAR;
/*SET_VAR have value from Nr_week_day*/

%LET l_decision = 0;/*I set default value in variable*/
/*below code I found in forum - this macro reverse query - check whether (1,3,6) is included today - in table KALENDARIUSZ*/
%macro nos_obs(dsn=,where_stmt=);
proc sql;
select
count(*)
into :l_decision
from &dsn.
&where_stmt.
;quit;
%mend ;
%nos_obs(dsn=Kalendariusz,where_stmt=where Nr_week_day in &&SET_VAR. and Ref_date = &EXTRACT_DATE_DT.);
%PUT &l_decision;

/*IF ABOVE CODE RETURN 1 - means that the nr_week_day is today */
/*When l_decisions is 1 then process should add this row to general_stock. If 0 - should add nothing.*/
%if &l_decision = 1 %then
%do;
Proc sql;
Create table STOCK_2_INSERT (drop=ROW_ID) as
Select
*
FROM WORK.STOCK_2
WHERE ROW_ID = &ITER
;quit;

Proc sql;
insert into GENERAL_STOCK
select * from work.STOCK_2_INSERT
;quit;

/*I clear temp table*/
Proc sql;
delete FROM WORK.STOCK_2_INSERT
;quit;
%end;
%else %if &l_decision = 0 %then
%do;
%end;
%end;
%mend GENERATE_STOCK;
%GENERATE_STOCK();

/*AND I LOOK AT GENERAL TABLE*/
Proc sql;
Create table SHOW_GENERAL_STOCK as
Select
*
FROM WORK.GENERAL_STOCK
;quit;









share|improve this question



























    up vote
    1
    down vote

    favorite












    You wrote that I shouldn't set %macro in %macro. so please help in my process.
    Genesis: I have one table where is stock all SAS processes which starting day by day - but various of report should be run various day - according to field "Nr_week_day". If today is contained in this field - I put this process to general_stock table to run.
    Below is my code with comment - what I'm trying to get.
    Generally - this code works, but it with macro in macro. maybe you have better idea what can work it.
    This process is related with my another "questions":
    SAS include dynamic path
    SAS Macro in macro



     data CONTROL_FILES_BASE;
    input Priority : 2.
    ACTIVE: 1.
    PROCES_NAME: $10.
    Nr_week_day: $10.

    ; cards;
    1 1 TEST_01 (1,3,6)
    2 1 TEST_02 0
    3 1 TEST_03 (4,5)
    ;

    Data Kalendariusz;
    infile cards dlm=',' dsd;
    input ref_date: date9.
    Nr_day_of_month
    Nr_week_day
    Number_date;
    Format ref_date DDMMYY10.;
    cards;
    01NOV2018, 1, 4, 20181101
    02NOV2018, 2, 5, 20181102
    03NOV2018, 3, 6, 20181103
    04NOV2018, 4, 7, 20181104
    05NOV2018, 5, 1, 20181105
    06NOV2018, 6, 2, 20181106
    07NOV2018, 7, 3, 20181107
    08NOV2018, 8, 4, 20181108
    09NOV2018, 9, 5, 20181109
    10NOV2018, 10, 6, 20181110
    11NOV2018, 11, 7, 20181111
    12NOV2018, 12, 1, 20181112
    13NOV2018, 13, 2, 20181113
    14NOV2018, 14, 3, 20181114
    15NOV2018, 15, 4, 20181115
    16NOV2018, 16, 5, 20181116
    17NOV2018, 17, 6, 20181117
    18NOV2018, 18, 7, 20181118
    19NOV2018, 19, 1, 20181119
    20NOV2018, 20, 2, 20181120
    21NOV2018, 21, 3, 20181121
    22NOV2018, 22, 4, 20181122
    23NOV2018, 23, 5, 20181123
    24NOV2018, 24, 6, 20181124
    25NOV2018, 25, 7, 20181125
    26NOV2018, 26, 1, 20181126
    27NOV2018, 27, 2, 20181127
    28NOV2018, 28, 3, 20181128
    29NOV2018, 29, 4, 20181129
    30NOV2018, 30, 5, 20181130
    ;

    /*COMMENT: I TAKE TODAY IN VARIABLE*/
    %LET EXTRACT_DATE_DT = date();

    /*COMMENT: I CREATE EMPTY TABLE TO STOCK OF PROCESS*/
    Proc sql;
    Create table GENERAL_STOCK as
    Select
    *
    FROM WORK.CONTROL_FILES_BASE
    WHERE ACTIVE = 2
    ;quit;

    /*START MAIN MACRO*/
    %macro GENERATE_STOCK();

    /*COMMENT: I check how many processes should be generated.*/
    PROC SQL noprint;
    Select
    count(*) into :i
    From work.CONTROL_FILES_BASE
    WHERE Nr_week_day <> '0'
    ;quit;
    %PUT &i;

    /*COMMENT: I separated process which should be check*/
    Proc sql;
    Create table STOCK_2 as
    Select
    monotonic() as ROW_ID,
    *
    FROM work.CONTROL_FILES_BASE
    WHERE Nr_week_day ne '0'
    ;quit;

    /*MAIN LOOP - I take field NR_WEEK_DAY and will check that this number of day is today - row by row*/
    %do ITER = 1 %To &i;

    Proc sql;
    Select
    Nr_week_day into :SET_VAR
    from STOCK_2
    WHERE ROW_ID = &ITER
    ;quit;
    %PUT &SET_VAR;
    /*SET_VAR have value from Nr_week_day*/

    %LET l_decision = 0;/*I set default value in variable*/
    /*below code I found in forum - this macro reverse query - check whether (1,3,6) is included today - in table KALENDARIUSZ*/
    %macro nos_obs(dsn=,where_stmt=);
    proc sql;
    select
    count(*)
    into :l_decision
    from &dsn.
    &where_stmt.
    ;quit;
    %mend ;
    %nos_obs(dsn=Kalendariusz,where_stmt=where Nr_week_day in &&SET_VAR. and Ref_date = &EXTRACT_DATE_DT.);
    %PUT &l_decision;

    /*IF ABOVE CODE RETURN 1 - means that the nr_week_day is today */
    /*When l_decisions is 1 then process should add this row to general_stock. If 0 - should add nothing.*/
    %if &l_decision = 1 %then
    %do;
    Proc sql;
    Create table STOCK_2_INSERT (drop=ROW_ID) as
    Select
    *
    FROM WORK.STOCK_2
    WHERE ROW_ID = &ITER
    ;quit;

    Proc sql;
    insert into GENERAL_STOCK
    select * from work.STOCK_2_INSERT
    ;quit;

    /*I clear temp table*/
    Proc sql;
    delete FROM WORK.STOCK_2_INSERT
    ;quit;
    %end;
    %else %if &l_decision = 0 %then
    %do;
    %end;
    %end;
    %mend GENERATE_STOCK;
    %GENERATE_STOCK();

    /*AND I LOOK AT GENERAL TABLE*/
    Proc sql;
    Create table SHOW_GENERAL_STOCK as
    Select
    *
    FROM WORK.GENERAL_STOCK
    ;quit;









    share|improve this question

























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      You wrote that I shouldn't set %macro in %macro. so please help in my process.
      Genesis: I have one table where is stock all SAS processes which starting day by day - but various of report should be run various day - according to field "Nr_week_day". If today is contained in this field - I put this process to general_stock table to run.
      Below is my code with comment - what I'm trying to get.
      Generally - this code works, but it with macro in macro. maybe you have better idea what can work it.
      This process is related with my another "questions":
      SAS include dynamic path
      SAS Macro in macro



       data CONTROL_FILES_BASE;
      input Priority : 2.
      ACTIVE: 1.
      PROCES_NAME: $10.
      Nr_week_day: $10.

      ; cards;
      1 1 TEST_01 (1,3,6)
      2 1 TEST_02 0
      3 1 TEST_03 (4,5)
      ;

      Data Kalendariusz;
      infile cards dlm=',' dsd;
      input ref_date: date9.
      Nr_day_of_month
      Nr_week_day
      Number_date;
      Format ref_date DDMMYY10.;
      cards;
      01NOV2018, 1, 4, 20181101
      02NOV2018, 2, 5, 20181102
      03NOV2018, 3, 6, 20181103
      04NOV2018, 4, 7, 20181104
      05NOV2018, 5, 1, 20181105
      06NOV2018, 6, 2, 20181106
      07NOV2018, 7, 3, 20181107
      08NOV2018, 8, 4, 20181108
      09NOV2018, 9, 5, 20181109
      10NOV2018, 10, 6, 20181110
      11NOV2018, 11, 7, 20181111
      12NOV2018, 12, 1, 20181112
      13NOV2018, 13, 2, 20181113
      14NOV2018, 14, 3, 20181114
      15NOV2018, 15, 4, 20181115
      16NOV2018, 16, 5, 20181116
      17NOV2018, 17, 6, 20181117
      18NOV2018, 18, 7, 20181118
      19NOV2018, 19, 1, 20181119
      20NOV2018, 20, 2, 20181120
      21NOV2018, 21, 3, 20181121
      22NOV2018, 22, 4, 20181122
      23NOV2018, 23, 5, 20181123
      24NOV2018, 24, 6, 20181124
      25NOV2018, 25, 7, 20181125
      26NOV2018, 26, 1, 20181126
      27NOV2018, 27, 2, 20181127
      28NOV2018, 28, 3, 20181128
      29NOV2018, 29, 4, 20181129
      30NOV2018, 30, 5, 20181130
      ;

      /*COMMENT: I TAKE TODAY IN VARIABLE*/
      %LET EXTRACT_DATE_DT = date();

      /*COMMENT: I CREATE EMPTY TABLE TO STOCK OF PROCESS*/
      Proc sql;
      Create table GENERAL_STOCK as
      Select
      *
      FROM WORK.CONTROL_FILES_BASE
      WHERE ACTIVE = 2
      ;quit;

      /*START MAIN MACRO*/
      %macro GENERATE_STOCK();

      /*COMMENT: I check how many processes should be generated.*/
      PROC SQL noprint;
      Select
      count(*) into :i
      From work.CONTROL_FILES_BASE
      WHERE Nr_week_day <> '0'
      ;quit;
      %PUT &i;

      /*COMMENT: I separated process which should be check*/
      Proc sql;
      Create table STOCK_2 as
      Select
      monotonic() as ROW_ID,
      *
      FROM work.CONTROL_FILES_BASE
      WHERE Nr_week_day ne '0'
      ;quit;

      /*MAIN LOOP - I take field NR_WEEK_DAY and will check that this number of day is today - row by row*/
      %do ITER = 1 %To &i;

      Proc sql;
      Select
      Nr_week_day into :SET_VAR
      from STOCK_2
      WHERE ROW_ID = &ITER
      ;quit;
      %PUT &SET_VAR;
      /*SET_VAR have value from Nr_week_day*/

      %LET l_decision = 0;/*I set default value in variable*/
      /*below code I found in forum - this macro reverse query - check whether (1,3,6) is included today - in table KALENDARIUSZ*/
      %macro nos_obs(dsn=,where_stmt=);
      proc sql;
      select
      count(*)
      into :l_decision
      from &dsn.
      &where_stmt.
      ;quit;
      %mend ;
      %nos_obs(dsn=Kalendariusz,where_stmt=where Nr_week_day in &&SET_VAR. and Ref_date = &EXTRACT_DATE_DT.);
      %PUT &l_decision;

      /*IF ABOVE CODE RETURN 1 - means that the nr_week_day is today */
      /*When l_decisions is 1 then process should add this row to general_stock. If 0 - should add nothing.*/
      %if &l_decision = 1 %then
      %do;
      Proc sql;
      Create table STOCK_2_INSERT (drop=ROW_ID) as
      Select
      *
      FROM WORK.STOCK_2
      WHERE ROW_ID = &ITER
      ;quit;

      Proc sql;
      insert into GENERAL_STOCK
      select * from work.STOCK_2_INSERT
      ;quit;

      /*I clear temp table*/
      Proc sql;
      delete FROM WORK.STOCK_2_INSERT
      ;quit;
      %end;
      %else %if &l_decision = 0 %then
      %do;
      %end;
      %end;
      %mend GENERATE_STOCK;
      %GENERATE_STOCK();

      /*AND I LOOK AT GENERAL TABLE*/
      Proc sql;
      Create table SHOW_GENERAL_STOCK as
      Select
      *
      FROM WORK.GENERAL_STOCK
      ;quit;









      share|improve this question















      You wrote that I shouldn't set %macro in %macro. so please help in my process.
      Genesis: I have one table where is stock all SAS processes which starting day by day - but various of report should be run various day - according to field "Nr_week_day". If today is contained in this field - I put this process to general_stock table to run.
      Below is my code with comment - what I'm trying to get.
      Generally - this code works, but it with macro in macro. maybe you have better idea what can work it.
      This process is related with my another "questions":
      SAS include dynamic path
      SAS Macro in macro



       data CONTROL_FILES_BASE;
      input Priority : 2.
      ACTIVE: 1.
      PROCES_NAME: $10.
      Nr_week_day: $10.

      ; cards;
      1 1 TEST_01 (1,3,6)
      2 1 TEST_02 0
      3 1 TEST_03 (4,5)
      ;

      Data Kalendariusz;
      infile cards dlm=',' dsd;
      input ref_date: date9.
      Nr_day_of_month
      Nr_week_day
      Number_date;
      Format ref_date DDMMYY10.;
      cards;
      01NOV2018, 1, 4, 20181101
      02NOV2018, 2, 5, 20181102
      03NOV2018, 3, 6, 20181103
      04NOV2018, 4, 7, 20181104
      05NOV2018, 5, 1, 20181105
      06NOV2018, 6, 2, 20181106
      07NOV2018, 7, 3, 20181107
      08NOV2018, 8, 4, 20181108
      09NOV2018, 9, 5, 20181109
      10NOV2018, 10, 6, 20181110
      11NOV2018, 11, 7, 20181111
      12NOV2018, 12, 1, 20181112
      13NOV2018, 13, 2, 20181113
      14NOV2018, 14, 3, 20181114
      15NOV2018, 15, 4, 20181115
      16NOV2018, 16, 5, 20181116
      17NOV2018, 17, 6, 20181117
      18NOV2018, 18, 7, 20181118
      19NOV2018, 19, 1, 20181119
      20NOV2018, 20, 2, 20181120
      21NOV2018, 21, 3, 20181121
      22NOV2018, 22, 4, 20181122
      23NOV2018, 23, 5, 20181123
      24NOV2018, 24, 6, 20181124
      25NOV2018, 25, 7, 20181125
      26NOV2018, 26, 1, 20181126
      27NOV2018, 27, 2, 20181127
      28NOV2018, 28, 3, 20181128
      29NOV2018, 29, 4, 20181129
      30NOV2018, 30, 5, 20181130
      ;

      /*COMMENT: I TAKE TODAY IN VARIABLE*/
      %LET EXTRACT_DATE_DT = date();

      /*COMMENT: I CREATE EMPTY TABLE TO STOCK OF PROCESS*/
      Proc sql;
      Create table GENERAL_STOCK as
      Select
      *
      FROM WORK.CONTROL_FILES_BASE
      WHERE ACTIVE = 2
      ;quit;

      /*START MAIN MACRO*/
      %macro GENERATE_STOCK();

      /*COMMENT: I check how many processes should be generated.*/
      PROC SQL noprint;
      Select
      count(*) into :i
      From work.CONTROL_FILES_BASE
      WHERE Nr_week_day <> '0'
      ;quit;
      %PUT &i;

      /*COMMENT: I separated process which should be check*/
      Proc sql;
      Create table STOCK_2 as
      Select
      monotonic() as ROW_ID,
      *
      FROM work.CONTROL_FILES_BASE
      WHERE Nr_week_day ne '0'
      ;quit;

      /*MAIN LOOP - I take field NR_WEEK_DAY and will check that this number of day is today - row by row*/
      %do ITER = 1 %To &i;

      Proc sql;
      Select
      Nr_week_day into :SET_VAR
      from STOCK_2
      WHERE ROW_ID = &ITER
      ;quit;
      %PUT &SET_VAR;
      /*SET_VAR have value from Nr_week_day*/

      %LET l_decision = 0;/*I set default value in variable*/
      /*below code I found in forum - this macro reverse query - check whether (1,3,6) is included today - in table KALENDARIUSZ*/
      %macro nos_obs(dsn=,where_stmt=);
      proc sql;
      select
      count(*)
      into :l_decision
      from &dsn.
      &where_stmt.
      ;quit;
      %mend ;
      %nos_obs(dsn=Kalendariusz,where_stmt=where Nr_week_day in &&SET_VAR. and Ref_date = &EXTRACT_DATE_DT.);
      %PUT &l_decision;

      /*IF ABOVE CODE RETURN 1 - means that the nr_week_day is today */
      /*When l_decisions is 1 then process should add this row to general_stock. If 0 - should add nothing.*/
      %if &l_decision = 1 %then
      %do;
      Proc sql;
      Create table STOCK_2_INSERT (drop=ROW_ID) as
      Select
      *
      FROM WORK.STOCK_2
      WHERE ROW_ID = &ITER
      ;quit;

      Proc sql;
      insert into GENERAL_STOCK
      select * from work.STOCK_2_INSERT
      ;quit;

      /*I clear temp table*/
      Proc sql;
      delete FROM WORK.STOCK_2_INSERT
      ;quit;
      %end;
      %else %if &l_decision = 0 %then
      %do;
      %end;
      %end;
      %mend GENERATE_STOCK;
      %GENERATE_STOCK();

      /*AND I LOOK AT GENERAL TABLE*/
      Proc sql;
      Create table SHOW_GENERAL_STOCK as
      Select
      *
      FROM WORK.GENERAL_STOCK
      ;quit;






      sas sas-macro






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 10 at 8:28

























      asked Nov 10 at 8:22









      DarkousPl

      428




      428






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          As explained in the answers to your other question, it's a bad idea to define a macro within another macro definition. In your example, what that means is you can move the definition of the utility macro %nos_obs:



          %macro nos_obs(dsn=,where_stmt=);
          proc sql;
          select
          count(*)
          into :l_decision
          from &dsn.
          &where_stmt.
          ;quit;
          %mend ;


          That block of code should not be inside the block:



          %macro GENERATE_STOCK;
          ...
          %mend GENERATE_STOCK;


          You can still call %nos_obs from within %generate_stock. Just don't nest the macro definitions. So you end up with:



          *define a macro;
          %macro nos_obs(dsn=,where_stmt=);
          ...
          %mend ;

          *define a macro that does some stuff and invokes another macro;
          %macro GENERATE_STOCK;
          ...
          %nos_obs(dsn=...)
          ...
          %mend GENERATE_STOCK;

          %generatestock


          That's the general point about not nesting macro definitions. To your big picture, it looks like you are writing a scheduler in SAS. Like linux cron or windows scheduler where you decide which programs to run based on the day of the week. Usually it is better to use a dedicated scheduler solution (cron, LSF, windows scheduler etc.) rather that write your own. Better means easier, more maintainable, more flexible, etc. They will let you manage dependencies, pause and restart, etc etc.



          That said, if you do write your own scheduler in SAS (lots of people do, it's hard to resist the temptation sometimes), I think the code you have shown is much more complex than it needs to be.



          You have a control dataset that lists the days on which each process should run:



          data CONTROL_FILES_BASE;
          input Priority : 2.
          ACTIVE: 1.
          PROCES_NAME: $10.
          Nr_week_day: $10.

          ; cards;
          1 1 TEST_01 (1,3,6)
          2 1 TEST_02 0
          3 1 TEST_03 (4,5)
          ;


          If you want to determine which processes should run today, you just need to find out what day of the week it is today, and select the records accordingly. Something like:



          data General_Stock ;
          set CONTROL_FILES_BASE ;
          where findc(Nr_week_day,put(weekday(today()),1.)) ;
          run ;


          When I'm writing this it's Saturday, so weekday(today()) returns 7 and the above selects 0 records, because there are no processes scheduled to run on Saturdays.



          If you want a macro, because you want to test to see which processes your control dataset will trigger on different dates, you can write a little macro where you input the extract date. Something like:



          %macro GENERATE_STOCK
          (data=/*name of input control dataset*/
          ,out= /*name of output dataset*/
          ,ExtractDate=/*extract date is a SAS date or expression like today() */
          );

          data &out ;
          set &data ;
          where findc(Nr_week_day,put(weekday(&extractDate),1.)) ;
          run ;

          title1 "Printout of &out genenerated when ExtractDate=%superq(ExtractDate)" ;
          proc print data=&out ;
          run ;
          title1 ;

          %mend GENERATE_STOCK ;


          Test like:



          %generate_stock(data=control_files_base,out=wantToday ,extractdate=today())
          %generate_stock(data=control_files_base,out=wantSunday ,extractdate="11Nov2018"d)
          %generate_stock(data=control_files_base,out=wantMonday ,extractdate="12Nov2018"d)
          %generate_stock(data=control_files_base,out=wantTuesday ,extractdate="13Nov2018"d)
          %generate_stock(data=control_files_base,out=wantWednesday,extractdate="14Nov2018"d)
          %generate_stock(data=control_files_base,out=wantThursday ,extractdate="15Nov2018"d)
          %generate_stock(data=control_files_base,out=wantFriday ,extractdate="16Nov2018"d)
          %generate_stock(data=control_files_base,out=wantSaturday ,extractdate="17Nov2018"d)





          share|improve this answer




















          • Oh my god, this is so easy... Yes, I know that my code is too complicated, but on the one hand I train macros, on the other hand I use only SAS Enterprise Guide where I set my codes below another process - set in timetable by IT. I can run my reports independently from somebody from IT in "time window" (three time by day) - so, that's why I'm writing my own schedule. Additional question: when I will try check by number day of month I can use these code?:
            – DarkousPl
            Nov 10 at 12:24










          • I change "findc" for "find" and tested for first day of month (in variable I set day - datka). Works good but can you look at whether it is a good solution? data CONTROL_FILES_BASE; input Priority : 2. ACTIVE: 1. PROCES_NAME: $20. Nr_day_month: $20. ; cards; 1 1 TEST_01 (3,11,12) 2 1 TEST_02 0 3 1 TEST_03 (4,5) ; %let datka = '01Nov2018'd; data General_Stock ; set CONTROL_FILES_BASE ; where find(Nr_day_month,put(day(&datka.),2.)) ; run ;
            – DarkousPl
            Nov 10 at 12:24







          • 1




            Yes similar approach should work for dates. I would suggest FINDW instead of FIND. find('(3,11,12)','2')will return 8, because it finds the string '2'. findw('(3,11,12)','2') will return 0, because it does not find the word '2'.
            – Quentin
            Nov 10 at 12:40







          • 1




            Thank you very much! Your help and explanations (for both solutions) are invaluable!
            – DarkousPl
            Nov 10 at 12:42










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237244%2fsas-macro-in-macro-how-change-the-process%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          2
          down vote



          accepted










          As explained in the answers to your other question, it's a bad idea to define a macro within another macro definition. In your example, what that means is you can move the definition of the utility macro %nos_obs:



          %macro nos_obs(dsn=,where_stmt=);
          proc sql;
          select
          count(*)
          into :l_decision
          from &dsn.
          &where_stmt.
          ;quit;
          %mend ;


          That block of code should not be inside the block:



          %macro GENERATE_STOCK;
          ...
          %mend GENERATE_STOCK;


          You can still call %nos_obs from within %generate_stock. Just don't nest the macro definitions. So you end up with:



          *define a macro;
          %macro nos_obs(dsn=,where_stmt=);
          ...
          %mend ;

          *define a macro that does some stuff and invokes another macro;
          %macro GENERATE_STOCK;
          ...
          %nos_obs(dsn=...)
          ...
          %mend GENERATE_STOCK;

          %generatestock


          That's the general point about not nesting macro definitions. To your big picture, it looks like you are writing a scheduler in SAS. Like linux cron or windows scheduler where you decide which programs to run based on the day of the week. Usually it is better to use a dedicated scheduler solution (cron, LSF, windows scheduler etc.) rather that write your own. Better means easier, more maintainable, more flexible, etc. They will let you manage dependencies, pause and restart, etc etc.



          That said, if you do write your own scheduler in SAS (lots of people do, it's hard to resist the temptation sometimes), I think the code you have shown is much more complex than it needs to be.



          You have a control dataset that lists the days on which each process should run:



          data CONTROL_FILES_BASE;
          input Priority : 2.
          ACTIVE: 1.
          PROCES_NAME: $10.
          Nr_week_day: $10.

          ; cards;
          1 1 TEST_01 (1,3,6)
          2 1 TEST_02 0
          3 1 TEST_03 (4,5)
          ;


          If you want to determine which processes should run today, you just need to find out what day of the week it is today, and select the records accordingly. Something like:



          data General_Stock ;
          set CONTROL_FILES_BASE ;
          where findc(Nr_week_day,put(weekday(today()),1.)) ;
          run ;


          When I'm writing this it's Saturday, so weekday(today()) returns 7 and the above selects 0 records, because there are no processes scheduled to run on Saturdays.



          If you want a macro, because you want to test to see which processes your control dataset will trigger on different dates, you can write a little macro where you input the extract date. Something like:



          %macro GENERATE_STOCK
          (data=/*name of input control dataset*/
          ,out= /*name of output dataset*/
          ,ExtractDate=/*extract date is a SAS date or expression like today() */
          );

          data &out ;
          set &data ;
          where findc(Nr_week_day,put(weekday(&extractDate),1.)) ;
          run ;

          title1 "Printout of &out genenerated when ExtractDate=%superq(ExtractDate)" ;
          proc print data=&out ;
          run ;
          title1 ;

          %mend GENERATE_STOCK ;


          Test like:



          %generate_stock(data=control_files_base,out=wantToday ,extractdate=today())
          %generate_stock(data=control_files_base,out=wantSunday ,extractdate="11Nov2018"d)
          %generate_stock(data=control_files_base,out=wantMonday ,extractdate="12Nov2018"d)
          %generate_stock(data=control_files_base,out=wantTuesday ,extractdate="13Nov2018"d)
          %generate_stock(data=control_files_base,out=wantWednesday,extractdate="14Nov2018"d)
          %generate_stock(data=control_files_base,out=wantThursday ,extractdate="15Nov2018"d)
          %generate_stock(data=control_files_base,out=wantFriday ,extractdate="16Nov2018"d)
          %generate_stock(data=control_files_base,out=wantSaturday ,extractdate="17Nov2018"d)





          share|improve this answer




















          • Oh my god, this is so easy... Yes, I know that my code is too complicated, but on the one hand I train macros, on the other hand I use only SAS Enterprise Guide where I set my codes below another process - set in timetable by IT. I can run my reports independently from somebody from IT in "time window" (three time by day) - so, that's why I'm writing my own schedule. Additional question: when I will try check by number day of month I can use these code?:
            – DarkousPl
            Nov 10 at 12:24










          • I change "findc" for "find" and tested for first day of month (in variable I set day - datka). Works good but can you look at whether it is a good solution? data CONTROL_FILES_BASE; input Priority : 2. ACTIVE: 1. PROCES_NAME: $20. Nr_day_month: $20. ; cards; 1 1 TEST_01 (3,11,12) 2 1 TEST_02 0 3 1 TEST_03 (4,5) ; %let datka = '01Nov2018'd; data General_Stock ; set CONTROL_FILES_BASE ; where find(Nr_day_month,put(day(&datka.),2.)) ; run ;
            – DarkousPl
            Nov 10 at 12:24







          • 1




            Yes similar approach should work for dates. I would suggest FINDW instead of FIND. find('(3,11,12)','2')will return 8, because it finds the string '2'. findw('(3,11,12)','2') will return 0, because it does not find the word '2'.
            – Quentin
            Nov 10 at 12:40







          • 1




            Thank you very much! Your help and explanations (for both solutions) are invaluable!
            – DarkousPl
            Nov 10 at 12:42














          up vote
          2
          down vote



          accepted










          As explained in the answers to your other question, it's a bad idea to define a macro within another macro definition. In your example, what that means is you can move the definition of the utility macro %nos_obs:



          %macro nos_obs(dsn=,where_stmt=);
          proc sql;
          select
          count(*)
          into :l_decision
          from &dsn.
          &where_stmt.
          ;quit;
          %mend ;


          That block of code should not be inside the block:



          %macro GENERATE_STOCK;
          ...
          %mend GENERATE_STOCK;


          You can still call %nos_obs from within %generate_stock. Just don't nest the macro definitions. So you end up with:



          *define a macro;
          %macro nos_obs(dsn=,where_stmt=);
          ...
          %mend ;

          *define a macro that does some stuff and invokes another macro;
          %macro GENERATE_STOCK;
          ...
          %nos_obs(dsn=...)
          ...
          %mend GENERATE_STOCK;

          %generatestock


          That's the general point about not nesting macro definitions. To your big picture, it looks like you are writing a scheduler in SAS. Like linux cron or windows scheduler where you decide which programs to run based on the day of the week. Usually it is better to use a dedicated scheduler solution (cron, LSF, windows scheduler etc.) rather that write your own. Better means easier, more maintainable, more flexible, etc. They will let you manage dependencies, pause and restart, etc etc.



          That said, if you do write your own scheduler in SAS (lots of people do, it's hard to resist the temptation sometimes), I think the code you have shown is much more complex than it needs to be.



          You have a control dataset that lists the days on which each process should run:



          data CONTROL_FILES_BASE;
          input Priority : 2.
          ACTIVE: 1.
          PROCES_NAME: $10.
          Nr_week_day: $10.

          ; cards;
          1 1 TEST_01 (1,3,6)
          2 1 TEST_02 0
          3 1 TEST_03 (4,5)
          ;


          If you want to determine which processes should run today, you just need to find out what day of the week it is today, and select the records accordingly. Something like:



          data General_Stock ;
          set CONTROL_FILES_BASE ;
          where findc(Nr_week_day,put(weekday(today()),1.)) ;
          run ;


          When I'm writing this it's Saturday, so weekday(today()) returns 7 and the above selects 0 records, because there are no processes scheduled to run on Saturdays.



          If you want a macro, because you want to test to see which processes your control dataset will trigger on different dates, you can write a little macro where you input the extract date. Something like:



          %macro GENERATE_STOCK
          (data=/*name of input control dataset*/
          ,out= /*name of output dataset*/
          ,ExtractDate=/*extract date is a SAS date or expression like today() */
          );

          data &out ;
          set &data ;
          where findc(Nr_week_day,put(weekday(&extractDate),1.)) ;
          run ;

          title1 "Printout of &out genenerated when ExtractDate=%superq(ExtractDate)" ;
          proc print data=&out ;
          run ;
          title1 ;

          %mend GENERATE_STOCK ;


          Test like:



          %generate_stock(data=control_files_base,out=wantToday ,extractdate=today())
          %generate_stock(data=control_files_base,out=wantSunday ,extractdate="11Nov2018"d)
          %generate_stock(data=control_files_base,out=wantMonday ,extractdate="12Nov2018"d)
          %generate_stock(data=control_files_base,out=wantTuesday ,extractdate="13Nov2018"d)
          %generate_stock(data=control_files_base,out=wantWednesday,extractdate="14Nov2018"d)
          %generate_stock(data=control_files_base,out=wantThursday ,extractdate="15Nov2018"d)
          %generate_stock(data=control_files_base,out=wantFriday ,extractdate="16Nov2018"d)
          %generate_stock(data=control_files_base,out=wantSaturday ,extractdate="17Nov2018"d)





          share|improve this answer




















          • Oh my god, this is so easy... Yes, I know that my code is too complicated, but on the one hand I train macros, on the other hand I use only SAS Enterprise Guide where I set my codes below another process - set in timetable by IT. I can run my reports independently from somebody from IT in "time window" (three time by day) - so, that's why I'm writing my own schedule. Additional question: when I will try check by number day of month I can use these code?:
            – DarkousPl
            Nov 10 at 12:24










          • I change "findc" for "find" and tested for first day of month (in variable I set day - datka). Works good but can you look at whether it is a good solution? data CONTROL_FILES_BASE; input Priority : 2. ACTIVE: 1. PROCES_NAME: $20. Nr_day_month: $20. ; cards; 1 1 TEST_01 (3,11,12) 2 1 TEST_02 0 3 1 TEST_03 (4,5) ; %let datka = '01Nov2018'd; data General_Stock ; set CONTROL_FILES_BASE ; where find(Nr_day_month,put(day(&datka.),2.)) ; run ;
            – DarkousPl
            Nov 10 at 12:24







          • 1




            Yes similar approach should work for dates. I would suggest FINDW instead of FIND. find('(3,11,12)','2')will return 8, because it finds the string '2'. findw('(3,11,12)','2') will return 0, because it does not find the word '2'.
            – Quentin
            Nov 10 at 12:40







          • 1




            Thank you very much! Your help and explanations (for both solutions) are invaluable!
            – DarkousPl
            Nov 10 at 12:42












          up vote
          2
          down vote



          accepted







          up vote
          2
          down vote



          accepted






          As explained in the answers to your other question, it's a bad idea to define a macro within another macro definition. In your example, what that means is you can move the definition of the utility macro %nos_obs:



          %macro nos_obs(dsn=,where_stmt=);
          proc sql;
          select
          count(*)
          into :l_decision
          from &dsn.
          &where_stmt.
          ;quit;
          %mend ;


          That block of code should not be inside the block:



          %macro GENERATE_STOCK;
          ...
          %mend GENERATE_STOCK;


          You can still call %nos_obs from within %generate_stock. Just don't nest the macro definitions. So you end up with:



          *define a macro;
          %macro nos_obs(dsn=,where_stmt=);
          ...
          %mend ;

          *define a macro that does some stuff and invokes another macro;
          %macro GENERATE_STOCK;
          ...
          %nos_obs(dsn=...)
          ...
          %mend GENERATE_STOCK;

          %generatestock


          That's the general point about not nesting macro definitions. To your big picture, it looks like you are writing a scheduler in SAS. Like linux cron or windows scheduler where you decide which programs to run based on the day of the week. Usually it is better to use a dedicated scheduler solution (cron, LSF, windows scheduler etc.) rather that write your own. Better means easier, more maintainable, more flexible, etc. They will let you manage dependencies, pause and restart, etc etc.



          That said, if you do write your own scheduler in SAS (lots of people do, it's hard to resist the temptation sometimes), I think the code you have shown is much more complex than it needs to be.



          You have a control dataset that lists the days on which each process should run:



          data CONTROL_FILES_BASE;
          input Priority : 2.
          ACTIVE: 1.
          PROCES_NAME: $10.
          Nr_week_day: $10.

          ; cards;
          1 1 TEST_01 (1,3,6)
          2 1 TEST_02 0
          3 1 TEST_03 (4,5)
          ;


          If you want to determine which processes should run today, you just need to find out what day of the week it is today, and select the records accordingly. Something like:



          data General_Stock ;
          set CONTROL_FILES_BASE ;
          where findc(Nr_week_day,put(weekday(today()),1.)) ;
          run ;


          When I'm writing this it's Saturday, so weekday(today()) returns 7 and the above selects 0 records, because there are no processes scheduled to run on Saturdays.



          If you want a macro, because you want to test to see which processes your control dataset will trigger on different dates, you can write a little macro where you input the extract date. Something like:



          %macro GENERATE_STOCK
          (data=/*name of input control dataset*/
          ,out= /*name of output dataset*/
          ,ExtractDate=/*extract date is a SAS date or expression like today() */
          );

          data &out ;
          set &data ;
          where findc(Nr_week_day,put(weekday(&extractDate),1.)) ;
          run ;

          title1 "Printout of &out genenerated when ExtractDate=%superq(ExtractDate)" ;
          proc print data=&out ;
          run ;
          title1 ;

          %mend GENERATE_STOCK ;


          Test like:



          %generate_stock(data=control_files_base,out=wantToday ,extractdate=today())
          %generate_stock(data=control_files_base,out=wantSunday ,extractdate="11Nov2018"d)
          %generate_stock(data=control_files_base,out=wantMonday ,extractdate="12Nov2018"d)
          %generate_stock(data=control_files_base,out=wantTuesday ,extractdate="13Nov2018"d)
          %generate_stock(data=control_files_base,out=wantWednesday,extractdate="14Nov2018"d)
          %generate_stock(data=control_files_base,out=wantThursday ,extractdate="15Nov2018"d)
          %generate_stock(data=control_files_base,out=wantFriday ,extractdate="16Nov2018"d)
          %generate_stock(data=control_files_base,out=wantSaturday ,extractdate="17Nov2018"d)





          share|improve this answer












          As explained in the answers to your other question, it's a bad idea to define a macro within another macro definition. In your example, what that means is you can move the definition of the utility macro %nos_obs:



          %macro nos_obs(dsn=,where_stmt=);
          proc sql;
          select
          count(*)
          into :l_decision
          from &dsn.
          &where_stmt.
          ;quit;
          %mend ;


          That block of code should not be inside the block:



          %macro GENERATE_STOCK;
          ...
          %mend GENERATE_STOCK;


          You can still call %nos_obs from within %generate_stock. Just don't nest the macro definitions. So you end up with:



          *define a macro;
          %macro nos_obs(dsn=,where_stmt=);
          ...
          %mend ;

          *define a macro that does some stuff and invokes another macro;
          %macro GENERATE_STOCK;
          ...
          %nos_obs(dsn=...)
          ...
          %mend GENERATE_STOCK;

          %generatestock


          That's the general point about not nesting macro definitions. To your big picture, it looks like you are writing a scheduler in SAS. Like linux cron or windows scheduler where you decide which programs to run based on the day of the week. Usually it is better to use a dedicated scheduler solution (cron, LSF, windows scheduler etc.) rather that write your own. Better means easier, more maintainable, more flexible, etc. They will let you manage dependencies, pause and restart, etc etc.



          That said, if you do write your own scheduler in SAS (lots of people do, it's hard to resist the temptation sometimes), I think the code you have shown is much more complex than it needs to be.



          You have a control dataset that lists the days on which each process should run:



          data CONTROL_FILES_BASE;
          input Priority : 2.
          ACTIVE: 1.
          PROCES_NAME: $10.
          Nr_week_day: $10.

          ; cards;
          1 1 TEST_01 (1,3,6)
          2 1 TEST_02 0
          3 1 TEST_03 (4,5)
          ;


          If you want to determine which processes should run today, you just need to find out what day of the week it is today, and select the records accordingly. Something like:



          data General_Stock ;
          set CONTROL_FILES_BASE ;
          where findc(Nr_week_day,put(weekday(today()),1.)) ;
          run ;


          When I'm writing this it's Saturday, so weekday(today()) returns 7 and the above selects 0 records, because there are no processes scheduled to run on Saturdays.



          If you want a macro, because you want to test to see which processes your control dataset will trigger on different dates, you can write a little macro where you input the extract date. Something like:



          %macro GENERATE_STOCK
          (data=/*name of input control dataset*/
          ,out= /*name of output dataset*/
          ,ExtractDate=/*extract date is a SAS date or expression like today() */
          );

          data &out ;
          set &data ;
          where findc(Nr_week_day,put(weekday(&extractDate),1.)) ;
          run ;

          title1 "Printout of &out genenerated when ExtractDate=%superq(ExtractDate)" ;
          proc print data=&out ;
          run ;
          title1 ;

          %mend GENERATE_STOCK ;


          Test like:



          %generate_stock(data=control_files_base,out=wantToday ,extractdate=today())
          %generate_stock(data=control_files_base,out=wantSunday ,extractdate="11Nov2018"d)
          %generate_stock(data=control_files_base,out=wantMonday ,extractdate="12Nov2018"d)
          %generate_stock(data=control_files_base,out=wantTuesday ,extractdate="13Nov2018"d)
          %generate_stock(data=control_files_base,out=wantWednesday,extractdate="14Nov2018"d)
          %generate_stock(data=control_files_base,out=wantThursday ,extractdate="15Nov2018"d)
          %generate_stock(data=control_files_base,out=wantFriday ,extractdate="16Nov2018"d)
          %generate_stock(data=control_files_base,out=wantSaturday ,extractdate="17Nov2018"d)






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 10 at 11:51









          Quentin

          4,7701819




          4,7701819











          • Oh my god, this is so easy... Yes, I know that my code is too complicated, but on the one hand I train macros, on the other hand I use only SAS Enterprise Guide where I set my codes below another process - set in timetable by IT. I can run my reports independently from somebody from IT in "time window" (three time by day) - so, that's why I'm writing my own schedule. Additional question: when I will try check by number day of month I can use these code?:
            – DarkousPl
            Nov 10 at 12:24










          • I change "findc" for "find" and tested for first day of month (in variable I set day - datka). Works good but can you look at whether it is a good solution? data CONTROL_FILES_BASE; input Priority : 2. ACTIVE: 1. PROCES_NAME: $20. Nr_day_month: $20. ; cards; 1 1 TEST_01 (3,11,12) 2 1 TEST_02 0 3 1 TEST_03 (4,5) ; %let datka = '01Nov2018'd; data General_Stock ; set CONTROL_FILES_BASE ; where find(Nr_day_month,put(day(&datka.),2.)) ; run ;
            – DarkousPl
            Nov 10 at 12:24







          • 1




            Yes similar approach should work for dates. I would suggest FINDW instead of FIND. find('(3,11,12)','2')will return 8, because it finds the string '2'. findw('(3,11,12)','2') will return 0, because it does not find the word '2'.
            – Quentin
            Nov 10 at 12:40







          • 1




            Thank you very much! Your help and explanations (for both solutions) are invaluable!
            – DarkousPl
            Nov 10 at 12:42
















          • Oh my god, this is so easy... Yes, I know that my code is too complicated, but on the one hand I train macros, on the other hand I use only SAS Enterprise Guide where I set my codes below another process - set in timetable by IT. I can run my reports independently from somebody from IT in "time window" (three time by day) - so, that's why I'm writing my own schedule. Additional question: when I will try check by number day of month I can use these code?:
            – DarkousPl
            Nov 10 at 12:24










          • I change "findc" for "find" and tested for first day of month (in variable I set day - datka). Works good but can you look at whether it is a good solution? data CONTROL_FILES_BASE; input Priority : 2. ACTIVE: 1. PROCES_NAME: $20. Nr_day_month: $20. ; cards; 1 1 TEST_01 (3,11,12) 2 1 TEST_02 0 3 1 TEST_03 (4,5) ; %let datka = '01Nov2018'd; data General_Stock ; set CONTROL_FILES_BASE ; where find(Nr_day_month,put(day(&datka.),2.)) ; run ;
            – DarkousPl
            Nov 10 at 12:24







          • 1




            Yes similar approach should work for dates. I would suggest FINDW instead of FIND. find('(3,11,12)','2')will return 8, because it finds the string '2'. findw('(3,11,12)','2') will return 0, because it does not find the word '2'.
            – Quentin
            Nov 10 at 12:40







          • 1




            Thank you very much! Your help and explanations (for both solutions) are invaluable!
            – DarkousPl
            Nov 10 at 12:42















          Oh my god, this is so easy... Yes, I know that my code is too complicated, but on the one hand I train macros, on the other hand I use only SAS Enterprise Guide where I set my codes below another process - set in timetable by IT. I can run my reports independently from somebody from IT in "time window" (three time by day) - so, that's why I'm writing my own schedule. Additional question: when I will try check by number day of month I can use these code?:
          – DarkousPl
          Nov 10 at 12:24




          Oh my god, this is so easy... Yes, I know that my code is too complicated, but on the one hand I train macros, on the other hand I use only SAS Enterprise Guide where I set my codes below another process - set in timetable by IT. I can run my reports independently from somebody from IT in "time window" (three time by day) - so, that's why I'm writing my own schedule. Additional question: when I will try check by number day of month I can use these code?:
          – DarkousPl
          Nov 10 at 12:24












          I change "findc" for "find" and tested for first day of month (in variable I set day - datka). Works good but can you look at whether it is a good solution? data CONTROL_FILES_BASE; input Priority : 2. ACTIVE: 1. PROCES_NAME: $20. Nr_day_month: $20. ; cards; 1 1 TEST_01 (3,11,12) 2 1 TEST_02 0 3 1 TEST_03 (4,5) ; %let datka = '01Nov2018'd; data General_Stock ; set CONTROL_FILES_BASE ; where find(Nr_day_month,put(day(&datka.),2.)) ; run ;
          – DarkousPl
          Nov 10 at 12:24





          I change "findc" for "find" and tested for first day of month (in variable I set day - datka). Works good but can you look at whether it is a good solution? data CONTROL_FILES_BASE; input Priority : 2. ACTIVE: 1. PROCES_NAME: $20. Nr_day_month: $20. ; cards; 1 1 TEST_01 (3,11,12) 2 1 TEST_02 0 3 1 TEST_03 (4,5) ; %let datka = '01Nov2018'd; data General_Stock ; set CONTROL_FILES_BASE ; where find(Nr_day_month,put(day(&datka.),2.)) ; run ;
          – DarkousPl
          Nov 10 at 12:24





          1




          1




          Yes similar approach should work for dates. I would suggest FINDW instead of FIND. find('(3,11,12)','2')will return 8, because it finds the string '2'. findw('(3,11,12)','2') will return 0, because it does not find the word '2'.
          – Quentin
          Nov 10 at 12:40





          Yes similar approach should work for dates. I would suggest FINDW instead of FIND. find('(3,11,12)','2')will return 8, because it finds the string '2'. findw('(3,11,12)','2') will return 0, because it does not find the word '2'.
          – Quentin
          Nov 10 at 12:40





          1




          1




          Thank you very much! Your help and explanations (for both solutions) are invaluable!
          – DarkousPl
          Nov 10 at 12:42




          Thank you very much! Your help and explanations (for both solutions) are invaluable!
          – DarkousPl
          Nov 10 at 12:42

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237244%2fsas-macro-in-macro-how-change-the-process%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Use pre created SQLite database for Android project in kotlin

          Darth Vader #20

          Ondo