PDA

View Full Version : [excel] popup o effetto sonoro, se il valore cella è >0


MARCOS_32
04-02-2010, 10:25
ciao ragazzi!
vi scrivo perchè dopo ore di ricerca su google, ancora non ho trovato quello che mi serve.

vengo subito al dunque:
ho diciamo 10 celle di excel contenenti formule che calcolano un valore in base a tutta una serie di dati.
quando una di queste celle assume un valore maggiore di zero, vorrei che comparisse un popup, o in alternativa, venisse eseguito un suono.

Se tutte le 10 celle sono >0 allora appariranno 10 popup

se 5 celle sono >0, allora appariranno 5 popup (e così via)

di "funzioni" in vba che fanno quello che cerco ne ho trovate tante..

il problema che le accomuna è che, se una delle 10 celle è >0, modificando una qualsiasi cella del foglio, il popup appare in continuazione; ovvero

cella a1 >0 (è una delle 10)
appare popup (e fin qui è tutto ok)

se poi vado a scrivere un valore nella B55 (cella a caso), ricompare il popup(e qui non va bene)

se scrivo nella D64 ricompare
se scrivo nella G33 ricompare

e via dicendo...

io invece voglio che il popup compaia SOLO se la cella interessata viene modificata...
mi sono spiegato?



grazie in anticipo

p.s.
escludete la formattazione condizionale, poichè è gia implementata...ma non è sufficiente :)

MarcoGG
04-02-2010, 12:28
Puoi tenere traccia solo della prima volta in cui le celle nell'intervallo desiderato ( nell'esempio "A1:A10" ) cambiano da >0 a <0, ad esempio impostando e poi leggendo la proprietà ID delle celle stesse.

Nell'esempio che ti faccio qui ho 10 celle, appunto, da A1 a A10. Queste celle, come nel tuo caso, contengono formule che calcolano una differenza tra 2 interi ( che ho messo su altre 2 colonne... ), quindi mi appoggio all'evento Worksheet_Calculate() del Foglio1 :

Private Sub Worksheet_Calculate()

Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value > 0 Then
R.ID = ">0"
Else
If R.ID = ">0" Then MsgBox R.Address & " <0 !" 'Pop-Up
R.ID = "<0"
End If
Next R

End Sub

In questo modo il pop-up scatta solo se precedentemente l'ID della cella esaminata era ">0", e poi modifica l'ID stesso in modo che l'alert non venga ripetuto all'infinito... ;)

MARCOS_32
05-02-2010, 09:14
Puoi tenere traccia solo della prima volta in cui le celle nell'intervallo desiderato ( nell'esempio "A1:A10" ) cambiano da >0 a <0, ad esempio impostando e poi leggendo la proprietà ID delle celle stesse.

Nell'esempio che ti faccio qui ho 10 celle, appunto, da A1 a A10. Queste celle, come nel tuo caso, contengono formule che calcolano una differenza tra 2 interi ( che ho messo su altre 2 colonne... ), quindi mi appoggio all'evento Worksheet_Calculate() del Foglio1 :

Private Sub Worksheet_Calculate()

Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value > 0 Then
R.ID = ">0"
Else
If R.ID = ">0" Then MsgBox R.Address & " <0 !" 'Pop-Up
R.ID = "<0"
End If
Next R

End Sub

In questo modo il pop-up scatta solo se precedentemente l'ID della cella esaminata era ">0", e poi modifica l'ID stesso in modo che l'alert non venga ripetuto all'infinito... ;)

Ciao!
prima di tutto grazie per la risposta...

ho provato il codice...ma non funziona come volevo...

ovvero, come dicevi tu, segnala solo il primo cambiamento....mentre a me serve che ad ogni cambiamento del valore della cella, appaia un pop-up.
Ma sopprattutto, mi interessa che scatti il pop-up solo se il valore della cella è maggiore o uguale al valore di un'altra cella.

Che tu sappia non è possibile?

MarcoGG
06-02-2010, 09:55
....mentre a me serve che ad ogni cambiamento del valore della cella, appaia un pop-up.
Ma sopprattutto, mi interessa che scatti il pop-up solo se il valore della cella è maggiore o uguale al valore di un'altra cella.



Semplice. Mettiamo che sia B1 la cella con il valore da confrontare :

Private Sub Worksheet_Calculate()

Dim valoreConfronto As Variant
valoreConfronto = Sheets("Foglio1").Range("B1").Value
Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value >= valoreConfronto And R.ID <> R.Text Then MsgBox R.Address & " Rilevato." 'Pop-Up
R.ID = R.Text
Next R

End Sub

;)

MARCOS_32
08-02-2010, 08:09
Semplice. Mettiamo che sia B1 la cella con il valore da confrontare :

Private Sub Worksheet_Calculate()

Dim valoreConfronto As Variant
valoreConfronto = Sheets("Foglio1").Range("B1").Value
Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value >= valoreConfronto And R.ID <> R.Text Then MsgBox R.Address & " Rilevato." 'Pop-Up
R.ID = R.Text
Next R

End Sub





;)


GRAZIEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE (mi limito a 36 "E" per non essere bannato per spam, in realtà ne vorrei mettere molte di più)


Era esattissimamente quello che cercavo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


mi hai salvato dalla disperazione


grazie ancora!!:D

MarcoGG
08-02-2010, 09:02
GRAZIEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE (mi limito a 36 "E" per non essere bannato per spam, in realtà ne vorrei mettere molte di più)


Era esattissimamente quello che cercavo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


mi hai salvato dalla disperazione


grazie ancora!!:D

Eh eh, ;) , non c'è come spiegarsi chiaro...

MARCOS_32
05-03-2010, 09:25
ehi ciao!
ascolta avrei un piccolo problemino:
il file di excel integra una macro, che a quanto pare va in conflitto col tuo codice.
mi da un errore di runtime (errore 13) quando eseguo la macro.
la macro sostanzialmente è un bottone che permette di inserire dei dati in una tabella.

se serve ti posso passare il file con la macro.

puoi aiutarmi? te ne sarei infinitamente grato :P

MarcoGG
10-03-2010, 09:29
Se è un conflitto, puoi risolvere sostanzialmente in 2 modi :

1. "On Error Resume Next" sul mio codice...

2. Usa una variabile di controllo Boolean. Sarà True per tutta la durata della tua routine, e mentre è True, il mio codice, opportunamente modificato allo scopo, non produrrà effetti. Come ultima istruzione sul tuo pulsante la setti a False...
;)

MARCOS_32
12-03-2010, 18:42
Se è un conflitto, puoi risolvere sostanzialmente in 2 modi :

1. "On Error Resume Next" sul mio codice...

2. Usa una variabile di controllo Boolean. Sarà True per tutta la durata della tua routine, e mentre è True, il mio codice, opportunamente modificato allo scopo, non produrrà effetti. Come ultima istruzione sul tuo pulsante la setti a False...
;)

intanto grazie mille per la risposta

1) non funziona...ho provato a metterlo in svariate posizioni ma non risolve il problema

2) non ho la più pallida idea di come iniziare :P. ho googlato un attimo ed ho trovato il come creare la variabile booleana e setterla in true...ma modificare il tuo codice e fare convivere tutto con la macro non so proprio da che parte girarmi :P



per quanto riguarda invece un effetto sonoro?
cioè al posto del popup viene eseguito un suono...magari da meno problemi... (mi va bene sia un beep sia un suono che ho sul pc..)

ho trovato diversi codici, ma quei pochi che funzionano, fanno emettere il suono OGNI volta che viene modificata una QUALSIASI cella...cosa chiaramente assurda...

sostanzialmente deve fare la stessa identica cosa del tuo codice, ma col suono....magari dico una cavolata, ma potrebbe essere meno problematico....



grazie anticipatamente

MarcoGG
13-03-2010, 13:02
2) non ho la più pallida idea di come iniziare :P. ho googlato un attimo ed ho trovato il come creare la variabile booleana e setterla in true...ma modificare il tuo codice e fare convivere tutto con la macro non so proprio da che parte girarmi :P


Era semplicissimo. Qualcosa come :

Private calcola As Boolean

Private Sub CommandButton1_Click()

calcola = False

'Routine pulsante
'...

calcola = True

End Sub

Private Sub Worksheet_Calculate()

If calcola = False Then Exit Sub

Dim valoreConfronto As Variant
valoreConfronto = Sheets("Foglio1").Range("B1").Value
Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value >= valoreConfronto And R.ID <> R.Text Then MsgBox R.Address & " Rilevato." 'Pop-Up
R.ID = R.Text
Next R

End Sub

In questo modo potevi inibire tutto quanto sta in Worksheet_Calculate() per tutta la durata dell'esecuzione della routine-pulsante, e ripristinarlo subito dopo il termine della stessa...


per quanto riguarda invece un effetto sonoro?
cioè al posto del popup viene eseguito un suono...magari da meno problemi... (mi va bene sia un beep sia un suono che ho sul pc..)

ho trovato diversi codici, ma quei pochi che funzionano, fanno emettere il suono OGNI volta che viene modificata una QUALSIASI cella...cosa chiaramente assurda...

sostanzialmente deve fare la stessa identica cosa del tuo codice, ma col suono....magari dico una cavolata, ma potrebbe essere meno problematico....


Basta che ti limiti a sostituire solo la parte in cui mostri la MsgBox. Ad esempio, uno dei tanti modi per riprodurre un file sonoro, mettiamo un .wav :

> Dichiarazione API :
Private Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long

> Codice precedente modificato :
Private Sub Worksheet_Calculate()

Dim valoreConfronto As Variant
valoreConfronto = Sheets("Foglio1").Range("B1").Value
Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value >= valoreConfronto And R.ID <> R.Text Then sndPlaySound "C:\suono.wav", 1 'Suono
R.ID = R.Text
Next R

End Sub
Con il secondo parametro a "1" su [ sndPlaySound "C:\suono.wav", 1 ], dovrebbe riprodurre il suono in modo asincrono, quindi non interferendo con l'esecuzione di altro eventuale codice VBA...
;)

MARCOS_32
15-03-2010, 12:22
Era semplicissimo. Qualcosa come :


In questo modo potevi inibire tutto quanto sta in Worksheet_Calculate() per tutta la durata dell'esecuzione della routine-pulsante, e ripristinarlo subito dopo il termine della stessa...



il bello è che te ne vieni fuori con un "era semplicissimo" :asd: :asd: :asd:

comunque sia ti ringrazio moltissimo, stassera massimo domani provo e ti faccio sapere :)

MarcoGG
15-03-2010, 17:37
il bello è che te ne vieni fuori con un "era semplicissimo" :asd: :asd: :asd:


:D Beh, dai, niente di che, oggettivamente...

Aggiungo anche un utilizzo ancora più semplice con la funzione Beep, che non richiede alcuna dichiarazione API :

Private Sub Worksheet_Calculate()

Dim valoreConfronto As Variant
valoreConfronto = Sheets("Foglio1").Range("B1").Value
Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value >= valoreConfronto And R.ID <> R.Text Then Beep 'Beep base di Windows
R.ID = R.Text
Next R

End Sub

;)

oruam097
03-04-2010, 14:32
ciao marcogg

di macro e vb non so praticamente nulla e gli ultimi post per me sono arabo.
stavo invece provando a mettere su excel il post del 4/02 delle 13.28 ed ieri in serata mi era anceh riuscito, ma ora non so perchè non sono più in grado.
in pratica faccio così:
dalle celle a1 fino ad a10 ho messo la formula a1= b1-c1 ; a2=b2-c2 e così via.
a quel punto vado su strumenti-macro-vb editor. copio il tuo posto poi salvo e chiudo excel. al riavvio mi chiede se voglio attivare macro, dico di si, ma quando i dati in a1:a10 dovrebbero modificarsi in modo tale da lanciare la pop up, questa popup non compare.
inoltre se nello stesso programma volessi fare una seconda macro che verifica le celle a11:a20, su parametri diversi dalla prima macro, come si potrebbe fare?
grazie mille per ogni risposta e/o suggerimento

MarcoGG
06-04-2010, 09:58
ciao marcogg

di macro e vb non so praticamente nulla e gli ultimi post per me sono arabo.
stavo invece provando a mettere su excel il post del 4/02 delle 13.28 ed ieri in serata mi era anceh riuscito, ma ora non so perchè non sono più in grado.
in pratica faccio così:
dalle celle a1 fino ad a10 ho messo la formula a1= b1-c1 ; a2=b2-c2 e così via.
a quel punto vado su strumenti-macro-vb editor. copio il tuo posto poi salvo e chiudo excel. al riavvio mi chiede se voglio attivare macro, dico di si, ma quando i dati in a1:a10 dovrebbero modificarsi in modo tale da lanciare la pop up, questa popup non compare.


Dipende da come vengono modificati i dati nelle celle soggette a controllo. L'evento Calculate è relativo al foglio. Se non interviene almeno una modifica manuale al contenuto di una cella di quel foglio, l'evento Calculate non viene scatenato. Non conoscendo l'insieme di operazioni che stanno a monte, nel tuo caso, non posso essere più preciso...


inoltre se nello stesso programma volessi fare una seconda macro che verifica le celle a11:a20, su parametri diversi dalla prima macro, come si potrebbe fare?
grazie mille per ogni risposta e/o suggerimento


Ad esempio così :
Private Sub Worksheet_Calculate()

'...
'...
Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If [CONDIZIONE = TRUE] And R.ID <> R.Text Then MsgBox R.Address & " Rilevato." 'Pop-Up
R.ID = R.Text
Next R
For Each R In Sheets("Foglio1").Range("A11:A20")
If [CONDIZIONE = TRUE] And R.ID <> R.Text Then MsgBox R.Address & " Rilevato." 'Pop-Up
R.ID = R.Text
Next R
'...

End Sub

oruam097
07-04-2010, 11:30
ciao marcoGG
grazie mille per la risposta.

in pratica quello che faccio è questo:
vado su macro, scrivo il nome della macro e poi clicco su crea
a quel punto scrivo:
sub macro777_Calculate()

Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value > 0 Then
R.ID = ">0"
Else
If R.ID = ">0" Then MsgBox R.Address & " <0 !" 'Pop-Up
R.ID = "<0"
End If
Next R

End Sub

ora se la cella a1 da positiva diventa negativa, io clicco su alt+f8 poi dò invio dalla tastiera e compare la pop up. io però vorrei che comparisse in automatico al verificarsi di quanto previsto nella macro.
penso dipenda dal fatto ceh tu hai scritto la macro preceduta da PRIVATE.
se per faccio la stessa cosa io, non ritrovo la macro appena creata. è come se non l'avesse salvata. metto tutto nella finestra di visual basic , chiudo il file excel salvandolo, ma poi riapro, faccio in modo che ad esempio, la cella a1 diventi negativa , ma non vedo la pop up. può essere o salto qualcosa di cui non mi rendoconto?

per quanto riguarda il tuo esempio di più macro in una, in pratica se si verifica .la condizione nella cella a1 e poi nella a11 mi compaiono comunque due popup per ciascun evento? allo stesso modo se si verificasse prima nella a11 e poi nella a1?

grazie mille per la risposta, sei stato gentilissimo , un pò di dimestichezza con excel ce l'ho, ma macro e vb sinceramente ne so meno di zero.
spero tu possa essermi anche questa volta di aiuto
buona giornata

MarcoGG
07-04-2010, 12:53
in pratica quello che faccio è questo:
vado su macro, scrivo il nome della macro e poi clicco su crea
a quel punto scrivo:
sub macro777_Calculate()

Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value > 0 Then
R.ID = ">0"
Else
If R.ID = ">0" Then MsgBox R.Address & " <0 !" 'Pop-Up
R.ID = "<0"
End If
Next R

End Sub

...


No. Non ci siamo.
Se crei una Sub "sub macro777_Calculate()", VBA la interpreta come una qualsiasi subroutine, che perciò è slegata dagli eventi predefiniti del WorkSheet. In pratica quel codice non partirà mai in automatico, al verificarsi di un particolare evento, ma solo su esecuzione esplicitamente chiamata dall'utente. Che poi tu ci metta il suffisso _Calculate() non conta nulla.

A questo punto i casi sono 2 :

1. Se, come nel caso dell'utente MARCOS_32, le celle nel Range di studio ( A1:A10 ) contengono Formule ( NON dati puri ) che cambiano valore in risposta ad operazioni che l'utente esegue direttamente sul WorkBook ( il che significa NON per via programmatica ), allora scatta l'evento _Calculate() del Foglio.
In quel caso il tuo codice va messo sotto Private Sub Worksheet_Calculate() :
Private Sub Worksheet_Calculate()

Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value > 0 Then
R.ID = ">0"
Else
If R.ID = ">0" Then MsgBox R.Address & " <0 !" 'Pop-Up
R.ID = "<0"
End If
Next R

End Sub

2. Se invece le celle nel Range di studio ( A1:A10 ) contengono dati puri che cambiano valore sempre in risposta ad operazioni dirette dell'utente, allora Calculate() non scatta più, e dovrai usare Private Sub Worksheet_Change(ByVal Target As Range).

Credo di essere stato chiaro, a livello di manuale direi... :D

oruam097
09-04-2010, 06:52
ciao MarcoGG

sei stato chiarissimo, però io non riesco ad aver questa benedetta macro
se vado su macro devo mettere un nome che voglio dare alla macro.
diciamo che voglio chiamarla macro1. la macro la metto in tutte le cartelle di lavoro.
a quel punto si attiva il tasto crea. clicco su crea e si apre vb.
all'interno scrivo:
Private Sub Worksheet_Calculate()

Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value > 0 Then
R.ID = ">0"
Else
If R.ID = ">0" Then MsgBox R.Address & " <0 !" 'Pop-Up
R.ID = "<0"
End If
Next R

End Sub
a questo punto salvo il foglio excel e lo riapro, ma la macro non esiste.
se invece scrivo:
sub macro777_Calculate()

Dim R As Range
For Each R In Sheets("Foglio1").Range("A1:A10")
If R.Value > 0 Then
R.ID = ">0"
Else
If R.ID = ">0" Then MsgBox R.Address & " <0 !" 'Pop-Up
R.ID = "<0"
End If
Next R

End Sub
allora la macro c'è, ma non lancia la pop up in automatico , ma solo con la combinazione alt+f8 - invio.

tu sei stato perfetto , ma essermi rincretinito d'un botto.....cosa è che sbaglio?
riesci a darmi una dritta ulteriore ?
grazie mille, ciao

MarcoGG
09-04-2010, 08:38
Lascia perdere la creazione guidata delle Macro. Entra direttamente nell'editor di codice di VBA e scrivi nel foglio di codice associato a Foglio1.

oruam097
09-04-2010, 09:25
di te so solo il nickname,
ma per oggi e tutto il fine settimana sei la mia divinità
GRAZIEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE

p.s. a questo punto fatta una pop up devo riuscirne a metterne altre.
se dovessi avere difficoltà ovviamente sai che tornerò a romperti le scatole.
:)

HAVE A NICE DAY

MARCOS_32
12-04-2010, 10:55
MarcoGG hai un pm ;)

oruam097
12-04-2010, 18:30
ciao a tutti.
marco-s/GG

ho una nuova difficoltà.

sto utilizzando il seguente codice:
Private Sub Worksheet_Calculate()
Dim R As Range
For Each R In Sheets("Foglio2").Range("A1")
If Sheets("Foglio2").Range("E1").Value < 0 Then
Sheets("Foglio2").Range("A1").Interior.ColorIndex = 1
Else
Sheets("Foglio2").Range("A1").Interior.ColorIndex = xlColorIndexNone
End If
Next R
For Each R In Sheets("Foglio2").Range("A2")
If Sheets("Foglio2").Range("E2").Value < 0 Then
Sheets("Foglio2").Range("A2").Interior.ColorIndex = 22
Else
Sheets("Foglio2").Range("A2").Interior.ColorIndex = xlColorIndexNone
End If
Next R
quindi accade che, se la cella a1 è negativa diventa nera. se la cella a2 è negativa diventa rosa.
io però vorrei che , quando si verifica un evento sulla cella a2, la cella a1 (anche se il suo evento si è già verificato e dunque è diventata nera) torni ad essere vuota(quindi non deve esserci riempimento)
è possibile fare una roba del genere?

marcoGG, intercedi per me....:)

ps. ma , marcos, pm che sta a significare?
cmq se pm è una buona cosa, buon PM a tutti
buona serata

MARCOS_32
12-04-2010, 21:06
ps. ma , marcos, pm che sta a significare?
cmq se pm è una buona cosa, buon PM a tutti
buona serata


:asd: :asd: :asd: :asd:

PM= private message = messaggio privato:)

buon pm anche a te!
:D

roby841
29-11-2013, 06:03
Ciao a tutti,
Dunque ho un foglio excel con varie matrici di ordine diverso che verranno compilate con numeri diversi, ma ciascuna ha la stessa struttura, ossia le righe e le colonne sono contrassegnate da un numero crescente da 1 a massimo cinaue e quindi i vari elementi della prima riga, ad esempio, sraranno denominati a11, a12, a13,a14 e a15 (per la matrice di ordine massimo).
Vorrei che al termine della compilazione di ciascuna matrice si colorassero di rosso alcune celle e comparisse magari un messaggio in corrispondenza, sulla base di alcune verifiche, ossia:
- se a12>= 1 e a23>=1 allora a13>>1
- se a13>=1 e a34>=1 allora a14>>1
- se a14>=1 e a45>=1 allora a15>>1
- se a23>=1 e a34>=1 allora a24>>1
- se a24>=1 e a45>=1 allora a25>>1
- se a34>=1 e a45>=1 allora a35>>1
Pertanto i valori delle celle a23, a34 e a45 dipende da più di una verifica.
Vi ho fatto l'esempio della matrice di ordine maggiore, ma lo stesso discorso vale anche per quelle di ordine minore, chiaramente con il vantaggio di minori verifiche.
E' possibile realizzare una macro di questo tipo?
Vi ringrazio.