2011-11-08 15 views
5

Mam arkusz z listą nazw w kolumnie B i kolumną ID w A. Zastanawiam się, czy istnieje jakaś formuła, która może przyjąć wartość w kolumnie B tego wiersza i wygenerować rodzaj ID na podstawie tekst? Każde imię jest niepowtarzalne i nigdy nie jest powtarzane w żaden sposób.Excel 2007 - Wygeneruj unikalny identyfikator na podstawie tekstu?

Najlepiej byłoby, gdybym nie musiał używać VBA naprawdę. Ale jeśli muszę, niech tak będzie.

+0

Jakieś wymagania dotyczące długości lub znaków używanych w identyfikatorze? – Excellll

Odpowiedz

3

Niestety, nie znalazł rozwiązanie z wzoru tylko nawet jeśli this thread może pomóc (próbuje obliczyć punkty w scrabble gry), ale nie mogę znaleźć sposób, aby mieć pewność, że wygenerowany hash byłoby unikatowy.

Jednak tutaj jest moje rozwiązanie, oparte na UDF (używany-Defined Function):

wpisz kod w module:

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 

i nazywają to w arkuszu niczym formuła:

=genId(A1) 

[EDYC] Dodano * i, aby uwzględnić zamówienie. To działa na moja jednostka testuje

+0

Cześć! Działa to całkiem nieźle :) Mimo to, otrzymuję te same wyniki dla kilku nazw, jeśli nazwa ma taką samą liczbę znaków. Myślę, że po prostu podzielę ciąg i wybiorę pierwszą literę każdego z nich, a następnie dodaję ten identyfikator. Prawdopodobnie powinien być unikalny wtedy :) –

+1

wygląda na to, że algo nie ma zamówienia! (wygeneruje to samo ID dla 'james Doe' i' Doe james'.) Zmienię moją odpowiedź, aby poprawić moją funkcję (FWIW, pomnożyłem identyfikator przez indeks, aby w jakiś sposób uwzględnić porządek. Mam nadzieję, że to wystarczy – JMax

+1

-1 To ** NIE ** generuje unikalny identyfikator –

0

Może być OTT do swoich potrzeb, ale można skorzystać z połączenia do CoCreateGuid aby uzyskać prawdziwy 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 

test używając

Sub testGUID() 
    MsgBox GUID 
End Sub 

Jak najlepiej wdrożyć zależy od twoich potrzeb. Jednym ze sposobów byłoby napisanie makra, aby GUID wypełnił kolumnę, w której istnieją nazwy. (Uwaga, używając go jako UDF jak to nie jest dobre, ponieważ powróci nowy GUID gdy przeliczonego)

EDIT
Zobacz this answer tworzenia skrótu SHA1 z ciągiem

0

Czy po prostu chcesz, aby rosnąca numeryczna kolumna identyfikacyjna znajdowała się obok Twoich wartości? Jeśli tak, i jeśli twoje wartości będą zawsze unikatowe, możesz to łatwo zrobić za pomocą formuł.

Jeśli Twoje wartości znajdowały się w kolumnie B, zaczynając od B2 pod nagłówkiem, w A2 wpisz: "= JEŻELI (B2 =" "," ", 1 + MAX (A $ 1: A1)) ". Możesz skopiować i wkleić to w dół, w miarę jak twoje dane się wydłużają, i zwiększy numeryczny identyfikator każdego wiersza w kolumnie B, który nie jest pusty.

Jeśli chcesz zrobić coś bardziej skomplikowanego, np. Zidentyfikować i ponownie zidentyfikować powtarzające się wartości lub zamrozić identyfikatory po ich wypełnieniu, daj mi znać. Obecnie, po wyczyszczeniu lub dodaniu wartości do listy, identyfikatory będą się przełączać w górę lub w dół, więc musisz zachować ostrożność w przypadku zmiany danych.

2

Rozwiązanie bez VBA.

Logika oparta na pierwszych 8 znakach + liczbie znaków w komórce.

= CODE(cell) która zwraca numer kodu dla pierwszej litery

= CODE(MID(cell,2,1)) zwraca ilość kodu dla drugiego listu

= IFERROR(CODE(MID(cell,9,1)) Jeśli 9-ty postać nie istnieje następnie powrócić 0

= LEN(cell) liczbę znaków w komórce

Jednoczące się jodły 8 kodów + dodawanie długości znaków na końcu

Jeśli 8 znaków nie wystarcza, powtórz dodatkowe kody dla kolejnych znaków w ciągu.

Ostateczna funkcja:

=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

To nie jest cytat wyjątkowy, ponieważ KOD jednego indywidualnego znaku może mieć 2 lub 3 cyfry; kombinacja powiedzmy 6 liter może mają ten sam kod, co kombinacja powiedzmy 5 innych liter. –

+0

Podaj takie przykłady. –

+0

Spróbuj przekształcić ciąg znaków kodów ASCII z powrotem na listy; Liczę co najmniej 6 sposobów na poprawne nazwy z tego ciągu przez odwrócenie znaków 1/2/3 cyfr wokół: 6510097109236666111983283116463280101116101 [spróbuj zaczynając od tego wzoru: 232331232223222333]. Pamiętaj - kluczem do obliczania danych wejściowych użytkownika są zawsze przypadki narożne. Jest to mało prawdopodobne, aby użytkownik wprowadził najwięcej bólu, jeśli wprowadzanie danych nie jest w stanie obsłużyć wszystkich przypadków. –

0

Unikalny identyfikator opiera się na szeregu konkretnych znaków w tekście. Użyłem identyfikatora opartego na samogłoskach i liczbach.

=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

Należy zauważyć, że działa to tylko wtedy, gdy nie ma ciągów, które mają takie same znaki, ale w innej kolejności. tzn. 21 skoczni i 12 skoczni będą takie same w tej metodzie. –

0

Mówisz, że masz pewność, że Twoje słowa nie mają duplikatów. Aby dalej ją popychać, czy masz pewność, że pierwsze 8 znaków w dowolnym słowie będzie unikatowe?

Jeśli tak, możesz użyć poniższej formuły. Działa poprzez pojedyncze kodowanie ASCII każdego znaku - 40 [przy założeniu normalnych znaków, to umieszcza liczby pomiędzy 8 & 57, a literami pomiędzy 57 & 122] i mnożenie tego kodu znaków przez 10^[umieszczenie cyfry znaku w słowie ]. Zasadniczo trwa to kod znaku [-40] i łączy każdy kod z następnym.

EDIT Należy pamiętać, że kod ten nie wymaga, aby co najmniej 8 znaków istnieć w swoim słowie, aby zapobiec błąd, jak rzeczywiste słowo do zakodowania ma 8 „0” jest dołączana do niego.

=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}),"#") 

Zauważ, że ponieważ używa wartości ASCII znaków, identyfikator # mogłyby zostać wykorzystane w celu identyfikacji bezpośrednio - to naprawdę nie tworzyć anonimowość, to po prostu zamienia 8 unikalnych znaków w unikalnym numerem. Jest obfuskany za pomocą -40, ale w rzeczywistości nie jest tak naprawdę "bezpieczny". -40 służy do uzyskania normalnych liter i cyfr w 2-cyfrowym zakresie, aby pomnożenie przez 10^0,2,4 itd. Stworzyło dwucyfrowy unikatowy dodatek do stworzonego kodu.

edycji do alternatywnej metody

miałem wcześniej próbował to zrobić tak, że będzie patrzeć na każdą literę alfabetu, policzyć ile razy pojawia się w słowie, a następnie pomnożyć przez 10, * [pozycja tej litery w alfabecie]. Problem z wykonaniem tego (patrz komentarz poniżej dla formuły) polega na tym, że wymagało to liczby 10^26-1, co wykracza poza dokładność zmiennoprzecinkową Excela. Mam jednak zmodyfikowaną wersję tej metody:

Ograniczając liczbę dozwolonych znaków w alfabecie, możemy uzyskać maksymalną całkowitą wielkość do 10^15-1, którą program Excel może poprawnie obliczyć.Wzór wygląda następująco:

=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) 

[w prawo („00000000000000” ... część wzoru jest przeznaczona do utrzymania wszystkich kodów taką samą liczbę znaków]

Zauważ, że tu jest alfabet nazwany ciąg, który zawiera znaki: "abcdehilmnorstu" .Na przykład, używając powyższej formuły, słowo "asdf" zlicza wystąpienia a, s i d, ale nie "f", którego nie ma w moim zakontraktowanym alfabecie. Kod "asdf" będzie:

Działa to wyłącznie z następującymi założeniami:

Litery niewymienione (ani cyfry/znaki specjalne) nie są wymagane, aby każde imię było niepowtarzalne. Na przykład asdf & asd będzie miał taki sam kod w powyższej metodzie.

I

Kolejność liter nie jest wymagane, aby każda nazwa unikalna. Na przykład asd & dsa miałby ten sam kod w powyższej metodzie.

+0

Uwaga: próbowałem to zrobić, indywidualnie licząc liczbę znaków od az w każdym słowie i umieszczając tę ​​liczbę (przyjmując 0-9) w cyfrze 10^26, i zadziałałoby, gdyby 10^26 było poza dokładnością Excela z wartościami zmiennoprzecinkowymi. Pokazano tutaj: = TEKST (SUMA (LEN (A3) * 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,5,26} -LEN (SUBSTYTUTA (A3, MID (alfabet, {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,5,16,17,18,19,20,21,22,23,24,25,26}), "# ") –

+0

[W powyższym przykładzie Alfabet to nazwany zakres zawierający pojedynczy ciąg" abcd ... z "]. –

Powiązane problemy