如何在Access中链接表单? (在它们之间传递值)

时间:2010-06-03 06:08:09

标签: ms-access ms-access-2007

我正在使用Access 2007,并且拥有这样的数据模型......

乘客 - 预订 - 目的地

因此,1名乘客可以进行多次预订,每次预订为1个目的地。

我的问题......

我可以创建一个表单以允许输入乘客详细信息, 但是我想添加一个NEXT按钮带我到表格输入预订的详细信息(即只是一个简单的目的地下拉列表)。 我添加了NEXT按钮,它有

的事件
RunCommand SaveRecord
OpenForm   Destination_form

但是,我无法确定如何将新表格传递给刚刚输入的乘客的主要钥匙(PassengerID)。

我真的只想要一个表格,并允许输入乘客详细信息和目的地的选择,然后在2个表格(乘客和预订)中创建条目,但我可以'这样做也可以。

有人可以帮帮我吗?

由于 杰夫波特

5 个答案:

答案 0 :(得分:7)

实际上我在这里给出的最好建议是不实际传递参数。在表单的on-open事件中简单,或者更好的是使用稍后的on-load事件只是为了在代码中选择一个PREVIOUS调用表单的引用。这种方法的优点在于,如果超时从一个参数转到10个参数,那么您不必修改参数解析代码,甚至不必修改调用代码。实际上,如果您决定检查调用表单中的先前值,则无法修改AT ALL。

所以,请记住使用开放式args只是一种单向事件。您不能使用它将值返回给调用表单。此外,所有的开放式参数都必须是弦乐。所以,你失去了任何约会打字的能力,比如真正的整数,甚至是日期和时间格式,这可能是解析出来的问题。正如你在这里看到的那样,解析字符串的代码无论如何都会变得有点混乱。

简单的解决方案是,在您想要来自PREVIOUS的值的每种形式中,只需声明模块级变量,如下所示

Dim frmPrevous         as form.

然后在加载事件的表单中,只需选择上一个表单的名称,如下所示:

Set frmPrevious = screen.ActiveForm

就是这样。我们完成了!

我们这里只写了一行代码。 (如果包含声明声明,请确定两个)。此时,在表单的当前代码中的任何位置,您可以通过执行以下操作来引用事件属性以及上一个表单中的任何字段或值

Msgbox "PK id of previous form = " & frmPrevious.ID

让我们说出于某种原因,您希望以前的表单以连续的形式重新加载记录。然后我们可以去:

frmPrevious.Requery

或者,强制记录保存:

frmPrevious.Dirty = false

因此,上面的内容几乎与在当前代码中使用“ME”一样自然和方便。我发现这很简单易行,我认为这应该是首先访问的一部分。

如上所述,用途是无穷无尽的,我可以从调用表单中检查任何列或值。您甚至可以将变量和函数声明为public,然后可以使用它们。

并且,请注意,这两种方式都有效。我可以在调用表单中填充和更改值。所以我可以从调用表单更新或更改任何值/列/控件的值。

并且绝对不需要解析。此外,如果通过不同的形式调用相同的现有表单,则上述代码步骤甚至可以工作。在所有情况下,可以在不修改代码的情况下拾取表单调用ID。

即使在这种情况下,我有许多不同的表单启动并调用此特定表单,您仍然可以拉出ID列。并且,在列可能与不同形式不同的情况下,您可以简单地在SAME名称的调用形式中声明公共变量或公共函数。因此,如果我想调用需要DateCreate的表单,但每个表单都没有DateCreate的一致列名(可能是invoiceDateCreate和inventory Date Create),那么您只需在调用表单中使用常量名称声明一个公共函数。然后我们可以去:

Msgbox "Date created of calling form record = " & frmPrevious.DateCreated

因此,创建的日期可以是上一种形式的公共变量或公共函数,可以是数据库中的任何可想到的列。

所以不要在表单之间传递值,只需传递一个对调用表单的引用,这不仅比这里显示的其他方法更灵活,它也是一种面向对象的方法,你不仅限于传递值。

您只需设置所需控件的值(frmPrevous.SomeContorlName),即可在调用表单中返回值。

如上所述,您不仅限于传递值,而是完全使用代码,诸如脏的属性以及调用表单中存在的任何其他内容。

我作为标准编码实践几乎采用了上述几种形式。我只是声明并设置前一个引用的表单。这样就可以在编写代码时将一个方便的先前表单引用用作“ME”引用。

使用这种编码标准,我还可以在不同形式的不同名称之间剪切和粘贴代码,作为一般规则,我的代码将继续运行而无需修改。

另外一个例子我的所有表单都有一个名为MyDelete的公共函数,它当然会删除表单中的记录,因此如果我想因为某些原因删除前一个调用表单中的记录,那么这是一件简单的事情。执行以下操作

frmPrevious.MyDelete

所以我可以保存以前表格中的数据。我可以重新查询前一个表单,我可以在前一个表单中运行代码,我可以将值返回到上一个表单,我可以检查值和所有列,只需要一行代码来设置对调用的引用形式。

答案 1 :(得分:1)

我这样做是通过在Property Let和Property Get中定义表单中的属性并在打开表单后将值传递给这些属性,如下所示:

目的地形式:

Dim strCallingForm As String
Dim lngKey As Long

Public Property Get callingform() As String
    callingform = strCallingForm
End Property

Public Property Let callingform(NewValue As String)
    strCallingForm = NewValue
End Property

Public Property Let PrimaryKey(NewValue As Long)
    lngKey = NewValue
End Property
呼叫形式

Sub btnGo_Click()
    Const cform As String = "frmDestinationForm"
    DoCmd.OpenForm cform
    Forms(cform).callingform = Me.Name
    Forms(cform).PrimaryKey = Me.PrimaryKey
    Me.Visible = False
End Sub

(结束)

答案 2 :(得分:0)

我会使用表单的openargs方法。这样,您就可以从任何其他表单将一个数据传递给新表单。您还可以通过发送分隔的参数字符串然后将它们拆分来扩展它。例如,我有一个用于编辑代理活动的表单,该表单是在日期中传递的,代理名称,代理ID和团队在打开的args中

DoCmd.OpenForm "frmEdit_agent_activity", , , , , acDialog, Item & "|" & Me.txtDate & "|" & Item.ListSubItems(1) & "|" & Item.ListSubItems(2)

然后表单使用它来预先填充控件

Private Sub Form_Load()
If IsMissing(Me.OpenArgs) = True Or IsNull(Me.OpenArgs) = True Then
    'no args, exit the form
    DoCmd.Close acForm, "frmEdit_agent_activity", acSaveNo
Else
    'this form has 4 open args
    '1 Staff ID
    '2 Date
    '3 Team_ID
    '4 Staff Name
    Me.txtStaff_ID = GetDelimitedField(1, Me.OpenArgs, "|")
    Me.txtDate = GetDelimitedField(2, Me.OpenArgs, "|")
    Me.txtTeam_ID = GetDelimitedField(3, Me.OpenArgs, "|")
    Me.txtStaff_name = GetDelimitedField(4, Me.OpenArgs, "|")
End If

End Sub

哦,这是GetDelimitedField函数

Function GetDelimitedField(FieldNum As Integer, DelimitedString As String, Delimiter As String) As String
Dim NewPos As Integer
Dim FieldCounter As Integer
Dim FieldData As String
Dim RightLength As Integer
Dim NextDelimiter As Integer
If (DelimitedString = "") Or (Delimiter = "") Or (FieldNum = 0) Then
    GetDelimitedField = ""
    Exit Function
End If
NewPos = 1
FieldCounter = 1
While (FieldCounter < FieldNum) And (NewPos <> 0)
    NewPos = InStr(NewPos, DelimitedString, Delimiter, vbTextCompare)
    If NewPos <> 0 Then
        FieldCounter = FieldCounter + 1
        NewPos = NewPos + 1
    End If
Wend
RightLength = Len(DelimitedString) - NewPos + 1
FieldData = Right$(DelimitedString, RightLength)
NextDelimiter = InStr(1, FieldData, Delimiter, vbTextCompare)
If NextDelimiter <> 0 Then
FieldData = Left$(FieldData, NextDelimiter - 1)
End If
GetDelimitedField = FieldData
End Function

答案 3 :(得分:0)

你考虑过子形态吗?对于一对多关系是理想的。链接子字段将自动从链接主字段中完成。

如果您需要操作中的子窗体示例,Northwind数据库随附所有版本的Access,或者您可以下载相关的。

2007 http://office.microsoft.com/en-us/templates/TC012289971033.aspx?CategoryID=CT102115771033

2000 http://www.microsoft.com/downloads/details.aspx?familyid=c6661372-8dbe-422b-8676-c632d66c529c&displaylang=en

答案 4 :(得分:0)

您可以使用OpenArgs 但我还建议您也考虑使用选项卡控件。 这允许您在同一个“屏幕不动产”上使用一组记录集,或使用子表单显示子记录集。 在这种情况下,您可以使用“下一步”按钮切换到选项卡控件的下一页。