Function 在MS-Access中使用VB实现可变范围

Function 在MS-Access中使用VB实现可变范围,function,ms-access,scope,vba,Function,Ms Access,Scope,Vba,我没有太多使用VB,但据我所知,scope的工作原理与C#中的相同。问题是,我在MS Access中使用VB,所以我不确定规则是否有点不同(尽管我假设它们没有)。以下代码显示分配给变量的值,这些变量仅在函数参数中声明。具体来看PurchaseOrderID,我不确定它是如何保留分配的值以用于处理它的函数的 Function Create(SupplierID As Long, EmployeeID As Long, OrderID As Long, PurchaseOrderID As Long

我没有太多使用VB,但据我所知,scope的工作原理与C#中的相同。问题是,我在MS Access中使用VB,所以我不确定规则是否有点不同(尽管我假设它们没有)。以下代码显示分配给变量的值,这些变量仅在函数参数中声明。具体来看PurchaseOrderID,我不确定它是如何保留分配的值以用于处理它的函数的

Function Create(SupplierID As Long, EmployeeID As Long, OrderID As Long, PurchaseOrderID As Long) As Boolean
    Dim rsw As New RecordsetWrapper
    If rsw.OpenRecordset("Purchase Orders") Then
        With rsw.Recordset
            .AddNew
            ![Supplier ID] = SupplierID
            If EmployeeID > 0 Then
                ![Created By] = EmployeeID
                ![Creation Date] = Now()
                ![Submitted By] = EmployeeID
                ![Submitted Date] = Now()
                ![Status ID] = Submitted_PurchaseOrder
            End If

            If OrderID > 0 Then
                ![Notes] = InsertString(PurchaseGeneratedBasedOnOrder, CStr(OrderID))
            End If
            If rsw.Update Then
                .Bookmark = .LastModified
                PurchaseOrderID = ![Purchase Order ID]
                Create = True
            End If
        End With
    End If
End Function


Function CreateLineItem(PurchaseOrderID As Long, ProductID As Long, UnitCost As Long, Quantity As Long) As Boolean
    Dim rsw As New RecordsetWrapper
    If rsw.OpenRecordset("Purchase Order Details") Then
        With rsw.Recordset
            .AddNew
            ![Purchase Order ID] = PurchaseOrderID
            ![Product ID] = ProductID
            ![Quantity] = Quantity
            ![Unit Cost] = UnitCost
            CreateLineItem = rsw.Update
        End With
    End If
End Function

有人能给我一些关于这方面的见解吗?

您可以通过值或引用将参数传递给VBA过程。如果在过程的声明中未指定
ByVal
ByRef
,则默认为
ByRef
。所以下面两个声明是等价的

Function DoSomething(PurchaseOrderID As Long) AS Boolean
Function DoSomething(ByRef PurchaseOrderID As Long) AS Boolean

这里的关键是
ByRef
允许将过程中参数的更改传输回调用方。

您可以通过值或引用将参数传递给VBA过程。如果在过程的声明中未指定
ByVal
ByRef
,则默认为
ByRef
。所以下面两个声明是等价的

Function DoSomething(PurchaseOrderID As Long) AS Boolean
Function DoSomething(ByRef PurchaseOrderID As Long) AS Boolean

这里的关键是
ByRef
允许将过程中参数的更改传输回调用者。

在VBA中,如何调用过程非常重要

即使被调用的过程已将其参数声明为ByRef,您也可以 可以通过将每个参数包含在 括号。”

--

VBA在所有Office应用程序中都是如此。例如,假设您有两个过程:

Sub SubByVal(ByVal Total As Integer)
    Total = 50
End Sub

Sub SubByRef(ByRef Total As Integer)
    Total = 50
End Sub
您可以运行一些测试:

Dim Total As Integer
Total = 100
这三个版本按预期工作,总计等于100

Call SubByVal(Total)
SubByVal (Total)
SubByVal Total
这两项工作按预期进行,总计等于50

Call SubByRef(Total)
SubByRef Total
然而,在这个版本中,尽管调用了ByRef,Total还是等于100,因为括号强制它使用ByVal

SubByRef (Total)

在VBA中,如何调用过程非常重要

即使被调用的过程已将其参数声明为ByRef,您也可以 可以通过将每个参数包含在 括号。”

--

VBA在所有Office应用程序中都是如此。例如,假设您有两个过程:

Sub SubByVal(ByVal Total As Integer)
    Total = 50
End Sub

Sub SubByRef(ByRef Total As Integer)
    Total = 50
End Sub
您可以运行一些测试:

Dim Total As Integer
Total = 100
这三个版本按预期工作,总计等于100

Call SubByVal(Total)
SubByVal (Total)
SubByVal Total
这两项工作按预期进行,总计等于50

Call SubByRef(Total)
SubByRef Total
然而,在这个版本中,尽管调用了ByRef,Total还是等于100,因为括号强制它使用ByVal

SubByRef (Total)

也许这最好由类型来处理。大概是这样的:

Type PurchaseSet
   PurchaseOrderID As Long
   OrderCreated as boolean
End Type


Function Create(SupplierID As Long, EmployeeID As Long, OrderID As Long ) As PurchaseSet
    Dim rsw As New RecordsetWrapper
    Dim ps as PurchaseSet 
   ps.OrderCreated = false

    If rsw.OpenRecordset("Purchase Orders") Then
        With rsw.Recordset
            .AddNew
            ![Supplier ID] = SupplierID
            If EmployeeID > 0 Then
                ![Created By] = EmployeeID
                ![Creation Date] = Now()
                ![Submitted By] = EmployeeID
                ![Submitted Date] = Now()
                ![Status ID] = Submitted_PurchaseOrder
            End If

            If OrderID > 0 Then
                ![Notes] = InsertString(PurchaseGeneratedBasedOnOrder, CStr(OrderID))
            End If
            If rsw.Update Then
                .Bookmark = .LastModified
                ps.PurchaseOrderID = ![Purchase Order ID]
                ps.OrderCreated = True

            End If
        End With
    End If

    Create = ps
End Function

也许这最好由类型来处理。大概是这样的:

Type PurchaseSet
   PurchaseOrderID As Long
   OrderCreated as boolean
End Type


Function Create(SupplierID As Long, EmployeeID As Long, OrderID As Long ) As PurchaseSet
    Dim rsw As New RecordsetWrapper
    Dim ps as PurchaseSet 
   ps.OrderCreated = false

    If rsw.OpenRecordset("Purchase Orders") Then
        With rsw.Recordset
            .AddNew
            ![Supplier ID] = SupplierID
            If EmployeeID > 0 Then
                ![Created By] = EmployeeID
                ![Creation Date] = Now()
                ![Submitted By] = EmployeeID
                ![Submitted Date] = Now()
                ![Status ID] = Submitted_PurchaseOrder
            End If

            If OrderID > 0 Then
                ![Notes] = InsertString(PurchaseGeneratedBasedOnOrder, CStr(OrderID))
            End If
            If rsw.Update Then
                .Bookmark = .LastModified
                ps.PurchaseOrderID = ![Purchase Order ID]
                ps.OrderCreated = True

            End If
        End With
    End If

    Create = ps
End Function

我认为Long是不可变的,即只通过值传递?在VBA/VB6中,任何类型的过程参数都是通过引用传递的,除非限定为
ByVal
@Nate请查看ByRef关键字和函数语句的访问帮助主题。@David它将解释此代码如何在没有错误的情况下运行。你知道更新版本的VB是否也是这样吗?@HansUp谢谢,你的答案基本上完全回答了我的问题。我认为Long是不可变的,即只通过值传递?在VBA/VB6中,除非限定为
ByVal
@Nate,否则任何类型的过程参数都是通过引用传递的。请查看ByRef关键字和函数语句的Access帮助主题。@David它将解释此代码如何在没有错误的情况下运行。你知道更新版本的VB是否也是如此吗?@HansUp谢谢,你的答案基本上完全回答了我的问题。