Access 2013 AuditTrail table 将 GUID 显示为中文符号

Access 2013 AuditTrail table showing GUID as chinese symbols

虽然 ID (PK) 是 GUID 并且当数据在我的 AuditTrail table 中显示为汉字。我不明白为什么它不显示实际 ID。

在我的 BeforeUpdate 事件中,我有以下代码,但不是 100%:

Option Compare Database
Option Explicit

Private Sub Form_BeforeUpdate(Cancel As Integer)
    On Error GoTo errHandler
    If Me.NewRecord Then
        Call AuditChanges("ID", "NEW")
    Else
        Call AuditChanges("ID", "EDIT")
    End If
    Exit Sub

errHandler:
    MsgBox "Error " & Err.Number & ": " & Err.Description & " in " & _
          VBE.ActiveCodePane.CodeModule, vbOKOnly, "Error" 

End Sub 

'I am using this code to for the AuditChanges
Sub AuditChanges (IDField As String, UserAction As String)
    On Error GoTo AuditChanges_Err
    Dim cnn As ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim ctl As Control
    Dim datTimeCheck As Date
    Dim strUserID As String

    Set cnn = CurrentProject.Connection
    Set rst = New ADODB.Recordset

    rst.Open "SELECT * FROM tblAuditTrail", cnn, adOpenDynamic, adLockOptimistic
    datTimeCheck = Now()
    strUserID = Environ("USERNAME")

    Select Case useraction

        Case "EDIT"
        For Each ctl In Screen.ActiveForm.Controls
            If ctl.Tag = "Audit" Then
                If Nz(ctl.Value) <> Nz(ctl.OldValue) Then
                    With rst
                        .AddNew
                        ![FormName] = Screen.ActiveForm.Name
                        ![RecordID] = Screen.ActiveForm.Controls(IDField).Value
                        ![FieldName] = ctl.ControlSource
                        ![OldValue] = ctl.OldValue
                        ![NewValue] = ctl.Value
                        ![UserID] = strUserID
                        ![DateTime] = datTimeCheck
                        .Update
                    End With
                End If
            End If
            Next ctl

        Case Else
            With rst
                .AddNew
                ![DateTime] = datTimeCheck
                ![UserID] = strUserID
                ![FormName] = Screen.ActiveForm.Name
                ![Action] = useraction
                ![RecordID] = Screen.ActiveForm.Controls(IDField).Value
                .Update
            End With
    End Select

AuditChanges_Exit:
    On Error Resume Next
    rst.Close
    cnn.Close
    Set rst = Nothing
    Set cnn = Nothing
    Exit Sub

AuditChanges_Err:
    MsgBox Err.Description, vbCritical, "ERROR!"
    Resume AuditChanges_Exit
End Sub

虽然 ID 没有正确显示。我尝试使用 StringFromGUID 但这会引发无法找到该字段的错误。 GUID 的示例是 {EF95C08E-D344-42B3-B678-2A64A50366DE}.

我希望有人能提供帮助,虽然这可能是错误的做法,但这是我迄今为止唯一能做到的。谢谢。

问题在于 Application.StringFromGUID 采用字节数组,而您已将 GUID 的字节存储为字符串。

Access 使用 UTF-16 来存储字符串。因为很大一部分双字节 UTF-16 字符是中文,所以如果将随机字节显示为字符串,通常会得到中文字符。

以下代码将它们转换回字节数组,然后调用 StringFromGUID。我已经使用默认区域设置在 Access 2016 上对其进行了测试。

Public Function StringFromStringGUID(strGUIDBytes As String) As String
    If Len(strGUIDBytes) = 8 Then
        Dim bytes() As Byte
        bytes = strGUIDBytes
        StringFromStringGUID = Application.StringFromGUID(bytes)
    Else
        'Invalid string, GUID = 16 bytes, Access stores UTF-16 strings = 2 bytes per character
    End If
End Function

您可以在 queries/VBA 中使用它来将这些字符串转换回 GUID