Я отвечу на основной вопрос Бемби спросил в комментариях:
Моя главная задача здесь, как вернуть значение из макроса.
Я собираюсь сыграть важную роль с Дирк. Он говорит:
A SAS macro inserts code. Она никогда не может возвращать значение, хотя в некоторых случаях вы можете имитировать функции
я не согласен. Макрос SAS возвращает текст, который вставляется в поток обработки. Возврат - это абсолютно подходящий термин для этого. И когда текст оказывается одиночным числовым, тогда хорошо сказать, что он возвращает значение.
Однако, макрос может возвращать только одно значение , если он имеет только макро заявления в дополнение к этому значению. Значение, каждая строка должна начинаться с %
. Все, что не начинается с %
, будет возвращено (и некоторые вещи, которые начинаются с %
, также могут быть возвращены).
Так важный вопрос, Как вернуть только значение из макроса.
В некоторых случаях, как этот, это вполне возможно с только кода макроса. Фактически, во многих случаях это технически возможно, хотя во многих случаях это больше, чем вы должны делать.
Связанный с Джеком Гамильтоном paper содержит пример, который здесь подходит. Он отклоняет этот пример, но это во многом потому, что его статья посвящена подсчету наблюдений в случаях, когда NOBS ошибочен - либо с предложением WHERE, либо в некоторых других случаях, когда наборы данных были изменены без обновления метаданных NOBS.
В вашем случае вы, кажется, счастливы доверять NOBS - так этот пример будет делать.
Макрос, который возвращает значение должно быть точно один о том, что либо это не макрос заявление синтаксиса, или является макрос заявление синтаксис, который возвращает значение в поток обработки. %sysfunc
- пример инструкции, которая делает это. Такие вещи, как %let
, %put
, %if
и т. Д. Являются инструкциями синтаксиса, которые ничего не возвращают (сами по себе); поэтому вы можете иметь столько, сколько хотите.
У вас также есть, чтобы иметь одно заявление, которое помещает значение в поток обработки: иначе вы ничего не получите из своего макроса.
Вот урезанная версия макроса Джека в конце страницы 3, упрощенно удалить nlobsf
, что он показывает неправильно:
%macro check;
%let dsid = %sysfunc(open(sashelp.class, IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());
%let nlobs = %sysfunc(attrn(&dsid, NLOBS));
%put &nlobs;
%let rc = %sysfunc(close(&dsid));
%mend;
Этого макрос не функции стиль макросов. Он ничего не возвращает в поток обработки! Это полезно для просмотра журнала, но не полезно для предоставления вам значения, с которым вы можете запрограммировать. Тем не менее, это хороший старт для макроса стиля функции, потому что вы действительно хотите, чтобы &nlobs
, правильно?
%macro check;
%let dsid = %sysfunc(open(sashelp.class, IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());
%let nlobs = %sysfunc(attrn(&dsid, NLOBS));
&nlobs
%let rc = %sysfunc(close(&dsid));
%mend;
Теперь это функция стиль макроса: он имеет одно утверждение, которое не является макро заявление синтаксис, &nlobs.
на простой линии все само по себе.
Это на самом деле больше, чем вам нужно одним утверждением; помните, как я сказал, что %sysfunc
возвращает значение в поток обработки?Вы можете удалить %let
часть этого заявления, оставив вас с
%sysfunc(attrn(&dsid, NLOBS))
И тогда значение будет размещен непосредственно в самом потоке обработки - что позволяет использовать его непосредственно. Конечно, отлаживать не так просто, если что-то пойдет не так, но я уверен, что вы можете обойти это, если вам нужно. Также обратите внимание на отсутствие полуколонны в конце инструкции - это потому, что для выполнения макрофункций не требуются точки с запятой, и мы не хотим возвращать любые посторонние точки с запятой.
Давайте хорошо себя и добавить несколько %local
с, чтобы получить это красиво и безопасно, и сделать имя набора данных параметра, потому что природа не приемлет макрос без параметров:
%macro check(dsetname=);
%local dsid nlobs rc;
%let dsid = %sysfunc(open(&dsetname., IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());
%let nlobs = %sysfunc(attrn(&dsid, NLOBS));
&nlobs
%let rc = %sysfunc(close(&dsid));
%mend;
%let classobs= %check(dsetname=sashelp.class);
%put &=classobs;
Там у вас есть : макрос стиля функции, который использует функцию nlobs
, чтобы узнать, сколько строк находится в любом конкретном наборе данных.
Мне нравится макрофункция Джек Гамильтона для подсчета обс: http://www2.sas.com/proceedings/sugi26/p095-26.pdf – Quentin
Спасибо за ссылку. Моя главная задача здесь - вернуть значение из макроса. Мне также очень хотелось бы знать, как сделать переменную «в» (в proc sql) локальной, а не глобальной. Это две вещи, которые мне нужно делать постоянно с другими макросами. – bambi
Вы уверены, что вам нужно знать, сколько? Обычно я просто хочу знать ничего или нет - нет. Что вы будете делать с NOBS? –