创建后切勿更新 Excel UDF

创建后切勿更新 Excel UDF

在 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

相关内容