| Worksheet_selectionchange di
Valentina |
Per un foglio excel (foglio1) ho scritto nel
modulo1 dell’editor vb una routine che viene attivata dall’evento
worksheet_selectionchange che ho scritto nel modulo di codice
associato al foglio1. ora, per implementare le funzionalità del mio
foglio excel, ho scritto un’altra routine (anch’essa nel modulo1)
sempre attivata dall’evento worksheet_selectionchange e che ho pure
scritto nel modulo di codice associato al foglio 1 e, praticamente,
sotto al precedente worksheet_selectionchange. nel modulo di
codice associato al foglio1 ho quindi 2 worksheet_selectionchange.
visual basic fa apparire un messaggio di errore “nome non univocoâ€.
a cosa si riferisce? che cosa devo modificare in sostanza? ringrazio
anticipatamente coloro che vorranno aiutarmi. -- valentina
|
|
| di Apoben64 |
| L'errore potrebbe derivare dall'utilizzo del
medesimo codice in un stesso modulo. prova invece usare due moduli e
sub con nomi diversi. |
|
| di Mauro |
Ciao valentina, nello stesso modulo hai definito 2
routine con lo stesso nome e questo non è permesso! non ti è
possibile raggruppare le azioni eseguite nei 2 moduli in un modulo
unico? |
|
| di Valentina |
Nel codice associato al foglio1 ho due routine
(diverse) ma che iniziano entrambe con:
worksheet_selectionchange(byval traget as range). e’ forse
questa “intestazione comune†a creare problemi? nel modulo1, invece,
ho due normali routine completamente diverse, anche nel nome.
ciascuna di queste due ultime routine viene richiamata, sotto
opportune condizioni, da una delle due worksheet_selectionchange di
cui ho detto. se il problema fosse la comune intestazione delle
routine nel codice associato al foglio1, non vedo in quale modo
posso differenziarle. quanto alle altre due, create nel modulo1,
esse sono di per sè assolutamente diverse in tutto, nome compreso.
dov’è il problema? ciao a tutti -- valentina
|
|
| di Big ronnie |
| Ciao valentina, l'unico modo è cercare di
raggruppare il codice in una sola macro worksheet_selectionchange.se
il codice non è molto scrivilo nel post e se possibile lo
sistemiamo.ciao |
|
| di Valentina |
Ringrazio mauro e big ronnie per la disponibilità
offerta. il codice che segue è tratto dalla rielaborazione di alcuni
post apparsi di recente nel sito. in un primo tempo (prima versione)
ho scritto questo codice nel foglio1:
private sub
worksheet_selectionchange(byval target as range) indirizzo = "j"
& range("bh2").text if
activecell.address(rowabsolute:=false, columnabsolute:=false) =
indirizzo then application.run ("macro1") end if end sub
e poi nel modulo1 ho scritto il codice:
sub macro1()
a = range("at35").value dim i as integer for i = 1 to 4
cells(35, 46) = a call macro2 next i end sub
private sub macro2() a = range("at35").value dim n as
byte, start as variant for n = 1 to 10 start = timer do
while timer < start + 1 / 10 loop if n mod 5 = 0 then
cells(35, 46) = "" next n range("at35").formula =
"=at33*(ao5)^2+av33*ao5+ax33" end sub
e tutto ciò
funziona perfettamente senza problemi. vengo al mio problema e
quesito. seguendo il suggerimento che mi avete dato ho
modificato questa procedura così (vedi spazio codice).
quest’ultima procedura esegue tutto correttamente ma rallenta
notevolmente qualsiasi operazione sul foglio. persino il semplice
spostamento con i tastini direzionali da una cella all’altra o
l’immissione di un valore in una cella richiede tempi di attesa.
perchè non accadeva con la prima versione? come posso ottenere lo
stesso risultato senza rallentamenti? grazie di cuore ad entrambi --
valentina
Nel codice del Foglio1:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Indirizzo = "J" & Range("BH2").Text
If ActiveCell.Address(RowAbsolute:=False, ColumnAbsolute:=False) = Indirizzo Then
Application.Run ("Macro1")
ElseIf Range(“L17â€).Value <> ҠThen
Application.Run(“Macro3â€)
End If
End Sub
Nel modulo1:
Sub Macro1()
a = Range("L17").Value
Dim i As Integer
For i = 1 To 4
Cells(17, 12) = a
Call Macro2
Next i
End Sub
Private Sub Macro2()
a = Range("L17").Value
Dim n As Byte, Start As Variant
For n = 1 To 10
Start = Timer
Do While Timer < Start + 1 / 10
Loop
If n Mod 5 = 0 Then Cells(17, 12) = ""
Next n
Range("L17").Formula = "=BK4"
End Sub
Sub Macro3()
a = Range("AT35").Value
Dim i As Integer
For i = 1 To 4
Cells(35, 46) = a
Call Macro4
Next i
End Sub
Private Sub Macro4()
a = Range("AT35").Value
Dim n As Byte, Start As Variant
For n = 1 To 10
Start = Timer
Do While Timer < Start + 1 / 10
Loop
If n Mod 5 = 0 Then Cells(35, 46) = ""
Next n
Range("AT35").Formula = "=AT33*(AO5)^2+AV33*AO5+AX33"
End Sub
| |
|
| di Big ronnie |
Il codice che hai creato va benissimo,forse è
troppo macchinoso.per esempio assegni alla variabile "a" la cella
"l17" e subito dopo assegni alla cella "l17" la variabile "a". ma
questo è la stessa cosa cioè "l17" è "l17".ho provato a semplificare
un pò il tuo codice in modo da farti un esempio diverso di
scrittura.a me funziona tutto perfettamente.per il rallentamento, ad
ogni cambiamento nel foglio devi attendere i lampeggi per poi poter
fare qualsiasi altra operazione. ciao valentina.
Nel Foglio1
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Indirizzo = "J" & Range("BH2")
If ActiveCell = Indirizzo Then Macro1
If Range("L17") <> "" Then Macro3
End Sub
Nel Modulo1
Sub Macro1()
Dim i As Integer
For i = 1 To 4
Call Macro2
Next i
End Sub
Private Sub Macro2()
Dim n As Byte, Start As Variant
For n = 1 To 10
Start = Timer
Do While Timer < Start + 1 / 10
Loop
If n Mod 5 = 0 Then Cells(17, 12) = ""
Next n
Range("L17").Formula = "=BK4"
End Sub
Sub Macro3()
Dim i As Integer
For i = 1 To 4
Call Macro4
Next i
End Sub
Private Sub Macro4()
Dim n As Byte, Start As Variant
For n = 1 To 10
Start = Timer
Do While Timer < Start + 1 / 10
Loop
If n Mod 5 = 0 Then Cells(35, 46) = ""
Next n
Range("AT35").Formula = "=AT33*(AO5)^2+AV33*AO5+AX33"
End Sub
| |
|
| di Valentina |
Ciao big ronnie! grazie per il tempo e l'attenzione
che mi stai dedicando. ho copiato e trascritto scrupolosamente
il tuo codice. funziona tutto ma il rallentamento persiste immutato
anche quando il lampeggiamento non è in atto. fai questa prova.
passando al foglio excel, prova a spostarti velocemente da una cella
all'altra con i tastini direzionali. il rallentamento è notevole
al punto che non è possibile lavorare normalmente con il foglio.
fammi sapere. ciao ronnie. |
|
| di Apoben64 |
Ciao a tutti , penso che per poter velocizzare il
lavoro quando si usano degli eventi sia necessario affidarsi anche
un pò alla teoria. personalemnte ho trovato utile queste
informazioni in questo link:
http://ennius.altervista.org/mike/procedure/mikevba100.htm
in particolare l'uso di "application.enableevents" per evitare
le continue attivazioni dell'evento change . potrebbe essere una
soluzione ai rallentamenti ! un saluto luca
|
|
| di Big ronnie |
| Ciao valentina, a me il rallentamento è dato solo
dal lampeggiare delle celle "l17" e "at35".prova ad accorciare i
tempi del lampeggio diminuendolo da 1/10 ad 1/100 per
esempio.un'altra possibile causa forse potrebbero essere le
caratteristiche del computer.ciao e fammi sapere. |
|
| di Valentina |
Ciao big ronnie. hai provato a spostarti
velocemente con i tastini direzionali in assenza delle condizioni
per far lampeggiare una delle due celle? dovresti vedere che il
rallentamento persiste ugualmente. ho provato a scrivere il
programma su altri computer: stesso risultato. e' normale che
durante il lampeggiamento non si possano eseguire altre operazioni
fino a che esso non termina, ma perchè deve rallentare anche quando
non ci sono le condizioni che richiedono il lampeggio? una cosa che
mi lascia perplessa è che nella prima stesura del programma (prima
versione, vedi post precedenti) il rallentamento non c'è. e ancora,
esistono programmi vba ben più complessi di questo e che nonostante
ciò non danno problemi del genere. credo che apoben64 stia
individuando la strada giusta: manca qualcosa al programma, ma cosa?
un saluto a tutti. -- valentina |
|
| di Apoben64 |
Ciao valentina, mi chiedo del perchè non provi ad
inserire l'istruzione pplication.enableevents che serve proprio
diminuire il rallentamento,o comunque stabilizza l'evento change;
certo è, che come dice big ronnie potrebbe essere anche colpa del
computer considernado che excel contrariamente ad access per
funzionare utilizza la memoria disponibile nel computer.
dimenticavo per l'inserimento dell'istruzione guarda il post
"avvio macro - evento change ". spero che sia quello che cerchi !
un saluto luca |
|
| di Big ronnie |
Ciao valentina,sono ripartito dal tuo primo codice
e devo dirti che così comè digitato non fa funzionare il
lampeggiamento,quindi tutte le azioni che fai sono a velocità
normale.l'errore sta nella sintassi di activecell.address nel
foglio1.se tu togli tutto ciò che sta all'interno delle
parentesi(comprese le parentesi) allora tutto funziona come vorresti
e cioè avviene il lampeggiamento in determinate condizioni e
purtroppo per te anche il rallentamento. p.s.: nel secondo
codice da te digitato ci sono degli apici(vedi scritta "l17" x
esempio) che non fanno funzionare il codice facendo dare messaggio
di errore.ciao,aspetto notizie. |
|
| di Valentina |
Penso che con un esempio molto semplificato
riusciamo ad inquadrare meglio (e forse risolvere) il problema. hai
questa situazione: nel foglio1 di excel hai la cella a1 con la
formula =d1; nella cella d1 hai la formula =se(f1=1;"pippo";" "); la
cella f1 è vuota ed è destinata all'immissione di numeri (1, 2,
...). il codice del foglio1 è: private sub
worksheet_selectionchange(byval target as range) if
range("a1").value <> "" then call lampeggio end if
end sub nel modulo1, invece, hai il codice riportato sotto
(vedi spazio). orbene, in questa situazione si ottiene il
lampeggio ogni volta che digiti "1" in f1 e subito dopo selezioni
un'altra cella qualsiasi. tutto ok, dunque. se provi però a
spostarti da una cella all'altra con i tastini direzionali (anche
non durante il lampeggio) si osserva il notevole rallentamento. io
credo che se riusciamo a risolvere il problema in una situazione
così semplificata sarà poi possibile risolvere situazioni più
complesse. apoben aveva suggerito di utilizzare l'istruzione
enableevents. bene, proviamo a inserirla nella situazione
semplificata, ma dove?. fammi sapere se non ho chiarito
sufficientemente il problema. ciao -- valentina
Sub lampeggio()
a = Range("a1").Value
Dim i As Integer
For i = 1 To 3
Cells(1, 1) = a
Call Flash_Sequence
Next i
End Sub
Private Sub Flash_Sequence()
a = Range("a1").Value
Dim n As Byte, Start As Variant
For n = 1 To 10
Start = Timer
Do While Timer < Start + 1 / 15
Loop
If n Mod 5 = 0 Then Cells(1, 1) = ""
Next n
Range("A1").Formula = "=D1"
End Sub | |
|
| di Big ronnie |
Ciao valentina, ho constatato che ciò che da
fastidio è la formula in "a1" che non permette ad excel il
riconoscimento della cella vuota e quindi il lampeggiamento(di
nulla) avviene comunque ritardando le azioni.potresti ovviare a
questo scrivendo in d1 =se(f1=1;"pippo";se(f1=1;a1=d1;"")),togliere
la formula in a1 e lasciare il codice che hai scritto così
com'è.ciao
|
|
| di Valentina |
| Ciao ronnie! certamente hai avuto una felice
intuizione riguardo alla formula in a1. purtroppo, però, non è
possibile eliminarla perchè in a1 arrivano messaggi dipendenti dal
parametro esistente in f1. in pratica, ad ogni parametro configurato
in f1, a1, collegata con f1, espone un "messaggio" di diverso tipo
(che auspicabilmente dovrebbe lampeggiare). cosi come proponi di
modificare le celle, il messaggio dovrebbe essere posto in a1
direttamente dall'utente mentre in realtà dovrebbe andarci in
automatico in base, come ho detto, la parametro di f1. ciao ronnie.
fammi sapere - valentina |
|
| di Big ronnie |
Ciao valentina, dal tuo esempio si capiva che
"a1" dipendeva dalla cella "d1",comunque sto cercando di
interpretare il tutto e forse credo di aver capito cosa cerchi di
fare.ti invio del codice con 3 esempi di cosa potrebbe valere
"f1",eventualmente fossero di più sitemalo aumentando i case.poi ho
modificato l'ultima riga della macro flash_sequence per evitare di
inserire di nuovo la formula in "a1".se anche questa volta non ci
siamo,fai l'esempio reale di cosa ti serve, evitiamo così la
confusione.ciao.
nel foglio1
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim F1 As Range
Set F1 = Worksheets(1).Range("f1")
If F1 >= 1 And F1 < 4 Then
Select Case F1
Case 1
Worksheets(1).Range("a1") = "A"
Case 2
Worksheets(1).Range("a1") = "B"
Case 3
Worksheets(1).Range("a1") = "C"
End Select
lampeggio
End If
End Sub
nel modulo1
Sub lampeggio()
a = Range("a1").Value
Dim i As Integer
For i = 1 To 3
Cells(1, 1) = a
Call Flash_Sequence
Next i
End Sub
Private Sub Flash_Sequence()
a = Range("a1").Value
Dim n As Byte, Start As Variant
For n = 1 To 10
Start = Timer
Do While Timer < Start + 1 / 15
Loop
If n Mod 5 = 0 Then Cells(1, 1) = ""
Next n
Range("A1") = Range("d1")
End Sub | |
|
| di Valentina |
Ciao big ronnie. ho avuto modo di testare il tuo
codice e...sei big davvero. funziona tutto e senza rallentamenti.
una domanda. e' proprio necessaria la condizione if f1>=1 and
f1<4 ? poichè io non ho queste limitazioni, posso evitarla
senza problemi? ed ancora, ho provato a sostituire
worksheet_selectionchange con worksheet_change (che per me sarebbe
più comodo) ma ottengo la segnalazione "stack di memoria esaurito".
ti viene in mente qualcosa? |
|
| di Big ronnie |
Ciao valentina, il ciclo "if" serve per non
chiamare la macro lampeggio in ogni case, comunque ti invio il
codice senza "if".per quanto riguarda l'evento change ti da errore
perchè ogni lampeggio è un "change",quindi entri in un ciclo
infinito non avendo più la possibilità di fare nilla fino
all'esaurimento della memoria.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim F1 As Range
Set F1 = Worksheets(1).Range("f1")
Select Case F1
Case 1
Worksheets(1).Range("a1") = "A"
lampeggio
Case 2
Worksheets(1).Range("a1") = "B"
lampeggio
Case 3
Worksheets(1).Range("a1") = "C"
lampeggio
End Select
End Sub
| |
|
| di Valentina |
| Capisco. un grazie di cuore, alla prossima! ciao
very big ronnie -- valentina |