2011-11-08 27 views
5

Ho un foglio con un elenco di nomi nella colonna B e una colonna ID in A. Mi chiedevo se c'è qualche tipo di formula che può assumere il valore nella colonna B di quella riga e generare un tipo di ID basato su il testo? Ogni nome è anche unico e non viene mai ripetuto in alcun modo.Excel 2007 - Genera ID univoco basato sul testo?

Sarebbe meglio se non dovessi usare VBA davvero. Ma se devo, così sia.

+0

Eventuali requisiti per la lunghezza o i caratteri utilizzati nell'ID? – Excellll

risposta

3

Spiacente, non ho trovato una soluzione con la formula unica, anche se this thread potrebbe aiutare (cercando di calcolare i punti in un scrabble gioco), ma non ho trovato un modo per essere sicuri che il hash generato sarebbe unico.

Eppure, ecco la mia soluzione, basata su un UDF (Funzione Utilizzato-Defined):

inserisce il codice in un modulo:

Public Function genId(ByVal sName As String) As Long 
'Function to create a unique hash by summing the ascii value of each character of a given string 
    Dim sLetter As String 
    Dim i As Integer 
    For i = 1 To Len(sName) 
     genId = Asc(Mid(sName, i, 1)) * i + genId 
    Next i 
End Function 

e lo chiamano nel foglio di lavoro come un formula:

=genId(A1) 

[EDIT] aggiunta la * i di prendere in considerazione l'ordine. Funziona sulla mia unità test

+0

Ciao! Funziona molto bene :) Anche se ottengo gli stessi risultati per alcuni nomi, se il nome ha la stessa quantità di caratteri. Penso che dividerò semplicemente la stringa e selezionerò la prima lettera di ciascuno e poi aggiungerò questo ID. Probabilmente dovrebbe essere unico quindi :) –

+1

sembra che algo manchi l'ordine! (genererà lo stesso ID per 'james Doe' e' Doe james'. Modificherò la mia risposta per migliorare la mia funzione (FWIW, ho moltiplicato l'id per l'indice in modo che in qualche modo tenga conto dell'ordine. Spero che sia sufficiente – JMax

+1

-1 Questo ** NON ** produce un ID univoco –

0

Può essere OTT per le vostre esigenze, ma è possibile utilizzare una chiamata a CoCreateGuid per ottenere un vero e proprio test GUID

Private Declare Function CoCreateGuid Lib "ole32" (ID As Any) As Long 

Function GUID() As String 
    Dim ID(0 To 15) As Byte 
    Dim i As Long 

    If CoCreateGuid(ID(0)) = 0 Then 
     For i = 0 To 15 
      GUID = GUID & Format(Hex$(ID(i)), "00") 
     Next 
    Else 
     GUID = "Error while creating GUID!" 
    End If 

End Function 

utilizzando

Sub testGUID() 
    MsgBox GUID 
End Sub 

come attuare al meglio dipende dalle tue esigenze. Un modo sarebbe quello di scrivere una macro per ottenere un GUID compilare una colonna in cui esistono i nomi. (Nota, usandolo come un'UDF come è non va bene, dal momento che restituirà un nuovo GUID quando ricalcolato)

EDIT
Vedi this answer per la creazione di un hash SHA1 di una stringa

0

Ti basta vuoi una colonna ID numerica incrementale da sedersi accanto ai tuoi valori? Se è così, e se i tuoi valori saranno sempre unici, puoi farlo facilmente con le formule.

Se i tuoi valori erano nella colonna B, a partire da B2 sotto le intestazioni, ad esempio, in A2 devi digitare la formula "= IF (B2 =" "," ", 1 + MAX (A $ 1: A1)) ". È possibile copiarlo e incollarlo fino all'estensione dei dati e incrementare un identificatore numerico per ogni riga nella colonna B che non è vuota.

Se devi fare qualcosa di più complicato, ad esempio identificare e ri-identificare i valori ripetuti, o rendere il blocco degli identificatori una volta popolati, fammi sapere. Al momento, quando cancelli o aggiungi valori all'elenco, gli identificatori si attivano e disattivano, pertanto devi fare attenzione se i dati cambiano.

2

Soluzione senza VBA.

Logica basata sui primi 8 caratteri + numero di caratteri in una cella.

= CODE(cell) che restituisce il numero di codice per la prima lettera

= CODE(MID(cell,2,1)) restituisce il numero di codice per la seconda lettera

= IFERROR(CODE(MID(cell,9,1)) Se 9 ° carattere non esiste poi tornare 0

= LEN(cell) numero di carattere in una cella

Concatenazione di abeti 8 codici + aggiunta della lunghezza del carattere alla fine

Se 8 caratteri non sono sufficienti, replicare i codici aggiuntivi per i caratteri successivi in ​​una stringa.

funzione finale:

=CODE(B2)&IFERROR(CODE(MID(B2,2,1)),0)&IFERROR(CODE(MID(B2,3,1)),0)&IFERROR(CODE(MID(B2,4,1)),0)&IFERROR(CODE(MID(B2,5,1)),0)&IFERROR(CODE(MID(B2,6,1)),0)&IFERROR(CODE(MID(B2,7,1)),0)&IFERROR(CODE(MID(B2,8,1)),0)&LEN(B2) 

enter image description here

+0

Questa non è una citazione unica, perché il CODICE di un singolo personaggio può essere 2 o 3 cifre, quindi un combinazione di dire 6 lettere maggio avere lo stesso codice di una combinazione di 5 altre lettere. –

+0

Fornire tali esempi. –

+0

Provate a convertire questa stringa di codici ASCII qui di nuovo in lettere; Conto almeno 6 modi per estrarre i nomi propri da questa stringa girando caratteri di 1/2/3 cifre intorno: 6510097109236666111983283116463280101116101 [prova ad iniziare con questo modello: 232331232223222333]. Ricorda: la chiave per calcolare gli input dell'utente si riferisce sempre ai casi d'angolo. Sono gli improbabili input dell'utente che creano più dolore se l'immissione dei dati non è in grado di gestire tutti i casi. –

0

Identificativo univoco in base al numero di caratteri specifici nel testo. Ho usato un identificatore basato su vocali e numeri.

=LEN($J$14)-LEN(SUBSTITUTE($J$14;"a";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"e";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"i";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"j";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"o";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"u";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"y";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"1";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"2";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"3";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"4";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"5";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"6";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"7";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"8";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"9";""))&LEN($J$14)-LEN(SUBSTITUTE($J$14;"0";"")) 
+0

Si noti che questo funziona solo se non ci sono stringhe che hanno gli stessi caratteri ma in un ordine diverso. vale a dire: 21 jump street e 12 jump street sarebbero gli stessi in questo metodo. –

0

Si dice che si è certi che non ci sono valori duplicati nelle parole. Per spingerlo oltre, sei sicuro che i primi 8 caratteri in ogni parola sarebbero unici?

In tal caso, è possibile utilizzare la seguente formula. Funziona prendendo singolarmente il codice ASCII di ogni personaggio - 40 [assumendo caratteri normali, questo mette i numeri tra 8 & 57 e lettere tra 57 & 122] e moltiplicando quel codice di caratteri di 10^[la posizione delle cifre di quel personaggio nella parola ]. Fondamentalmente prende quel codice di carattere [-40] e concatena ogni codice al successivo.

EDIT Si noti che questo codice non richiede più che nella parola siano presenti almeno 8 caratteri per impedire un errore, poiché la parola effettiva da codificare è adesa ad 8 "0".

=TEXT(SUM((CODE(MID(LOWER(RIGHT(REPT("0",8)&A3,8)),{1,2,3,4,5,6,7,8},1))-40)*10^{0,2,4,6,8,10,12,14}),"#") 

Si noti che, come tale utilizza i valori ASCII dei caratteri, l'ID # potrebbe essere utilizzato per identificare direttamente il nome - questo in realtà non crea l'anonimato, appena gira 8 personaggi unici in un numero univoco. È offuscato con il -40, ma non proprio "sicuro" in questo senso. Il -40 è solo per ottenere lettere e numeri normali nell'intervallo di 2 cifre, in modo che moltiplicando per 10^0,2,4 ecc. Si creerà un add-on unico di 2 cifre per il codice creato.

EDIT PER ALTERNATIVA METODO

precedenza avevo tentato di fare questo in modo che sarebbe guardare ad ogni lettera dell'alfabeto, contare il numero di volte che compare nella parola, e poi moltiplicare per 10 * [la posizione di quella lettera nell'alfabeto]. Il problema con questa operazione (vedere il commento sotto per la formula) è che richiedeva un numero di 10^26-1, che va oltre la precisione in virgola mobile di Excel. Tuttavia, ho una versione modificata di questo metodo:

Limitando il numero di caratteri consentiti nell'alfabeto, è possibile ottenere la dimensione totale massima possibile a 10^15-1, che Excel può calcolare correttamente.La formula è simile al seguente:

=RIGHT(REPT("0",15)&TEXT(SUM(LEN(A3)*10^{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}-LEN(SUBSTITUTE(A3,MID(Alphabet,{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},1),""))*10^{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}),"#"),15) 

[destra ("00.000 miliardi" ... parte della formula è destinata a mantenere tutti i codici lo stesso numero di caratteri]

Si noti che qui, alfabeto è un stringa denominata che contiene i caratteri: "abcdehilmnorstu" .Ad esempio, utilizzando la formula precedente, la parola "asdf" conta le istanze di a, s edd, ma non "f" che non è nel mio alfabeto contratto. codice di "asdf" sarebbe:

Questo funziona solo con le seguenti ipotesi:

Le lettere non elencate (né numeri/caratteri speciali) non sono tenuti a rendere ogni nome univoco. Ad esempio, asdf & asd avrebbe lo stesso codice nel metodo precedente.

E,

L'ordine delle lettere non è tenuto a rendere ogni nome univoco. Ad esempio, asd & dsa avrebbe lo stesso codice nel metodo precedente.

+0

Nota: ho provato a farlo contando individualmente il numero di caratteri da az in ogni parola e ponendo quel numero (supponendo 0-9) nella cifra di un numero 10^26, e avrebbe funzionato se 10^26 non fosse Non esente dalla precisione di Excel con valori a virgola mobile. Indicato qui: = TESTO (SOMMA (LEN (A3) * 10^{1,2,3,4,5,6,7,1,9,10,11,12,13,14,15,16,17, 18,19,20,21,22,23,24,25,26} -LEN (SOSTITUTO (A3, MID (Alfabeto, {1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}, 1), "")) * 10^{1,2,3, 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}) ", # ") –

+0

[Nell'esempio precedente, Alphabet è un intervallo denominato contenente una singola stringa di" abcd ... z "]. –