#sas
Вопрос:
В приведенном ниже коде неверно оценивается оператор IF, отправляющий электронное письмо. Я не уверен, почему. Я попытался проверить наличие нуля, но это тоже не сработало. Это просто всегда отправляет первое действие в этом заявлении. В приведенной ниже инструкции ТАБЛИЦА 1 существует без записей, а ТАБЛИЦА 2 не существует. Я думаю, что это как-то связано с тем, что amp;CNT3 заполняется числом(*) в инструкции proc sql.
%IF %SYSFUNC(exist(TABLE1)) %THEN %DO;
PROC SQL;
SELECT COUNT(*) INTO : CNT3 FROM TABLE1;
QUIT;
%END;
%ELSE %DO;
%LET CNT3=0;
%END;
%put amp;cnt3.;
%IF %SYSFUNC(exist(TABLE2)) %THEN %DO;
PROC SQL;
SELECT COUNT(*) INTO : CNT4 FROM TABLE2;
QUIT;
%END;
%ELSE %DO;
%LET CNT4=0;
%END;
%put amp;cnt4.;
%IF (amp;CNT3 ^=0 AND amp;CNT3^='0') %THEN %DO;
PROC EXPORT DATA=TABLE1.
DBMS=XLSX
OUTFILE="data/REPORT1.xlsx"
REPLACE;
SHEET="TEST1";
RUN;
%END;
%IF (amp;CNT4 ^=0 AND amp;CNT4^='0') %THEN %DO;
PROC EXPORT DATA=amp;ENV..AUTH_ERRORLOG_amp;REC_DATE.
DBMS=XLSX
OUTFILE="data/REPORT1.xlsx"
REPLACE;
SHEET="TEST2";
RUN;
%END;
%let EMAIL_SUBJECT = "TEST EMAIL.";
FILENAME OUTBOX EMAIL 'TEST@TEST.COM';
DATA _NULL_;
IF (amp;CNT3 ^=0 AND amp;CNT3 ^='0') OR (amp;CNT4 ^=0 AND amp;CNT4^='0') THEN
DO;
FILE OUTBOX
TO=('TEST@TEST.COM')
SUBJECT= amp;EMAIL_SUBJECT.
ATTACH=("/data/REPORT1.xlsx" CONTENT_TYPE="APPLICATION/XLSX");
END;
ELSE DO;
FILE OUTBOX
TO=('TEST@TEST.COM')
SUBJECT= amp;EMAIL_SUBJECT.;
PUT"NO ERRORS FOUND";
END;
RUN;
Комментарии:
1. Вы включили
symbolgen
иmlogic
? Это значительно поможет в устранении неполадок.2. Похоже, что amp;CNT3 принимает значение 0, но перед ним много пробелов. Я попытался подровнять его, но, похоже, это ничего не изменило.
3. Если вы не хотите, чтобы PROC SQL включал пробелы в созданные макропеременные, используйте ключевое слово TRIMMED.
... into :cnt3 trimmed ...
4. Этот код отлично работает для меня, когда я использую его как есть без изменений (кроме создания таблицы 1 с 0 записями), поэтому вы предоставляете недостаточно информации, чтобы ответить на вопрос.
Ответ №1:
Здесь может происходить множество вещей, поэтому давайте попробуем немного прояснить это, чтобы посмотреть, решит ли это ваши проблемы.
Во-первых, давайте возьмем количество наблюдений из метаданных интересующих таблиц вместо подсчета всех наблюдений. Это отличный воспроизводимый макрос, который я настоятельно рекомендую сохранить в качестве всегда доступного sasauto:
%macro nobs(data);
%local dsid nobs rc;
%let nobs = -1;
%if(%sysfunc(exist(amp;data.)) ) %then %do;
%let dsid = %sysfunc(open(amp;data.));
%let nobs = %sysfunc(attrn(amp;dsid., nlobs));
%let rc = %sysfunc(close(amp;dsid.));
%end;
amp;nobs.
%mend;
Это будет действовать как функция и возвращать количество наблюдений для таблицы SAS. Если он не существует, он возвращает -1. Например:
%put The number of obs in sashelp.cars is %nobs(sashelp.cars);
%put The number of obs in a non-existent table is %nobs(doesntexist);
Выход:
The number of obs in sashelp.cars is 428
The number of obs in a non-existent table is -1
Теперь мы гарантируем, что всегда возвращаем число без пробелов. Давайте заменим логику программы:
%if(%nobs(table1) > 0) %then %do;
PROC EXPORT DATA=TABLE1
DBMS=XLSX
OUTFILE="data/REPORT1.xlsx"
REPLACE;
SHEET="TEST1";
RUN;
%end;
%if(%nobs(table2) > 0) %then %do;
PROC EXPORT DATA=amp;ENV..AUTH_ERRORLOG_amp;REC_DATE.
DBMS=XLSX
OUTFILE="data/REPORT1.xlsx"
REPLACE;
SHEET="TEST2";
RUN;
%end;
%let EMAIL_SUBJECT = "TEST EMAIL.";
FILENAME OUTBOX EMAIL 'TEST@TEST.COM';
DATA _NULL_;
IF (%nobs(table1) > 0 OR %nobs(table2) > 0) then do;
FILE OUTBOX
TO=('TEST@TEST.COM')
SUBJECT= amp;EMAIL_SUBJECT.
ATTACH=("/data/REPORT1.xlsx" CONTENT_TYPE="APPLICATION/XLSX");
END;
ELSE DO;
FILE OUTBOX
TO=('TEST@TEST.COM')
SUBJECT= amp;EMAIL_SUBJECT.;
PUT"NO ERRORS FOUND";
END;
RUN;
Ответ №2:
Этот тест не имеет никакого смысла
amp;CNT3 ^=0 AND amp;CNT3 ^='0'
либо в логике макросов, либо в логике шага данных.
Если CNT3 будет иметь такие значения 0
, как 123
или даже 123
тогда, просто проверьте, равен ли он нулю или нет:
amp;cnt3 ne 0