2011-11-08 20 views
5

Tengo una hoja con una lista de nombres en la columna B y una columna de ID en A. Me preguntaba si hay algún tipo de fórmula que pueda tomar el valor en la columna B de esa fila y generar algún tipo de ID basado en ¿el texto? Cada nombre también es único y nunca se repite de ninguna manera.Excel 2007 - ¿Genera una ID única basada en texto?

Sería mejor si no tuviera que usar realmente VBA. Pero si tengo que hacerlo, que así sea.

+0

¿Algún requisito para la longitud o los caracteres utilizados en la ID? – Excellll

Respuesta

3

Lo sentimos, no he encontrado una solución con la fórmula única, incluso si this thread podría ayudar (tratando de calcular los puntos en un scrabble juego), pero no he encontrado una manera de ser que el hash generada sería único.

Sin embargo, aquí está mi solución, basada en un UDF (función definida por el Used):

poner el código en un módulo:

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 

y lo llaman en su hoja de cálculo como una fórmula:

=genId(A1) 

[EDIT] Añadido el * i para tener en cuenta la orden. Funciona en mi unidad de prueba

+0

¡Hola! Esto funciona bastante bien :) Aunque, obtengo los mismos resultados para algunos nombres, si el nombre tiene la misma cantidad de caracteres. Creo que voy a dividir la cadena y elegir la primera letra de cada uno y luego agregar esta identificación. Probablemente debería ser único, entonces :) –

+1

parece que le falta el orden a algo. (generará la misma ID para 'james Doe' y' Doe james'. Editaré mi respuesta para mejorar mi función (FWIW, he multiplicado la identificación por el índice para que de alguna manera tenga en cuenta la orden). Espero que sea suficiente – JMax

+1

-1 Esto ** NO ** produce una ID única –

0

Puede ser OTT para sus necesidades, pero se puede utilizar una llamada a CoCreateGuid para conseguir una verdadera prueba 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 

usando

Sub testGUID() 
    MsgBox GUID 
End Sub 

mejor manera de aplicar depende de tus necesidades Una forma sería escribir una macro para obtener un GUID que rellene una columna donde existan nombres. (Nota, usándolo como una UDF como es no es bueno, ya que devolverá un nuevo GUID cuando recalculado)

EDITAR
Ver this answer para crear un hash SHA1 de una cadena

0

¿Sólo ¿Desea una columna de ID numérica creciente para sentarse junto a sus valores? Si es así, y si sus valores siempre serán únicos, puede hacerlo fácilmente con fórmulas.

Si sus valores estaban en la columna B, comenzando en B2 debajo de sus encabezados, por ejemplo, en A2 escribiría la fórmula "= IF (B2 =" "," ", 1 + MAX (A $ 1: A1)) ". Puede copiar y pegar eso en la medida en que sus datos se extienden, e incrementará un identificador numérico para cada fila en la columna B que no está en blanco.

Si necesita hacer algo más complicado, como identificar y volver a identificar los valores que se repiten, o hacer que los identificadores se "congelen" una vez que se completen, avíseme. Actualmente, cuando borra o agrega valores a su lista, los identificadores se alternarán hacia arriba y hacia abajo, por lo que debe tener cuidado si sus datos cambian.

2

Solución sin VBA.

Lógica basada en los primeros 8 caracteres + número de caracteres en una celda.

= CODE(cell) que devuelve el número de código para primera letra

= CODE(MID(cell,2,1)) rendimientos número de código para la segunda carta

= IFERROR(CODE(MID(cell,9,1)) Si no existe noveno carácter luego regresar 0

= LEN(cell) número de caracteres en una celda

Concatenantes abetos 8 códigos + adición de longitud de carácter en el extremo

Si 8 caracteres no son suficientes, entonces replique códigos adicionales para los siguientes caracteres en una cadena.

función final:

=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

Esto no es una cita única, porque el CÓDIGO de un carácter individual puede ser de 2 o 3 dígitos; combinación de decir 6 letras puede tienen el mismo código que una combinación de decir 5 letras más. –

+0

Proporcione tales ejemplos. –

+0

Intente convertir esta cadena de códigos ASCII aquí a letras; Cuento al menos 6 maneras de hacer nombres propios de esta cadena volteando 1/2/3 dígitos de los caracteres alrededor de: 6510097109236666111983283116463280101116101 [intente comenzar con este patrón: 232331232223222333]. Recuerde: la clave para las entradas de usuario que se calcula siempre es tratar con casos de esquina. Son las entradas poco probables del usuario las que crean más dolor si su entrada de datos no puede manejar todos los casos. –

0

Identificador único basado en el número de caracteres específicos en el texto. Usé un identificador basado en vocales y números.

=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

Tenga en cuenta que esto solo funciona si no hay cadenas que tengan los mismos caracteres pero en un orden diferente. es decir: 21 calle de salto y 12 calle de salto serían lo mismo en este método. –

0

Dice que confía en que no haya valores duplicados en sus palabras. Para impulsarlo aún más, ¿estás seguro de que los primeros 8 caracteres de una palabra serían únicos?

Si es así, puede usar la fórmula siguiente. Funciona tomando individualmente el código ASCII de cada personaje - 40 [asumiendo caracteres normales, esto pone números entre 8 & 57, y letras entre 57 & 122], y multiplicando ese código de caracteres por 10^[la colocación de los dígitos de ese personaje en la palabra ] Básicamente toma el código de carácter [-40] y concatena cada código con el siguiente.

EDIT Tenga en cuenta que este código ya no requiere que existan al menos 8 caracteres en su palabra para evitar un error, ya que la palabra actual que se codifica tiene 8 "0" 's adjuntos.

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

Tenga en cuenta que, ya que utiliza los valores ASCII de los caracteres, el ID # podría ser utilizado para identificar el nombre directamente - esto realmente no crear el anonimato, sólo se convierte 8 caracteres únicos en un número único. Está ofuscado con el -40, pero no es realmente "seguro" en ese sentido. El -40 es solo para obtener letras y números normales en el rango de 2 dígitos, por lo que multiplicar por 10^0,2,4 etc. creará un complemento único de 2 dígitos para el código creado.

EDITAR PARA Método alternativo

que ya había intentado hacer esto por lo que se vería en cada letra del alfabeto, contar el número de veces que aparece en la palabra, y luego se multiplican por 10 * [la posición de esa letra en el alfabeto]. El problema al hacer esto (ver el comentario a continuación para la fórmula) es que requirió un número de 10^26-1, que está más allá de la precisión del punto flotante de Excel. Sin embargo, tengo una versión modificada de ese método:

Al limitar el número de caracteres permitidos en el alfabeto, podemos obtener el máximo tamaño posible de 10^15-1, que Excel puede calcular correctamente.La fórmula es la siguiente:

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

[la derecha ("00000000000000" ... parte de la fórmula está destinado a mantener todos los códigos de la misma cantidad de caracteres]

Tenga en cuenta que aquí, es un alfabeto cadena llamada que contiene los caracteres: "abcdehilmnorstu". Por ejemplo, usando la fórmula anterior, la palabra "asdf" cuenta las instancias de a, s y d, pero no 'f' que no está en mi alfabeto contraído. código de "asdf" sería:

Esto solo funciona con las siguientes suposiciones:

Las letras no enumeradas (ni los números ni los caracteres especiales) no son necesarias para que cada nombre sea único. Por ejemplo, asdf & asd tendría el mismo código en el método anterior.

Y,

El orden de las letras no está obligado a hacer que cada nombre único. Por ejemplo, asd & dsa tendría el mismo código en el método anterior.

+0

Nota: traté de hacer esto contando individualmente el número de caracteres de az en cada palabra y colocando ese número (suponiendo 0-9) en el dígito de un número de 10^26, y hubiera funcionado si 10^26 wasn está fuera de la precisión de Excel con valores de coma flotante. Aquí se muestra: = TEXTO (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,25,26} -LEN (SUSTITUTO (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

[En el ejemplo anterior, el alfabeto es un rango con nombre que contiene una sola cadena de" abcd ... z "]. –

Cuestiones relacionadas