BookmarkSubscribeRSS Feed
David_Billa
Rhodochrosite | Level 12

In the below code, I want value of TARGET variable to resolve as per below mentioned if else statement. But it's not working as excepted. Based on the file name and macro variable, value of TARGET for one record is right but for other file name, I want the value of TARGET is as SOURCE but I'm getting missing value.

 

Am I missing something in else if and else Statement?

 

Macro variable NL_RB resolves to 0169,0417

 

Files placed in 'INPATH' are,

IFR_GT_TRD_2_0163_1_20201009T075212.csv
IFR_GT_TRD_2_0169_1_20201009T075212.csv

 

%let function=NL;
%let inpath=/var/sasdata/GT;
%let lh_path=/var/sasdata/LH;
%let nl_path=/var/sasdata/NL;

data files ;
  length id 8 msg filename source target $256 ;
  did=dopen("source");
  if did<=0 then do;
      msg=sysmsg(); 
      put msg; 
      stop;
  end;
  do id=1 to dnum(did);
    filename=dread(did,id);

    if scan(lowcase(filename),-1,'.')='csv' and ("&function" EQ 'NL' or "&function" EQ 'LH') then do;
    source="&inpath" ||"/"|| filename;

    if "&function" EQ 'NL' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do;
    flag = 0;
    do i = 1 to countw("&nl_rb.",",");
    if indexw(filename,scan("&nl_rb.",i,","),"_")
    then do;
    flag = 1;
    target = "&nl_path"||"/"||filename;
    end;
    end;
    end;

    else if "&function" EQ 'LH' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do;
    flag = 0;
    do i = 1 to countw("&lh_rbukrs.",",");
    if indexw(filename,scan("&lh_rbukrs.",i,","),"_")
    then do;
    flag = 1;
    target = "&lh_path"||"/"||filename;
    end;
    end;
    end;

    else target="&inpath" ||"/"|| filename;
    end;
        output;
    end;

  did=dclose(did);
  drop did msg;
run;

 

Actual Output:

 

id filename source target flag
1 IFR_GT_TRD_2_0163_1_20201009T075212.csv /var/sasdata/GT/IFR_GT_TRD_2_0163_1_20201009T075212.csv   0
2 IFR_GT_TRD_2_0169_1_20201009T075212.csv /var/sasdata/GT/IFR_GT_TRD_2_0169_1_20201009T075212.csv /var/sasdata/NL/IFR_GT_TRD_2_0169_1_20201009T075212.csv 1

 

Excepted Output:

 

id filename source target flag
1 IFR_GT_TRD_2_0163_1_20201009T075212.csv /var/sasdata/GT/IFR_GT_TRD_2_0163_1_20201009T075212.csv /var/sasdata/GT/IFR_GT_TRD_2_0163_1_20201009T075212.csv 0
2 IFR_GT_TRD_2_0169_1_20201009T075212.csv /var/sasdata/GT/IFR_GT_TRD_2_0169_1_20201009T075212.csv /var/sasdata/NL/IFR_GT_TRD_2_0169_1_20201009T075212.csv 1
4 REPLIES 4
andreas_lds
Jade | Level 19

Start with fixing the inconsistent indentation of your code, so that blocks can be easier recognised. I don't debug left-aligned code.

Kurt_Bremser
Super User

Do what I told you in your other thread: make your code readable (the current formatting is useless crap, pardon the word), so you can follow the branches more easily.

It seems ro arise because 0163 is not in your macro variable.

ballardw
Super User

You say "Macro variable NL_RB resolves to 0169,0417"

 

Guessing that you actually want a 0163 in there somewhere as the position in the "expected" output that matches the 0169 on the first row is 0163.

 

So if you tell the program to look for something but not matching what you expect then do not expect the output to be as desired.

 

You might also want to learn the concatenation functions other than the || operator such as

target = "&nl_path"||"/"||filename;

could be

target = catx('/', "&nl_path", filename);

Which can avoid some of the potential issues that arise with || and trailing blanks in values, plus is easier on th eyes if you are placing multiple / between many strings.

Tom
Super User Tom
Super User

Save yourself (and those trying to follow your questions) a lot of time and run the step to generate the list of file first. 

%let inpath=/var/sasdata/GT;

data files ;
  length id 8 msg filename $256 ;
  did=dopen("source");
  if did<=0 then do;
      msg=sysmsg(); 
      put msg; 
      stop;
  end;
  do id=1 to dnum(did);
    filename=dread(did,id);
    output;
  end;
  did=dclose(did);
  drop did msg;
run;

Then run a separate step to try to apply your renaming/moving rules. 

%let lh_path=/var/sasdata/LH;
%let nl_path=/var/sasdata/NL;
%let function=NL;

data files_to_move ;
  set files;
  length source target $256 ;

  if scan(lowcase(filename),-1,'.')='csv' and ("&function" EQ 'NL' or "&function" EQ 'LH') then do;
    source="&inpath" ||"/"|| filename;

    if "&function" EQ 'NL' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do;
      flag = 0;
      do i = 1 to countw("&nl_rb.",",");
        if indexw(filename,scan("&nl_rb.",i,","),"_") then do;
          flag = 1;
          target = "&nl_path"||"/"||filename;
        end;
      end;
    end;

    else if "&function" EQ 'LH' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do;
      flag = 0;
      do i = 1 to countw("&lh_rbukrs.",",");
        if indexw(filename,scan("&lh_rbukrs.",i,","),"_") then do;
          flag = 1;
          target = "&lh_path"||"/"||filename;
        end;
      end;
    end;

    else target="&inpath" ||"/"|| filename;
    output;
  end;
run;

Then you don't risk messing up the code to read the list of files and you don't force us to try and figure out what parts of the program are related to getting the list of file names and which part is related to your actual question.  Plus now you can post a data step that creates the list of filenames you want share with us so we can help you figure out how to manipulate them.  Just post a simple data step like this:

data files;
  input filename :$256. ;
cards;
IFR_GT_TRD_2_0163_1_20201009T075212.csv
IFR_GT_TRD_2_0169_1_20201009T075212.csv
;

Please explain the RULES in words that the code is trying to implement. What is &FUNCTION?  Are there always 7 parts to the filename separated by underscores? What do the parts of the filenames mean? 

 

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 986 views
  • 1 like
  • 5 in conversation