Excel 2007 – 基于文本生成唯一的ID?

我有一个工作表,B列中有一个名称列表,A列中有一个ID列。我想知道是否有某种公式可以在该行的列B中取值,并根据文本生成某种types的ID ? 每个名字也是独一无二的,不会以任何方式重复。

如果我不必真的使用VBA,那将是最好的。 但是,如果我必须这样做。

对不起,我没有find一个公式解决scheme,即使这个线程可能有帮助(试图计算拼字游戏中的点),但我没有find一种方法来确保生成的哈希将是唯一的

然而,这里是我的解决scheme,基于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) 

[编辑]增加* i考虑到的顺序。 它适用于我的unit testing

没有VBA的解决scheme。

基于前8个字符的逻辑+单元格中的字符数。

= CODE(cell)返回第一个字母的代码编号

= CODE(MID(cell,2,1))返回第二个字母的代码号码

= IFERROR(CODE(MID(cell,9,1))如果第9个字符不存在,则返回0

= LEN(cell)的字符数

连接第一个8位代码+在末尾添加字符长度

如果8个字符不够,则为string中的下一个字符复制附加代码。

最终function:

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

在这里输入图像说明

可能是您的需要的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 

testing使用

 Sub testGUID() MsgBox GUID End Sub 

如何最好的实施取决于你的需求。 一种方法是写一个macros来获得一个GUID填充名称存在的列。 (注意,使用它作为udf是不行的,因为它将在重新计算时返回一个新的GUID)

编辑
看到这个答案创build一个string的SHA1哈希

你只是想要一个递增的数字ID列旁边的值? 如果是这样,并且如果你的值永远是唯一的,你可以很容易地用公式做到这一点。

如果您的值在列B中,那么从A2开始,例如在A2中,您可以input公式“= IF(B2 =”“,”,1 + MAX(A $ 1:A1))“。 只要数据扩展,就可以将其复制并粘贴,并且它将为B列中的每一行增加一个数字标识符,该标识符不为空。

如果您需要做更复杂的事情,比如识别和重新标识重复值,或者在标识符填充后使标识符“冻结”,请告诉我。 目前,当您清除或添加值到列表中时,标识符会自行上下切换,因此如果数据更改,则需要小心。

基于文本中特定字符数的唯一标识符。 我使用了一个基于元音和数字的标识符。

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

你说你相信你的话没有重复的价值。 为了进一步推进,你是否确信任何单词中的前8个字符都是唯一的?

如果是这样,你可以使用下面的公式。 它通过单独采取每个字符的ASCII代码来工作–40 [假设正常字符,这使得数字在8和57之间,字母在57和122之间],并且将字符代码乘以10 [字符在字中的数字位置]。 基本上它采用了字符代码[-40],并将每个代码连接到下一个代码。

编辑请注意,此代码不再需要在您的单词中至less存在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值,所以可以使用ID#直接标识名称 – 这不会真正创build匿名,它只会将8个唯一字符转换为唯一的数字。 这是-40的混淆,但不是真正的“安全”在这个意义上。 -40只是在2位数范围内得到正常的字母和数字,所以乘以10 ^ 0,2,4等将创build一个2位独特的附加到创build的代码。

编辑替代方法

我以前曾试图这样做,以便查看字母表中的每个字母,计算它出现在单词中的次数,然后乘以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”部分是为了保持所有代码的字符数相同]

请注意,在这里,Alphabet是一个命名string,其中包含字符“abcdehilmnorstu”。 例如,使用上面的公式,单词“asdf”计算a,s和d的实例,但不包括不在我的缩写字母表中的“f”。 asdf的代码是:

001000000001001

这只适用于以下假设:

未列出的字母(也不是数字/特殊字符)不需要使每个名字都是唯一的。 例如,asdf&asd在上面的方法中会有相同的代码。

和,

这些字母的顺序不需要使每个名字都是唯一的。 例如,asd&dsa在上面的方法中将具有相同的代码。