Recentemente ho ereditato un programma SAS che sembra qualcosa di simile:Perché l'utilizzo di CALL EXECUTE per eseguire un errore di macro quando viene eseguito direttamente funziona?
%MACRO ComplicatedStuff(GroupId=);
%LET FileId = %SYSFUNC(OPEN(Work.BigDataSet));
%PUT 'Doing something really difficult with ' &GroupId.;
%LET CloseRC = %SYSFUNC(CLOSE(&FileId.));
%MEND ComplicatedStuff;
%ComplicatedStuff(GroupId=ABC1);
%ComplicatedStuff(GroupId=DEF2);
%ComplicatedStuff(GroupId=3GHI);
%ComplicatedStuff(GroupId=J4KI);
Essendo un programmatore multi-sfaccettato, ho guardato questo e ho pensato "sicuramente posso fare questo un almeno un po 'più dinamico". Certo, basta, sono stato in grado di sviluppare quello che pensavo fosse una soluzione semplice utilizzando CALL EXECUTE
:
DATA Work.IDs;
INPUT ID $4.
;
DATALINES;
ABC1
DEF2
3GHI
J4KI
RUN;
DATA Work.CommandDebug;
SET Work.IDs;
Command = CATS(
'%ComplicatedStuff(GroupId=', ID, ');'
);
CALL EXECUTE(Command);
RUN;
ero felice con questa soluzione fino a quando venne il momento di FTP i file generati da ComplicatedStuff a un server diverso. Il nostro server SAS è in esecuzione su Unix e gli amministratori SAS hanno creato una piccola macro utile per chiamare %sas_sftp
(perché, mi è stato detto, il codice x
diventa davvero brutto). Purtroppo, non posso pubblicare il codice %sas_sftp
- appartiene alla mia azienda e non credo che lo vogliano su SO.
ho tentato di chiamare la macro %sas_sftp
proprio come avevo chiamato il %ComplicatedStuff
macro (sia come seconda CALL EXECUTE
all'interno dello stesso passo dei dati, e in un secondo tempo i dati), ma solo il primo file (circa 30) sarebbe fallo arrivare a destinazione. Quando ho guardato il log, sembrava che la seconda macro iniziasse ad essere eseguita prima che il ftp fosse finito (il ftp pipe, o qualunque cosa fosse, non era stato rilasciato prima del successivo ftp), quindi i successivi ftp stavano semplicemente fallendo silenziosamente a causa di indisponibilità delle risorse (presumo).
Ho pensato che EXECUTE avrebbe praticamente accodato le mie macro chiamate e poi le avrebbe eseguite come se fossero disposte sequenzialmente nel codice (come erano originariamente) - una alla volta. Chiaramente sta succedendo qualcos'altro perché, mentre il primo approccio sopra ha funzionato senza problemi, la mia soluzione dinamica ha fallito. Ho versato lo CALL EXECUTE: How and Why e lo SAS documentation, ma temo di non capire di cosa stanno parlando.
Alla fine ho trovato un lavoro (o meglio, un collega ne ha trovato uno) che ho postato sotto come una "risposta", ma mi piacerebbe davvero che qualcuno spiegasse la funzione ESEGUI e come funziona.
Perché il mio primo tentativo, utilizzando CALL EXECUTE
, non funziona?
Non è chiaro dalla domanda in cui si trova il problema. Hai detto che stai provando ad eseguire quest'altra macro '% sas_sftp' ma non la mostri nel tuo codice. Stai cercando di aggiungere un secondo 'CALL EXECUTE' allo stesso passo di dati o hai un secondo passo di dati che esegue solo la parte'% sas_sftp'? E a proposito, ho anche una macro utility con lo stesso nome! Il problema potrebbe essere esattamente ciò che sta facendo la macro. Non penso che la mente possa essere eseguita con 'CALL EXECUTE' o perché crea ed esegue uno script' expect'. – BellevueBob
@BellevueBob - Non riesco a pubblicare la macro sas_sftp, in parte perché non ho accesso al codice e in parte perché non è mia da pubblicare su un forum pubblico. Ho provato ad aggiungere un secondo 'CALL EXECUTE' al passaggio dei dati. Quando ciò non ha funzionato, ho provato un secondo passaggio DATA _NULL_. Stesso risultato in entrambi i casi. – JDB
In realtà speravo di vedere un esempio del codice che stavi usando che aveva l'errore, non la stessa macro. La risposta potrebbe essere semplice come utilizzare la funzione macro '% nrstr' durante la chiamata. In altre parole, mostri il codice che funziona ma non mostra ciò che non funziona. – BellevueBob