% SCAN с модификатором M дает неверные результаты - PullRequest
0 голосов
/ 17 апреля 2019

Может кто-нибудь подсказать, почему два приведенных ниже кода имеют разные выходные данные?

У меня есть макрос var FILETYPE, который разрешается в файл // Пропущено первое значение.

%let b=%scan("&filetype",1,",",M);
%put &b;
%let c=%scan("&filetype",2,",",M);
%put &c;
%let d=%scan("&filetype",3,",",M);
%put &d;
%mend;
%tt;`

Iполучить следующий вывод:

SYMBOLGEN:  Macro variable FILETYPE resolves to ,File
SYMBOLGEN:  Macro variable B resolves to 

SYMBOLGEN:  Macro variable FILETYPE resolves to ,File
SYMBOLGEN:  Macro variable C resolves to 

SYMBOLGEN:  Macro variable FILETYPE resolves to ,File
SYMBOLGEN:  Macro variable D resolves to File
File

Когда макрос var C должен был преобразоваться в File, но его значение все равно NULL, а D получает значение File.

Та же логика в простом шаге данных работает правильно.

data a;
b=scan("&filetype",1,',','M');
c=scan("&filetype",2,',','M');
run;
Output :
b=blank
c=File

Может кто-нибудь подсказать, почему функция SCAN с модификатором M работает нормально на шаге данных, но не в макросе?

Ответы [ 2 ]

2 голосов
/ 17 апреля 2019

В макросе работает точно так же, как и в коде шага данных.Проблема заключается в том, что вы добавили двойные кавычки как в строку для сканирования, так и в список используемых разделителей.Таким образом, эквивалентный шаг данных будет:

%let filetype=A,B;
data _null_;
  length string word $100;
  string=quote(symget('filetype'));
  do i=1 to 4;
    word=scan(string,i,'","','M');
    put i= word=:$quote.;
  end;
run;

, который приводит к такому результату:

i=1 word=""
i=2 word="A"
i=3 word="B"
i=4 word=""

То, что вы, вероятно, хотели сделать в коде макроса, было:

%scan(%superq(filetype),1,%str(,),M)

В обычном коде SAS вам нужно добавлять кавычки вокруг строковых литералов, чтобы анализатор знал, что вы не имели в виду имя переменной.В макросе, который не нужен, все является строкой.Вы используете триггеры макросов & и %, чтобы дать парсеру понять, когда следует обращаться с ним по-разному.

При создании списка с разделителями для использования в коде макроса создайте его с другим разделителем и избегайтевсе кавычки макросов, необходимые для работы с запятыми.

... into :filetype separated by '|' ...
%scan(&filetype,1,|,m)
1 голос
/ 17 апреля 2019

Не заключайте в кавычки аргументы в макросах. Вам НЕОБХОДИМО буквально преобразовать запятую в качестве аргумента как %str(,), чтобы он НЕ рассматривался как разделитель аргументов.

%scan ( &filetype , 1, %str(,), M )

Если значение filetype содержит важные для макроса символы, вам может потребоваться заключить в кавычки макрос или аргумент superq. Если возврат может содержать важные для макроса символы, которые не должны быть разрешены, вы можете использовать %QSCAN для их маскировки.

...