2015-01-13 5 views
5

Quindi ho una lista di stringhe, per cui alcune stringhe contengono duplicati.Rimozione di duplicati da una cella in excel

Ad esempio:

13-Hexadecenoic acido; 13-metil-4-pentadecenoic acido, acido 14-metil-6-pentadecenoic; 15-Hexadecanolide; 3-Hexadecenoic acido; 4 hexadecenoic acido 13-esadecenoico acido; acido 13-metil-4-pentadecenoico; 14-metil-6-pentadecenoico acido; 15-esadecanolide; acido 3-esadecenoico; acido 4-esadecenoico;

Così mi sono imbattuto in una macro on-line e ottimizzato per lavorare per il mio problema, che va in questo modo:

Function stringOfUniques(inputString As String) As String 
    Dim inArray() As String 
    Dim xVal As Variant 
    inArray = Split(inputString, ";") 
    For Each xVal In inArray 
     If InStr(stringOfUniques, Trim(xVal)) = 0 Then _ 
     stringOfUniques = stringOfUniques & Trim(xVal) & "," 
    Next xVal 

End Function 

E per alcuni dei miei corde questo funziona brillantemente, ma per l'esempio di sopra di essa restituirà la stringa con i duplicati rimossi, ma stranamente eliminerà entrambe le copie di una delle parole "acido 3-esadecenoico". Quindi, in pratica

Cosa dovrei ottenere:

13-Hexadecenoic acida; 13-metil-4 pentadecenoic- acido, acido 14-metil-6-pentadecenoic; 15-Hexadecanolide; 3-Hexadecenoic acido ; Acido 4-esadecenoico;

Quello che realmente ottenere:

13-Hexadecenoic acido; 13-metil-4 pentadecenoic- acido, acido 14-metil-6-pentadecenoic; 15-Hexadecanolide; 4 hexadecenoic acido ;

C'è qualcosa nel mio codice che sta causando questo?

+0

Scuse per la esempio, probabilmente non è il più facile per gli occhi – user2062207

+5

Immagino che abbia qualcosa a che fare con 'InStr' -> _Ritorna un numero che specifica la posizione iniziale della prima occorrenza di una ** stringa all'interno di un'altra ** ._ Quindi probabilmente è andando a trattare l'acido 13-esadecenoico come un duplicato di acido 3-esadecenoico. Quindi, anche dopo aver rimosso il primo acido 3-esadecenoico, troverà ancora l'acido 13-esadecenoico e rimuoverà il secondo – chancea

+0

. Grazie per il vostro Aiuto! – user2062207

risposta

9

Probabilmente ci sono diversi modi per farlo, ma gli oggetti sono ottimi per forzare l'unicità.

Function stringOfUniques(inputString As String, delimiter as String) 
Dim xVal As Variant 
Dim dict as Object 
Set dict = CreateObject("Scripting.Dictionary") 

For Each xVal In Split(inputString, delimiter) 
    dict(xVal) = xVal 
Next xVal 

stringOfUniques = Join(dict.Keys(),",") 
End Function 

Questa funzione è stato modificato per accettare un argomento delimitatore variabile, in modo da passare la stringa di input e delimitatore: ";" alla funzione che restituisce una stringa separata da virgole.

Una nota sul Dizionari: coppie

Dizionari chiave negozio/valore. Le chiavi devono essere univoche.

Nell'esempio, utilizzo una semplice assegnazione all'oggetto del dizionario: dict(key) = key. Un dizionario automaticamente aggiunge o sovrascrive un elemento quando viene fatto riferimento alla sua chiave, quindi questo è un modo davvero semplice di forzare l'unicità.

In altre circostanze (ad es., Si vuole conteggio il numero di occorrenze di ogni tasto), si vorrebbe verificare utilizzando la dict.Exists(key) al fine di modificare il value senza sovrascrivere la coppia chiave/valore, ad esempio:

'Assigns a "count" value to the dictionary for each unique Key 
For Each xVal In Split(inputString, delimiter) 
    If dict.Exists(xVal) Then 
     dict(xVal) = dict(xVal) + 1 
    Else 
     dict(xVal) = 1 
    End If 
Next xVal 

'Read the "count" from each key: 
For Each xVal in dict.Keys() 
    MsgBox xVal & " appears " & dict(xVal) & " times" 
Next 
+0

Fantastico! Grazie mille! – user2062207