如何在Excel中创建GUID?

73

我需要一个函数来在Excel单元格中添加GUID。我发现这个Stack Overflow上的旧问题,但不起作用。它建议使用以下函数:

=CONCATENATE(DEC2HEX(RANDBETWEEN(0,4294967295),8),"-",DEC2HEX(RANDBETWEEN(0,6553‌​5),4),"-"
    ,DEC2HEX(RANDBETWEEN(16384,20479),4),"-",DEC2HEX(RANDBETWEEN(32768,49151‌​),4),"-"
    ,DEC2HEX(RANDBETWEEN(0,65535),4),DEC2HEX(RANDBETWEEN(0,4294967295),8))

我一直无法让连接方法正常工作,所以尝试使用“&”符号进行连接。这似乎有效,但是在第二个DEX2HEX块中,我收到了一个无法解释的错误:DEC2HEX(RANDBETWEEN(0,6553‌​5),4)。Excel公式评估器显示它无效,但我似乎完全找不出原因。有任何想法吗?


为什么不直接使用同一问题中提供的VBA代码呢? - LittleBobbyTables - Au Revoir
你使用的是哪个版本的Excel?据我所知,RANDBETWEEN函数只在2007年后的版本中引入。如果你使用的是2003版本,请将其替换为INT(RAND()*65535)函数。 - Peter Albert
@PeterL.:啊,我明白了。我太蠢了,下次应该更好地阅读问题... :-) - Peter Albert
1
@LittleBobbyTables 尝试过了,但好像也没起作用。该函数只是产生了一个 #!VALUE 错误。 - fraxture
1
我想我不必指出这并没有生成“真正”的GUID——因为它们没有版本号。有关详细信息,请参阅https://en.wikipedia.org/wiki/Globally_unique_identifier。 - Fowl
显示剩余6条评论
14个回答

107
自现代版的Excel起,使用逗号而非分号作为语法分隔符。我发布这个答案是为了方便其他人,这样他们就不必替换字符串——我们都有点懒……呃……人类,对吧?
或者,如果你像我一样讨厌GUID大喊大叫,那么我们可以像这样全部小写化。
=LOWER(CONCATENATE(DEC2HEX(RANDBETWEEN(0,4294967295),8),"-",DEC2HEX(RANDBETWEEN(0,65535),4),"-",DEC2HEX(RANDBETWEEN(0,65535),4),"-",DEC2HEX(RANDBETWEEN(0,65535),4),"-",DEC2HEX(RANDBETWEEN(0,4294967295),8),DEC2HEX(RANDBETWEEN(0,65535),4)))

13
逗号和分号的区别在于本地化,而不是现代或不太现代的Excel。然而,回答很好。 - trigras
8
我需要分号,即=CONCATENATE(DEC2HEX(RANDBETWEEN(0;4294967295);8);" - ";DEC2HEX(RANDBETWEEN(0;42949);4);" - ";DEC2HEX(RANDBETWEEN(0;42949);4);" - ";DEC2HEX(RANDBETWEEN(0;42949);4);" - ";DEC2HEX(RANDBETWEEN(0;4294967295);8);DEC2HEX(RANDBETWEEN(0;42949);4)) - Matt
3
如果相信 RANDBETWEEN(0,42949) 应该是 RANDBETWEEN(0,65535),否则 GUID 的四位数字部分将仅在 0000 和 A7C5 之间,而它们应该一直到 FFFF。 - Reversed Engineer
2
@ReversedEngineer 你说得对。我感到印象深刻,一部分是因为你注意到了它,另一部分是因为在将近5年的时间里没有其他人注意到它!我相信我最初使用的是4294967295,它对应于16^8,即8个连续的F。然后,我选择了前4个初始的十进制数字。我的错。 - Konrad Viltersten
1
请注意,这不是UUID v4。第三组需要以4开头。 - Gerhard Powell
显示剩余12条评论

37

我正在使用以下函数在 v.2013 版本的 Excel VBA 宏代码中:

Public Function GetGUID() As String 
    GetGUID = Mid$(CreateObject("Scriptlet.TypeLib").GUID, 2, 36) 
End Function 

无法在Excel 2013中使用PeterL的解决方案...经过总共10秒的调试函数,我发现你的解决方案更适合我。完美地工作。谢谢! - Jason Cragun
11
这个应该替代 Frazture 的答案,因为它更加直接,并且依赖系统生成 Guid。Fraxture 的解决方案(无意冒犯)甚至不能创建有效的 Guid,因为它没有考虑当前时间、MAC 地址等因素。它们也不包括 Guid 版本位。Guid 不仅仅是一组随机字符,它们背后有意义。更多信息请参见:https://en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm - Josh M.
4
注意:在安装 Windows 更新后,库可能会出现问题(权限被拒绝)。https://dev59.com/u6Pia4cB1Zd3GeqPx2bJ - Radek
2
我确认@Radek的评论,在Office进行安全更新后,此机制不再起作用。 https://dev59.com/1FcO5IYBdhLWcg3wtz_1#45332789记录了Microsoft推荐的方法,以防止上述函数导致“权限被拒绝”错误或使用替代函数。 - DeChrist
声明函数 CoCreateGuid Lib "ole32" (ByRef GUID As Byte) As Long 公共函数 GenerateGUID() As String Dim ID(0 To 15) As Byte Dim N As Long Dim GUID As String Dim Res As Long Res = CoCreateGuid(ID(0))For N = 0 To 15 GUID = GUID & IIf(ID(N) < 16, "0", "") & Hex$(ID(N)) If Len(GUID) = 8 Or Len(GUID) = 13 Or Len(GUID) = 18 Or Len(GUID) = 23 Then GUID = GUID & "-" End If Next N GenerateGUID = GUIDEnd Function - rchacko

36
=CONCATENATE(
    DEC2HEX(RANDBETWEEN(0;4294967295);8);"-";
    DEC2HEX(RANDBETWEEN(0;42949);4);"-";
    DEC2HEX(RANDBETWEEN(0;42949);4);"-";
    DEC2HEX(RANDBETWEEN(0;42949);4);"-";
    DEC2HEX(RANDBETWEEN(0;4294967295);8);
    DEC2HEX(RANDBETWEEN(0;42949);4)
)

1
我使用Excel 2013将所有分号替换为逗号。 - biscuit314
9
我需要将“;”替换为“,”,然后一切都运行得很好!谢谢 :) '=CONCATENATE(DEC2HEX(RANDBETWEEN(0,4294967295),8),"-",DEC2HEX(RANDBETWEEN(0,42949),4),"-",DEC2HEX(RANDBETWEEN(0,42949),4),"-",DEC2HEX(RANDBETWEEN(0,42949),4),"-",DEC2HEX(RANDBETWEEN(0,4294967295),8),DEC2HEX(RANDBETWEEN(0,42949),4))' - Eugene Scray
6
如果它走起来像 GUID,说起话来也像 GUID,那么它就不是 GUID。 - IvanP
1
请注意,这不会生成有效的4号GUID/UUID版本,请参见https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)。问题中的公式非常好(https://dev59.com/qGw05IYBdhLWcg3wykvn#12219726),或者查看Masud、Fredder或nidkil的答案。 - Sir Kill A Lot
如果认为 RANDBETWEEN(0;42949) 应该是 RANDBETWEEN(0;65535),否则 GUID 的四位数字部分只会在 0000 和 A7C5 之间,而它们应该一直到 FFFF。 - Reversed Engineer

14
=LOWER(
    CONCATENATE(
        DEC2HEX(RANDBETWEEN(0,POWER(16,8)),8), "-", 
        DEC2HEX(RANDBETWEEN(0,POWER(16,4)),4),"-","4", 
        DEC2HEX(RANDBETWEEN(0,POWER(16,3)),3),"-",
        DEC2HEX(RANDBETWEEN(8,11)),
        DEC2HEX(RANDBETWEEN(0,POWER(16,3)),3),"-",
        DEC2HEX(RANDBETWEEN(0,POWER(16,8)),8),
        DEC2HEX(RANDBETWEEN(0,POWER(16,4)),4)
    )
)

从 git @mobilitymaster 获取。


1
我把这个代码粘贴到一个单元格里,它似乎很好地工作了。但是当我把它粘贴到另一个单元格中时,第一个单元格发生了变化。然后我尝试了另一个单元格,前两个单元格都发生了变化...为什么会这样? - Chris Seline
1
这是由于 Excel 中的自动计算设置导致的。如果您进入 Excel 选项,然后选择公式,您将看到一个名为“工作簿计算”的选项,如果您禁用它,它将仅在手动按下底部窗格中的按钮时运行计算。 - Ray Suelzer
1
警告:此公式中间有一个随机常数“4”... - Sancarn
1
@Sancarn:它生成一个有效的版本4 GUID/UUID,请参见https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)(还请注意使用RANDBETWEEN(8,11)强制使用的另外两个固定位)。 - Sir Kill A Lot
1
@Sancarn:这就是GUID/UUID的定义方式。在不同版本中,所有这些位和字节都有不同的含义(例如,版本3和5基于命名空间哈希)。只有第4版是随机的,除了那些用来区分它们与其他版本/变体的几个版本和变体位。维基百科文章还有一个关于冲突的条目,这可能是正确的 :-),针对第4版,它声明:“……在103万亿个第4版UUID中找到重复项的概率是十亿分之一。” - Sir Kill A Lot
显示剩余2条评论

10
这个问题与函数本身无关。经过一番搜索,问题出在复制和粘贴上。试着把你原始问题中发布的 RANDBETWEEN(0,65535) 字符串复制并粘贴到十六进制编辑器中,你会发现在 65535 中实际上有两个空字符。
00000000  52 41 4E 44 42 45 54 57 45 45 4E 28 30 2C 36 35  RANDBETWEEN(0,65
00000010  35 33 00 00 35 29                                53‌..​5)

2
你是真正的黑客和天才。 - hongsy
@hongsy:谢谢!真的非常感激;o) - user1945782

3

对我来说,这在Excel西班牙语中是正确的。

=CONCATENAR(
DEC.A.HEX(ALEATORIO.ENTRE(0,4294967295),8),"-",
DEC.A.HEX(ALEATORIO.ENTRE(0,65535),4),"-",
DEC.A.HEX(ALEATORIO.ENTRE(16384,20479),4),"-",
DEC.A.HEX(ALEATORIO.ENTRE(32768,49151),4),"-",
DEC.A.HEX(ALEATORIO.ENTRE(0,65535),4),
DEC.A.HEX(ALEATORIO.ENTRE(0,4294967295),8)
)

1
荷兰版Excel的公式:
=KLEINE.LETTERS(
    TEKST.SAMENVOEGEN(
        DEC.N.HEX(ASELECTTUSSEN(0;MACHT(16;8));8);"-";
        DEC.N.HEX(ASELECTTUSSEN(0;MACHT(16;4));4);"-";"4";
        DEC.N.HEX(ASELECTTUSSEN(0;MACHT(16;3));3);"-";
        DEC.N.HEX(ASELECTTUSSEN(8;11));
        DEC.N.HEX(ASELECTTUSSEN(0;MACHT(16;3));3);"-";
        DEC.N.HEX(ASELECTTUSSEN(0;MACHT(16;8));8);
        DEC.N.HEX(ASELECTTUSSEN(0;MACHT(16;4));4)
    )
)

0

德国Excel的公式:

=KLEIN(
    VERKETTEN(
        DEZINHEX(ZUFALLSBEREICH(0;POTENZ(16;8));8);"-";
        DEZINHEX(ZUFALLSBEREICH(0;POTENZ(16;4));4);"-";"4";
        DEZINHEX(ZUFALLSBEREICH(0;POTENZ(16;3));3);"-";
        DEZINHEX(ZUFALLSBEREICH(8;11));
        DEZINHEX(ZUFALLSBEREICH(0;POTENZ(16;3));3);"-";
        DEZINHEX(ZUFALLSBEREICH(0;POTENZ(16;8));8);
        DEZINHEX(ZUFALLSBEREICH(0;POTENZ(16;4));
    )
)

您可能在这个地方缺少了闭合括号 ) - user1945782

0

在尝试了许多选项并遇到了新版本Excel(2016)的各种问题后,我发现了这篇来自微软的帖子,它非常有效。我使用了一些来自danwagner.co帖子的代码对其进行了改进。

Private Declare PtrSafe Function CoCreateGuid Lib "ole32.dll" (Guid As GUID_TYPE) As LongPtr

Private Declare PtrSafe Function StringFromGUID2 Lib "ole32.dll" (Guid As GUID_TYPE, ByVal lpStrGuid As LongPtr, ByVal cbMax As Long) As LongPtr

Function CreateGuidString(Optional IncludeHyphens As Boolean = True, Optional IncludeBraces As Boolean = False)
    Dim Guid As GUID_TYPE
    Dim strGuid As String
    Dim retValue As LongPtr

    Const guidLength As Long = 39 'registry GUID format with null terminator {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

    retValue = CoCreateGuid(Guid)

    If retValue = 0 Then
        strGuid = String$(guidLength, vbNullChar)
        retValue = StringFromGUID2(Guid, StrPtr(strGuid), guidLength)

        If retValue = guidLength Then
            '   valid GUID as a string
            '   remove them from the GUID
            If Not IncludeHyphens Then
                strGuid = Replace(strGuid, "-", vbNullString, Compare:=vbTextCompare)
            End If

            '   If IncludeBraces is switched from the default False to True,
            '   leave those curly braces be!
            If Not IncludeBraces Then
                strGuid = Replace(strGuid, "{", vbNullString, Compare:=vbTextCompare)
                strGuid = Replace(strGuid, "}", vbNullString, Compare:=vbTextCompare)
            End If


            CreateGuidString = strGuid
        End If
    End If

End Function


Public Sub TestCreateGUID()
    Dim Guid As String
    Guid = CreateGuidString() '<~ default
    Debug.Print Guid
End Sub

原始的 MS 帖子中有其他选项,可以在此处找到: https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-msoffice_custom-mso_2010/guid-run-time-error-70-permission-denied/c9ee4076-98af-4032-bc87-40ad7aa7cb38


如果我尝试这个,就会出现错误:用户定义的类型未声明(Windows 10,Excel 2019)。 - habakuk
@habakuk,这需要在先前的回答中定义GUID_TYPE - Craig

0

肯·汤普森是对的!- 对我来说,这种方法也适用(Excel 2016),但类型定义GUID_TYPE被跳过,因此完整的脚本如下:

Private Type GUID_TYPE
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(7) As Byte
End Type

Private Declare PtrSafe Function CoCreateGuid Lib "ole32.dll" (Guid As GUID_TYPE) As LongPtr

Private Declare PtrSafe Function StringFromGUID2 Lib "ole32.dll" (Guid As GUID_TYPE, ByVal lpStrGuid As LongPtr, ByVal cbMax As Long) As LongPtr

Function CreateGuidString(Optional IncludeHyphens As Boolean = True, Optional IncludeBraces As Boolean = False)
    Dim Guid As GUID_TYPE
    Dim strGuid As String
    Dim retValue As LongPtr

    Const guidLength As Long = 39 'registry GUID format with null terminator {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

    retValue = CoCreateGuid(Guid)

    If retValue = 0 Then
        strGuid = String$(guidLength, vbNullChar)
        retValue = StringFromGUID2(Guid, StrPtr(strGuid), guidLength)

        If retValue = guidLength Then
            '   valid GUID as a string
            '   remove them from the GUID
            If Not IncludeHyphens Then
                strGuid = Replace(strGuid, "-", vbNullString, Compare:=vbTextCompare)
            End If

            '   If IncludeBraces is switched from the default False to True,
            '   leave those curly braces be!
            If Not IncludeBraces Then
                strGuid = Replace(strGuid, "{", vbNullString, Compare:=vbTextCompare)
                strGuid = Replace(strGuid, "}", vbNullString, Compare:=vbTextCompare)
            End If


            CreateGuidString = strGuid
        End If
    End If

End Function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接