在 excel 中,我尝试使用 vba UDF 在表中生成 UUID 列,但我只希望它在第一次调用时运行,以便它生成的 UUID 永远不会改变。
制作 UUID 很简单(修改自https://nolongerset.com/createguid/-编辑:添加了对单元格 A1 的检查,以确保其能够正常工作(下面是@MGonet 的回答):
'These Declare lines go at the very top of the code module
#If VBA7 Then
Private Declare PtrSafe Function CoCreateGuid Lib "ole32" (id As Any) As Long
#Else
Private Declare Function CoCreateGuid Lib "ole32" (id As Any) As Long
#End If
' ----------------------------------------------------------------
' Procedure : CreateGUID
' Author : Dan ([email protected])
' Source : http://allapi.mentalis.org/apilist/CDB74B0DFA5C75B7C6AFE60D3295A96F.html
' Adapted by : Mike Wolfe
' Republished: https://nolongerset.com/createguid/
' Date : 8/5/2022
' ----------------------------------------------------------------
Private Function CreateGUID() As String
'Application.OnRepeat Text:="Paste Next Date", _
'Procedure:="Application.thisCell.Text"
If (Application.thisCell.Address <> "$A$1") Then
Const S_OK As Long = 0
Dim id(0 To 15) As Byte
Dim Cnt As Long, GUID As String
If CoCreateGuid(id(0)) = S_OK Then
For Cnt = 0 To 15
CreateGUID = CreateGUID & IIf(id(Cnt) < 16, "0", "") + Hex$(id(Cnt))
Next Cnt
CreateGUID = LCase(Left$(CreateGUID, 8) & "-" & _
Mid$(CreateGUID, 9, 4) & "-" & _
Mid$(CreateGUID, 13, 4) & "-" & _
Mid$(CreateGUID, 17, 4) & "-" & _
Right$(CreateGUID, 12))
Else
MsgBox "Error while creating GUID!"
End If
Else
CreateGUID = Application.thisCell.Text
End If
End Function
我想要的是将其包装在一个If
语句中,以确定该函数是否已经计算过。经过一番折腾,我尝试了:
Public Function CreateGUID() As String
If (Application.thisCell.Characters = "") Then
'Generate UUID
Else
CreateGUID = Application.thisCell.Value
End If
End Function
然而这似乎不起作用。我也试过应用程序.onrepeat,但这似乎也不起作用。有没有其他方法可以确定公式是否已被求值?
答案1
我不知道你想在实践中如何使用这个公式。
如果您想在单元格中保留公式,这可以让您复制带有公式的单元格,但它们将包含相同的值,因此您需要激活它们以获取新值。您可以使用 UDF 实现这一点:
Function OneCall()
If Application.ThisCell.Text = 0 Then
OneCall = CreateGUID
Else
OneCall = Application.ThisCell.Text
End If
End Function
如果重新计算工作表,单元格内容保持不变,但是如果您编辑单元格,则会生成新值。
如果您更喜欢一次性函数,则可以尝试另一种方法。在这种情况下,函数结果将被常量替换,因此它不会因重新计算而自动更改。但每次您想要生成新值时,都必须在单元格中输入新的函数调用=EOneCall()
这是一组两个函数,因为我们的函数应该被间接调用。
Function OneCall2() As String
With Application.ThisCell
If .Address <> "$A$1" Then
.Value = CreateGUID
End If
End With
End Function
Function EOneCall() As String
EOneCall = Evaluate("OneCall2()")
End Function