Reputation: 919
I have not used VB much but as far as I can tell scope works the same as in C#. The problem is, I'm using VB in MS Access so I am unsure if the rules are a bit different (though I assume they are not). The following code shows values being assigned to variables which have only been declared within the function parameters. Specifically looking at PurchaseOrderID, I am unsure as to how it is retaining its assigned value for use in the function proceeding it.
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
Can someone give me some insight on this?
Upvotes: 1
Views: 297
Reputation: 21
Perhaps this is best handled by types. Something like this:
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
Upvotes: 2
Reputation: 91376
In VBA, how you call a procedure can be important.
"Even if a called procedure has declared its parameters as ByRef, you can force those to be ByVal by enclosing each argument within parentheses."
-- http://www.cpearson.com/excel/byrefbyval.aspx
This is true of VBA in all Office applications. For example, let us say you have two procedures:
Sub SubByVal(ByVal Total As Integer)
Total = 50
End Sub
Sub SubByRef(ByRef Total As Integer)
Total = 50
End Sub
And you run a few tests:
Dim Total As Integer
Total = 100
These three versions work as expected and Total is equal to 100
Call SubByVal(Total)
SubByVal (Total)
SubByVal Total
These two work as expected and Total is equal to 50
Call SubByRef(Total)
SubByRef Total
However, in this version, in spite of calling ByRef, Total is equal to 100, because it is forced to ByVal by the parentheses.
SubByRef (Total)
Upvotes: 2
Reputation: 97131
You can pass arguments to a VBA procedure by value or by reference. If you don't specify either ByVal
or ByRef
in the procedure's declaration, it defaults to ByRef
. So the following two declarations are equivalent ...
Function DoSomething(PurchaseOrderID As Long) AS Boolean
Function DoSomething(ByRef PurchaseOrderID As Long) AS Boolean
The key here is that ByRef
allows changes to the argument within the procedure to be transmitted back to the caller.
Upvotes: 1