Excel 2007 - генерировать уникальный идентификатор на основе текста? - PullRequest
7 голосов
/ 08 ноября 2011

У меня есть лист со списком имен в столбце B и столбцом идентификатора в A. Мне было интересно, есть ли какая-то формула, которая может принимать значение в столбце B этой строки и генерировать какой-то вид на основе идентификаторапо тексту?Каждое имя также уникально и никогда не повторяется.

Было бы лучше, если бы мне действительно не пришлось использовать VBA.Но если мне придется, пусть будет так.

Ответы [ 6 ]

3 голосов
/ 02 февраля 2015

Решение Без VBA.

Логика на основе первых 8 символов + количество символов в ячейке.

= CODE(cell), которая возвращает кодовый номер для первой буквы

= CODE(MID(cell,2,1)) возвращает кодовый номер для второй буквы

= IFERROR(CODE(MID(cell,9,1)) Если 9-го символа не существует, вернуть 0

= LEN(cell) количество символов в ячейке

Объединение первых 8коды + добавление длины символа в конце

Если 8 символов недостаточно, скопируйте дополнительные коды для следующих символов в строке.

Финальная функция:

=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

1 голос
/ 08 ноября 2011

Извините, я не нашел решения с формулой, даже если эта тема может помочь (попытка подсчитать очки в игре scrabble ), но я не нашел способ убедиться, что сгенерированный хеш будет уникальным .

Тем не менее, вот мое решение, основанное на UDF (используемая функция):

Поместите код в модуль:

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

И назовите это в своем рабочем листе как формула:

=genId(A1)

[EDIT] Добавлен * i для учета заказа. Работает на моих юнит-тестах

0 голосов
/ 28 августа 2015

Вы говорите, что уверены, что в ваших словах нет повторяющихся значений.Чтобы продвинуться дальше, уверены ли вы, что первые 8 символов в любом слове будут уникальными?

Если это так, вы можете использовать приведенную ниже формулу.Он работает, индивидуально беря код ASCII каждого символа - 40 [принимая нормальные символы, это ставит цифры между 8 и 57 и буквы между 57 и 122], и умножая код этих символов на 10 ^ [размещение цифр этого символа в слове].По сути, он берет этот символьный код [-40] и объединяет каждый код в следующий.

EDIT Обратите внимание, что этот код больше не требует, чтобы в вашем слове существовало как минимум 8 символов, чтобы предотвратитьошибка, поскольку к фактическому слову, которое должно быть закодировано, добавлено 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}),"#")

Обратите внимание, что, поскольку при этом используются значения символов ASCII, идентификатор # может использоваться для идентификацииимя напрямую - это не создает анонимности, оно просто превращает 8 уникальных персонажей в уникальный номер.Он запутан с -40, но не совсем «безопасен» в этом смысле.-40 - это просто получение нормальных букв и цифр в диапазоне 2 цифр, так что умножение на 10 ^ 0,2,4 и т. Д. Создаст уникальное дополнение из 2 цифр к созданному коду.

РЕДАКТИРОВАТЬ ДЛЯ АЛЬТЕРНАТИВНОГО МЕТОДА

Ранее я пытался сделать это так, чтобы он просматривал каждую букву алфавита, подсчитывал количество раз, которое он встречается в слове, а затем умножал этона 10 * [позиция этой буквы в алфавите].Проблема с этим (см. Комментарий ниже для формулы) заключается в том, что для этого требуется число 10 ^ 26-1, что выше точности Excel с плавающей запятой.Однако у меня есть модифицированная версия этого метода:

Ограничивая количество разрешенных символов в алфавите, мы можем получить максимально возможный общий размер до 10 ^ 15-1, который Excel может правильно рассчитать.Формула выглядит следующим образом:

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

[Правая часть ("00000000000000" ... части формулы предназначена для того, чтобы все коды имели одинаковое количество символов]

Обратите внимание, что здесьАлфавит - это именованная строка, содержащая символы: «abcdehilmnorstu». Например, используя приведенную выше формулу, слово «asdf» подсчитывает случаи a, s и d, но не «f», которого нет в моемсокращенный алфавит. Код «asdf» будет выглядеть следующим образом:

001000000001001

Это работает только со следующими допущениями:

Буквы не указаны (ни цифры / специальные символы)не обязательно делать каждое имя уникальным. Например, asdf & asd будет иметь такой же код в вышеуказанном методе.

И,

Порядок букв не требуется, чтобы сделать каждоеимя уникальное. Например, asd & dsa будет иметь такой же код в приведенном выше методе.

0 голосов
/ 28 августа 2015

Уникальный идентификатор, основанный на количестве определенных символов в тексте.Я использовал идентификатор на основе гласных и цифр.

=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 голосов
/ 09 ноября 2011

Вы хотите, чтобы столбец числового идентификатора увеличивался рядом с вашими значениями? Если это так, и если ваши значения всегда будут уникальными, вы можете очень легко сделать это с помощью формул.

Если бы ваши значения были в столбце B, начиная с B2, например, под заголовками, в A2 вы должны ввести формулу "= IF (B2 =" "," ", 1 + MAX (A $ 1: A1))" , Вы можете скопировать и вставить это по мере расширения ваших данных, и оно будет увеличивать числовой идентификатор для каждой строки в столбце B, который не является пустым.

Если вам нужно сделать что-нибудь более сложное, например, идентифицировать и повторно идентифицировать повторяющиеся значения или заставить идентификаторы «зависать» после заполнения, дайте мне знать. В настоящее время, когда вы очищаете или добавляете значения в свой список, идентификаторы переключаются вверх и вниз, поэтому вы должны быть осторожны, если ваши данные изменятся.

0 голосов
/ 08 ноября 2011

Может быть OTT для ваших нужд, но вы можете использовать звонок на CoCreateGuid, чтобы получить настоящий 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

Тест с использованием

Sub testGUID()
    MsgBox GUID
End Sub

Как лучшеРеализация зависит от ваших потребностей.Одним из способов было бы написать макрос, чтобы получить GUID для заполнения столбца, в котором существуют имена.(обратите внимание, что использовать его как udf как есть, нехорошо, поскольку он будет возвращать новый GUID при пересчете)создание SHA1-хэша строки

...