Macros SAS:Dowhile循环不迭代

Macros SAS:Dowhile循环不迭代,macros,while-loop,sas,do-while,Macros,While Loop,Sas,Do While,我有一个保存的csv_文件SAS数据集,其中包含以下条目: name path aapl F:\Data\aapl.csv msft F:\Data\msft.csv ibm F:\Data\ibm.csv goog F:\Data\goog.csv 然后,我使用此SAS数据集定位csv文件,并使用以下宏将其导入SAS,该宏具有while循环: options symbolgen mlogic nomprint; /*Leave options on as SAS will issue a

我有一个保存的
csv_文件
SAS数据集,其中包含以下条目:

name path
aapl F:\Data\aapl.csv
msft F:\Data\msft.csv
ibm F:\Data\ibm.csv
goog F:\Data\goog.csv
然后,我使用此SAS数据集定位csv文件,并使用以下宏将其导入SAS,该宏具有
while
循环:

options symbolgen mlogic nomprint;  
/*Leave options on as SAS will issue a message when Do While Loop is false*/

%let dsname = csv_files;                               
%let libto = l;


%Macro get_data(n,index);  

     /*n: is a counting macro variable representing the lower limit of the number of CSV files
 to be read into SAS. Index: is a variable that can be thought of as 
observation number( row number) representing the upper limit 
of the number  of CSV files to be read into SAS.*/

%DO %WHILE (&n <=&index);
data _NULL_;
set &libto..&dsname end=last;
if _N_ =&n then Do;
call symput('path',path);      /*  Get file path from CSV_files*/
call symput('dsn',name);       /* Get dataset name from CSV_files*/                     
if not last  then index+1;     /* Create macro variable Index */
else if last then call symput ('index',index);  
End;
run;

proc import datafile= "&path"             
     out= &libto..&dsn
     dbms=dlm
     replace;
     delimiter=","  ;            
     getnames=yes;
run;
%End;

%Mend get_data;

/* Macro Call*/
%get_data(1,4);
%let dsname = csv_files;                                                   
%let libto = l;

%Macro get_data(n,index);       
%let dsname = csv_files;                                                   
%let libto = l;

%do i=&n %to &index;
data _NULL_;
set &libto..&dsname end=last;
if _N_ =&i then Do;
call symput('path',path);      /*  Get file path from CSV_files*/
call symput('dsn',name);       /* Get dataset name from CSV_files*/                     
if not last  then index+1;     /* Create macro variable Index */
else if last then call symput ('index',index);  
End;
run;

proc import datafile= "&path"             
     out= &libto..&dsn
     dbms=dlm
     replace;
     delimiter=","  ;            
     getnames=yes;
run;
%End;
%End;

%Mend get_data;

/* Macro Call*/
%get_data(1,4);
我得到的错误如下:

ERROR 180-322: Statement is not valid or it is used out of proper order.
我在代码中的多行中得到了这个结果,但从我的CSV文件生成了4个SAS数据集中的最后3个

我还得到了代码中
&dsn
的错误:

ERROR 22-322: Syntax error, expecting one of the following: ;, (, DATAFILE, DATATABLE, DBMS,
          DEBUG, FILE, OUT, REPLACE, TABLE, _DEBUG_.

也许,这是因为您没有在每次迭代中增加&n宏变量?我建议更换你的手表

%DO %WHILE...
循环

 %DO i=&n %TO &index;
...
if _N_=&i then ...;
更新

这就是我所运行的,它起作用了。它与您的问题中的更新代码完全相同,除了:

-我添加了数据步骤来创建csv_文件数据集

-我删除了第二条%END语句

-添加了LIBNAME以分配l库

-将路径中的F:-驱动器更改为C:-驱动器(只是因为我没有F-drive):


如果只想将它们读入SAS数据集中,可以尝试使用
infle
语句中的
FILEVAR=
选项<当您知道多个外部文件的路径时,code>FILEVAR
可以读取这些文件

data files;
    length path $40;
    input name $ path $;
    datalines;
    sample1 C:\sasdata\sample1.csv 
    sample2 C:\sasdata\sample2.csv
    test C:\Cstuff\test.csv
    ;
run;

data want(drop=name);
     set files;
     infile dummy filevar=path DLM=',' length=reclen end=done missover;
     do while (not done);
        input A B C;
        output;
     end;
run;

在玩弄代码时,我找到了一种方法,使用
While
将所有四个csv文件导入SAS,我不知道为什么这与我以前使用
DO
While

options symbolgen mlogic nomprint;  


%let dsname = csv_files;                                                   
%let libto = l;
libname l 'C:\SASDATA\';

%Macro get_data(n,index);       

%IF &n <= &index %then %Do;

%DO %WHILE (&n <=&index);

data _NULL_;
set l.csv_files end=last;
if _N_ =&n then Do;
call symput('path',Path);                /*  Get file path from Datalog*/
call symput('dsn',Name);       /* Get dataset name from Datalog*/                       
if not last  then index+1;                 /* Create macro variable Index */
else if last then call symput ('index',index);  
End;
run;

proc import datafile= "&path"             
     out= &libto..&dsn
     dbms=dlm
     replace;
     delimiter=","  ;            
     getnames=yes;
run;


%End;
%End;

Data _NULL_;
set &libto..&dsname;
%IF &n gt &Index %then %Put ERROR Ending execution: Check values of n and Index (n must be less than or equal to index);
run;
%Mend get_data;

/* Macro Call*/

%get_data(1,1,4);
选项symbolgen mlogic nomprint;
%让dsname=csv_文件;
%设libto=l;
libname l'C:\SASDATA\';
%宏获取_数据(n,索引);

%如果(&n),请确保已启用MPRINT、SYMBOLGEN和MLOGIC选项。然后您可以在日志中看到宏变量的值。是的,我看到了。我把它忘在上面的代码里了。说得好。看起来您的%End比必需的多了一个。如果我删除了一个%End,我会为1个未关闭的DO语句收到一个错误…我运行了您的更新代码,并且在没有第二个%End语句的情况下运行得非常好(这很有意义,因为您只有一个%DO语句)。我将把我的代码添加到我的答案中。我做了您建议的更改,但由于某些原因,它跳过了要导入SAS数据集中的第一个条目。我得到了
&libto
&dsname
无法识别…因为我的其他Entries并非如此,这很奇怪。你能复制/粘贴到你的问题的确切代码(所有更改)和源数据吗?看起来你有一个比必要的多%End。
options symbolgen mlogic nomprint;  


%let dsname = csv_files;                                                   
%let libto = l;
libname l 'C:\SASDATA\';

%Macro get_data(n,index);       

%IF &n <= &index %then %Do;

%DO %WHILE (&n <=&index);

data _NULL_;
set l.csv_files end=last;
if _N_ =&n then Do;
call symput('path',Path);                /*  Get file path from Datalog*/
call symput('dsn',Name);       /* Get dataset name from Datalog*/                       
if not last  then index+1;                 /* Create macro variable Index */
else if last then call symput ('index',index);  
End;
run;

proc import datafile= "&path"             
     out= &libto..&dsn
     dbms=dlm
     replace;
     delimiter=","  ;            
     getnames=yes;
run;


%End;
%End;

Data _NULL_;
set &libto..&dsname;
%IF &n gt &Index %then %Put ERROR Ending execution: Check values of n and Index (n must be less than or equal to index);
run;
%Mend get_data;

/* Macro Call*/

%get_data(1,1,4);