Как я могу генерировать GUID в Excel? - PullRequest
44 голосов
/ 11 августа 2011

У меня есть файл Excel с одним заказом в каждой строке, и я хочу, чтобы каждый заказ имел уникальный идентификатор, поэтому будет столбец Уникальный идентификатор.Каждый раз, когда я заполняю строку, я хочу, чтобы Excel автоматически заполнял для меня столбец Уникальный идентификатор.Я провел некоторое исследование и был направлен в сторону GUID.Я нашел следующий код:

Function GenGuid() As String
Dim TypeLib As Object
Dim Guid As String
Set TypeLib = CreateObject("Scriptlet.TypeLib")
Guid = TypeLib.Guid
' format is {24DD18D4-C902-497F-A64B-28B2FA741661}
Guid = Replace(Guid, "{", "")
Guid = Replace(Guid, "}", "")
Guid = Replace(Guid, "-", "")
GenGuid = Guid
End Function

, но я не уверен, как я могу это реализовать.Любая помощь будет принята с благодарностью.Заранее спасибо.

Ответы [ 11 ]

36 голосов
/ 31 августа 2012

Следующее выражение Excel оценивает GUID V4:

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

-или (в зависимости от настройки локали / десятичного разделителя и разделителей списка) -

=CONCATENATE(DEC2HEX(RANDBETWEEN(0;4294967295);8);"-";DEC2HEX(RANDBETWEEN(0;65535);4);"-";DEC2HEX(RANDBETWEEN(16384;20479);4);"-";DEC2HEX(RANDBETWEEN(32768;49151);4);"-";DEC2HEX(RANDBETWEEN(0;65535);4);DEC2HEX(RANDBETWEEN(0;4294967295);8))

Обратите внимание, что первый символ третьей группы всегда равен 4 для обозначения GUID / UUID V4 (сгенерированного псевдослучайного числа) согласно разделу 4.4 RFC 4122.

Также обратите внимание, что первый символ четвертой группы всегда находится между 8 и B для одного и того же RFC.

Стандартный отказ от ответственности: результирующие GUID / UUID не являются криптографически стойкими.

30 голосов
/ 17 апреля 2014

Я использовал следующую функцию в v.2013 excel vba для создания GUID и работает хорошо.

Public Function GetGUID() As String 
    GetGUID = Mid$(CreateObject("Scriptlet.TypeLib").GUID, 2, 36) 
End Function 
10 голосов
/ 24 января 2013

Я знаю, что на этот вопрос дан ответ, но я думаю, что рассматриваемый код должен выглядеть примерно так, как на этой странице: http://snipplr.com/view/37940/

Не тестировался, но этот код, похоже, подключается к Windows APIчтобы получить его GUID - я бы попробовал поместить его в открытый модуль и набрать =GetGUId() в ячейке Excel, чтобы посмотреть, что я получу.Если он работает в VB6, у вас есть большие шансы, что он работает и в VBA:

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

Private Declare Function CoCreateGuid Lib "OLE32.DLL" (pGuid As GUID) As Long

Public Function GetGUID() As String
'(c) 2000 Gus Molina

    Dim udtGUID As GUID

    If (CoCreateGuid(udtGUID) = 0) Then

        GetGUID = _
            String(8 - Len(Hex$(udtGUID.Data1)), "0") & Hex$(udtGUID.Data1) & _
            String(4 - Len(Hex$(udtGUID.Data2)), "0") & Hex$(udtGUID.Data2) & _
            String(4 - Len(Hex$(udtGUID.Data3)), "0") & Hex$(udtGUID.Data3) & _
            IIf((udtGUID.Data4(0) < &H10), "0", "") & Hex$(udtGUID.Data4(0)) & _
            IIf((udtGUID.Data4(1) < &H10), "0", "") & Hex$(udtGUID.Data4(1)) & _
            IIf((udtGUID.Data4(2) < &H10), "0", "") & Hex$(udtGUID.Data4(2)) & _
            IIf((udtGUID.Data4(3) < &H10), "0", "") & Hex$(udtGUID.Data4(3)) & _
            IIf((udtGUID.Data4(4) < &H10), "0", "") & Hex$(udtGUID.Data4(4)) & _
            IIf((udtGUID.Data4(5) < &H10), "0", "") & Hex$(udtGUID.Data4(5)) & _
            IIf((udtGUID.Data4(6) < &H10), "0", "") & Hex$(udtGUID.Data4(6)) & _
            IIf((udtGUID.Data4(7) < &H10), "0", "") & Hex$(udtGUID.Data4(7))
    End If

End Function

Спасибо, Гас Молина!

Если этот код работает (чего я не делаюсомневаюсь), я думаю, вы получите новый набор GUID всякий раз, когда функция будет оценена, что означает каждый раз, когда вычисляется лист - например, когда вы сохраняете книгу.Обязательно скопируйте-pastespecial-values, если вам нужны GUID для дальнейшего использования ... что вполне вероятно.

3 голосов
/ 24 ноября 2017

Я нашел красивое решение здесь:
http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=751237&msg=8634441

Option Explicit

Private Type GUID
  Data1 As Long
  Data2 As Integer
  Data3 As Integer
  Data4(0 To 7) As Byte
End Type
Private Declare Function CoCreateGuid Lib "ole32" (pguid As GUID) As Long
Private Declare Function StringFromGUID2 Lib "ole32" ( _
  rguid As GUID, ByVal lpsz As Long, ByVal cchMax As Long) As Long

Public Function CreateGUID() As String
  Dim NewGUID As GUID
  CoCreateGuid NewGUID
  CreateGUID = Space$(38)
  StringFromGUID2 NewGUID, StrPtr(CreateGUID), 39
End Function
2 голосов
/ 28 сентября 2017

Подход VBA, основанный на генерации случайных чисел с использованием функции Rnd(), а не на внешних вызовах API или Scriptlet.TypeLib:

Public Function CreateGUID() As String
    Do While Len(CreateGUID) < 32
        If Len(CreateGUID) = 16 Then
            '17th character holds version information
            CreateGUID = CreateGUID & Hex$(8 + CInt(Rnd * 3))
        End If
        CreateGUID = CreateGUID & Hex$(CInt(Rnd * 15))
    Loop
    CreateGUID = "{" & Mid(CreateGUID, 1, 8) & "-" & Mid(CreateGUID, 9, 4) & "-" & Mid(CreateGUID, 13, 4) & "-" & Mid(CreateGUID, 17, 4) & "-" & Mid(CreateGUID, 21, 12) & "}"
End Function

По сути, это реализация ответа NekojiruSou на языке VBA (он также генерирует GUID v4) и имеет те же ограничения, но будет работать в VBA и может быть проще в реализации.

Обратите внимание, что вы можете опустить последнюю строку, чтобы не возвращать черточки и фигурные скобки в результате.

2 голосов
/ 19 декабря 2012

То же самое для немецкий Версия для Excel:

=VERKETTEN(DEZINHEX(ZUFALLSBEREICH(0;4294967295);8);"-";DEZINHEX(ZUFALLSBEREICH(0;65535);4);"-";DEZINHEX(ZUFALLSBEREICH(16384;20479);4);"-";DEZINHEX(ZUFALLSBEREICH(32768;49151);4);"-";DEZINHEX(ZUFALLSBEREICH(0;65535);4);DEZINHEX(ZUFALLSBEREICH(0;4294967295);8))
1 голос
/ 25 января 2018

Поскольку обновление Windows вывело «Scriptlet.TypeLib», попробуйте следующее:

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

В качестве альтернативы,

, если вы подключаетесь к SQL Server 2008 или новее, попробуйте использоватьВместо этого используется SQL NEWID ().

0 голосов
/ 10 апреля 2019

Я создал функцию VBA, которая работает как на Mac, так и на Windows:

https://github.com/Martin-Carlsson/Business-Intelligence-Goodies/blob/master/Excel/GenerateGiud/GenerateGiud.bas

'Generates a guid, works on both mac and windows 
Function Guid() As String
    Guid = RandomHex(3) + "-" + _
        RandomHex(2) + "-" + _
        RandomHex(2) + "-" + _
        RandomHex(2) + "-" + _
        RandomHex(6)
End Function

'From: https://www.mrexcel.com/forum/excel-questions/301472-need-help-generate-hexadecimal-codes-randomly.html#post1479527
Private Function RandomHex(lngCharLength As Long)
    Dim i As Long
    Randomize
    For i = 1 To lngCharLength
        RandomHex = RandomHex & Right$("0" & Hex(Rnd() * 256), 2)
    Next
End Function
0 голосов
/ 21 июля 2017

Недавно я столкнулся с проблемами при использовании CreateObject ("Scriptlet.TypeLib") в некотором коде vba.

Поэтому на основе функций Excel NekojiruSou было написано следующее, которое должно работать без каких-либо специальных функций Excel.Это может быть использовано для разработки пользовательской функции в Excel.

Public Function Get_NewGUID() As String
    'Returns GUID as string 36 characters long

    Randomize

    Dim r1a As Long
    Dim r1b As Long
    Dim r2 As Long
    Dim r3 As Long
    Dim r4 As Long
    Dim r5a As Long
    Dim r5b As Long
    Dim r5c As Long

    'randomValue = CInt(Math.Floor((upperbound - lowerbound + 1) * Rnd())) + lowerbound
    r1a = RandomBetween(0, 65535)
    r1b = RandomBetween(0, 65535)
    r2 = RandomBetween(0, 65535)
    r3 = RandomBetween(16384, 20479)
    r4 = RandomBetween(32768, 49151)
    r5a = RandomBetween(0, 65535)
    r5b = RandomBetween(0, 65535)
    r5c = RandomBetween(0, 65535)

    Get_NewGUID = (PadHex(r1a, 4) & PadHex(r1b, 4) & "-" & PadHex(r2, 4) & "-" & PadHex(r3, 4) & "-" & PadHex(r4, 4) & "-" & PadHex(r5a, 4) & PadHex(r5b, 4) & PadHex(r5c, 4))

End Function

Public Function Floor(ByVal X As Double, Optional ByVal Factor As Double = 1) As Double
    'From: http://www.tek-tips.com/faqs.cfm?fid=5031
    ' X is the value you want to round
    ' Factor is the multiple to which you want to round
        Floor = Int(X / Factor) * Factor
End Function

Public Function RandomBetween(ByVal StartRange As Long, ByVal EndRange As Long) As Long
    'Based on https://msdn.microsoft.com/en-us/library/f7s023d2(v=vs.90).aspx
    '         randomValue = CInt(Math.Floor((upperbound - lowerbound + 1) * Rnd())) + lowerbound
        RandomBetween = CLng(Floor((EndRange - StartRange + 1) * Rnd())) + StartRange
End Function

Public Function PadLeft(text As Variant, totalLength As Integer, padCharacter As String) As String
    'Based on https://stackoverflow.com/questions/12060347/any-method-equivalent-to-padleft-padright
    ' with a little more checking of inputs

    Dim s As String
    Dim inputLength As Integer
    s = CStr(text)
    inputLength = Len(s)

    If padCharacter = "" Then
        padCharacter = " "
    ElseIf Len(padCharacter) > 1 Then
        padCharacter = Left(padCharacter, 1)
    End If

    If inputLength < totalLength Then
        PadLeft = String(totalLength - inputLength, padCharacter) & s
    Else
        PadLeft = s
    End If

End Function

Public Function PadHex(number As Long, length As Integer) As String
    PadHex = PadLeft(Hex(number), 4, "0")
End Function
0 голосов
/ 21 января 2017

Если вы вставляете записи в базу данных, вы можете использовать этот способ для создания GUID.

Это, пожалуй, самый простой и легкий способ реализации, поскольку вам не нужна сложная VBA функция при использовании встроенной функции SQL.

В операторе используется NewID(),

Синтаксис выглядит следующим образом:

INSERT INTO table_name (ID,Column1,Column2,Column3)
VALUES (NewID(),value1,value2,value3) 

В синтаксисе VBA он выглядит следующим образом:

strSql = "INSERT INTO table_name " _
       & "(ID,Column1,Column2,Column3) " _
       & "VALUES (NewID(),value1,value2,value3)"

А если вам нужно объединить значения, простообрабатывать его как строку и объединять, как обычно для оператора SQL,

strSql = "INSERT INTO table_name " _
       & "(ID,Column1,Column2,Column3) " _
       & "VALUES (" & "NewID()" & "," & "value1" & "," & "value2" & "," & "value3" & ")"
...