#sas #sas-macro
Вопрос:
У меня есть макрофункция, определенная как показано ниже.
%macro sqlloop(event_id, empl_nbr_var, fleet, base, position);
...lots of code...
%mend;
этот макрос создает таблицу под названием export_table2
, которую я хочу складывать друг на друга каждый раз, когда я запускаю этот код. Я попробовал ниже
data executed;
set work.vars;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2 summary_pilots;
run;
но это приводит к ошибке, так как summary_pilots не существует, поскольку я пытаюсь ссылаться на него. Я также попробовал странную работу, когда я вынул первую строку vars
в новую таблицу и удалил ее из старой, а затем попытался выполнить приведенный ниже код (где row1-первая строка, а vars-все, кроме первой строки).
data _null_;
set Work.row1;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2;
run;
data executed;
set work.vars;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2 summary_pilots;
run;
и он все еще функционирует не совсем так, как я хочу. Это включает только первую таблицу (из строки 1) и самую последнюю таблицу, созданную макросом. Я понимаю, почему это происходит, так как call execute запускает их все сразу и записывает все старые таблицы, но я все еще не знаю, как это исправить. Любая попытка поместить его в более ранний этап обработки данных также потерпела неудачу. есть какие-нибудь предложения?
Комментарии:
1. Используйте приложение PROC.
Ответ №1:
Во-первых, код для добавления должен быть внутри %sqlloop
, если это возможно. Если нет, создайте макрос-оболочку вокруг %sqlloop, что-то вроде
%macro write_loop(parameters...);
%sqlloop (parameters)
data summary_pilots... ;
run;
%mend write_loop;
А потом call execute
это. Вы также можете добавить вторую call execute
строку, но это излишне сложно. Есть также способы сделать %sqlloop
то, что, возможно, даст вам один набор данных вместо наборов данных по строкам, что было бы лучше всего во многих ситуациях. Существует также возможность предоставления уникального набора данных для каждого %sqlloop
выполнения. Мне нравится включение в макрос в большинстве случаев, когда один набор данных не работает, но есть причины, по которым вы можете предпочесть уникальные наборы данных.
Во-вторых, у вас есть куча вариантов, в зависимости от деталей, как заставить все это работать. PROC APPEND
это хорошее начало, как отметил Том в комментариях; это работает, если набор данных, который вы добавляете, всегда по столбцам идентичен тому, что было там раньше.
proc append base=summary_pilots data=export_table2;
quit;
Это создаст summary_pilots
его при первом запуске. Это действительно работает только в том случае, если столбцы всегда совпадают — звучит так, как будто это вероятно? FORCE
опция также возможна, но в основном она бесполезна для такого рода вещей, если вы не гарантируете, что первый набор данных является полным набором данных с переменной.
Если они не совпадают, то вам остается бежать, прежде чем что-либо еще:
data summary_pilot;
stop;
run;
Конечно, не пытайтесь открыть его — он не откроется, в нем нет строк и столбцов, — но он существует и может быть вашей «базой». Вы также можете определить столбцы в нем, если у вас есть хороший «шаблон»; Я делаю это для некоторых проектов.
Комментарии:
1. Все это, кстати, предполагает, что ваше решение с помощью
sqlloop
является правильным решением — оно может быть, но в большинстве случаев это не так; но вы не сказали, что делаете, поэтому я не могу сказать.