Domanda Si puo' mantenere il valore di una variabile quando si fa riferimento ad un'altra macro chiamata col CALL.

cromagno

Excel/VBA Expert
Supermoderatore
Expert
9 Agosto 2015
6.544
83
39
Sardegna
2013 (64 bit)
215
mi chiedo e ti chiedo, perchè se utilizzo ByRef devo indicare anche As? perchè se metto Range oppure Variant nulla cambia (almeno credo)
Se usi ByRef, il tipo DEVE corrispondere tra la dichiarazione iniziale e quella dell'argomento che viene passato, pena un errore di runtime. Usando ByVal, invece, si crea una copia della variabile, che può anche essere "convertita" durante il passaggio. Se ad esempio ho una variabile "blnTest" dichiarata nella Sub1 come Boolean, e voglio passarla alla Sub2, posso scrivere:
Sub2(ByVal blnPassata As Long), e nella Sub2 verrà convertita e trattata come Long, ma non:
Sub2(ByRef blnPassata As Long), che genererà un errore di tipo non corrispondente Saluto_saluto
:dubbioso:
in teoria non dovrebbe essere così ma non ho un pc per poter provare quindi mi fido... per adesso ';)
 

FEDERIC4

Utente abituale
17 Dicembre 2017
250
16
TARANTO
2013
1
Ciao a tutti

scossa @scossa
Vedo di "spiegarmelo" meglio il suggerimento.

a) se nelle 3 macro test mettessimo SOLO cellabis come parametro (senza nessun'altra indicazione) vedremmo in A1 (con degli stop opportuni) cambiare il valore da 2 a 4, a 8 e a 10 in quanto, per default, è come se avessimo messo ByRef

b) se nella test e nella test2 come parametro mettessi ByVal cellabis, vedremmo in A1 il dato passare da 2 a 10 (non vedremmo il 4 e l'8)

c) se nella test come parametro mettessi ByVal cellabis as Range e nella test2 mettessi ByVal cellabis as Variant, vedremmo il dato in A1 passare da 2 a 4 e poi a 10 (salta l'8)

d) nulla cambierebbe se in test3 mettessi come parametro SOLO cellabis, oppure ByRef cella bis, oppure ByRef cellabis As Variant, oppure ByRef cellabis As Range (quest'ultimo l'ho inserito per prova).

E' tutto corretto?
Ovvio che si metterà ByVal quando serve ma, mi chiedo e ti chiedo, perchè se utilizzo ByRef devo indicare anche As? perchè se metto Range oppure Variant nulla cambia (almeno credo).

Grazie per la risposta. Ciao,
Mario
Buon giorno a tutti, allego un piccolo esempio di gestione variabili che non funziona , in questo caso come andrebbe impostato il tutto?
 

Allegati

klingklang

Ciappinaro VBA_Expert
Expert
20 Ottobre 2017
4.527
113
42
San Giovanni in Persiceto (BO)
www.excelswissknife.com
2016, 365
302
Di cui, tra l'altro, ho visto che ne avevate già discusso in passato
Le discussioni sul VBA sono poi sempre le stesse... ambito delle variabili, Set Object = Nothing... del resto il linguaggio non presenta novità sostanziali (se non la compatibilità con i nuovi oggetti disponibili) da.... boh, 10 anni? 20 anni?
 

dracoscrigno

CioccaPiatti & VBA Expert
Expert
1 Maggio 2016
3.818
63
office pro 2010
45
Hai dimenticato una cosa fondamentale: i parametri

Non ho tempo di seguire ma...

Non ho toccato l argomentoa byval byref apposta perchè è bene trattarlo a parte e perchè, non riguarda l ambito delle variabili ma quale effetto hanno su di esse, gli effetti sulle stesse, se passati con argomenti via riferimento o via valore...
Ovviamente ricordando che gli oggetti sono SEMPRE via riferimento)
 

scossa

Excel/VBA Expert
Moderatore
Expert
14 Luglio 2015
1.241
48
59
Verona Provincia
scossavr.altervista.org
.
5
... Ovviamente ricordando che gli oggetti sono SEMPRE via riferimento
Non sono d'accordo.
Ti basta provare il codice seguente per capire la differenza tra le due chiamate:
Visual Basic:
Public Sub prova()
  Dim cella As Range

  Set cella = Foglio1.Range("A1")

  cella.Value = 2
  Call test4(cella)
  Debug.Print cella Is Nothing '-> False
  Call test5(cella)
  Debug.Print cella Is Nothing '-> True
End Sub

Public Sub test4(ByVal cellabis As Range)
  Debug.Print cellabis Is Nothing '-> False
  cellabis = 4
  Set cellabis = Nothing
  Debug.Print cellabis Is Nothing '-> True
End Sub

Public Sub test5(ByRef cellabis As Range)
  Debug.Print cellabis Is Nothing '-> False
  cellabis = 8
  Set cellabis = Nothing
  Debug.Print cellabis Is Nothing '-> True
End Sub
Considerando che per default i parametri sono passati ByRef si capisce che dimenticarlo può causare grossi problemi.
 

FEDERIC4

Utente abituale
17 Dicembre 2017
250
16
TARANTO
2013
1
... Ovviamente ricordando che gli oggetti sono SEMPRE via riferimento
Non sono d'accordo.
Ti basta provare il codice seguente per capire la differenza tra le due chiamate:
Visual Basic:
Public Sub prova()
  Dim cella As Range

  Set cella = Foglio1.Range("A1")

  cella.Value = 2
  Call test4(cella)
  Debug.Print cella Is Nothing '-> False
  Call test5(cella)
  Debug.Print cella Is Nothing '-> True
End Sub

Public Sub test4(ByVal cellabis As Range)
  Debug.Print cellabis Is Nothing '-> False
  cellabis = 4
  Set cellabis = Nothing
  Debug.Print cellabis Is Nothing '-> True
End Sub

Public Sub test5(ByRef cellabis As Range)
  Debug.Print cellabis Is Nothing '-> False
  cellabis = 8
  Set cellabis = Nothing
  Debug.Print cellabis Is Nothing '-> True
End Sub
Considerando che per default i parametri sono passati ByRef si capisce che dimenticarlo può causare grossi problemi.
Hai dato un' occhiata a quella macro un po' obsoleta ma funzionante che ho inviato? come posso adattare la tua macro alla mia???
 

FEDERIC4

Utente abituale
17 Dicembre 2017
250
16
TARANTO
2013
1
Hai dato un' occhiata a quella macro un po' obsoleta ma funzionante che ho inviato? come posso adattare la tua macro alla mia???
Ciao,
aperta e chiusa.
Riscrivila in modo leggibile poi se ne parla.
Hai dato un' occhiata a quella macro un po' obsoleta ma funzionante che ho inviato? come posso adattare la tua macro alla mia???
Ciao,
aperta e chiusa.
Riscrivila in modo leggibile poi se ne parla.
 

FEDERIC4

Utente abituale
17 Dicembre 2017
250
16
TARANTO
2013
1
Ciao,
:dubbioso: eppure funizona se non fosse per la perdita del valore delle variabili. Comunque ti ricordo che se mi permetto
di chiedere un aiuto in questo autorevole forum e' proprio perche' non sono un fenomeno nella programmazione.
 

ges

Excel/VBA Expert
Amministratore
Expert
21 Giugno 2015
19.616
133
Como
2011MAC 2016WIN
399
Ciao,
a parte l'interessante discussione che ne è venuta, per il tuo lavoro forse ti stai complicando la vita.

Se i dati ti serve richiamarli per poi usarli da un'altra parte non c'è bisogno di passarli a un'altra procedura per poi richiamarli, basterebbe caricarli in una matrice nella stessa sub routine e poi li usi quando vuoi.

Dovresti spiegare cosa vuoi fare dopo averli tenuti in memoria e forse possiamo trovare una soluzione più idonea allo scopo.
 

dracoscrigno

CioccaPiatti & VBA Expert
Expert
1 Maggio 2016
3.818
63
office pro 2010
45
... Ovviamente ricordando che gli oggetti sono SEMPRE via riferimento
Non sono d'accordo.
Ti basta provare il codice seguente per capire la differenza tra le due chiamate:
Visual Basic:
Public Sub prova()
  Dim cella As Range

  Set cella = Foglio1.Range("A1")

  cella.Value = 2
  Call test4(cella)
  Debug.Print cella Is Nothing '-> False
  Call test5(cella)
  Debug.Print cella Is Nothing '-> True
End Sub

Public Sub test4(ByVal cellabis As Range)
  Debug.Print cellabis Is Nothing '-> False
  cellabis = 4
  Set cellabis = Nothing
  Debug.Print cellabis Is Nothing '-> True
End Sub

Public Sub test5(ByRef cellabis As Range)
  Debug.Print cellabis Is Nothing '-> False
  cellabis = 8
  Set cellabis = Nothing
  Debug.Print cellabis Is Nothing '-> True
End Sub
Considerando che per default i parametri sono passati ByRef si capisce che dimenticarlo può causare grossi problemi.

Scossa... di la verità... mi stai prendendo in giro... Lo vede anche mio nipote di quattro anni che la cella A1 cambia AD OGNI istruzione presente nelle varie routine.
Cosa che non è vera per i tipi di dato semplici (di tipo valore, per l' appunto)
certo, non può notare la sottigliezza della creazione di un nuovo riferimento che punta all' oggetto piuttosto che un riferimento che punta ad un altro riferimento ma si... visti gli esperti che girano qui attorno, direi che si può sorvolare su questa curiosità...


Comunque grazie perchè mi hai rinfrescato su una cosa che ormai avevo preso al contrario: se mi avessero chiesto avrei detto che il default è il ByVal...
comunque.. ritornate in topic che dovreste dare il buon esempio visto che siete i moderatori e qui dentro, il postante, non ci capisce più una sega.
 

FEDERIC4

Utente abituale
17 Dicembre 2017
250
16
TARANTO
2013
1
Ciao,
a parte l'interessante discussione che ne è venuta, per il tuo lavoro forse ti stai complicando la vita.

Se i dati ti serve richiamarli per poi usarli da un'altra parte non c'è bisogno di passarli a un'altra procedura per poi richiamarli, basterebbe caricarli in una matrice nella stessa sub routine e poi li usi quando vuoi.

Dovresti spiegare cosa vuoi fare dopo averli tenuti in memoria e forse possiamo trovare una soluzione più idonea allo scopo.
Ciao,
a parte l'interessante discussione che ne è venuta, per il tuo lavoro forse ti stai complicando la vita.

Se i dati ti serve richiamarli per poi usarli da un'altra parte non c'è bisogno di passarli a un'altra procedura per poi richiamarli, basterebbe caricarli in una matrice nella stessa sub routine e poi li usi quando vuoi.

Dovresti spiegare cosa vuoi fare dopo averli tenuti in memoria e forse possiamo trovare una soluzione più idonea allo scopo.
Si forse hai ragione mi sto intortando in qualcosa che puo' avere una soluzione nella stessa routine in maniera piu' semplice ,cerchero' di postare al piu' presto il programma che sto cercando di creare.
Grazie
 

Sostieni ForumExcel

Aiutaci a sostenere le spese e a mantenere online la community attraverso una libera donazione!