2014-12-12 1 views
0

У меня есть проблема, связанная с макросом, которую я сейчас пытаюсь развить и понять. Любой указатель на решение этого было бы весьма признателен :-)SAS Macro - создать бегущий макрос в качестве конкатенации другого набора макросов

Это выходит что-то подобное ниже:

У меня есть «N» [переменная] число Макропеременные «Key», которые разрешают к

& Key1 = 1 & Ключ = 2 & Key3 = 3 ............... .. .......... & Keyn = п

Я хочу, чтобы создать автоматический запуск макроса «MasterKey», который выходит что-то вроде

& MasterKey = 1 & Masterkey2 = 12 & MasterKey = 123 .......... ..........

т.е. & MasterKeyN = 123 ... ..n

Как я могу получить эту работу, чтобы создать «& MasterkeyN», где N не фиксируется, как может быть переменной в зависимости от каждого набора случаев с [1-п ] ключи?

Большое спасибо.

Nad

+0

Откуда берутся второй набор значений, 1, 12, 123? – Reeza

+0

Если я буду следовать за вами правильно, & Masterkey10 = 12345678910 и т. Д. Я не уверен, почему вы используете эту конвекцию именования, но помните, что максимальная длина имени макроса составляет 32 символа, поэтому не потребуется многого мимо этого. Возможно, стоит упомянуть, как это будет использоваться, поскольку лучшее решение, вероятно, будет доступно – Longfish

+3

Это очень похоже на проблему в программном дизайне, а не на то, что действительно стоит решить. почему ты хочешь сделать это? Какова конечная цель программы? – Joe

ответ

1

Я думаю, что это, вероятно, не является полезным методом, но я отвечу на него в любом случае.

Я также предполагаю, что &Key1..n может иметь значения, отличные от числа, хранящегося в них, и вы хотите, чтобы эти значения были собраны в переменные &MasterKey1..n.

Что вам нужно сделать, это использовать вложенный цикл и немного узнать о том, как разрешаются макропеременные.

%let key1=A; 
%let key2=B; 
%let key3=C; 

%global MasterKey1 MasterKey2 MasterKey3; *so they work outside of the macro; 

%macro create_master(numKeys=); 
    %do master=1 %to &numKeys;    *Outer loop for the MasterKeys we want to make; 
    %let temp=; 
    %do keyiter = 1 %to &master;   *Inner loop for the keys that fall into the MasterKey; 
     %let temp = &temp.&&Key&keyiter.; *&& delays macro variable resolution one time.; 
    %end; 
    %let MasterKey&master.=&temp.; 
    %end; 
%mend create_master; 
%create_master(numkeys=3); 

%put &=MasterKey1 &=MasterKey2 &=MasterKey3; 

Магия здесь &&. В основном, во время разбора макропеременной вы имеете дело с одним или двумя & s за раз. Если это помогает помещать в цикле некоторые операторы %put, чтобы увидеть, как они работают.

Для начала перейдем к концу. На этой итерации &temp=AB&Keyiter=3 и &Key3=C.

0. &temp.&&Key&keyiter 
1. AB&Key3 
2. ABC 

Так от 0 до 1, анализатор видит &temp., период, обозначающее конец одной переменной, поэтому он смотрит на то, что: &temp.=AB и заменяет его с AB. Затем он видит два & s и заменяет их одним &, но не пытается разрешить что-либо с ними. Затем он видит Key, никаких амперсандов там нечего делать. Затем он видит &keyiter, хорошо, замените это 3.

Тогда от 1 до 2, он видит AB, игнорирует его как следует. Затем он видит &Key3 (два амперсанда стали одним не забывать), и теперь он знает, что нужно решить это до C, что и делает - таким образом ABC.

+0

Обратите внимание, что в этом нет ничего «автоматического», потому что SAS не работает таким образом. Вам нужно будет повторно запустить макрос, если его нужно будет заселить (но вы можете сделать это в любое время в основном мгновенно). – Joe

0

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

У меня есть несколько таблиц клиентов и транзакций. Цель состоит в том, чтобы сопоставить/объединить две таблицы на основе типа соответствия + ключевого слова процесса и соответствующих ключей (соответствующие ключи являются полями в таблицах. Инструкции по сопоставлению приведены таблицей, аналогичной таблице внизу. Я пытаюсь построить макрос, содержащий команды соединения на основе определенного типа соответствия и ключа процесса, например, для сопоставления типа = Профиль и Process key = 3, я хочу создать макрос, содержащий строку (ссылка ниже), которая затем может быть отправлена ​​в Proc команда SQL: ]

Table1.Name=Table2.Name 
And Table1.Address=Table2.Address 

]

Я создал макрос для каждого ключа согласования на основе типа соответствия и ключа процесса, и хотел иметь динамическую конкатенацию клавиш [с добавлением «и» текста до второго и последующих ключей]. Проблема, с которой я столкнулась, - нет фиксированного количества совпадающих ключей для любого заданного типа соответствия и ключа процесса.

Matching_Type Process_Key Matching_Keys 
Profile 1 Name 
Profile 1 Address 
Profile 1 Gender 
Market 1 Name 
Market 1 Income 
Profile 2 Name 
Profile 2 Address 
Profile 2 Gender 
Profile 2 DoB 
Profile 2 Phone_Number 
Market 2 Name 
Market 2 Address 
Market 2 Gender 
Market 2 Income 
Market 2 Transaction_Amount 
Market 2 Credit_Card_Number 
Profile 3 Name 
Profile 3 Address 

Решение:

%macro test; 
proc sql noprint; 
select left(put(count(distinct matching_type||left(put(process_key,8.))),8.)) into :num 
from test; 
select distinct matching_type, process_key into :matchkey1 - :matchkey&num, :processkey1-:processkey&num 
from test; 
%do i=1 %to # 
%global &&matchkey&i&&processkey&i; 
select 'table1.'||trim(matching_keys)||' = table2.'||trim(matching_keys) into :&&matchkey&i&&processkey&i separated by ' and ' 
from test 
where matching_type="&&matchkey&i" and process_key=&&processkey&i; 
%end; 
quit; 
%mend; 

options mprint; 
%test; 

%put _user_; 

Большое спасибо всем.