在access中使用VBA的GUI。来自查询的记录集

在access中使用VBA的GUI。来自查询的记录集,vba,ms-access,ms-access-2007,recordset,Vba,Ms Access,Ms Access 2007,Recordset,用VBA在Access中制作GUI(这学期我第一次看到它,对我来说很不寻常)。我得到了表Authors,其中有列author\u id,姓,名和表书,其中列author\u id,书名。 我在表单上找到了一个按钮,点击该按钮应该要求用户输入作者的姓氏,然后搜索并显示该作者的所有书籍 所以我试图从Authors表中找到author id,然后从Books表中显示author.author\u id等于Books.author\u id的所有书籍 我在想,我需要创建包含author\u id值的临时

用VBA在Access中制作GUI(这学期我第一次看到它,对我来说很不寻常)。我得到了表
Authors
,其中有列
author\u id
和表
,其中列
author\u id
书名
。 我在表单上找到了一个按钮,点击该按钮应该要求用户输入作者的姓氏,然后搜索并显示该作者的所有书籍

所以我试图从Authors表中找到author id,然后从Books表中显示author.author\u id等于Books.author\u id的所有书籍

我在想,我需要创建包含author\u id值的临时查询,然后使用类似于
“从[Books]中选择[Books].[book\u name]作为[Bookname],其中[Books].[author\u id]=[test].[id]”的SQLquery创建此查询的记录集
但我在这里结巴了-我只是想检查一下这个东西是否工作,但它说有一个错误
3061

Private Sub authorlist_Click()

    Dim dbs As Database, authorsRS, booksRS As Recordset, queryStr, idbynameQuery, srchASurStr, strOutput, srId As String, qdf As QueryDef

    Set dbs = CurrentDb()

    srchASurStr = InputBox("Input author surname, please", , , 100, 100)

    strQuery = "SELECT [Authors].[author_id] AS [ID] FROM [Authors] WHERE [Authors].[last_name] =  " & srchASurStr & ""



    Set authorsRS = dbs.OpenRecordset(strQuery, dbOpenSnapshot)

    With dbs
        Set qdf = .CreateQueryDef("test", strQuery)
        DoCmd.OpenQuery "test"
        .QueryDefs.Delete "test"
    End With


End Sub

你能帮我弄清楚到底是怎么回事吗?是否有更简单的方法来显示某些作者的所有书籍(可能不使用SQL查询)?

SQL语句中的字符串值需要用单引号(
)或双引号(
)括起来:

如果没有引号:

SELECT author_id FROM authors WHERE last_name = Smith
Smith
将被理解为字段名而不是字符串值。因此,您的代码应该如下所示:

'Chr returns a string from a character code. 34 is the code for "
strQuery = "SELECT author_id FROM authors WHERE last_name = " & Chr(34) & srchASurStr & Chr(34)
在VBA中,可以通过将双引号加倍来用字符串转义双引号:

strQuery = "SELECT author_id FROM authors WHERE last_name = """ & srchASurStr & """"

SQL注入:请记住,如果用户输入的字符串中包含
,则可能会出现错误,因为生成的SQL语句具有无效语法:

SELECT author_id FROM authors WHERE last_name = "Smi"th"
避免此问题的正确方法是使用参数。
一些注意事项:

  • 您可以在查询中引用表单控件:
    [Forms]![表单名称]![ControlName]
    。因此,您可以创建一个保存的查询,该查询基于表单文本框进行过滤,而不是使用inputbox
  • 考虑使用组合框让用户从列表中进行选择,而不是让用户键入自由文本。组合框可以有多列,组合框的值是第一列(
    作者id
    ),显示的值是另一个表达式(
    姓氏
    姓氏&&&&first\u姓名
    )。如果将ColumnWidths属性设置为0(对于第一列),将显示下一列
  • <> >如果您喜欢使用文本框,请考虑在查询中使用<>代码> 运算符,以显示其所有代码的< <代码> LSTYNAMED> /COD>包含用户字符串:

    从姓氏为“%sm%”的作者中选择作者id

    将返回史密斯、斯迈思和阿斯莫德斯


我建议您设置一个表单和子表单。表单可以包含作者详细信息,子表单可以包含该作者的书籍,您可以进一步添加一个文本框,用户可以用部分作者姓名填写该文本框。然后,您可以对主窗体应用筛选器,以显示具有该名称的所有作者

Me.Filter = "Author Like '*" & Me.Search & "*'"
Me.FilterOn = True

这方面有很多变体,用户可以从组合框或列表框中选择名称。表单可以是一个连续表单,标题中有一个过滤器/搜索等等。

您有表单吗?顺便说一句,这些字段名会让你发疯——大多数人建议不要在列和表名中使用字母和(如果你真的必须)数字以外的任何名称,例如LastName。但它仍然无法打开recordset@DanilGholtsman它给了你什么错误?发生错误时strQuery的值是多少?(
View->Locals Window
)好的查询是可以的,因为我认为idbynameQuery:“选择[Authors].[author\u id]作为[Authors]的[id],其中[Authors].[last\u name]=Dostoevsky]:Variant/String它用黄色高亮显示此>设置Authors=dbs.OpenRecordset(strQuery,dbOpenSnapshot)并且说运行时错误3061,应该有更多的参数,因为正如我所说的,查询应该是
SELECT[Authors].[author\u id]as[id]FROM[Authors],其中[Authors].[last\u name]=“Dostoevsky”
(在
Dostoevsky
周围加引号)。否则,Access会将
陀思妥耶夫斯基
计算为一个表达式-一个字段或一个命名参数,并且找不到任何名为
陀思妥耶夫斯基
@DanilGholtsman的字段/参数。您能告诉我答案正文中缺少什么吗,这让你在评论中明白了吗?哦,我总是避免使用所有这些主窗体,实际上不知道如何正确使用它。在哪里可以找到有关它的教程和示例?
Me.Filter = "Author Like '*" & Me.Search & "*'"
Me.FilterOn = True