[Frage] Smartparts – Best practice – «Übergabe» Array an Subroutine

Schlagworte:
  • Allplan 2019-1
  • Smartparts
  • Array
  • Subroutine
  • RETURN without GOSUB
  • Plugin-Download

Hallo

Welches ist die optimale Methode, um mehrere Arrays nacheinander der gleichen Subroutine zu übergeben?

Versuche ich einen Parameter (Array) einer neuen Temp-Variabel (Array) zuzuweisen, funktioniert die Subroutine an sich. Jedoch erhalte ich beim RETURN-Befehl den Fehler «RETURN without GOSUB».
In der Subroutine hat es keine offenen IF-Abfragen oder FOR-Schleifen. Woher kommt der Fehler?

Weise ich den Parameter (Array), ev. innerhalb einer eigenen Subroutine, mittels FOR-NEXT einer neuen Temp-Variabel zu funktioniert alles wie gewünscht. Dies verkompliziert aber alles enorm. Vor allem wenn in der Subroutine mehrere verschiedenen Arrays verwendet werden.

Alternativ kann man für jeden Parameter eine angepasste Kopie der Subroutine machen.

Welches ist eure Lösung für dieses Problem?

Gruss
Hansruedi

Hello,

Use a subroutine by GOSUB.
If the subroutine is in the same script or in the Master script, the array will be accessible (as if it were a global variable).
RETURN is used here to indicate the end of the subroutine, not to return a result.
___________

Verwenden Sie eine Subroutine von GOSUB.
Wenn sich das Subroutine im selben Skript oder im Master-Skript befindet, kann auf das Array zugegriffen werden (als wäre es eine globale Variable).
RETURN wird hier verwendet, um das Ende des Subroutines anzuzeigen und kein Ergebnis zurückzugeben.


Hello Bertrand

Thank you for your answer. I think you misunderstood my question.

I use a subroutine by GOSUB. But i want to use the same subroutine for different parameters.
I hope the pseudocode shows my question better. What's the best way to call DoCalculation with the different parameters?

Pseudocode:

Dim Para0 = {{100, 200, 300, 400}}
Dim Para1 = {{1, 2, 3, 4}, {10, 10, 10 ,10}}
Dim Para2 = {{11, 12, 13, 14}, {20, 20, 20 ,20}}
Dim Para3 = {{21, 22, 23, 24}, {30, 30, 30 ,30}}

Answer1 = DoCalculation(Para0, Para1)
Answer2 = DoCalculation(Para0, Para2)
Answer3 = DoCalculation(Para0, Para3)

Function DoCalculation (Arr1, Arr2)
   SomeNumbersinBigArray = Some calculations with parameters Arr1 and Arr2
   DoCalculation = SomeNumbersinBigArray
End Function

Hi Hansruedi,

Your code could be this:

DIM Para0 [ ] , Para1 [ ] [ ] , Para2 [ ] [ ] , Para3 [ ] [ ] 
Para0 [ 1 ] = 100 
Para0 [ 2 ] = 200 
Para0 [ 3 ] = 300 
Para0 [ 4 ] = 400 
 
Para1 [ 1 ] [ 1 ] = 1 
Para1 [ 2 ] [ 1 ] = 2 
Para1 [ 3 ] [ 1 ] = 3 
Para1 [ 4 ] [ 1 ] = 4 
Para1 [ 1 ] [ 2 ] = 10 
Para1 [ 2 ] [ 2 ] = 10 
Para1 [ 3 ] [ 2 ] = 10 
Para1 [ 4 ] [ 2 ] = 10 
 
Para2 [ 1 ] [ 1 ] = 11 
Para2 [ 2 ] [ 1 ] = 12 
Para2 [ 3 ] [ 1 ] = 13 
Para2 [ 4 ] [ 1 ] = 14 
Para2 [ 1 ] [ 2 ] = 20 
Para2 [ 2 ] [ 2 ] = 20 
Para2 [ 3 ] [ 2 ] = 20 
Para2 [ 4 ] [ 2 ] = 20 

Para3 [ 1 ] [ 1 ] = 21 
Para3 [ 2 ] [ 1 ] = 22 
Para3 [ 3 ] [ 1 ] = 23 
Para3 [ 4 ] [ 1 ] = 24 
Para3 [ 1 ] [ 2 ] = 30 
Para3 [ 2 ] [ 2 ] = 30 
Para3 [ 3 ] [ 2 ] = 30 
Para3 [ 4 ] [ 2 ] = 30 

DIM ParaA [ ] , ParaB [ ] [ ] 
DIM Answer1 [ ] , Answer2 [ ] , Answer3 [ ] 
ParaA = Para0 
ParaB = Para1 
GOSUB "DoCalculation" 
Answer1 = Result

ParaB = Para2 
GOSUB "DoCalculation" 
Answer2 = Result

ParaB = Para3 
GOSUB "DoCalculation" 
Answer3 = Result

...

END 

"DoCalculation": 
DIM Result [ ] 
SomeNumbersinBigArray = Some calculations with parameters ParaA and ParaB
Result = SomeNumbersinBigArray
RETURN


Hello

Your code works fine.
But if I put the parameter assignment in a separate subroutine, I get the error «RETURN without GOSUB».

Why am I getting this error?

GOSUB "SetPara" 

GOSUB "DoCalculation" 
answer1 = result 

parab = para2 
GOSUB "DoCalculation" 
answer2 = result 

parab = para3 
GOSUB "DoCalculation" 
answer3 = result 

END 

"SetPara": 
DIM para0 [ ] , para1 [ ] [ ] , para2 [ ] [ ] , para3 [ ] [ ] 
para0 [ 1 ] = 100 
para0 [ 2 ] = 200 
para0 [ 3 ] = 300 
para0 [ 4 ] = 400 

para1 [ 1 ] [ 1 ] = 1 
para1 [ 2 ] [ 1 ] = 2 
para1 [ 3 ] [ 1 ] = 3 
para1 [ 4 ] [ 1 ] = 4 
para1 [ 1 ] [ 2 ] = 10 
para1 [ 2 ] [ 2 ] = 10 
para1 [ 3 ] [ 2 ] = 10 
para1 [ 4 ] [ 2 ] = 10 

para2 [ 1 ] [ 1 ] = 11 
para2 [ 2 ] [ 1 ] = 12 
para2 [ 3 ] [ 1 ] = 13 
para2 [ 4 ] [ 1 ] = 14 
para2 [ 1 ] [ 2 ] = 20 
para2 [ 2 ] [ 2 ] = 20 
para2 [ 3 ] [ 2 ] = 20 
para2 [ 4 ] [ 2 ] = 20 

para3 [ 1 ] [ 1 ] = 21 
para3 [ 2 ] [ 1 ] = 22 
para3 [ 3 ] [ 1 ] = 23 
para3 [ 4 ] [ 1 ] = 24 
para3 [ 1 ] [ 2 ] = 30 
para3 [ 2 ] [ 2 ] = 30 
para3 [ 3 ] [ 2 ] = 30 
para3 [ 4 ] [ 2 ] = 30 

DIM paraa [ ] , parab [ ] [ ] 
DIM answer1 [ ] , answer2 [ ] , answer3 [ ] 
paraa = para0 
parab = para1 

RETURN 

"DoCalculation": 
DIM Result [ ] 
SomeNumbersinBigArray = Some calculations with parameters ParaA and ParaB
Result = SomeNumbersinBigArray
RETURN

I will assign the parameters in the main program. And then call the subroutine.

Greetings and thanks

Offensichtlich funktioniert die Zuweisung eines Arrays, welches in einer Subroutine deklariert wurde, zu einem anderen Array nicht!
Das wird den Grund haben, dass man unnötige temporäre Arrays und Kopiervorgänge mit Arrays verhindern will.
Im SmartPart-Script sind alle Variablen global! Auch ein scheinbar "temporäres Array" existiert noch nach dem RETURN!

Statt ein temporäres Array zu erzeugen, die Zuweisungen dort zu machen, und dann am Schluss das temporäre Array in das benötigte Array zu kopieren, sollte man gleich die Zuweisung am globalen Array machen!
Ich sehe da kein Problem, sondern eher eine eingebaute "Hilfe", um zu viele temporäre Arrays und deren unnötiges Kopieren zu vermeiden.

Man könnte die Zuweisung der Ergebnisse nach dem RETURN machen:

!Deklaration der Ergebnis-Arrays
DIM paraa [ ] , parab [ ] [ ]

!Berechnen der Werte : Ergebnisse in para0,para1
GOSUB "SetPara" 

!Zuweisung der Ergebnisse
paraa = para0 
parab = para1

END 

"SetPara": 
DIM para0 [ ]
DIM para1 [ ] [ ]
para0 [ 1 ] = 100 
para0 [ 2 ] = 200 
para0 [ 3 ] = 300 
para0 [ 4 ] = 400 

para1 [ 1 ] [ 1 ] = 1 
para1 [ 2 ] [ 1 ] = 2 
para1 [ 3 ] [ 1 ] = 3 
para1 [ 4 ] [ 1 ] = 4 
para1 [ 1 ] [ 2 ] = 10 
para1 [ 2 ] [ 2 ] = 10 
para1 [ 3 ] [ 2 ] = 10 
para1 [ 4 ] [ 2 ] = 10 

RETURN

oder gleich das eigentliche Array zum Setzen der Werte benutzen:

!Deklaration der Ergebnis-Arrays
DIM paraa [ ] , parab [ ] [ ]

!Berechnen der Werte
GOSUB "SetPara" 

END 

"SetPara": 
paraa [ 1 ] = 100 
paraa [ 2 ] = 200 
paraa [ 3 ] = 300 
paraa [ 4 ] = 400 

parab [ 1 ] [ 1 ] = 1 
parab [ 2 ] [ 1 ] = 2 
parab [ 3 ] [ 1 ] = 3 
parab [ 4 ] [ 1 ] = 4 
parab [ 1 ] [ 2 ] = 10 
parab [ 2 ] [ 2 ] = 10 
parab [ 3 ] [ 2 ] = 10 
parab [ 4 ] [ 2 ] = 10 

RETURN

Das produziert ein sehr viel kürzeres Script, und spart zwei Arrays ein!
Die Anzahl der Variablen/Array wirkt sich auch auf das Laufzeitverhalten aus, denn jede Variable muss anhnd ihres Names erst mal im Variablen-Speicher gesucht werden. Das dauert bei steigender Anzahl von Variablen zunehmend länger!

Zitiert von: Nemo
Statt ein temporäres Array zu erzeugen, die Zuweisungen dort zu machen, und dann am Schluss das temporäre Array in das benötigte Array zu kopieren, sollte man gleich die Zuweisung am globalen Array machen!

Wie kann ich mit dieser Methode die gleiche Subroutine mit verschiedenen Parametern aufrufen?

!Deklaration der Arrays
DIM aa [ ] , bb [ ] [ ]

!Deklaration der Sub - Arrays
DIM sub1 [ ]
DIM sub2 [ ] [ ]


!Laden der Sub - Arrays
sub1=aa
sub2=bb

!Berechnen der Werte : Ergebnisse in sub1,sub2
GOSUB "SetPara" 

!Abholen der Ergebnisse
aa = sub1 
bb = sub2



DIM cc [ ] , dd [ ] [ ]

!Laden der Sub - Arrays
sub1=parac
sub2=parad

GOSUB "SetPara" 

!Abholen der Ergebnisse
cc = sub1 
cc = sub2

END 

"SetPara": 

sub1 [ 1 ] = 100 
sub1 [ 2 ] = 200 
sub1 [ 3 ] = 300 
sub1 [ 4 ] = 400 

sub2 [ 1 ] [ 1 ] = 1 
sub2 [ 2 ] [ 1 ] = 2 
sub2 [ 3 ] [ 1 ] = 3 
sub2 [ 4 ] [ 1 ] = 4 
sub2 [ 1 ] [ 2 ] = 10 
sub2 [ 2 ] [ 2 ] = 10 
sub2 [ 3 ] [ 2 ] = 10 
sub2 [ 4 ] [ 2 ] = 10 

RETURN