我有一张工作表,其中包含B列中的名称列表和A中的ID列。我想知道是否有某种公式可以获取该行B列中的值并生成某种基于ID的在文字上?每个名称也是唯一的,不会以任何方式重复。
如果我不必真的使用VBA,那将是最好的。但如果必须,那就这样吧。
答案 0 :(得分:3)
没有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)
答案 1 :(得分:1)
抱歉,即使this thread可能有所帮助(尝试计算拼字游戏游戏中的积分),我也没有找到含公式的解决方案,但我找不到方法确保生成的哈希值 unique 。
然而,这是我的解决方案,基于 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
以考虑订单。它适用于我的单元测试
答案 2 :(得分:0)
根据您的需要可能是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哈希值,请参阅this answer
答案 3 :(得分:0)
您是否只想将增量数字ID列放在您的值旁边?如果是这样,并且如果您的值始终是唯一的,则可以使用公式轻松完成此操作。
如果您的值在B列中,例如从标题下方的B2开始,则在A2中键入公式“= IF(B2 =”“,”“,1 + MAX(A $ 1:A1))” 。您可以将数据向下复制并粘贴到数据扩展的位置,并且它将为B列中非空白的每一行增加一个数字标识符。
如果您需要执行更复杂的操作,例如识别和重新识别重复值,或者在填充后使标识符“冻结”,请告知我们。目前,当您清除或向列表中添加值时,标识符将自动上下切换,因此如果数据发生更改,则需要小心。
答案 4 :(得分:0)
基于文本中特定字符数的唯一标识符。我使用了一个基于元音和数字的标识符。
=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";""))
答案 5 :(得分:0)
你说你确信你的话没有重复的值。为了进一步推动它,您是否确信任何单词中的前8个字符都是唯一的?
如果是这样,您可以使用以下公式。它的工作原理是单独拍摄每个字符的ASCII码 - 40 [假设正常字符,这使得数字在8和8之间。 57和57之间的字母和& 122],并将这些字符代码乘以10 ^ [字符中的字符数字位置]。基本上它需要字符代码[-40],并将每个代码连接到下一个代码。
编辑请注意,此代码不再要求您的单词中至少包含8个字符以防止出错,因为要编码的实际单词有8" 0"& #39;附加到它。
=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#直接识别名称 - 这实际上不会创建匿名,它只会将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" ......公式的一部分是为了保持所有代码的字符数相同)
请注意,这里,Alphabet是一个包含字符的命名字符串:" abcdehilmnorstu"。例如,使用上面的公式,单词" asdf"计算a,s和d的实例,但不计算' f'我的签约字母表中没有。 " asdf"的代码将是:
001000000001001
这仅适用于以下假设:
不需要列出的字母(也不是数字/特殊字符)使每个名称都是唯一的。例如,asdf& asd在上面的方法中会有相同的代码。
和
不需要字母的顺序来使每个名称都是唯一的。例如,asd& dsa在上述方法中具有相同的代码。