74

I need a function to add a GUID to cells in excel. I found this previous question on stackoverflow, but it is not working. It suggests the following function:

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

I have been unable to get the concatenate method to work, and so tried it using the "&" figure to concatenate anyway. That seemed to work, but then I get an inexplicable error on the second DEX2HEX block: DEC2HEX(RANDBETWEEN(0,6553‌​5),4). The Excel formula evaluator says it's invalid, but I can't seem to figure out why at all. Any ideas?

Paul
  • 4,160
  • 3
  • 30
  • 56
fraxture
  • 5,113
  • 4
  • 43
  • 83

14 Answers14

98

As of modern version of Excel, there's the syntax with commas, not semicolons. I'm posting this answer for convenience of others so they don't have to replace the strings- We're all lazy... hrmp... human, right?

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

Or, if you like me dislike when a guid screams and shouts and you, we can go lower-cased like this.

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

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • 12
    Comas and semicolons differs because of localization but not because of modern or not so modern Excel. However good answer – trigras Dec 08 '17 at 08:40
  • Perfect! Tested and using – Zin Min Jan 17 '19 at 16:05
  • 8
    I needed semicolons, i.e. `=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 Aug 15 '19 at 13:54
  • @Matt I think this is my highest upvoted answer ever. Kind of sad because I'm much more skilled in other techs. I'm glad for whatever I get, of course, but still... :) – Konrad Viltersten Aug 15 '19 at 16:28
  • @KonradViltersten - Don't misunderstand me, your answer was useful for me, and I upvoted it. Just wanted to mention that for some reasons, my Excel version wants semicolons instead of commas for separating the parameters - don't know where that can be configured (but as [trigras](https://stackoverflow.com/users/2010685/trigras) mentioned, surely a localization issue). However, with commas, it won't work on my end, but with semicolons - so I thought it might be useful for some folks to put it in the comments. – Matt Aug 16 '19 at 08:36
  • @Matt I can't speak for his experience. I believe that has changes between different version but it might also depend on localization. The important thing is to remember that it's always a subject to change so one should try both this and that if it stops working. Thanks for the upvote. I do enjoy those small tickies, haha. – Konrad Viltersten Aug 16 '19 at 21:49
  • 3
    If believe `RANDBETWEEN(0,42949)` should be `RANDBETWEEN(0,65535)`, otherwise the four digit parts of the GUID will only be between 0000 and A7C5 , whereas they should go all the way to FFFF – Reversed Engineer Oct 26 '21 at 11:46
  • 2
    @ReversedEngineer You are correct. I'm impressed partly because you noticed it and partly because no one else did in almost 5 years! I believe I started with `4294967295`, which corresponds to `16^8`, i.e. 8 consecutive `F`. Then, I picked the 4 first initial, decimal digits. My bad. – Konrad Viltersten Oct 27 '21 at 05:19
  • If anybody needs it on a spanish (español) Excel installation: `=CONCATENAR(DEC.A.HEX(ALEATORIO.ENTRE(0;4294967295);8);"-";DEC.A.HEX(ALEATORIO.ENTRE(0;65536);4);"-";DEC.A.HEX(ALEATORIO.ENTRE(0;65536);4);"-";DEC.A.HEX(ALEATORIO.ENTRE(0;65536);4);"-";DEC.A.HEX(ALEATORIO.ENTRE(0;4294967295);8);DEC.A.HEX(ALEATORIO.ENTRE(0;65536);4))` – Marc Nov 15 '21 at 15:19
  • 1
    Note that this is not UUID v4. The 3rd group needs to start with 4. – Gerhard Powell Feb 24 '23 at 19:35
  • @GerhardPowell I'm not sure if I'm getting you correctly. Could you provide any reference to support that statement, please? As far I'm aware, there's no restrictions to what any of the defined groups consist of. – Konrad Viltersten Feb 25 '23 at 15:59
  • @KonradViltersten: https://www.uuidtools.com/decode – Gerhard Powell Mar 03 '23 at 21:27
  • @GerhardPowell I see that the M-digit denotes version and that **may** be 4. However, it's not stated that it **should** be 4. Are you saying that the version the suggested Excel formula produces **is** 4? How can one determine that? Please help me understand. – Konrad Viltersten Mar 04 '23 at 07:56
  • Random UUIDs are version 4. All the versions are allocated to different purposes. http://guid.one/guid – Gerhard Powell Mar 06 '23 at 22:05
  • 1
    @GerhardPowell I had no idea about that property of GUIDs. I'm humbled and amazed. Thank you very much for educating me. This was nerdily exquisite piece of knowledge. – Konrad Viltersten Mar 07 '23 at 19:32
  • The issue with the formula posted by the user is that there are two null characters (`CHAR(0)`) in one of the 65535 characters. See my answer below. – Paul Apr 14 '23 at 09:56
  • @Paul Is that comment addressing the answer of mine, the original question or any of the comments? – Konrad Viltersten Apr 15 '23 at 10:31
38

I am using the following function in v.2013 excel vba macro code

Public Function GetGUID() As String 
    GetGUID = Mid$(CreateObject("Scriptlet.TypeLib").GUID, 2, 36) 
End Function 
rchacko
  • 1,965
  • 23
  • 24
  • couldnt get PeterL's solution to work in Excel 2013.. and after a total of 10 seconds of debugging the function, I found your solution to be a better fit for me. Works perfect. thanks! – Jason Cragun Aug 21 '14 at 21:22
  • 11
    This should be used instead of Frazture's answer because it is much more straightforward and relies on the system to generate the guid. Fraxture's solution (no offense) does not even create a valid guid as it doesn't take things such as the current time, MAC address, etc. into account. They also won't include the guid version bit. Guids are not just a set of random characters, there is meaning behind them. More info here: https://en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm – Josh M. Apr 12 '16 at 15:37
  • 4
    Attention: there may be problem with the library (Permission denied) after installing win update: https://stackoverflow.com/questions/45082258/vba-set-typelib-createobjectscriptlet-typelib-permission-denied – Radek Jul 20 '17 at 11:17
  • 2
    I confirm @Radek 's comment that after a security update to Office, this mechanism no longer works. https://stackoverflow.com/a/45332789/575559 documents the Microsoft recommended methods to prevent the above function from causing a "permission denied" error OR to make use of an alternative function. – DeChrist Sep 20 '17 at 10:55
  • Declare Function CoCreateGuid Lib "ole32" (ByRef GUID As Byte) As Long Public Function 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 = GUID End Function – rchacko Aug 23 '18 at 04:06
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)
)
Paul
  • 4,160
  • 3
  • 30
  • 56
  • 1
    Using Excel 2013 I had to replace all semi-colons with commas. – biscuit314 Oct 25 '16 at 15:50
  • 9
    I needed to replace the ";" with "," and then everything worked out great! Thanks :) '=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 Dec 07 '16 at 19:38
  • 6
    If it walks like a GUID and talks like a GUID it's not a GUID. – IvanP May 11 '17 at 07:40
  • 1
    Please note that this doesn't generate a valid version 4 GUID/UUID, see https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) The formula in the question is perfectly fine (https://stackoverflow.com/a/12219726/729642), or look at the answers from Masud, Fredder, or nidkil. – Sir Kill A Lot May 24 '19 at 15:50
  • If believe `RANDBETWEEN(0;42949)` should be `RANDBETWEEN(0;65535)`, otherwise the four digit parts of the GUID will only be between 0000 and A7C5 , whereas they should go all the way to FFFF – Reversed Engineer Oct 26 '21 at 11:45
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)
    )
)

Taken from git @mobilitymaster.

Paul
  • 4,160
  • 3
  • 30
  • 56
Masud
  • 475
  • 6
  • 6
  • 1
    I pasted this once into a cell and it seemed to work well. But then I pasted it into another cell and the first cell changed. Then I tried another cell and the first 2 cells changed... why does it do that? – Chris Seline Nov 27 '17 at 15:43
  • That is very interesting observation, I was not aware of that. I used 'outside dragging option' in excel to generate guid in batch. Here is a kind of hacky and incomplete explanation, I found the function =randbetween(x,y) changes its value everytime we hit 'enter' anywhere with a new value. One way to stop the random generation I think is generate the guid in batch using 'outside dragging' and then copy all of them and pasting only the value. – Masud Dec 05 '17 at 01:44
  • 1
    It is due to the Automatic calculation setting on in excel. If you go into Excel Options, then Formulas, then you will see something called "Workbook Calcuation" if you disable it, it will only run the calculations when you manually press the button in the bottom pane. – Ray Suelzer Nov 05 '18 at 23:04
  • 1
    WARNING: This has a random constant "4" in the middle of the formula... – Sancarn Dec 18 '18 at 15:16
  • 1
    @Sancarn: It generates a valid version 4 GUID/UUID, see https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) (Also note the other 2 fixed bits which are forced by using RANDBETWEEN(8,11)) – Sir Kill A Lot May 24 '19 at 15:48
  • @SirKillALot interesting, never knew about these. Still have no idea what the point of them is... You're just increasing the likeliness of a duplicate? – Sancarn Jun 10 '19 at 20:25
  • 1
    @Sancarn: That's how GUID/UUIDs are defined. In the different versions all those bits and bytes have different meanings (e.g. version 3 and 5 are based on namespace hashes). Only Version 4 is meant to be random, except those couple version and variant bits to distinguish them from the other versions/variants.                                                                            The Wikipedia article also has en entry about collisions, which is probably correct :-), stating for version 4: "... the probability to find a duplicate within 103 trillion version-4 UUIDs is one in a billion." – Sir Kill A Lot Jun 10 '19 at 22:42
10

This is not a problem with the function at all.

It took me a bit of digging, but the problem is in copying and pasting. Try copying this: RANDBETWEEN(0,6553‌​5) string, posted in your original question, and paste it into a Hex Editor, then you'll see that there are actually two null characters in the 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)
Paul
  • 4,160
  • 3
  • 30
  • 56
3

for me it is correct, in Excel spanish

=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

The formula for Dutch 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)
    )
)
Paul
  • 4,160
  • 3
  • 30
  • 56
nidkil
  • 1,295
  • 1
  • 17
  • 28
0

The formula for French Excel:

=CONCATENER(
DECHEX(ALEA.ENTRE.BORNES(0;4294967295);8);"-";
DECHEX(ALEA.ENTRE.BORNES(0;42949);4);"-";
DECHEX(ALEA.ENTRE.BORNES(0;42949);4);"-";
DECHEX(ALEA.ENTRE.BORNES(0;42949);4);"-";
DECHEX(ALEA.ENTRE.BORNES(0;4294967295);8);
DECHEX(ALEA.ENTRE.BORNES(0;42949);4))

As noted by Josh M, this does not provide a compliant GUID however, but this works well for my current need.

Lionel Hamayon
  • 1,240
  • 15
  • 25
0

The formula for German 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));
    )
)
Fredder
  • 19
  • 2
0

After trying a number of options and running into various issue with newer versions of Excel (2016) I came across this post from MS that worked like a charm. I enhanced it bit using some code from a post by 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

There are additional options in the original MS post found here: 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

0

Ken Thompson is right! - for me also this way works (excel 2016), but type definition GUID_TYPE is skipped, so full scripting is:

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
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
-1

The formula for Polish version:

=ZŁĄCZ.TEKSTY(
    DZIES.NA.SZESN(LOS.ZAKR(0;4294967295);8);"-";
    DZIES.NA.SZESN(LOS.ZAKR(0;42949);4);"-";
    DZIES.NA.SZESN(LOS.ZAKR(0;42949);4);"-";
    DZIES.NA.SZESN(LOS.ZAKR(0;42949);4);"-";
    DZIES.NA.SZESN(LOS.ZAKR(0;4294967295);8);
    DZIES.NA.SZESN(LOS.ZAKR(0;42949);4)
)
Paul
  • 4,160
  • 3
  • 30
  • 56
long
  • 3,692
  • 1
  • 22
  • 38
  • 1
    Please note that this doesn't generate a valid version 4 GUID/UUID, see https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) The formula in the question is perfectly fine (https://stackoverflow.com/a/12219726/729642), or look at the answers from Masud, Fredder, or nidkil. – Sir Kill A Lot May 24 '19 at 15:50
-3

Italian version:

=CONCATENA(
    DECIMALE.HEX(CASUALE.TRA(0;4294967295);8);"-";
    DECIMALE.HEX(CASUALE.TRA(0;42949);4);"-";
    DECIMALE.HEX(CASUALE.TRA(0;42949);4);"-";
    DECIMALE.HEX(CASUALE.TRA(0;42949);4);"-";
    DECIMALE.HEX(CASUALE.TRA(0;4294967295);8);
    DECIMALE.HEX(CASUALE.TRA(0;42949);4))
Paul
  • 4,160
  • 3
  • 30
  • 56
Michele
  • 1,213
  • 2
  • 18
  • 36
  • 2
    Please note that this doesn't generate a valid version 4 GUID/UUID, see https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) The formula in the question is perfectly fine (https://stackoverflow.com/a/12219726/729642), or look at the answers from Masud, Fredder, or nidkil. – Sir Kill A Lot May 24 '19 at 15:49
-3

ESP:

=CONCATENAR(
    DEC.A.HEX(ALEATORIO.ENTRE(0;4294967295);8);"-"; 
    DEC.A.HEX(ALEATORIO.ENTRE(0;42949);4);"-"; 
    DEC.A.HEX(ALEATORIO.ENTRE(0;42949);4);"-"; 
    DEC.A.HEX(ALEATORIO.ENTRE(0;42949);4);"-"; 
    DEC.A.HEX(ALEATORIO.ENTRE(0;4294967295);8); 
    DEC.A.HEX(ALEATORIO.ENTRE(0;42949);4)
)
Paul
  • 4,160
  • 3
  • 30
  • 56
  • 2
    Please note that this doesn't generate a valid version 4 GUID/UUID, see https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) The formula in the question is perfectly fine (https://stackoverflow.com/a/12219726/729642), or look at the answers from Masud, Fredder, or nidkil. – Sir Kill A Lot May 24 '19 at 15:49