2

是否可以循环遍历表的记录以填充 html 电子邮件而不重复电子邮件的开头和结尾?

在此示例中,我收到一封包含 5 个 1 行表的邮件(因为WORK.MyEmailTable是 5 个记录的表并set在数据步骤中创建了一个循环):

data _null_;
   file mymail;
   set WORK.MyEmailTable;

   put '<html><body><table>';

   ***loop through all records;
   put '<tr>';
   put %sysfunc(cats('<td>',var1,'</td>'));
   put %sysfunc(cats('<td>',var2,'</td>'));
   put %sysfunc(cats('<td>',var3,'</td>'));
   put '</tr>';

   put '</table></body></html>';

run;

我希望有 1 个 5 行的表。

当您在数据步骤中 使用时,我不知道是否有一种方法可以递归地防止put邮件的开头和结尾。set

(如果不清楚,请告诉我,我会更新。)

谢谢,

4

2 回答 2

2

您可以使用_n_自动 datastep 变量让您知道您何时处于第一次观察,并使用set语句选项end=知道您处于最后一次观察:

data _null_;
    file mymail;
    set WORK.MyEmailTable end=eof;

    if _n_ eq 1 then do;
      put '<html><body><table>';
    end;

    /*loop trhough all records*/
    put '<tr>';
    put %sysfunc(cats('<td>','_n_=',n,' eof=',eof,' ',var1,'</td>'));
    put %sysfunc(cats('<td>','_n_=',n,' eof=',eof,' ',var2,'</td>'));
    put %sysfunc(cats('<td>','_n_=',n,' eof=',eof,' ',var3,'</td>'));
    put '</tr>';

    if eof then do;
      put '</table></body></html>';
    end;
run;

我已将值添加_n_eof输出中,以便您可以清楚地看到它们是如何工作的。

于 2015-10-21T14:40:00.337 回答
1

Rob 的方法几乎是标准的,但如果您更喜欢编写显式循环脚本(这对于非 SAS 程序员来说阅读起来更舒服),还有另一种选择。这将与 Rob 的答案完全相同,甚至可以编译为相同的机器代码。

data _null_;
    file mymail;

    put '<html><body><table>';
    do _n_ = 1 by 1 until (eof);
    /*loop trhough all records*/
      set WORK.MyEmailTable end=eof;
      put '<tr>';
      put %sysfunc(cats('<td>',var1,'</td>'));
      put %sysfunc(cats('<td>',var2,'</td>'));
      put %sysfunc(cats('<td>',var3,'</td>'));
      put '</tr>';
    end;
    put '</table></body></html>';
    stop;
run;

_n_这里没有任何特殊含义(就像在 Rob 的回答中一样);它是按惯例使用的,因为这种方式实际上与通常具有相同的含义。

您需要使用end=eof来创建一个eof在数据集的最后一条记录上为 true 的变量;否则数据步骤将过早终止(在实际命中您的最终语句之前)。您还需要stop告诉它不要回到开始 - 否则它会,并且会放置一个新的起始部分,然后在它遇到set. (试试看。)

do _n_=1 by 1 until (eof);是一种使用增量循环的特定于 SAS 的方式;例如,它类似于 c/c++ for (_n_=1; !eof; _n_++)- 它允许您拥有一个自动递增的 do 循环,同时拥有一个单独的、不相关的停止条件。

于 2015-10-21T15:02:25.897 回答