Concatenare con una condizione
Hai un problema con Excel? 
Concatenare con una condizione
di gius_87 (utente non iscritto) data: 09/07/2013 12:06:15
Ciao a tutti,
io ho una funzione che permette di concatenare tutte le celle di un intervallo di dati (vedi sotto).
Volevo chiedere, qualcuno sa se sia possibile aggiungere delle condizioni al concatenamento?
Mi spiego meglio, ora la funzione è del tipo:
=unisci('intervallo')
mi chiedo se fosse possibile renderla del tipo
=unisci.se('intervallo da concatenare';'intervallo criterio';'criterio')
in modo tale che il criterio possa essere preso anche da una colonna adiacente.
Grazie mille a tutti dell'attenzione
Function unisci(B As Range)
Dim A
For i = 1 To B.Cells.Count
If B(i).Value <> "" Then
A = A & B(i).Value
End If
Next
unisci = Left(A, Len(A))
End Function |
di Vecchio Frac data: 09/07/2013 13:37:05
Se crei una funzione personalizzata, dentro puoi farci quello che vuoi, e pilotare col codice tutte le operazioni che desideri (utilizzando la sintassi corretta: il punto non è ammesso nei nomi di routine VBA perchè è un carattere speciale e si usa per fare altro).
di gius_87 (utente non iscritto) data: 09/07/2013 15:46:25
Grazie, della risposta.
Il punto nel nome della funzione era indicativo
Immaginavo che si potesse pilotare il codice verso tutte le operazioni che uno desideri, ma cercavo una mano nel fare ciò. Il codice che ho postato l'ho creato spulciando ed unendo codici trovati qui e là sul web... Qualcuno sa dirmi come inserire la la condizione?
Grazie in anticipo!
di HarryBosch data: 09/07/2013 17:14:49
Cioè, una cosa del tipo sotto?
Ovviamente da adattare al tuo caso...
Function fnz_Unisci(Intervallo_da_concatenare As Range, Intervallo_criterio As Range, Criterio As Variant)
Dim c As Range
If Intervallo_criterio = Criterio Then
For Each c In Intervallo_da_concatenare
fnz_Unisci = fnz_Unisci & " " & c.Value
Next
End If
End Function
|
di gius_87 (utente non iscritto) data: 09/07/2013 17:25:44
Si, direi di si, anche se non ho capito come modificarla. Scusami ma con la 'creazione' di funzioni mi sto muovendo da poco... Come dovrei adattarla?
Grazie
di Vecchio Frac data: 09/07/2013 21:04:00
Bè, dipende dal criterio che intendi utilizzare per eseguire la concatenazione.
E' un semplice If dopotutto.
Harry ti ha costruito la funzione che chiedevi, parametrizzata come in richiesta; non devi adattarla, devi utilizzarla :)
Cos'è che non ti quadra?
di gius_87 (utente non iscritto) data: 10/07/2013 10:04:11
Non mi funziona... :-P
Cmq ho risolto, posto sotto la mia soluzione.
Grazie comunque della disponibilità
Function fnz_Unisci(Intervallo_da_concatenare As Range, Intervallo_criterio As Range, Criterio As Variant)
Dim c
For i = 1 To Intervallo_criterio.Cells.Count
If Intervallo_criterio(i).Value = Criterio Then
c = c & Intervallo_da_concatenare(i).Value
End If
Next
fnz_Unisci = Left(c, Len(c))
End Function |
di gius_87 (utente non iscritto) data: 10/07/2013 10:06:51
Scusate, ho dimenticato di "spuntare" la risoluzione
Ciao
di HarryBosch data: 10/07/2013 19:33:50
Vorrai dire: "Non mi funziona... come mi aspettavo"... semmai ^_^
Comunque la tua revisione non mi risulta chiara. Se fai un esempietto pratico magari la aggiustiamo a dovere :)
di gius_87 (utente non iscritto) data: 11/07/2013 10:03:11
HO allegato un file con la mia funzione
non ho capito il tuo «Vorrai dire: "Non mi funziona... come mi aspettavo"... semmai ^_^»
Se prima di postare si verificasse quello che si scrive sarebbe meglio cmq
Ciao
di HarryBosch data: 11/07/2013 10:58:10
Non c'è bisogno di scaldarsi... ti avevo messo una faccina sorridente ^_^
Inoltre sono così scrupoloso che quello che propongo lo verifico sempre, anche se sono sicuro del risultato.
La funzione che ti avevo indicato era, come ben precisato, da adattare al tuo specifico caso: non per niente si definiscono UDF (User Defined Functions).
E infatti, basandoti sul mio esempio, sei riuscito a trovare una soluzione che garantisse il risultato atteso.
Non potevo certamente sapere il tuo intento iniziale, cosa che con il file di esempio è diventata chiara.
La tua funzione può creare un risultato inatteso nel caso i due intervalli selezionati non fossero corrispondenti; per esempio, se erroneamente scrivessi:
=Unisci_città(A1:A107;B2:B107;I2)
la funzione restituisce un valore, ma sbagliato.
In questi casi è conveniente lavorare sull'intera matrice di dati, selezionano l'indice della colonna che si interessa controllare; come ad esempio per la funzione Cerca.Verticale.
Ti propongo una revisione:
- il primo argomento richiama l'intera matrice di dati
- il secondo argomento l'indice della colonna da utilizzare come confronto
- il terzo argomento sempre il criterio
In base alla tua tabella:
=fnz_Unisci(A1:B107;1;I2)
il secondo argomento è 1 perché la prima colonna della matrice ha indice 0.
La prima colonna della matrice sarà sempre quella riportata nel risultato della funzione
Function fnz_Unisci(Intervallo_Dati As Range, Indice_colonna_criterio As Integer, Criterio As Variant)
Dim c As Range
For Each c In Intervallo_Dati
If c.Offset(, Indice_colonna_criterio) = Criterio Then
fnz_Unisci = fnz_Unisci & " - " & c.Value
End If
Next
If fnz_Unisci <> "" Then
fnz_Unisci = Replace("@" & fnz_Unisci, "@ - ", "")
Else
fnz_Unisci = "Nessuna corrispondenza"
End If
End Function
|
di HarryBosch data: 11/07/2013 11:10:00
Piccola revisione... ovviamente bisogna ciclare soltanto la prima colonna della matrice.
Altrimenti si rischia di trovare qualche valore di troppo in caso di tabelle con più dati; oltre ad una velocizzazione del codice :)
Function fnz_Unisci(Intervallo_Dati As Range, Indice_colonna_criterio As Integer, Criterio As Variant)
Dim c As Range
For Each c In Intervallo_Dati.Columns(1).Cells
If c.Offset(, Indice_colonna_criterio) = Criterio Then
fnz_Unisci = fnz_Unisci & " - " & c.Value
End If
Next
If fnz_Unisci <> "" Then
fnz_Unisci = Replace("@" & fnz_Unisci, "@ - ", "")
Else
fnz_Unisci = "Nessuna corrispondenza"
End If
End Function
|
di gius_87 (utente non iscritto) data: 11/07/2013 11:39:20
Mumble, preferisco non avere vincoli di matrice, perché spesso mi trovo a non avere le serie di dati così "puliti" e messi in colonna in tal modo. Nel senso che molto spesso ho matrici con parecchi campi e non sempre la colonna da concatenare è la prima e quella del criterio e subito a fianco
Ho preferito inserire un valore di errore alla mia funzione in modo da accorgermi se prendo intervalli non coincidenti, dato che è un errore ;)
Function fnz_unisci(Intervallo_da_concatenare As Range, Intervallo_criterio As Range, Criterio As Variant)
Dim c
For i = 1 To Intervallo_criterio.Cells.Count
If Intervallo_criterio(i).Value = Criterio Then
c = c & Intervallo_da_concatenare(i).Value & " - "
End If
Next
fnz_unisci = Left(c, Len(c))
If Intervallo_criterio.Cells.Count <> Intervallo_da_concatenare.Cells.Count Then
fnz_unisci = "#VALORE!"
End If
End Function |
di HarryBosch data: 11/07/2013 11:48:12
Puoi ovviamente scegliere la funzione che ritieni più soddisfacente, l'importante è sempre il risultato finale.
Tieni presente che nella funzione che ti ho inserito la matrice dei dati la selezioni te, quindi la prima colonna può trovarsi ovunque nel foglio. E la colonna criterio non deve essere per forza quella adiacente ma anche molte colonne più a destra. sarà l'indice che ti indica quante colonne spostarti.
Vedi il file che ti allego come esempio....
di gius_87 (utente non iscritto) data: 11/07/2013 12:07:27
Avevo capito che il funzionamento fosse "simile" al cerca.vert ed è proprio per questo che mi sembrava un po' "rigida"
perché ho il vincolo del num. di colonne da contare (in alcuni fogli ho anche più di 50 colonne)... e stare a contare a mano quante colonne ho è un po' una rottura eh eh
inoltre, la colonna da concatenare dev'essere per forza a sinistra di quella dei criteri (ed anche in questo caso non è detto che io ce l'abbia sempre in tale posizione)
Anyway, thank you
di Vecchio Frac data: 11/07/2013 14:58:10
cit. "Se prima di postare si verificasse quello che si scrive sarebbe meglio cmq"
---> Harry è l'ultima persona al mondo cui si deve rivolgere una critica di questo tipo: mai visto uno più prudente di lui, quando scrive qualcosa :)
Non mi è piaciuto questo intervento.
Vuoi Approfondire?