如何在MS Access中链接表单中不同表的字段

时间:2017-09-22 12:11:12

标签: ms-access access-vba ms-access-2010

忍受我;凭借丰富的SQL经验,我的MS Access经验非常少。

这是基本的数据结构:

我有一个Employee表,一个Training表和一个加入的Employee_Training表(多对多关系)。有一份员工清单,以及这些员工可以做的可能培训清单。任何员工都可以参加几个培训课程,每个参赛作品都有一个记录的出勤日期。

我正在尝试制作一个以下列方式执行的表单:

  • 您从页面顶部的组合框中选择一名员工
  • 表单包含所有可能的培训课程列表,每个培训课程都带有标签和文本框。如果员工参加了培训课程,相应的文本框中会显示出勤日期,否则文本框将为空白。
  • 我希望能够在空白文本框中输入日期,或者在非空白文本框中更改日期。
  • 我无法使用DataSheet视图,因为大约有150种培训类型,需要将其转换为可打印的形式,因此信息会在表单的列中压缩,如下所示:

粗略布局:

Select Employee: [ John Smith | v ]
Training type 1: [          ]  Training type 25: [          ] 
Training type 2: [          ]  Training type 26: [ 05/06/15 ] 
Training type 3: [          ]  Training type 27: [          ] 
...                            ...

表单最初是手工创建的,但现在是由VBA脚本创建的,不过我认为这里不太相关。

如何构建表单的记录源和文本框的控件源,以便让我看到我想看到的内容,并编辑我需要编辑的内容?

3 个答案:

答案 0 :(得分:0)

你必须删除数据表格式。 如果你使用Recordset对象,你可以使用绑定到组合框的查询 一些小的vba代码,用于将数据保存到表中。 我认为如果您使用报告而不是表格,则访问中的打印会更灵活:)

答案 1 :(得分:0)

首先,要打印输出数据,您将创建一个报告。所以放弃了由于重复数据而在这里遇到问题或问题的想法。您可以将报告格式化为发票或其他任何内容。你有“很多”选择的想法会影响这个选择,这根本不是问题。您的表格/报告可能不包括所有150个选项,并且难以阅读。如果你真的必须,那么你可以包括所有150个选择以及选择显示日期的“唯一”选择。

接下来:尝试在表单上显示150个选项真的很难 - 你在表单上快速耗尽了空间。甚至你上面的模型显示了一个重复数据显示的数据表 - 如果它持续150行,你不太可能在屏幕上完全适应所有这些而不使用某种重复数据显示。

想想您使用的任何现有软件 - 非常罕见地同时看到150个选项 - 您必须从列表中“选择”。想一想会计包中的发票表单 - 您可以显示所有选项 - 您必须滚动或“搜索”一下以缩小选择范围。

最简单的方法是让主要表格基于员工(所以姓名,电话和所有爵士乐)。然后子表单将显示一个组合框以选择培训/课程,然后显示一个日期框以输入日期。 (日期甚至可以自动默认为今天,或者课程开始日期或其他)。

结果是你点+射击,点+射击 - 就像点击一样,点击点击进程类型。

以下是Access中的发票表单示例。为了制作这个动画,我没有触摸键盘 - 它只是鼠标点击,鼠标点击等。但是组合框允许部分匹配和搜索缩小列表显示(再次与您的长列表,你不想折磨用户!)。因此,您可以在组合框中键入“少数几个”字符,以缩小选择列表范围。

enter image description here

我的意思是,无论哪种方式,你都要强迫用户从150种选择中挑选。然而,必须“滚动”150个选项总是只能查看该人已经采取的课程将对用户施加酷刑。

所以只显示选择的课程 - 当你抚养学生时,你可以很容易地看到他们有什么课程,并且按照动画显示,添加其他课程会很容易。

如上所述,下垂列表可以“删除”现有选项,或者如果已选择任何课程则显示日期。防止重复的简单逻辑将添加到更新事件之前的组合框中。

答案 2 :(得分:0)

这个问题有很多可能的解决方案。我会尽量接近你粗糙的布局。我想象一个包含3个表格的数据库:
*表:员工(EmpID,EmpName)
*表:培训(TraID,TraName)
*表:Employee_Training(EmpTraID,ET_EmpID,ET_TraID,ET_Date)

根据如下查询创建连续表单:

SELECT Training.TraID, Training.TraName, Employee_Training.EmpTraID, Employee_Training.ET_EmpID, Employee_Training.ET_Date FROM Training LEFT JOIN Employee_Training ON Training.TraID = Employee_Training.ET_TraID;

在主窗体的标题部分中,放置一个名为" ChosenEmpoyee"的组合框。作为这个组合框的记录源 "SELECT EmpID, EmpName FROM Employee",2列,ColumnWidths设置为"0;5"以隐藏第一列。需要EmpID的列来过滤记录。

从组合框中选择一名员工时,afterupdate事件会将表单的记录源更改为如下例所示的查询:

SELECT Training.TraID, Training.TraName, A.EmpTraID, A.ET_EmpID, A.ET_Date FROM ( SELECT Employee_Training.EmpTraID, Employee_Training.ET_EmpID, Employee_Training.ET_TraID, Employee_Training.ET_Date {
{1}} {
{1}}

执行此操作的代码:

Private Sub ChosenEmployee_AfterUpdate()
Dim SQL As String

    SQL = "" & _
" SELECT Training.TraID, Training.TraName, A.EmpTraID, A.ET_EmpID, A.ET_Date " & _
" FROM (SELECT EmpTraID, ET_EmpID, ET_TraID, ET_Date " & _
"       FROM Employee_Training WHERE ET_EmpID = " & ChosenEmployee & _
"       ) As A " & _
" RIGHT JOIN Training ON Training.TraID = A.ET_TraID"

    Me.RecordSource = SQL
    Me.Requery
End Sub

<小时/> 问题的第二部分;具有5列的连续形式,在5个具有相同名称的文本框中显示信息: TraID / TraName / EmpTraID / ET_EmpID / ET_Date

通过在标题中的组合框中选择来选择雇员。 双击文本框将选择培训 期望的行。如果已有日期,EmpTraID将会 值大于0。

执行此操作的代码:

Private Sub AT_Date_DblClick(Cancel As Integer)
Dim S As String
Dim D As Date
Dim SQL As String
Dim EmpTraID As Long

    S = "Please give the date of attendance."
    S = InputBox(S)
    If Not IsDate(S) Then
        S = "I'm sorry, the entered value > is not recognised as a date."
        MsgBox S, vbExclamation
        'Cancel = True
    Else
        D = CDate(S)
        S = "Are you sure to enter the following date of attendance ?" & vbCrLf & Format(D, "dddd, dd mmmm yyyy")
        If MsgBox(S, vbYesNo + vbDefaultButton2 + vbQuestion) = vbYes Then
            '
            ' the following 2 lines will result into troubles ...
            ' Ms Access is not able to alter values
            ' in a recordset based on a query with a JOIN-statement
            '
            'Me.AT_Date = CDate(S)
            'Me.Refresh
            '
            ' if there was already a date then
            '   change the date by using AttTraiID
            ' else
            '   insert a record in AttTrai_T
            ' end if
            '
            EmpTraID = Nz(Me.EmpTraID.Value, 0)
            If EmpTraID <> 0 Then
                SQL = ""
                SQL = SQL & "UPDATE Employee_Training "
                SQL = SQL & " SET ET_Date = "
                SQL = SQL & " #" & Format(D, "mm/dd/yyyy") & "# " ' US-date-format needed when using '#' in a query in MsAccess
                SQL = SQL & " WHERE EmpTraID = " & EmpTraID
            Else
                SQL = ""
                SQL = SQL & "INSERT INTO Employee_Training "
                SQL = SQL & " (ET_EmpID, AT_TraID, ET_Date) "
                SQL = SQL & " VALUES "
                SQL = SQL & " (" & ChosenEmployee
                SQL = SQL & " ," & Nz(Me.TraID.Value, 0)
                SQL = SQL & " , #" & Format(D, "mm/dd/yyyy") & "# " ' US-date-format needed when using '#' in a query in MsAccess
                SQL = SQL & " )"
            End If

            CurrentDb.Execute SQL
            DoEvents: DoEvents: DoEvents
            Me.Requery

        End If
    End If
End Sub