Я пытаюсь вызвать MACRO в SAS CI (используя Node Process), но получаю сообщение об ошибке (1012 или 3000) при попытке выполнения. Этот код отлично работает в SAS Enterprise Guide.
Я попытался удалить синтаксис «выполнить вызов», но мне это не удалось.
DATA _NULL_ ;
SET SMS_TEMP END = EOF ;
IF _N_ = 1 THEN DO UNTIL (EOF);
%build_JSON;
END ;
PUT 'Complete';
STOP ;
RUN ;
Полный код:
DATA _NULL_ ;
SET SMS_TEMP END = EOF ;
IF _N_ = 1 THEN DO UNTIL (EOF);
CALL EXECUTE('%build_JSON');
END ;
PUT 'FINAL';
STOP ;
RUN ;
%macro build_JSON;
FILENAME CODE TEMP;
DATA _NULL_;
SET SMS_TEMP;
FILE CODE ;
PUT
'WRITE VALUES "TP_SMS" ' CODSMS :$QUOTE. ';'
/ 'WRITE VALUES "NM_REMETENTESMS" ' REMETENTE :$QUOTE. ';'
/ 'WRITE VALUES "NR_TELEFONECELULARSMS" ' MOBILE :$QUOTE. ';'
/ 'WRITE VALUES "TX_MENSAGEMSMS" ' MSGTEXT :$QUOTE. ';'
/ 'WRITE VALUES "DT_PARAENVIOSMS" ' DATAPARA :$QUOTE. ';'
/ 'WRITE VALUES "DT_LIMITEENVIOSMS" ' DATALIMI :$QUOTE. ';'
/ 'WRITE VALUES "DS_CHAVEORIGEMSMS" ' RESP :$QUOTE. ';'
;
RUN;
PROC JSON OUT="%SYSFUNC(GETOPTION(WORK))/TEST.JSON" PRETTY KEYS NOSASTAGS;
WRITE OPEN OBJECT;
%INCLUDE CODE;
WRITE CLOSE;
RUN;
FILENAME CODE CLEAR;
%MEND build_JSON;
Я ожидаю, что буду работать с макросами в SAS CI (используя код SAS в Node Process).
Как мне это сделать?
Я попытаюсь объяснить, что именно мне нужно: у меня есть набор данных, который мне нужно создать файл JSON для каждой строки из моего набора данных. После я вызову другой макрос с процессом API. Мой цикл должен быть таким: прочитать (1), создать файл JSON (2), выполнить макрос API (3). Исключить файл из (json) и найти следующий регистр;
Вы показали только частичный код для второго шага, создания файла JSON из набора данных. Что вы собираетесь делать с файлом JSON? Выдает ли то, что вы с ним делаете, какие-либо результаты, которые вам нужно агрегировать?
Сначала убедитесь, что вы определили макрос, прежде чем вызывать его.
Во-вторых, ваш макрос каждый раз делает одно и то же, поэтому нет смысла вызывать его несколько раз.
Так зачем вообще макрос? Почему бы просто не вызвать код, который генерирует макрос?
Или, может быть, вы хотите, чтобы ваш макрос принимал входной параметр? Например, имя набора данных для преобразования в JSON? Если да, то откуда будет браться список наборов данных?
Обратите внимание, что ваш первый шаг не может работать, так как ваш макрос генерирует несколько шагов. Первый сгенерированный оператор PROC или DATA завершит ваш шаг данных в середине определения блока DO/END, поэтому он завершится ошибкой, поскольку SAS никогда не увидит закрывающий END для открывающего DO.
Привет Том, ты прав. Я попытаюсь объяснить, что именно мне нужно: у меня есть набор данных, который мне нужно создать файл JSON для каждой строки из моего набора данных. После я вызову другой макрос с процессом API. Мой цикл должен быть таким: прочитать (1), создать файл JSON (2), выполнить макрос API (3). Исключить файл из (json) и найти следующий регистр;
Существует путаница в отношении того, что вы зацикливаете. Ваш внешний шаг данных читает SMP_TEMP
, но ваш шаг данных, который записывает данные JSON, генерирует серию операторов WRITE
для каждого наблюдения в наборе данных SMS_TEMP. Вы просто хотите, чтобы он написал одно наблюдение? Вы хотите, чтобы он записал все наблюдения, которые существуют для определенного значения некоторой переменной ID?
Привет Том, большое спасибо за ваш интерес и время. Я опубликовал новый ответ ниже, где я показываю вам новый код. У вас есть идеи, как я могу это решить?
Я сделал некоторые корректировки в своем коде:
DATA _NULL_ ;
IF _N_ = 1 THEN DO UNTIL (EOF);
SET SMS_TEMP END = EOF ;
PUT 'Number line:' NumbLINE;
CALL SYMPUTX('NRL',NumbLINE);
CALL SYMPUTX('RESPTRACKING',RESP);
CALL EXECUTE('%BUILD_JSON');
/*CALL EXECUTE('%CALLAPI'); --- In dev*/
/*CALL EXECUTE('%DELETEFILE'); --- In dev*/
END ;
ELSE DO;
PUT 'FINISH';
END;
RUN ;
Этот код выше отвечает за вызов всех моих МАКРОСОВ один за другим до конца файла.
%MACRO BUILD_JSON;
FILENAME CODE TEMP;
DATA _NULL_;
SET SMS_TEMP;
WHERE NROLINHA EQ &NRL.;
FILE CODE ;
PUT
'WRITE VALUES "PITP_SMS" ' CODSMS :$QUOTE. ';'
/ 'WRITE VALUES "PINM_REMETENTESMS" ' REMETENTE :$QUOTE. ';'
/ 'WRITE VALUES "PINR_TELEFONECELULARSMS" ' MOBILE :$QUOTE. ';'
/ 'WRITE VALUES "PITX_MENSAGEMSMS" ' MSGTEXT :$QUOTE. ';'
/ 'WRITE VALUES "PIDT_PARAENVIOSMS" ' DATAPARA :$QUOTE. ';'
/ 'WRITE VALUES "PIDT_LIMITEENVIOSMS" ' DATALIMI :$QUOTE. ';'
/ 'WRITE VALUES "PIDS_CHAVEORIGEMSMS" ' RESP :$QUOTE. ';'
;
RUN;
PROC JSON OUT="%SYSFUNC(GETOPTION(WORK))/TEST.JSON" PRETTY KEYS NOSASTAGS;
WRITE OPEN OBJECT;
%INCLUDE CODE;
WRITE CLOSE;
RUN;
FILENAME CODE CLEAR;
%MEND BUILD_JSON;
Я ожидаю создать подпрограмму для создания файла JSON -> затем-> вызвать макрос API для отправки этого JSON -> затем-> исключить этот файл -> затем-> повторить. Для каждой строки моего набора данных я буду называть этот циклический процесс, и, похоже, он работает так же хорошо, по крайней мере, в SAS Enterprise Guide.
Эта проблема возникает только тогда, когда я попытался выполнить этот код в SAS Customer Intelligence (CI) через узел процесса.
Теперь у вас возникла проблема синхронизации между установкой переменных макроса с помощью CALL SYMPUTX() и запуском макроса. Передайте значения макросу как параметры, а не как глобальные переменные макроса, и проблема синхронизации исчезнет.
При вызове макроса из CALL EXECUTE
он будет немедленно выполняться до момента, когда произойдет генерация кода. Это может сбить с толку начинающих пользователей этой функции и имеет побочные эффекты, описанные в документации и материалах конференций.
Чтобы явно указать операторы вызова макроса куча, чтобы они происходили только после завершения шага, EXECUTE
должен использовать аргумент, который %NRSTR
оборачивает вызов макроса.
call execute ('%NRSTR(
исходный код, который вызывает макрос)');
Вы должны определить макрос, прежде чем вызывать его.