在组合框查找中添加一些AI

介绍 如果您在数据库应用程序上进行大量的手动输入,您可能会喜欢组合框的自动完成功能。与默认的Windows组合框控件的标准首字母响应不同,组合框实现有无数种。你可以找到一些非常令人印象深刻但却免费的实现,从普通的JavaScript到AJAX控件;每个项目的复选框或单选按钮、图标或图像、多列、多个首字母匹配、颜色(或格式)分组和任何位置字母匹配(高亮显示)。 我的需求相当简单;我想要Access style组合框,它允许首字母匹配和多列,我想要第一个匹配是最常用的或最可能的匹配。这可以通过SQL严格地完成。 举例来说,假设您需要在人 力资源部门的约翰•史密斯、人力资源部门的简•史密斯和销售部门的约翰•史密斯之间做出选择。 第一种方法是查询employee表,并将三列(lastname, firstname, department)合并在一个列中(按字母顺序排列),得到: 隐藏,复制Code

Smith Jane HR
Smith John HR
Smith John Sales

在输入“Smith J”后,“Jan”将出现在组合框中。我想让"John"先出现,只是因为"John"比" Janes "多。 第二种方法是将字段分隔在不同的列中。现在,order子句使用三列: 隐藏,复制Code

Smith | Jane | HR
Smith | John | HR
Smith | John | Sales

这并没有完成很多工作,但是通过添加姓和名的频率计数(即employee表中有多少John Smiths、Jane Smiths等),事情开始看起来很有希望: 隐藏,复制Code

Smith | 1 | Jane | HR
Smith | 2 | John | HR
Smith | 2 | John | Sales

通过发布一个新的order子句,频率列按降序排列,我们可以生成: 隐藏,复制Code

Smith | 2 | John | HR
Smith | 2 | John | Sales
Smith | 1 | Jane | HR

现在输入"Smith J"后,第一个John就会出现。这样我就不用再按下箭头键了。 实现 如前所述,这只是一个例证。我的实际应用程序涉及两个表,它们具有一对多的关系。我有一个商店表(零售商,供应商,修理店等)和一个相关的表格,从这些商店的收据。由于许多商店实际上是零售或服务链,所以我将商店名称和编号保存在单独的字段中。最初,这帮助我总结了我的“7- 11”费用,独立于我访问的7- 11。 我需要的是历史上最常光顾的商店按降序显示。以下是用于在收据表单中输入新收据的原始商店组合框的部分显示: 隐藏,复制Code

Store    Description    Address
346    7-Eleven 24625    3230 W DAVIS ST
341    7-Eleven 26264    100 N GREENVILLE AVE
132    7-Eleven 32870    1004 W MCDERMOTT R
171    7-Eleven 33302    10565 CUSTER RD
15     7-Eleven 33690    7818 ROWLETT RD
12     7-Eleven 33697    3975 LAKE FOREST

Store列是惟一的ID, Description列连接存储名称和编号,第三列只是一个内存辅助。下面是用作组合框记录源的T-SQL语句: 隐藏,复制Code

SELECT   Store,
         Name & ' ' & Number AS Description,
         Address

FROM     Stores

ORDER BY Name, Number;

要在order子句中使用访问频率,我们首先需要将名称和编号分开,就像下图所示: 隐藏,复制Code

SELECT   Store,
         Name,
         Number,
         Address

FROM     Stores

ORDER BY Name, Number;

现在我们可以使用这个查询(让我们称它为q1)作为一个组查询的源,该组查询对每个商店的收据进行计数: 隐藏,复制Code

SELECT   Store,
         Name & ' ' & Number AS Description,
         Address

FROM     q1 LEFT JOIN Receipts ON q1.Store = Receipts.Store

GROUP BY Store, Name, Number, Address

ORDER BY Name, COUNT(Receipts.Receipt) DESC, Number;

查询结果如下: 隐藏,复制Code

Store  Description     Address               CountOfReceipt
15     7-Eleven 33690  7818 ROWLETT RD       30
346    7-Eleven 24625  3230 W DAVIS ST       1
341    7-Eleven 26264  100 N GREENVILLE AVE  1
132    7-Eleven 32870  1004 W MCDERMOTT R    1
171    7-Eleven 33302  10565 CUSTER RD       1
12     7-Eleven 33697  3975 LAKE FOREST      1

从技术上讲,没有分组,因为使存储惟一的所有字段都参与到group子句中。还请注意,我们仍然使用最初的商店名称和编号的连接;编号只需要参与order子句。 收据计数显示只是为了说明目的。虽然这个名单一开始会让人觉得有点不顺眼,或者有点混乱,但很有可能下一家光顾了30次的7- 11是我要去的。这将使我不必显示列表,也不必显示键的数量或在列表中向下滚动寻找正确选择的时间。这种节省是渐进的,也就是说,当另一家7-Eleven有客人光顾时,它将出现在名单的第二位。按照商店编号进行排序也很重要,这样当两个或更多商店的收据计数相同时,它就具有优先级,如前面的示例所示。 顺便说一句,并非所有商店都有商店编号,有些“数字”实际上是字母数字,如“3A”或“II”。让我们看看如何处理这些。 一个商店可以是唯一的数据库术语(例如,有一个单一的记录“湖景花店”)。一些连锁店在内部保留店铺编号;收据或网站上都没有任何提示。在这种情况下,存储编号被保留为空(值为NULL),并且在description字段的数字周围添加一些“立即if”逻辑,以便连接不会失败(并可被删除)。如果你需要细节,这里是T-SQL (Access/VB)版本的描述栏: 隐藏,复制Code

Description: q1.Name & IIf(IsNull(q1.Number),'',' ' & q1.Number)

关于字母数字的商店编号,w没有太多e。如果将存储编号字段设置为严格的数字字段,则必须为那些使用字母数字存储编号(代码)的存储设计自己的映射。如果你把它作为一个文本字段,你将不得不忍受一些畸变,如Cici的披萨7006 Cici的披萨94之前显示在列表中,仅仅因为他们有相同数量的收据和输入的顺序(存储ID是提示): 隐藏,复制Code

Store    Description         Address                   CountOfReceipt
84       Cici's Pizza 181    3520 LAKEVIEW PKWY        6
85       Cici's Pizza 1      2936 LAVON DR             3
87       Cici's Pizza 10     2220 COIT RD STE 300      2
86       Cici's Pizza 7006   1105 E PARKER RD STE 112  1
340      Cici's Pizza 2      N GREENVILLE AVE          1
360      Cici's Pizza 94     479 E I30                 1

您可以使用前面的零重新编号存储,或者您使用另一个表达式执行q1中的升序数字: 隐藏,复制Code

Number1: Val(Nz([Number],0))

Nz函数将null替换为0,Val函数处理“3A”和“II”。不幸的是,这并不是一个完美的解决方案;“3A”会变成3,“II”会变成0。此外,如果存储用前面的字母字符编码(如“A1”、“B3”等),这些代码也将通过这种方法归零。我尝试了一些额外的逻辑,但没有成功。如果你有办法,请告诉我;目标是保留以字母开头的字符串,并将以数字开头的字符串转换为实际的数值。 到目前为止,前面的表达式完成了频率排序,与适当的存储数字排序作为回退: 隐藏,复制Code

Store    Description        Address                     CountOfReceipt
84       Cici's Pizza 181   3520 LAKEVIEW PKWY          6
85       Cici's Pizza 1     2936 LAVON DR               3
87       Cici's Pizza 10    2220 COIT RD STE 300        2
340      Cici's Pizza 2     N GREENVILLE AVE            1
360      Cici's Pizza 94    479 E I30                   1
86       Cici's Pizza 7006  1105 E PARKER RD STE 112    1

下面是最后一条q1 T-SQL语句: 隐藏,复制Code

SELECT   Store,
         Name,
         Val(Nz([Number],0)) AS Number1,
         Address

FROM     Stores

ORDER BY Name, Val(Nz([Number],0));

和组合框的记录源: 隐藏,复制Code

SELECT   Store,
         Name & IIf(Number1=0,'',' ' & Number1) AS Description,
         Address

FROM     q1 LEFT JOIN Receipts ON q1.Store = Receipts.Store

GROUP BY Store, Name, Number1, Address

ORDER BY Name, COUNT(Receipts.Receipt) DESC, Number1;

现在你明白了吧。针对一对多关系(例如,订单和订单细节、产品和费用等)的频率计数(或可能性)订购方法。一点点人工智能不会伤害任何人;大多数用户一开始可能不喜欢它,但是一天查找200或300次之后,他们就会喜欢了! 的兴趣点 我试图使T-SQL语句尽可能通用;如果您在MS Access中实际使用代码,请确保在VB函数中使用双引号而不是单引号。 历史 第一个版本。 本文转载于:http://www.diyabc.com/frontweb/news379.html

原文地址:https://www.cnblogs.com/Dincat/p/13443946.html