Risultato macro

lucasugar

Utente Junior
Professione: Disegnatore meccanico
Software: GBG
Regione: Lombardia
#1
Salve a tutti,
ho una domanda banale a cui non ho mai trovato risposta.
Se io creo la seguente macro:

DEFINE aaa
LOCAL a
LET a 123
a
END_DEFINE

e poi digito DISPLAY aaa, il programma visualizza 123 (come è giusto che sia).

Se invece digito:

LET b aaa
DISPLAY b

il programma visualizza il seguente errore: *** La macro A non è definita

Qualcuno sa spiegarmi perché alla macro "b" non viene assegnato il valore 123 (che è il valore di "aaa") ?

Grazie
 

painaz

Utente Standard
Professione: ingegnere
Software: proe
Regione: veneto
#2
Te lo dice: ad "b" non riesce ad assegnare il valore "aaa" perchè il sistema non ha la minima idea di cosa sia "aaa".
Se non viene dichiarata come una variabile locale (cioè che esiste solo all'interno di uno spezzone di programma che inizia con DEFINE e muore con END_DEFINE) il programma quando trova una stringa fa questo:

1) controlla se è un comando interno (tipo EDIT_PART, SMASH, INQ_ENV etc etc)
2) controlla se è una macro

Sul vecchio Me10 io facevo così: file macro esporta. Li leggevo tutte le macro non compilate in codice binario, ovvero le macro editabili con notepad. Ed ho imparato, manuali alla mano, a personalizzarmi e programmare Me10

Un altro metodo è aprire il file il file "customize.m": il comando "imput" dice quali macro sono caricate e dove le pesca. Leggendole si impara molto
 

lucasugar

Utente Junior
Professione: Disegnatore meccanico
Software: GBG
Regione: Lombardia
#3
Ciao painaz, grazie per la risposta.
Non mi sono spiegato bene. Se creo la seguente macro:

DEFINE aaa
123
END_DEFINE

digitando DISPLAY aaa, visualizza 123.

digitando:

LET b aaa (dove "aaa" è la macro definita sopra)
DISPLAY b

visualizza sempre 123.

Se creo la macro:

DEFINE aaa
LOCAL a
LET a 123
a
END_DEFINE

digitando DISPLAY aaa, visualizza 123.

digitando:

LET b aaa (dove "aaa" è la seconda macro definita sopra)

visualizza l'errore: *** La macro A non è definita.

Sembra che la funzione LET che in "LET b aaa" vada in conflitto con la funzione LET all'interno della macro "aaa".

In tanti anni ho cercato di capire il perché di questo comportamento che in altri linguaggi di programmazione non si verifica. Se questo è un limite del linguaggio di ME10, continuerò a sviluppare macro che aggirano in qualche modo il problema. Volevo solo sapere se sbaglio qualcosa o se esiste un sistema di cui non sono a conoscenza.

Grazie...
 

cacciatorino

Moderatore SolidEdge
Staff Forum
Professione: Ingegnere meccanico
Software: SolidEdge CoCreate Salome-Meca
Regione: Porto Recanati, ma con l'appennino nel cuore
#4
Se creo la macro:

DEFINE aaa
LOCAL a
LET a 123
a
END_DEFINE

digitando DISPLAY aaa, visualizza 123.

digitando:

LET b aaa (dove "aaa" è la seconda macro definita sopra)

visualizza l'errore: *** La macro A non è definita.

.
Non e' che devi aggiungere

LOCAL b
prima di
LET b

Dico a caso, non conosco l'ambiente di programmazione.
 

lucasugar

Utente Junior
Professione: Disegnatore meccanico
Software: GBG
Regione: Lombardia
#5
Ciao cacciatorino,
anche facendo come da te suggerito, ottengo sempre l'errore: *** La macro A non è definita
Grazie comunque per il tentativo.
 

painaz

Utente Standard
Professione: ingegnere
Software: proe
Regione: veneto
#6
Ma l'istruzione

LOCAL b

è al'interno di un blocco di programma delimitato da

DEFINE
....
END_DEFINE

?

Se mi dici in concreto cosa vuoi fare posso provare a darti una mano.
 

lucasugar

Utente Junior
Professione: Disegnatore meccanico
Software: GBG
Regione: Lombardia
#7
In concreto e in generale vorrei creare macro che contengano la funzione LET e il cui risultato possa essere direttamente assegnato ad un'altra macro con un'altra funzione LET. Cioè:

Se io creo la macro:

DEFINE aaa
123
END_DEFINE

e poi da linea di comando digito DISPLAY aaa, il programma visualizza 123 (che è il valore di "aaa"). E fin qui tutto funziona come deve.

Se da linea di comando digito in sequenza:

LET b aaa (dove "aaa" è la macro definita sopra)
DISPLAY b

il programma visualizza sempre 123 (che è il valore di "aaa" assegnato a "b"). E di nuovo, fin qui tutto OK.

Se creo la macro:

DEFINE aaa
LOCAL a
LET a 123
a
END_DEFINE

e poi da linea di comando digito DISPLAY aaa, il programma visualizza 123 (che è il valore assegnato ad "a" nella macro "aaa"). Ancora, fin qui tutto OK.

Ora, se da linea di comando digito LET b aaa (dove "aaa" è la seconda macro definita sopra), il programma visualizza l'errore "*** La macro A non è definita", invece di assegnare a "b" il valore 123 restituito dalla macro "aaa".

A mio parere questo è un comportamento anomalo: sembra che la funzione chiamante "LET b aaa" vada in conflitto con la funzione "LET a 123" all'interno della macro "aaa".

Ovviamente posso aggirare il problema modificando la macro "aaa" e utilizzando macro globali:

DEFINE aaa
LET macro_result 123
END_DEFINE

poi da linea di comando digito:

aaa
LET b macro_result

e in "b" ho il risultato della macro "aaa". Però mi sembra poco professionale e poco pulito. Io so programmare in altri linguaggi (Lisp di AutoCAD, LPG di GBG, Visual Basic), e con questi linguaggi non ho mai riscontrato problemi di questo genere.

Ora, in particolare, vediamo la seguente macro che all'interno di una stringa sostituisce una sottostringa con un'altra sottostringa:

DEFINE REPLSTR

PARAMETER s
PARAMETER os
PARAMETER ns

LOCAL i
LOCAL s1
LOCAL s2

LET s1 ''

LET s2 s
LOOP
LET i (POS s2 os)
EXIT_IF (i = 0)
LET s1 (s1 + (SUBSTR s2 1 (i - 1)) + ns)
LET i (i + (LEN os))
LET s2 (SUBSTR s2 i ((LEN s2) - i + 1))
END_LOOP

LET s1 (s1 + s2)

LET MACRO_RESULT s1

END_DEFINE

Se da linea di comando digito:

REPLSTR 'pippo' 'p' 'm'

nella macro MACRO_RESULT avrò la stringa 'mimmo'.

Ma se io modificassi la macro in questo modo:

DEFINE REPLSTR

PARAMETER s
PARAMETER os
PARAMETER ns

LOCAL i
LOCAL s1
LOCAL s2

LET s1 ''

LET s2 s
LOOP
LET i (POS s2 os)
EXIT_IF (i = 0)
LET s1 (s1 + (SUBSTR s2 1 (i - 1)) + ns)
LET i (i + (LEN os))
LET s2 (SUBSTR s2 i ((LEN s2) - i + 1))
END_LOOP

LET s1 (s1 + s2)

s1 { <----------------------- voglio restituire direttamente la stringa !!!!!!!!!!!!!!!!!!! }

END_DEFINE

digitando da linea di comando:

DISPLAY REPLSTR 'pippo' 'p' 'm'

il programma visualizza 'mimmo'.

Digitando invece (sempre da linea di comando):

LET b (REPLSTR 'pippo' 'p' 'm')

il programma visualizza l'errore: *** Inserire ')'

Digitando:

LET b REPLSTR 'pippo' 'p' 'm' (stavolta senza parentesi)
DISPLAY b

il programma visualizza: 'pippo'

Io vorrei che digitando:

LET b (REPLSTR 'pippo' 'p' 'm')

la macro "b" contenesse la stringa 'mimmo'.


Spero di essermi spiegato...
 

painaz

Utente Standard
Professione: ingegnere
Software: proe
Regione: veneto
#8
Accidenti se si è spiegato!!!!!

Sono sincero: le sue conoscenze di programmazione Me10 sono sicuramente superiori alle mie.

Anche io mi sono imbattuto in problemi di manipolazione delle stringhe, in particolare avevo questo problema:
dato un assieme salvare tutte le sotto parti esportandole in file dwg. Quindi se ho un assieme con 100 parti dovevo ottenere 100 file dwg, uno per ogni parte.

Il primo problema è stato che se ci sono più parti con lo stesso nome
il comando

STORE DWG nome_parte DEL_OLD File_name

falliva. L'ho risolto assegnando un numero univoco progressivo da "attaccare" al nome della parte per arrivare a una lista parti senza doppioni di nomi

Il secondo problema è quando una parte ha un nome del tipo "pippo |materiale"

perchè con TRIM posso eliminare il carattere " " (stringhe vuote), però non so come eliminare il carattere "|"

E questo non l'ho risolto.

Per ora sono arrivato a questo:

DEFINE mi2dwg
LOCAL X
LOCAL conta
LOCAL parte
LOCAL lista_parti
LOCAL File_name
PB_LTAB_UPDATE
LET lista_parti 'PBT_LTAB'
LET X 1
LET conta 0
LOOP
LET X (X+1)
LET conta (conta+1)
EXIT_IF (X>(LTAB_ROWS lista_parti))
LET Parte (READ_LTAB lista_parti X 2)
EDIT_PART Parte
inq_env 7
LET File_name (INQ 301)
LET File_name (STR File_name+"_"+STR conta)
rename_part File_name
inq_env 7
LET File_name (INQ 301)
STORE DWG File_name DEL_OLD File_name
END_LOOP
END
END
LET messaggio ("esportato in EXPORT")
DISPLAY messaggio
END_DEFINE

Comunque, tornando al suo problema: proverò a darci una occhiata. Sembra un problema di conflitto fra variabili di tipo locale
e globali.

Ma ripeto, lei è sicuramente più esperto di me.
 

painaz

Utente Standard
Professione: ingegnere
Software: proe
Regione: veneto
#9
Stranamente forse ho capito il problema.

Stavo sistemando la macro per salvare le parti in dwg che ho messo nel mio ultimo post.

quindi Me10 carica il file macro

mi2dwg.m (con all'interno la macro mi2dwg)

poi fo fatto una macro (xmi2dwg) che usa le stesse variabili, stesso programma, ho solo aggiunto alla fine alcune istruzioni e salvato tutto nel file

xmi2dwg.m

Me10 le carica tutte e due:

.....
input 'D:\data_ME\macro\cambia_colore.m'
input 'D:\data_ME\macro\mi2dwg.m'
input 'D:\data_ME\macro\xmi2dwg.m'
.....

(dal file customize.m)

l'ho testata, tutto ok. Poi ho rilanciato la macro VECCHIA, giusto per curiosità, macro che ha sempre funzionato e sorpresa...

"*** La macro lista_parti non è definita"

da notare che lista_parti è la prima variabile definita con il comando LET sia nella macro mi2dwg che in xmi2dwg

Il problema sembra essere questo: se ridefinisci una variabile con LET, e questa variabile compare in due macro distinte o due blocchi distinti DEFINE END_DEFINE Me10 non la riconosce più.

Puoi ridefinire una variabile con LET solo all'interno di uno STESSA macro.

Non so se mi sono spiegato.... .... a spiegarlo a parole è un po un casino.
 

lucasugar

Utente Junior
Professione: Disegnatore meccanico
Software: GBG
Regione: Lombardia
#10
Per prima cosa, se ci diamo del tu mi sento più a mio agio.

Forse ho capito male, ma, giusto per provare, ho creato le seguenti macro:

DEFINE mi2dwg
LOCAL lista_parti
LET lista_parti 'PBT_LTAB'
DISPLAY lista_parti
END_DEFINE

DEFINE xmi2dwg
LOCAL lista_parti
LET lista_parti 'PBT_LTAB'
DISPLAY lista_parti
END_DEFINE

Lanciandole entrambe non mi dà nessun errore. Sicuro di non aver omesso qualcosa? O magari usiamo versioni diverse di ME10. Io uso la release 17.0. Anche se sarebbe assurdo se non potessero esistere variabili locali con lo stesso nome all'interno di macro distinte.

Riguardo invece all'univocità dei nomi delle parti, con INQ_PART -> (INQ 302) si ottiene un nome univoco della parte nel formato ~1, ~2, ecc., se ti può servire.

Per l'eliminazione del carattere "|", potresti usare la macro REPLSTR che ho postato in precedenza, modificando la tua macro in questo modo:

...
EDIT_PART Parte
inq_env 7
REPLSTR (INQ 301) "|" ""
LET File_name MACRO_RESULT
...

Tornando al mio problema iniziale, l'ideale sarebbe poter scrivere:

...
EDIT_PART Parte
inq_env 7
LET File_name (REPLSTR (INQ 301) "|" "")
...

Ma è proprio quello che il programma non sembra accettare (mentre in altri linguaggi di programmazione sarebbe del tutto normale).

Una curiostità: nella tua macro mi2dwg ho notato il comando/funzione PB_LTAB_UPDATE. Nella guida non è documentato. Sai dirmi a cosa serve?
 

painaz

Utente Standard
Professione: ingegnere
Software: proe
Regione: veneto
#11
Ciao, l'ho trovata documentata qui:

http://me10macro.awardspace.com/tipstricks.html

in particolare:

You might want to use the function pb_ltab_update to make sure the partstructure of the drawing is updated into the ltab "PBT_LTAB"

"si dovrebbe usare la funzione pb_ltab_update per assicurarsi che la struttura parti contenuta nella tabella PBT_LTAB sia aggiornata"

L'istruzione non sarebbe necessaria nella mia macro, ma può capitare di scrivere macro ove venga manipolata in qualche punto la lista parti e si vuole forzare Me10 ad aggiornarla nel caso siano necessarie manipolazioni successive della lista parti.

Quanto al tuo problema purtroppo non ho soluzioni da suggerire: in effetti l'errore che ho riscontrato non era legato all'uso di variabili con lo stesso nome in macro diverse.

Dai una occhiata al link che ho messo, potrebbe esserti utile.


Io sono fermo alla preistoria (Me10.50), non ho idea se sia un comando valido per le versioni successive.