将字符串与表字段值进行比较

Posted

技术标签:

【中文标题】将字符串与表字段值进行比较【英文标题】:Compare String with Table fields value 【发布时间】:2019-08-16 16:59:39 【问题描述】:

各位程序员大家好,我是 MS Access 的新手,但对 Excel(包括 VBA)有一定的经验。我已经搜索了几天,到目前为止测试了几个零成功的建议。这已经令人沮丧了,我决定直接询问我的情况。

从加载的表单中,我让用户通过 Inputbox 输入密码,我需要我的代码在我的表 Crewlist、字段 Password 中搜索该字符串,并且条件是另一个字段 Admin(是/否) .

为了方便搜索,我创建了一个查询表,其中包含字段为 Admin(均为 Yes)和字段为 Password 的所有人。

期待任何特定的解决方案。到目前为止,我已经尝试过创建数组和记录集。

编辑 (例如,根据要求 - 包含要比较的所需信息的表)

Field1 Field2 Field3("管理员")

姓名1 密码1 否

姓名2 密码2 是

姓名3 密码3 是

"If" 语句将 Inputbox 字符串与 Field2 进行比较,其中 Admin=Yes Dlookup 将返回第一个结果,即 Password2,但 Name3 和 password3 也应进行查找和比较)。

需要记录集和简单的 SQL 代码,我正在处理它。

【问题讨论】:

【参考方案1】:

我建议为此任务使用简单的DLookup 表达式,例如,假设用户输入的密码存储在变量pwd 中,您可以使用:

DLookup("Password","Crewlist","Admin = True and Password = '" & pwd & "'")

如果没有找到匹配项,DLookup 函数将返回 Null,您可以使用 If 语句和 IsNull 函数进行测试,例如:

If IsNull(DLookup("Password","Crewlist","Admin = True and Password = '" & pwd & "'")) Then
    MsgBox "Invalid Password!"
Else
    ' Do Stuff
End If

这里,我只指定Password字段作为要查找的字段,因为DLookup需要一个特定的字段,其值应该被返回。您可以改为使用 DCount 函数并测试返回值是否非零,例如:

If DCount("*","Crewlist","Admin = True and Password = '" & pwd & "'") > 0 Then
    ' Do Stuff
Else
    MsgBox "Invalid Password!"
End If

在按钮的事件处理程序中实现,可以写成:

Private Sub Command0_Click()
    Dim pwd As String
    pwd = InputBox("Enter Password:", "Password")

    If pwd <> vbNullString Then
        If IsNull(DLookup("Password", "Crewlist", "Admin = True and Password = '" & pwd & "'")) Then
            MsgBox "Invalid Password!"
        Else
            MsgBox "Access Granted!"
        End If
    End If
End Sub

请注意,这只是检查密码,因此,仅使用上述代码,用户可以为 任何 Admin 用户指定密码并被授予访问权限。

您可以通过附加提示轻松检查用户名:

Private Sub Command0_Click()
    Dim usr As String
    Dim pwd As String

    usr = InputBox("Enter Username:", "Username")
    If usr <> vbNullString Then
        pwd = InputBox("Enter Password:", "Password")
        If pwd <> vbNullString Then
            If IsNull(DLookup("Password", "Crewlist", "Admin = True and Username = '" & usr & "' and Password = '" & pwd & "'")) Then
                MsgBox "Invalid Username or Password!"
            Else
                MsgBox "Access Granted!"
            End If
        End If
    End If
End Sub

但是,如果您要设计自己的模式表单,其中包含用于用户名的文本框或组合框以及用户可以在其中指定密码的文本框,这将更加专业。


除此之外,以纯文本形式将密码存储在数据库中是不好的做法:考虑使用适当的 hash function 对密码进行哈希处理并存储哈希值。然后,将相同的散列函数应用于用户输入,并使用生成的散列值来测试数据库中的匹配项。

这样,只有用户知道密码——因为散列是一个单向过程,即使是数据库管理员也不知道用户的密码。如果用户需要更改他们的密码,他们将获得一个可以更改的新临时密码,或者在其他一些身份验证之后提供一个新密码。

作为一般规则,永远不要相信任何能够向您发送原始密码的服务 - 这表明此类服务正在存储密码而不进行加密/屏蔽。

【讨论】:

您好 Lee Mac,感谢您的快速回复。 DlookUp 是我最初的尝试,因为我习惯了 Excel 中的 VlookUp。但是,如果只有一个密码设置为管理员,则 Dlookup 可以正常工作。在我的表格中,我打算将多个密码设置为 admin,并将 Inputbox 中的字符串与这些密码进行比较。 我不确定我是否遵循...您是说可能有多个记录具有相同的Admin 值和相同的Password 值?如果是这样,为什么使用DLookup 会出现问题?您能否编辑您的问题以显示一些描述该问题的示例数据? 让我试着简化这个例子。字段1“名称”,字段2“密码”字段3“管理员是/否”。如果 Admin = Yes,则要与 field2 比较的输入框字符串。所以多个管理员可以输入他们自己的密码。 所以 Dlookup 函数会在第一个字段符合条件时停止搜索,但不会选择连续的管理员密码,因此不会与 Inputbox 字符串进行比较。 在这种情况下,我看不出使用 DLookup 不起作用的原因 - 您能否提供一个示例(例如,编辑您的问题以包含示例数据表和给定的输入) 你认为这种方法会失败吗?【参考方案2】:

这是我今天早上在阅读了一些有关记录集和循环的示例后得到的。我在 VBA 中的代码

Sub Auto_Logo0_Dblclick
Dim AdmPass As String
AdmPass = Inputbox ("Admin password required")

'next part is taken from my guide book for Access
Dim Con1 As ADODB.Connection
Set Con1 = CurrentProject.Connection
Dim rcrdPass As New ADODB.Recordset
rcrdPass.Activeconnection = Con1

'SQL part
 Dim mysql as String
    mySQL = "SELECT Crewlist.Surname, Crewlist.Password,"
    mySQL = mySQL & " Crewlist.Admin"
    mySQL = mySQL & " From Crewlist"
    mySQL = mySQL & " Where (Crewlist.Admin = 'Yes')"
 rcrdPass.Open mySQL
    With rcrdPass
          If Not .BOF And Not .EOF Then
             .MoveFirst
             .MoveLast
           While (Not .EOF)
              If AdmPass = rcrdPass.Fields("Password") Then
                 Call DoCmd.SelectObject(acTable,,True)
                 Else Msgbox ("Wrong password, try again")
                 End If
             .MoveNext
           Wend
      End If
 End With
 rcrdPass.Close
 Set rcrdPass = Nothing
 Set Con1 = Nothing
 End sub

【讨论】:

代码正常运行,但未达到预期。截至目前,只有最后一个密码与输入框字符串进行比较。 MySQL 后端?通常登录凭据包含用户名和密码(散列)。您从船员列表中获取用户,然后将输入密码与存储的密码进行比较。如果只比较所有密码,如果密码不唯一怎么办?在查询条件中使用密码(/用户)限制记录集,是/否字段为真/假(0/0)。扩展 Where 子句Where Crewlist.Admin &lt;&gt; 0 AND Crewlist.Password = '" &amp; AdmPass &amp; "'""(不要忘记哈希!)。无需移动 firdt/last,除非您想计算记录(记录集始终以第一条记录打开,或者在 .EOF 处为空)。 感谢您对 ComputerVersteher 发表评论。首先要注意的是,我将使用是/否检查来修改管理字段,现在它是简单的文本“是”或“否”。第二点 - 如果两个名字被声明为管理员,如果他们的密码相同就没有问题,这是很不寻常的。我想通过只输入他们的密码来为用户保持简单,如果一个设置为管理员,表单将被解锁以进行编辑等等。注意第 3 点,我将删除 Movefirst 和 movelast。 mySQL 是我选择的名称,它在表“Crewlist”中查找,如果字段 Admin=Yes,则进行过滤。 这会让人们感到困惑。只需将其命名为SQL 或更详细的SqlCrewlistAdmin。选择您的 naming convention 并以此为依据(大写/小写名称)

以上是关于将字符串与表字段值进行比较的主要内容,如果未能解决你的问题,请参考以下文章

将选定日期与表列或 MySQL 查询生成的日期数组进行比较

MySQL 将 DATE 字符串与 DATETIME 字段中的字符串进行比较

MySQL字符串列与整数比较

JET OLEDB 参数如何将字符串与 Access DB 中的文本字段进行比较

将字符串与数据库中的字符串进行比较返回 false

将值列表与表格进行比较