2

首先,我想非常清楚地表明,我对 Access 和 VBA 的了解充其量是极其有限的。我有一个员工数据库系统,由于其年代久远,容易出现小数据损坏问题,并且由于 2003/2007 年和 2010 年之间的差异而导致控制中断。虽然我已经设法解决了大部分问题,但其中有我特别值得关注的是我们用来管理对数据库的访问的脚本。该系统分为两个文件,一个是用户可以访问数据库的前端,一个是包含所有表的后端文件。

我遇到的问题是处理用户登录的前端表单。访问系统的设置方式是用户输入他们的 SSN,然后脚本在表中找到他们的 SSN,如果存在,则查看是否选中了访问复选框。如果他们有访问权限,他们将被定向到主菜单,如果没有,他们会收到一条拒绝消息。但是我发现由于某种原因,如果人员表中的条目具有不完整的 SSN,则脚本会中断并且任何人都可以访问数据库。

有一个在前端运行的查询,它查看主人员表并仅提取前两列,SSAN 和 Access。

表单本身有一个可见的文本框“Text8”和一个隐藏的组合框“Combo4”。Combo4 对行源 ( SELECT qryAccess.SSAN FROM qryAccess;) 使用前面提到的查询,而 Text8 是用户输入其 SSN 的位置。

这是现在的代码:

Option Compare Database

Private Sub Combo4_AfterUpdate()
    ' Find the record that matches the control.
    Dim rs As Object

    Set rs = Me.Recordset.Clone
    rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
    If Not rs.EOF Then Me.Bookmark = rs.Bookmark

    If Me![Access] = True Then
    DoCmd.RunMacro "Access"
    Else
    DoCmd.OpenForm "frmDenied"
    End If
End Sub

Private Sub Text8_AfterUpdate()
Me![Combo4] = Me![Text8]

    ' Find the record that matches the control.
    Dim rs As Object

    Set rs = Me.Recordset.Clone
    rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
    If Not rs.EOF Then Me.Bookmark = rs.Bookmark

    If Me![Access] = True Then
    DoCmd.RunMacro "Access"
    Else
    DoCmd.OpenForm "frmDenied"
    End If
End Sub

就像我之前说的,只要 SSN 的每个条目都是完整的 9 位数字,这个系统就可以工作。但是,如果由于某种原因该条目不是我刚刚在我的数据库中找到的完整的 9(不,我不知道是什么导致了这种情况发生,有一个输入掩码,000-00-0000;;_ ),这个系统坏了。您可以为 SSN 输入“abc”并获得对数据库的访问权限。

如何编写一个小脚本来预先检查表中不符合设置的 9 位格式的 SSN 条目,如果找到它们,将它们重置为未使用的数字,例如 000000000、000000001 等?

此外,如果您对如何简化现有代码有任何建议,我将非常乐意接受。

4

3 回答 3

1

由于看起来这更像是“我如何找到用户”而不是“我如何修复现有条目”,所以让我把帽子扔进戒指。

除非我完全误解了这一点,否则现有的(和接受的答案)功能是可怕的。您可以用更少的代码更有效地完成这一切。首先,删除Combo4。没必要。然后这样做:

Private Sub Text8_AfterUpdate()
Dim X as Integer

X = DLookup("Access", "qryAccess", "SSAN = '" & Me!Text8 & "'")

    If Nz(X) = True Then
    DoCmd.RunMacro "Access"
    Else
    DoCmd.OpenForm "frmDenied"
    End If
End Sub

这就是你所需要的。如果用户的 SSN 存储不正确,他将被拒绝。7位数,8位数,没有区别。只有完全匹配才能通过。也就是说,假设 0 = False 和 1 = True,无论如何这应该是默认值。

于 2013-08-01T20:42:47.593 回答
1

您有一个文本字段SSAN,并且使用该输入掩码,破折号不包含在存储的值中。所以有效值将是 9 位字符串。

如果这是正确的,您可以使用查询来识别任何无效的存储值。

SELECT y.SSAN, Len(SSAN) AS LenghtOfSSAN
FROM YourTable AS y
WHERE Len(SSAN)<>9 OR y.SSAN ALike '%[!0-9]%';

该查询将返回SSAN包含 < 或 > 9 个字符的行,以及包含数字以外字符的任何值。

请注意,ALike关键字告诉 db 引擎期待 ANSI 通配符。如果您更喜欢 Access 的*通配符,请将其更改为Like '*[!0-9]*'

修复存储值后,为该SSAN字段 ( Like "#########") 添加验证规则以要求所有值包含 9 位数字。

于 2013-08-01T19:17:35.603 回答
1

将此功能添加到您的应用程序

Public Function IsValidSSN(ByVal SSN As String) As Boolean

'Determines if SSN is a valid social security number
'requires SSN to be in either "#########" or "###-##-####" format

        IsValidSSN = (SSN Like "###-##-####") Or _
            SSN Like ("#########")

End Function

还将您的功能更改为:

Private Sub Combo4_AfterUpdate()
    ' Find the record that matches the control.
  If IsValidSSN(Me![Combo4]) Then  
    Dim rs As Object

    Set rs = Me.Recordset.Clone
    rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
    If Not rs.EOF Then Me.Bookmark = rs.Bookmark

    If Me![Access] = True Then
    DoCmd.RunMacro "Access"
    Else
    DoCmd.OpenForm "frmDenied"
    End If
  Else
    DoCmd.OpenForm "frmDenied"
  End IF
End Sub

Private Sub Text8_AfterUpdate()
    Me![Combo4] = Me![Text8]

 If IsValidSSN(Me![Text8]) Then 
    ' Find the record that matches the control.
    Dim rs As Object

    Set rs = Me.Recordset.Clone
    rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
    If Not rs.EOF Then Me.Bookmark = rs.Bookmark

    If Me![Access] = True Then
    DoCmd.RunMacro "Access"
    Else
    DoCmd.OpenForm "frmDenied"
    End If
  Else
    DoCmd.OpenForm "frmDenied"
  End If
End Sub

编辑

另外,您为什么要使用组合框输入 SSN?您可以在文本框上使用输入掩码。另外,我强烈建议您将系统转换为 SSN 以外的其他标识,因为通过在打开应用程序时按住 shift 键,很容易通过此代码查看包含每个人的 SSN 的表。至于简化您的代码,只需完全删除该组合框即可。如果他们将其输入到文本框中,则无需将其放入隐藏的组合框中。

于 2013-08-01T18:55:56.967 回答