VBS indici lista Array

Dim obj()

se dichiaro un Array vuoto senza indice, come faccio a sapere che l’indice è vuoto?

nel senso se fosse obj(0) con UBound(obj) mi torna la lunghezza dell’indice e posso incrementarlo con:

ReDim Preserve obj(UBound(obj)+1)

qual’é il modo corretto per inizializzare un Array?
debbo inizializzarlo e poi verificare la lunghezza e se vuoto?

Per inizializzare un array come ?
Quanto va lungo questo array ?

Questo è il minimo sindacale …

Dim list()
Redim list(0)

Se ti limiti a dichiarare la matrice senza ridimensionarla la funzione Ubound ti
genera un errore difficile da gestire.

PS: hai abbandonato il C#?

Io di solito negli script usavo il ‘superminimo’ :wink:

redim list( -1 )

Per partire con la array vuota …

Ciao Sergio !

ciao Emilio, Sergio.

eeee questo è la cosa che mi tocca gestire essendo che non conosco la lunghezza essendo variabile

appunto me ne sono accorto, una bella gatta da pelare non pensavo fosse così contorta la cosa

:slight_smile: no non’é questo, il fatto è che ho ripreso un codice fatto agli inizi di quando mi iscrissi qui sul forum
proprio i primi rudimenti che ho imparato grazie a Voi tutti, solo che adesso vedo molte lacune e vorrei modificare un paio di cose, quindi sto cercando di fare mente locale sul funzionamento e su come gestire al meglio la cosa mentre all’epoca ho usato alcune scorciatoie per evitare i vari problemi

comunque tornando alla questione ieri sera sono arrivato a questa conclusione sembra funzionicchia:

ReDim Preserve obj(0)
If VarType(obj(0)) = vbEmpty Then
	obj(0) = Rhino.LastCreatedObjects
Else
	ReDim Preserve obj(UBound(obj) + 1)
	obj(UBound(obj)) = Rhino.LastCreatedObjects
End If

mmmm :thinking: :thinking:

non avevo mai pensato ad una cosa simile. . .

ma poi Emilio come viene gestisci la cosa l’indice -1 viene eliminato?
se ad un’azione incremento il valore, quello iniziale -1 che fine fa?

ps lo so che non ho inserito il Dim prima del ReDim ma dalle prove fatte sembra che non dia problemi

Emilio ho fatto delle prove veloci sembra che non dia problemi :+1:

inizio con:

ReDim obj(-1)

e poi continuio con:

ReDim Preserve obj(UBound(obj) + 1)
obj(UBound(obj)) = Rhino.LastCreatedObjects

alla fine se stampo la lunghezza con Rhino.Print UBound(obj)
parte sempre da 0 l’indice -1 non viene conteggiato

E’ esattamente come facevo io per partire da una array vuota e aggiungere un elemento per volta.
Non esiste nessun elemento (-1).
Redim (-1) genera una array vuota.

2 Mi Piace

Quelle pochissime volte che mi è capitato una situazione del genere ho sempre
preferito non considerare l’elementi ad indice 0 così la funzione ubound
restituisce il numero di elementi considerando il primo elemento utile quello
corrispondente all’indice 1. Riporto un esempio banale: dichiarato un’array
dinamico, si inseriscono a random fino a 10 numeri interi (funzione makeRandom).
La funzione printA crea una stringa contenente i valori contenuti nell’array.

Option Explicit

Sub makeRandom(ByRef a)
	Randomize
	Dim n,i,ub
	n = int(9 * rnd()) + 1
	msgbox "Aggiunti n° " & n & " elementi."
	ub = ubound(a)
	ReDim Preserve a(ub+n)
	For i=1 To n
		a(ub + i) = i
	Next
End Sub

Sub printA(ByRef a, ByRef s)
	s = ""
	Dim i
	If ubound(a) = 0 Then
		s = "La matrice non contiene elementi"
		Exit Sub
	End If
	
	For i=1 To ubound(a) - 1
		s = s & a(i) & " | " 
	Next
	s = s & a(ubound(a))
End Sub

Sub Main()

	Dim s
	Dim a()
	ReDim a(0)
	Call printA(a, s)
	msgbox s
	makeRandom a
	printA a, s
	msgbox s
	makeRandom a
	printA a, s
	msgbox s
	
End Sub

Call Main()
1 Mi Piace

Non che mi ricordi granche’ :wink:.
Ma forse preferivo usare le array in modo ‘standard’ per passarle ai metodi RhinoScript. :thinking:

Comunque …
Ma non aggiungono qualche altro linguaggio per gli script ?
Io inizio a stufarmi dei soliti VBS eccetera.
:wink: :smile:

1 Mi Piace

Emilio, hai mai pensato di creare un linguaggio di programmazione? :smile:

non mi sembra tanto banale anzi anche abbastanza intrecciata come soluzione. . .

Eh, di stupidate ne penso diverse … :smile:.
Ma queste cose e’ meglio lasciarle a chi e’ capace.
Trovo piu’ divertente cercare di capire qualcosa sui linguaggi esistenti. :grinning:

3 Mi Piace

Se mi dici dove non hai compreso il codice te lo spiego volentieri.
Anche in privato.
Ciao!

ciao Sergio,

diciamo che non’é una cosa specifica ma è il codice nel complesso che non vedo il quadro generale
nel senso se scendo riga x riga i comandi li leggo sono semplici ma è il senso complessivo che mi sfugge

Sub printA(ByRef a, ByRef s)

oltre a quanto detto sopra sinceramente, la parte di questo codice mi è un po ostica

Ciao Salvio

Function printA(a)
	Dim i,s
	If ubound(a) = 0 Then
		s = "La matrice non contiene elementi"
		Exit Function 
	End If
	s = ""
	For i=1 To ubound(a) - 1
		s = s & a(i) & " | " 
	Next
	s = s & a(ubound(a))
	printA = s
End Function

Se scritta così dovrebbero esserci meno dubbi. Si dovrà aggiustare anche Main …

Gli argomenti di una Sub (o Function) possono esse i “valori” contenuti nella variabili (ByVal)
oppure riferimenti alle variabili / indirizzi di memoria(ByRef). In vbs ByVal è di default: non
serve scriverlo (vedi di seguito …).

Non essendo un gran estimatore delle Function di vbs sfrutto ByRef.

Function Somma(Valore1,Valore2)
Somma = Valore1+Valore2
End Function

Sub Main()
Dim a,b
a=1
b=2
msgbox Somma(a,b)
End Sub

è equivalente a

Sub Somma(Valore1,Valore2, ByRef Ris)
Ris = Valore1+Valore2
End Sub

Sub Main()
Dim a,b,c
a=1
b=2
Somma a,b,c
MsgBox c
End Sub

All’interno della Sub Somma potresti anche modificare la variabile Valore1 ma
trattandosi di una “copia locale” non avrà nessun effetto sulla variabile a di Main.

A questo punto è lecito chiedersi perché è prevista l’opzione ByVal nonostante sia di default.
Alcune variabili tipo matrici oppure oggetti (istanze di classi) non vengono “bloccate” in
quanto di fatto indirizzi di memoria. Nel caso fosse necessario, si deve forzare in modo
esplicito inserendo ByVal.

Scusa Sergio, a me risulta che in VBS il default per i parametri sia ByRef.
A te no ? :thinking:

1 Mi Piace

Hai ragione … vecchiaia :joy: :joy: :rofl:
Probabilmente ByVal è di default in VB / VB.NET.

1 Mi Piace

ok grazie per le spiegazioni esaustive è sempre buona cosa avere maggiori dettagli su cose che anche se viste mille volte però non si conoscono bene i dettagli :+1:

“valori” contenuti nella variabili (ByVal) su questo ci sono

riferimenti alle variabili / indirizzi di memoria(ByRef). su questa affermazione mi sfugge il concetto
cosa intendi con indirizzi di memoria e che scopo ha?

Salvio
le variabili risiedono in memoria e sono individuate da un indirizzo. ByVal fa una copia dei dati
mentre ByRef trasmette un indirizzo. Con ByVal, alla funzione vengono trasmessi i “dati grezzi”
da elaborare mentre con ByRef deleghi alla funzione l’onere di recuperare (agli indirizzi di memoria)
i dati da elaborare. E qui si apre un mondo … E’ meglio ByVal oppure ByRef? E’ sempre possibile
usare ByVal?

appunto queste sono domande che dopo la tua spiegazione mi sono fatto anch’io, ci sono risposte?

ps in pratica con ByVal e come dire ad una persona vammi a prendere quel faldone, mentre con
ByRef la stessa persona ti dice che quel faldone sta in un dato luogo te lo puoi andare a prendere.
in conclusione che differenza c’e’ nell’uso di ByVal che copia i dati e ByRef che ti indirizza ai dati. . .

E’ ancora più “stretto”: gli dai il faldone di persona.