Excel - attivare macro da una cella

Asked By Pino on 25-Jul-10 08:46 AM
Ho un foglio excel che utilizzo per stampare gli indirizzi sulle buste e
sulle ricevute A.R.

Il foglio è composto da 25 righe per altrettanti nominativi  e nelle varie
celle inserisco

cognome, nome, indirizzo, località, cap e un particolare codice.

La cella del cap è bloccata perché è compilata con la funzione cerca.vert
che preleva

i dati da un elenco di tutti i comuni italiani posto in un altro foglio.

Il problema sorge quando la località è una città che non ha un unico cap

(come Roma, Milano ecc) che, nell'elenco in questione, sono indicate con

il loro codice generico: per Roma 00100, per Milano 02100 ecc

Vorrei in questo caso che compaia un avviso che segnali la circostanza e che

consenta di digitare il cap effettivo, se è conosciuto, o di inserire quello
generico.

L'elenco delle 41 città con più cap è posto nello stesso foglio di tutti gli
altri comuni.

Ho provato a creare una macro attivata dal valore delle varie celle località
ma non ci sono riuscito-

Grazie per il vostro aiuto.




giovanna replied to Pino on 25-Jul-10 05:12 AM
Il 7/25/2010, Pino ha detto :
ciao,
senza macro, ti va bene una formattazione condizionale?
Dopo aver definito un nome per l'elenco dei 41 comuni (es. elenco),
potresti utilizzare la formula (in formattaz. condizionale,
selezionando la colonna dei CAP):
=CONTA.SE(elenco;D1)  (se colonna D i CAP)
e scegli il formato...

--
ciao
giovanna
.......................
www.riolab.org
.........................
Pino replied to giovanna on 25-Jul-10 09:41 AM
Grazie per la risposta ma, probabilmente sono stato poco chiaro.
Il foglio è protetto e la cella del cap è bloccata per consentire il salto
automatico alla cella successiva.
Inoltre nell'avviso che desidero compaia deve essere riportato anche il
codice generico della città in quanto chi inserisce i dati potrebbe non
conoscere anche quello.
giovanna replied to Pino on 25-Jul-10 05:59 AM
Nel suo scritto precedente, Pino ha sostenuto :


Ah, vero. Sul fatto della cella bloccata ho scordato di commentare,
volevo suggerire di sbloccare...
Ma, c'? qualcosa che non comprendo. Tu dici:


Dunque CERCA:VERT() la "compila"!
Chi inserisce i dati quindi, che deve fare?
Io pensavo: cella non bloccata --> avviso (cella formattata)--> SE
conosciuto il codice specifico, immissione corretta, Se no, lasciare
generico (trovato da CERCA.VERT())
Ma evidentemente qualcosa mi sfugge ancora!

--
ciao
giovanna
.......................
www.riolab.org
.........................
Pino replied to giovanna on 25-Jul-10 10:09 AM
Grazie per la risposta ma, probabilmente non sono stato chiaro.
Il foglio è protetto e la cella è bloccata per consentire il salto
automatico alla cella successiva.
Inoltre, nell'avviso che vorrei, deve essere riportato anche
il cap generico della città in quanto chi inserisce i dati potrebbe
non conoscere anche quello.
Pino replied to giovanna on 25-Jul-10 10:17 AM
Ciao Giovanna
Cerco di chiarire meglio.
Per ogni riga dopo aver inserito nome cognome, indirizzo inserisco la città,
poiché la cella del CAP è bloccata, se CERCA.VERT trova il dato lo
inserisce automaticamente e salta alla cella successiva.
Io vorrei che, se la città inserita è una di quelle 41 con più cap zonali,
compaia un avviso che riporti in ogni caso il CAP generico e consenta
di lasciarlo invariato o di anche di modificarlo e di inserirlo nella cella.
Grazie.
giovanna replied to Pino on 25-Jul-10 06:27 AM
Pino ci ha detto :

mmm, quindi la tabella su cui "cerca" CERCA.VERT() NON contiene i CAP
delle 41 citt??
Le cose devono stare per forza cos??
Io comunque suggerirei, se puoi, di mostrare un fac simile del file,
caricandolo in un server free file hosting.

--
ciao
giovanna
.......................
www.riolab.org
.........................
Pino replied to giovanna on 25-Jul-10 10:30 AM
Lo farei volentieri ma non so proprio come farlo.
Puoi darmi delle indicazioni?
Grazie
Pino
Scossa replied to Pino on 25-Jul-10 07:36 AM
o cap
che
uello

Questo esempio fa pi=F9 o meno quello che chiedi:

In foglio2  citt=E0 cap e campo UNICO (VERO =3D solo un cap, FALSO =3D citt=
=E0
con pi=F9 cap)

CITTA	CAP	    UNICO
TRENTO	38100	VERO
VERONA	37100	FALSO
VICENZA	36100	VERO

Selezioni i dati escluso la riga di intestazione ed attribuisci il
nome CAP

in C4 la seguente formula:

=3DSE(CERCA.VERT(B4;CAP;3;0);CERCA.VERT(B4;CAP;
2;0);DIGITA(CERCA.VERT(B4;CAP;2;0)))

quando digiti in B4 una citt=E0 (p.e. verona) con UNICO=3DFALSO ti viene
chiesto di digitare il cap.

Ovviamente i riferimenti delle celle li cambi con i tuoi.

Se non vuoi usare il nome (CAP) devi sostituirlo con i riferimenti ai
dati delle citt=E0:
ad esempio Foglio2!$A$4:$C$50.

Questo il codice da inserire in un modulo standard:

'----------------------
' in un modulo standard

Option Explicit

Public Function Digita(ByVal sCAP As String) As Long 'String

Do
sCAP =3D Application.InputBox("digitare il CAP di zona: ", _
Loop While IsNumeric(sCAP) =3D False
Digita =3D CLng(sCAP)

End Function

'----------------------

Fai sapere se hai risoloto, grazie.

Bye!
Scossa
giovanna replied to Pino on 25-Jul-10 07:55 AM
Il 7/25/2010, Pino ha detto :

Risolverai con il suggerimento di Scossa.
Per caricare dei file da condividere, ad es:
http://www.megaupload.com/
e poi metti qui il link per il download

--
ciao
giovanna
.......................
www.riolab.org
.........................
Pino replied to Scossa on 25-Jul-10 04:58 PM
Questo esempio fa più o meno quello che chiedi:

In foglio2  città cap e campo UNICO (VERO = solo un cap, FALSO = città
con più cap)

CITTA CAP     UNICO
TRENTO 38100 VERO
VERONA 37100 FALSO
VICENZA 36100 VERO

Selezioni i dati escluso la riga di intestazione ed attribuisci il
nome CAP

in C4 la seguente formula:

=SE(CERCA.VERT(B4;CAP;3;0);CERCA.VERT(B4;CAP;
2;0);DIGITA(CERCA.VERT(B4;CAP;2;0)))

Questo il codice da inserire in un modulo standard:

Option Explicit

Public Function Digita(ByVal sCAP As String) As Long 'String

Do
sCAP = Application.InputBox("digitare il CAP di zona: ", _
Loop While IsNumeric(sCAP) = False
Digita = CLng(sCAP)

End Function

Grazie Scossa.
Ho provato il tuo codice in un foglio inserendo sola una riga e tutto
funziona.
Però quando lo inserisco nel mio foglio e digito una città con più cap il
programma si blocca e mi richiede sempre di inserire un cap.
Seguendo il suggetrimento di Giovanna, se vuoi, poi scaricare il mio file a
cui
ho eliminato  le altre macro che mi servono per la stampa delle buste.
Grazie
http://www.megaupload.com/?d=4NGP52QU
Scossa replied to Pino on 25-Jul-10 02:52 PM
cap il

Il problema =E8 nella routine che usi all'evento _change().

Sostituisci il codice della sub Digita() con questo:

'---------------------
Public bMore

Public Function Digita(ByVal sCAP As String) As Long 'String
If Not bMore Then
Do
sCAP =3D Application.InputBox("digitare il CAP di zona: ", _
Loop While IsNumeric(sCAP) =3D False
Digita =3D CLng(sCAP)
End If

End Function
'---------------------------


E sostituisci il codice di WorkSheet_Change() con questo:

'----------------------
Private Sub WorkSheet_Change(ByVal Target As Range)
Dim v As Variant, c As Long
If Not Intersect(Target, Range("A:D")) Is Nothing Then
v =3D Target.Cells(1, 1).Value
bMore =3D False
If Not IsEmpty(v) Then
Application.EnableEvents =3D False
v =3D StrConv(v, 3): c =3D InStr(1, v, "'"): If c > 0 And c < Len(v)
Then _
Mid(v, c + 1, 1) =3D UCase(Mid(v, c + 1, 1))
' trasforma in maiuscolo la prima lettera di ogni parola
'v =3D StrConv(v, 1) ' trasforma in maiuscolo
'v =3D StrConv(v, 2) ' trasforma in minuscolo
'v =3D UCase((Left(v, 1))) & LCase(Right(v, Len(v) - 1))
' trasforma in maiuscolo solo la prima lettera della prima
parola
Target.Cells(1, 1).Value =3D v
bMore =3D True
Application.EnableEvents =3D True
End If
End If
End Sub
'-------------------------


Bye!
Scossa
Pino replied to Scossa on 25-Jul-10 10:47 PM
Ho modificato le due routine ma c'è un ancora un problema.
Sempre quando inserisco una città con CAP multizona devo digitare due volte
il CAP
per far sparire il messaggio di avviso e proseguire con i dati.
Grazie per la tua cortesia.
Pino
Scossa replied to Pino on 26-Jul-10 03:03 AM
Allora, visto che gi=E0 usi le macro, cambiamo completamente.

Elimina la macro Digita() e la variabile public bMore.

Elimina dalla colonna dei cap tutti i cerca.vert.

Sostituisci il codice dell'evento _change con questo:

Private Sub WorkSheet_Change(ByVal Target As Range)
Dim cella As Range

For Each cella In Target
If Not Intersect(cella, Range("A:D")) Is Nothing Then
Dim v As Variant, c As Long
Dim rngCap As Range
Dim bUn As Boolean
With cella
v =3D .Value
If v <> "" Then
Application.EnableEvents =3D False
v =3D StrConv(v, 3)
c =3D InStr(1, v, "'")
If c > 0 And c < Len(v) Then
Mid(v, c + 1, 1) =3D UCase(Mid(v, c + 1, 1))
End If
.Value =3D v
If Not Intersect(cella, Range("D:D")) Is Nothing Then
Set rngCap =3D Range("CAP").Find(What:=3D.Value, _
After:=3DRange("CAP").Cells(1, 1), LookIn:=3DxlValues, _
LookAt:=3DxlPart, SearchOrder:=3DxlByColumns, _
SearchDirection:=3DxlPrevious, MatchCase:=3DFalse)
If Not rngCap Is Nothing Then
bUn =3D rngCap.Offset(0, 2)
.Parent.Unprotect
.Offset(0, 1) =3D rngCap.Offset(0, 1)
If Not bUn Then
.Offset(0, 1) =3D _
Application.InputBox("digitare il CAP di zona: ", _
End If
.Parent.Protect
Else
'.Offset(0, 1) =3D ""
End If
End If
Application.EnableEvents =3D True
End If
End With
End If
Next cella
End Sub


Eventualmente puoi migliorare la gestione della protezione del foglio,
usando il metodo userinterfaceonly.

Bye!
Scossa
Scossa replied to Scossa on 26-Jul-10 08:18 AM
Meglio questo:


Private Sub WorkSheet_Change(ByVal Target As Range)
Dim cella As Range

For Each cella In Target
If Not Intersect(cella, Range("A:D")) Is Nothing Then
Dim v As Variant, c As Long
Dim rngCap As Range
Dim bUn As Boolean
With cella
v = .Value
If v <> "" Then
Application.EnableEvents = False
v = StrConv(v, 3)
c = InStr(1, v, "'")
If c > 0 And c < Len(v) Then
Mid(v, c + 1, 1) = UCase(Mid(v, c + 1, 1)) ' trasforma in
maiuscolo la prima lettera di ogni parola
End If
.Value = v
If Not Intersect(cella, Range("D:D")) Is Nothing Then
Set rngCap = [CAP].Find(What:=.Value, _
After:=[CAP].Cells(1, 1), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, MatchCase:=False)
.Parent.Unprotect
If Not rngCap Is Nothing Then
bUn = rngCap.Offset(0, 2)

.Offset(0, 1) = rngCap.Offset(0, 1)
If Not bUn Then
.Offset(0, 1) = _
Application.InputBox("digitare il CAP di zona: ", _
End If
Else
.Offset(0, 1) = _
Application.InputBox("digitare il CAP di zona: ", _
End If
.Parent.Protect
End If
Application.EnableEvents = True
End If
End With
End If
Next cella
End Sub



Bye!
Scossa
Pino replied to Scossa on 26-Jul-10 06:05 PM
Spero di non arrecarti troppo disturbo ma c'è ancora un problema.
Ho sostituito la routine come mi hai consigliato però la ricerca dei
CAP in alcuni casi dà risultati errati.
In verità anche la precedente dava lo stesso problema:
Quando il nome della citàà inserita è contenuto anche nel nome di altra
città
viene prelevato il CAP errato.
Mi spiego: se inserisco Bari restituisce il CAP di Sibari, la stessa cosa se
inserisco ROMA, viene dato il CAP di Cervara di Roma; con Verona segnala
il CAP di Villafranca di Verona.
Ti mando il link del file che contiene tutti i cap dei comuni italiani
Attendo fiducioso.
Ancora grazie.
Pino


http://www.megaupload.com/?d=LUQ24SSG
Scossa replied to Pino on 26-Jul-10 03:51 PM
Hai ragione, sostituisci in:

Set rngCap = [Cap].Find(What:=.Value, _
After:=[Cap].Cells(1, 1), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, MatchCase:=False)

LookAt:=xlPart

con

LookAt:=xlWhole


Bye!
Scossa
Pino replied to Scossa on 27-Jul-10 04:26 PM
Perfetto tutto funziona.
Grazie.
Se posso approfittare ancora della tua cortesia ti chiedo è possibile far
apparire un messaggio, tipo quello che hai creato per i CAP multizona,
quando non viene trovato il CAP.
Così da poterlo inserire manualmente
Ciao
Scossa replied to Pino on 27-Jul-10 01:39 PM
ar

L'ultima versione che avevo postato lo faceva gi=E0, comunque riposto il
codice:

Private Sub WorkSheet_Change(ByVal Target As Range)
Dim cella As Range

For Each cella In Target
If Not Intersect(cella, Range("A:D")) Is Nothing Then
Dim v As Variant, c As Long
Dim rngCap As Range
Dim bUn As Boolean
With cella
v =3D .Value
If v <> "" Then
Application.EnableEvents =3D False
v =3D StrConv(v, 3)
c =3D InStr(1, v, "'")
If c > 0 And c < Len(v) Then
Mid(v, c + 1, 1) =3D UCase(Mid(v, c + 1, 1))
' trasforma in maiuscolo la prima lettera di ogni parola
End If
.Value =3D v
If Not Intersect(cella, Range("D:D")) Is Nothing Then
Set rngCap =3D [Cap].Find(What:=3D.Value, _
After:=3D[Cap].Cells(1, 1), LookIn:=3DxlValues, _
LookAt:=3DxlWhole, SearchOrder:=3DxlByColumns, _
SearchDirection:=3DxlPrevious, MatchCase:=3DFalse)
.Parent.Unprotect
If Not rngCap Is Nothing Then
bUn =3D rngCap.Offset(0, 2)

.Offset(0, 1) =3D rngCap.Offset(0, 1)
If Not bUn Then
.Offset(0, 1) =3D _
Application.InputBox("digitare il CAP di zona: ", _
End If
Else
.Offset(0, 1) =3D _
Application.InputBox("digitare il CAP di zona: ", _
End If
.Parent.Protect
End If
Application.EnableEvents =3D True
End If
End With
End If
Next cella
End Sub


Bye!
Scossa
Pino replied to Scossa on 29-Jul-10 06:11 PM
L'ultima versione che avevo postato lo faceva già, comunque riposto il
codice:
Hai assolutamente ragione.
Grazie di tutto.
Pino
Scossa replied to Pino on 29-Jul-10 03:19 PM
Grazie a te per il riscontro.

Bye!
Scossa