这是您上一个问题的副本。您不必重新创建一个新问题以使其再次可见:只需使用更多数据编辑您的原始问题,它就会再次出现在顶部。
当时没有人能够回答,因为这太模糊了。对于这些类型的系统,工人的实际工作方式是解决方案的驱动力:您需要简化他们的行动,以便它们自然流动,并且不需要比严格必要的更多的动作、确认和处理。
所以,让我们尝试一下。
假设
因为我对你的环境、设备和流程了解不够,所以我对这个问题做一些假设:
一台计算机安装在秤附近用于数据输入。
条码扫描器和秤都连接到计算机
条形码阅读器的行为类似于 HID 设备(就像在键盘上输入的一样)
条码阅读器配置为在每次扫描后添加一个 CR(回车)后缀(所有阅读器都具有这种类型的配置)。
员工条形码印在(上方或下方)产品 ID 上,即贴在鱼上的标签。
员工 ID 条形码的格式为:@123456
其中 123456 是员工 ID。
前缀允许系统检测扫描的@
条形码是员工 ID。
使用Code128或类似代码打印字母数字字符串。
假设鱼条形码标签位于鱼身上或印在卡片上。
鱼条码标签可以是任何东西,但不能以 . 开头@
。
我们假设秤有一个界面。由于您没有提及您使用哪一个或如何从 PC 中检索数据,因此我们必须假设秤提供了一个 SDK,或者可以让您读取当前重量的东西。
让我们调用该函数ReadScale()
并假设它返回一个带有重量的浮点数,无论测量对您的任务有意义。
工作进程
在这里,我们再次做出一些假设。根据您的确切设置以及物理执行的操作流程,情况可能会有很大不同,在这种情况下,您的软件可能也需要表现不同。
我假设权重和数据输入是最终操作:到那时标签已经贴在鱼/产品上。
可能的过程:
或者:
第一种选择需要较少的操作,但它要求标签在产品在秤上时可见以便扫描。这可能是真的,也可能不是。
软件解决方案
有一千种不同的方法可以实现您想要的,但既然您提到了 Access,我们将假设您对此感到满意。
此外,它提供了一种很好的方法来制作解决方案原型,因为它很容易更新 Access 应用程序。
我假设 SQL Server 数据库与将托管 Access 应用程序的数据输入计算机位于同一 LAN 上。
如果不是这种情况,或者如果您必须使用 Wifi,那么连接到数据库和保存数据的方式会有所不同(并且可能会更复杂一些)。
数据流
当员工扫描条形码时,应用程序将收到一串键,就好像员工实际在键盘上键入一样:
例如,假设用户扫描员工 ID,然后扫描产品 ID。计算机将收到以下数据流,就好像它来自键盘一样:
@443678¶
876657098¶
该¶
符号仅代表条形码扫描仪添加的 CR 代码后缀(与 ENTER 键相同的代码)。
SQL Server 数据库
我假设您在 SQL ServerProductLog
的数据库中有一个表。Fishery
该ProductLog
表将仅记录每种鱼/产品的数据集:
ID : Auto-increment ID (IDENTITY), to identify each record uniquely
EmployeeID : Stores the Employee ID (INT/CHAR)
ProductID : stores the Product ID (INT/CHAR)
Weight : Store the measured weight (FLOAT)
TimeStamp : records the operation's exact date and time (DATETIME).
现在将ProductLog
表链接到您的 Access 应用程序前端。
然后我们就可以像使用本地 Access 表一样使用它。
数据输入表
让我们不要去做最基本的事情:创建一个空白表单并为其添加 3 个大标签,您将调用它们labelEmployeeID
:labelProductID
和labelWeight
.
编辑表单的属性,使其变为模态并停留在应用程序的前面,除其他外:
Default View : Single Form
Record Selector : No
Pop up : yes
Modal : yes
key Preview : Yes (on the Events page)
打开 VBA IDE 以编辑表单的代码并添加以下内容:
Option Compare Database
Option Explicit
' The SQL Server Connection String. Update to match your database '
Const SQLSERVERCONSTR As String = "ODBC;DRIVER=SQL Server;SERVER=MYSERVER;DATABASE=Fishery;Trusted_Connection=Yes;"
' Just clear the labels on the screen when we open the form '
Private Sub Form_Load()
labelEmployeeID.Caption = "-"
LabelProductID.Caption = "-"
labelWeight.Caption = "-"
End Sub
' Most of the processing is done here: the barcode scanner will act '
' as if the scanned code was typed on the keyboard. '
' We trap each keystroke and use a basic state machine to reconstruct '
' each barcode and process them once they have been received '
Private Sub Form_KeyPress(KeyAscii As Integer)
' Status = 0 : Waiting for any barcode input '
' Status = 1 : Currently reading EmployeeID barcode '
' Status = 2 : Currently reading ProductID barcode '
' Status = 3 : All barcode data read '
Static Status As Integer
' Keep track of our barcodes '
Static EmployeeID As String
Static ProductID As String
' All barcodes entered, but not processed yet, do not accept more entry '
If Status = 3 Then Exit Sub
' We received a CR, check if we have both barcodes and complete '
If KeyAscii = vbKeyReturn Then
Dim employeeCodeReceived As Boolean
Dim productCodeReceived As Boolean
employeeCodeReceived = (EmployeeID <> vbNullString)
productCodeReceived = (ProductID <> vbNullString)
' Update UI to reflect the completed code we scanned '
If employeeCodeReceived Then
labelEmployeeID.Caption = "Employee : " & EmployeeID
Else
labelEmployeeID.Caption = "-"
End If
If productCodeReceived Then
LabelProductID.Caption = "Product : " & ProductID
Else
LabelProductID.Caption = "-"
End If
labelWeight.Caption = "-"
' If both have been received, complete the transaction '
If employeeCodeReceived And productCodeReceived Then
Status = 3
' Get the weight from the scales '
Dim weight As Double
weight = ReadScale()
' Display the weight '
labelWeight.Caption = "Weight : " & Format(weight, "0.000") & " kg"
' Save to log '
Save EmployeeID, ProductID, weight
' Reset barcode data '
EmployeeID = vbNullString
ProductID = vbNullString
End If
Status = 0
Exit Sub
End If
Dim c As String
c = Chr(KeyAscii)
' We're starting a barcode '
If Status = 0 Then
If c = "@" Then
Status = 1
EmployeeID = vbNullString
Exit Sub ' Skip the @ prefix '
Else
Status = 2
ProductID = vbNullString
End If
End If
If Status = 1 Then
EmployeeID = EmployeeID & c
ElseIf Status = 2 Then
ProductID = ProductID & c
End If
End Sub
Private Sub Save(ByVal EmployeeID As String, ByVal ProductID As String, ByVal weight As Double)
' We use ADO and late binding to avoid requiring a library reference '
Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
' Open using options adOpenDynamic(2) and adLockOptimistic(3) '
rs.Open "ProductLog", SQLSERVERCONSTR, 2, 3
' Add a new record and close '
With rs
.AddNew
!EmployeeID = EmployeeID
!ProductID = ProductID
!weight = weight
!timestamp = Now()
.Update
.Close
End With
Set rs = Nothing
End Sub
' Magic function to be replaced by whatever you need to do to read the scale '
Private Function ReadScale() As Double
Randomize
ReadScale = Rnd() * 2
End Function
所有这一切当然是一个特别简单的实现,它基于可能与您的特定情况匹配或不匹配的简单假设。
没有错误处理,甚至不是很好的代码,但它可以帮助您将一些东西放在一起并开始使用。
利用
要尝试模拟数据输入过程,只需打开表单并使用键盘。
例如,输入以下内容(先输入 ProductID然后EmployeeID 也可以):
@TIMOTHY¶
987654¶
将出现此屏幕,并自动记录数据:
样本数据库
我已经公开了一个示例数据库,其中显示了正在运行的代码。
它将数据保存到自己的演示中。
下载它。
结论
同样,构建这些仓库数据输入应用程序时的主要问题是将数据输入建模为实际的流线型物理过程。
如果您不考虑用户的实际环境和实践,您的解决方案可能会适得其反,需要工人付出更多努力,并使他的工作变得尴尬而不是高效。