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

时间:2018-07-10 16:14:14

标签: vba ms-access guid

尽管 ID (PK)是GUID,并且数据显示在我的 AuditTrail 表以汉字显示。我不知道为什么它没有显示实际的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}

我希望有人可以提供帮助,尽管这可能是错误的方法,但这是迄今为止我唯一设法解决的方法。谢谢。

1 个答案:

答案 0 :(得分:1)

问题在于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

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