2017-01-20 4 views
1

Я провел круги на этом в течение 1,5 часов, поэтому я ухожу и прошу помочь здесь. То, что я пытаюсь сделать, просто мертво, но я не могу для жизни меня найти ссылку, описывающую этот процесс.Как получить числовое значение аргумента макроса, установленного на шаге данных

У меня есть следующий шаг данных:

data _null_; 
    some_date = "01JAN2000"D; 
    call symput('macro_input_date',left(put(some_date),date9.))); 
    %useful_macro(&macro_input_date); 
run; 

где значение даты передается функции макроса (Я новичок в них). Я хотел бы использовать числовое значение значения даты - давайте будем дикими и скажем, что хочу получить значение года, умножить его на значение дня и вычесть остаток после деления значения месяца на 3. Я могу Кажется, что из входных данных получается только значение года. Я пробовал различные вещи, такие как

  • symget, как «голые» и предваряются «%», с аргументами, которые представляют все возможные перестановки следующих вариантов:
    • имеют голую ссылку на переменная, например macro_input_date
    • заключить в одинарные кавычки, например. 'macro_input_date'
    • заключить в двойные кавычки, например. msgstr "0". & macro_input_date
  • прямой призыв к %sysfunc(year(<argument as variously specified above>)

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

Спасибо!

+0

Что вы пытаетесь сделать что вам нужно перейти к макропеременной и отступить? Нужно больше информации. В противном случае основной ответ заключается не в этом ... Что такое «полезная функция макросов»? То, как вы это указали, не является макрофункцией (они должны быть на правой стороне знака равенства). – Joe

+0

Является ли ваша проблема только одним из сроков? Переместите оператор 'RUN;' перед вызовом '% useful_macro()', если вы хотите, чтобы макрос использовал значение, вызываемое 'вызывающим symput()'. – Tom

+0

@Joe, вы правы, я должен был присвоить значение. По сути, я использую GUI (DI) и хочу преобразовать, например, значения даты в соответствующее целочисленное представление (например, 20000101). Это достаточно легко сделать с шагом данных, но я хочу быть эффективным и делать это в преобразовании, которое уже выполняет итерацию через данные. С ограничениями GUI это означает, что выражения для перетаскивания * и * используются с двумя преобразованиями. Чтобы упорядочить повторяющийся процесс, я хочу создать функцию, которая может быть вызвана из преобразований графического интерфейса. Вы видите превосходный подход? Благодаря! – Rookatu

ответ

1

Учитывая, что вы спросили о функциях макросов, я угадаю, что ваш пример обработки даты - это всего лишь пример. Говоря о макрофункциях в целом, важно понять, что макрофункция (вообще) не будет выполнять какую-либо обработку самостоятельно, она просто создаст некоторый код шага данных для выполнения какой-либо задачи. Итак, для чего-то, как ваш надуманный пример, шаг данных код будет что-то вроде:

data out; 
    set in; * Assume this contains a numeric called 'some_date'; 
    result = year(some_date) * day(some_date) - mod(month(some_date), 3); 
run; 

Для macroise это, вам не нужно передавать значения данных в макрос, вам просто нужно передать переменную имя:

%macro date_func(var=); 
    year(&var) * day(&var) - mod(month(&var), 3) 
%mend; 

data out; 
    set in; * Assume this contains a numeric called 'some_date'; 
    result = %date_func(var=some_date); 
run; 

Обратите внимание, что значение параметра var здесь буквальный текст some_date, не значения переменного шага some_date данных. Есть и другие способы сделать это, конечно, - вы могли бы на самом деле пройти этот макрос финиковой буквальным и он будет работать:

data out; 
    set in; * Assume this contains a numeric called 'some_date'; 
    result = %date_func(var="21apr2017"d); 
run; 

так что все зависит от того, что вы пытаетесь сделать ... Может быть, вы хотите присвоить результат другой макропеременной, поэтому он не обязательно должен быть частью шага данных, и в этом случае вы можете сделать аналогичную вещь с функциями %sysfunc и т. д.

+0

Спасибо за информацию! Как это будет работать, если для вычисления требуется несколько строк кода? Я здесь в девственных водах и не знаю, что делать с отсутствием ";" в макросе. В любом случае, я смог проглотить все в одном выражении, так что это сработало. Благодаря! – Rookatu

+0

Полуколоны (';') в макросе не обязательно. Тело макроса - все биты, которые не являются макросами, такими как% LET или% IF, просто передаются базовому процессору SAS после того, как любые макропеременные были разрешены и т. Д. В этом теле нет необходимости содержать в двоеточие, и в подобных случаях вы действительно не хотите этого. Вызов макроса также не нужен в виде двоеточия - точка с запятой в моем примере является частью инструкции шага данных. Включите MPRINT и попробуйте изменить его на result =% date_func (var = some_date) + 50; чтобы понять, что я имею в виду. –

+0

Я понял, что это что-то в этом роде. Это помогло мне учиться намного быстрее, чем часы работы в Интернете, которые я потратил. Еще раз спасибо! – Rookatu

0

Если вы просто пытаетесь получить год, вы могли бы сделать что-то вроде:

data _null_; 
    some_date = "01JAN2000"D; 
    call symput('macro_input_date',left(put(some_date,date9.))); 
    yearval = substr(symget('macro_input_date'),6,4); 
    put yearval=; 
run; 

макроса значение (&macro_input_date) не фактическое значение даты (14610), но текст 01JAN2000. Таким образом, вы не можете использовать функцию year (если вы не вернете ее INPUT), вы можете использовать substr, чтобы захватить часть года.

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

0

У вас просто проблемы с литературой даты? Ваш шаг данных код

data _null_; 
    some_date = "01JAN2000"D; 
    call symput('macro_input_date',left(put(some_date),date9.))); 
run; 

только собирается сделать то же самое, как

%let macro_input_date=01JAN2000 ; 

Теперь, если вы хотите обработать эту строку символов, если она представляет собой дату, то вам нужно либо обернуть его up как date literal

"&macro_input_date"d 

Или преобразуйте его.

%sysfunc(inputn(&macro_input_date,date9)) 

Почему бы не просто сохранить фактическое значение даты в макропеременной?

call symputx('macro_input_date',some_date); 

Тогда это не будет выглядеть как дата для вас, но это будет выглядеть как дата к функции YEAR().