Summary
Number of forms: | 34 |
Number of main forms: | 19 |
Number of subforms: | 0 |
Forms
Active Orders Subform for Home Datasheet (SubForm)
Parent (s):
#
Date
Status
Customer
Amount
Customer Details SingleForm
Auto_Logo0
&Go to
Company
First Name
Last Name
Job Title
Business Phone
Mobile Phone
Fax Number
Street
City
State/Province
Zip/Postal Code
Country/Region
E-mail
Web Page
Notes
Primary Contact
Phone Numbers
Address
Customer Orders subform
Invoice #
Customer
Order Date
Shipped
Ship Name
Ship Address
Shipping
Taxes
Invoice Total
Sub Total
Customer List SplitForm
Auto_Logo0
Customer List
ID
Company
First Name
Last Name
E-mail Address
Business Phone
Job Title
Notes
Home Phone
Mobile Phone
Fax Number
Address
Zip/Postal Code
State/Province
City
Country/Region
Customer Orders Subform Datasheet (SubForm)
Parent (s):
Invoice #
Customer
Order Date
Shipped
Ship Name
Ship Address
Shipping
Taxes
Invoice Total
Sub Total
Employee Details SingleForm
Auto_Logo0
&Go to
First Name
Last Name
Company
Job Title
Business Phone
Home Phone
Mobile Phone
Fax Number
Street
City
State/Province
Zip/Postal Code
Country/Region
E-mail
Web Page
Notes
Phone Numbers
Address
Orders subform
Order #
Customer
Order Date
Shipped
Ship Name
Ship Address
Employee
Shipping
Taxes
Invoice Total
Sub Total
Employee List SplitForm
Auto_Logo0
Employee List
&Reports
ID
First Name
Last Name
E-mail Address
Business Phone
Company
Job Title
Home Phone
Mobile Phone
Fax Number
Address
City
State/Province
Zip/Postal Code
Country/Region
Notes
Employee Orders Subform Datasheet (SubForm)
Parent (s):
Order #
Customer
Order Date
Shipped
Ship Name
Ship Address
Employee
Shipping
Taxes
Invoice Total
Sub Total
Home SingleForm
Auto_Logo1
Northwind Traders
I am:
Active Orders
Inventory to Reorder
Quick Links
sbfActiveOrders
#
Date
Status
Customer
Amount
sbfInventoryToReorder
Product
Qty Available
Reorder Level
Box133
sbfSalesPivot
Country/Region:
Last Name:
First Name:
Shipped Date:
Order ID:
Sale Amount:
Inventory List ContinuousForm
Auto_Logo0
Inventory List
Total Inventory
Allocated Inventory
Available Inventory
Inventory Due from Supplier
Combined Total
Target
Level
Qty To
Reorder
Purchase from Supplier
Product
- cmdPurchase_Click
Option Compare Database Option Explicit
Private Sub cmdPurchase_Click() If Not Me![Qty To Reorder] > 0 Then MsgBoxOKOnly NoNeedToRestock ElseIf Inventory.RestockProduct(Me![Product ID]) Then Me.Requery MsgBoxOKOnly RestockSuccess Else MsgBoxOKOnly RestockingFailed End If End Sub
Inventory to reorder Subform for Home Datasheet (SubForm)
Parent (s):
Product
Qty Available
Reorder Level
Login Dialog SingleForm
Image26
Northwind Login
Select Employee:
The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious. No association with any real company, organization, product, domain name, email address, logo, person, places, or events is intended or should be inferred.
Order Details SingleForm
Auto_Logo0
Status:
BoxOrderHeader
Customer
Salesperson
E-mail Address
Order Date
sbfOrderDetails
Product
Qty
Unit Price
Discount
Total Price
Status
boxShippingData
Shipping Company
Ship Date
Shipping Fee
boxShippingAddress
Ship Name
Ship Address
City
State/Province
Zip/Postal Code
Country/Region
Payment Type
Payment Date
Payment/Order
Notes
Form |
---|
...
|
...
|
- SetDefaultShippingAddress
- cmdDeleteOrder_Click
- cmdClearAddress_Click
- ClearShippingAddress
- cmdCompleteOrder_Click
- cmdCreateInvoice_Click
- cmdShipOrder_Click
- Customer_ID_AfterUpdate
- Form_Current
- Form_Load
- GetDefaultSalesPersonID
- ValidateShipping
- ValidatePaymentInfo
- SetFormState
- ValidateOrder
Option Compare Database Option Explicit
Sub SetDefaultShippingAddress() If IsNull(Me![Customer ID]) Then ClearShippingAddress Else Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Customers Extended", "[ID] = " & Me.Customer_ID) Then With rsw.Recordset Me![Ship Name] = ![Contact Name] Me![Ship Address] = ![Address] Me![Ship City] = ![City] Me![Ship State/Province] = ![State/Province] Me![Ship ZIP/Postal Code] = ![ZIP/Postal Code] Me![Ship Country/Region] = ![Country/Region] End With End If End If End Sub
Private Sub cmdDeleteOrder_Click() If IsNull(Me![Order ID]) Then Beep ElseIf Me![Status ID] = Shipped_CustomerOrder Or Me![Status ID] = Closed_CustomerOrder Then MsgBoxOKOnly CannotCancelShippedOrder ElseIf MsgBoxYesNo(CancelOrderConfirmPrompt) Then If CustomerOrders.Delete(Me![Order ID]) Then MsgBoxOKOnly CancelOrderSuccess eh.TryToCloseObject Else MsgBoxOKOnly CancelOrderFailure End If End If End Sub
Private Sub cmdClearAddress_Click() ClearShippingAddress End Sub
Private Sub ClearShippingAddress() Me![Ship Name] = Null Me![Ship Address] = Null Me![Ship City] = Null Me![Ship State/Province] = Null Me![Ship ZIP/Postal Code] = Null Me![Ship Country/Region] = Null End Sub
Private Sub cmdCompleteOrder_Click() If Me![Status ID] <> Shipped_CustomerOrder Then MsgBoxOKOnly OrderMustBeShippedToClose ElseIf ValidateOrder(Closed_CustomerOrder) Then Me![Status ID] = Closed_CustomerOrder eh.TryToSaveRecord MsgBoxOKOnly OrderMarkedClosed SetFormState End If End Sub
Private Sub cmdCreateInvoice_Click() Dim OrderID As Long Dim InvoiceID As Long OrderID = Nz(Me![Order ID], 0) ' Gracefully exit if invoice already created If CustomerOrders.IsInvoiced(OrderID) Then If MsgBoxYesNo(OrderAlreadyInvoiced) Then CustomerOrders.PrintInvoice OrderID End If ElseIf ValidateOrder(Invoiced_CustomerOrder) Then ' Create Invoice Record If CustomerOrders.CreateInvoice(OrderID, 0, InvoiceID) Then ' Mark all Order Items Invoiced ' Need to change Inventory Status to SOLD from HOLD Dim rsw As New RecordsetWrapper With rsw.GetRecordsetClone(Me.sbfOrderDetails.Form.Recordset) While Not .EOF If Not IsNull(![Inventory ID]) And ![Status ID] = OnHold_OrderItemStatus Then rsw.Edit ![Status ID] = Invoiced_OrderItemStatus rsw.Update Inventory.HoldToSold ![Inventory ID] End If rsw.MoveNext Wend End With ' Print the Invoice CustomerOrders.PrintInvoice OrderID SetFormState End If End If End Sub
Private Sub cmdShipOrder_Click() If Not CustomerOrders.IsInvoiced(Nz(Me![Order ID], 0)) Then MsgBoxOKOnly CannotShipNotInvoiced ElseIf Not ValidateShipping() Then MsgBoxOKOnly ShippingNotComplete Else Me![Status ID] = Shipped_CustomerOrder If IsNull(Me![Shipped Date]) Then Me![Shipped Date] = Date End If eh.TryToSaveRecord SetFormState End If End Sub
Private Sub Customer_ID_AfterUpdate() SetFormState False If Not IsNull(Me![Customer ID]) Then SetDefaultShippingAddress End If End Sub
Private Sub Form_Current() SetFormState End Sub
Private Sub Form_Load() SetFormState End Sub
Function GetDefaultSalesPersonID() As Long GetDefaultSalesPersonID = GetCurrentUserID() End Function
Function ValidateShipping() As Boolean If IsNull(Me![Shipper ID]) Then Exit Function If Nz(Me![Ship Name]) = "" Then Exit Function If Nz(Me![Ship Address]) = "" Then Exit Function If Nz(Me![Ship City]) = "" Then Exit Function If Nz(Me![Ship State/Province]) = "" Then Exit Function If Nz(Me![Ship ZIP/Postal Code]) = "" Then Exit Function ValidateShipping = True End Function
Function ValidatePaymentInfo() As Boolean If IsNull(Me![Payment Type]) Then Exit Function If IsNull(Me![Paid Date]) Then Exit Function ValidatePaymentInfo = True End Function
Sub SetFormState(Optional fChangeFocus As Boolean = True) If fChangeFocus Then Me.Customer_ID.SetFocus Dim Status As CustomerOrderStatusEnum Status = Nz(Me![Status ID], New_CustomerOrder) TabCtlOrderData.Enabled = Not IsNull(Me![Customer ID]) Me.cmdCreateInvoice.Enabled = (Status = New_CustomerOrder) Me.cmdShipOrder.Enabled = (Status = New_CustomerOrder) Or (Status = Invoiced_CustomerOrder) Me.cmdDeleteOrder.Enabled = (Status = New_CustomerOrder) Or (Status = Invoiced_CustomerOrder) Me.cmdCompleteOrder.Enabled = (Status <> Closed_CustomerOrder) Me.[Order Details_Page].Enabled = (Status = New_CustomerOrder) Me.[Shipping Information_Page].Enabled = (Status = New_CustomerOrder) Me.[Payment Information_Page].Enabled = (Status <> Closed_CustomerOrder) Me.Customer_ID.Locked = (Status <> New_CustomerOrder) Me.Employee_ID.Locked = (Status <> New_CustomerOrder) Me.sbfOrderDetails.Locked = (Status <> New_CustomerOrder) End Sub
Function ValidateOrder(Validation_OrderStatus As CustomerOrderStatusEnum) As Boolean If IsNull(Me![Customer ID]) Then MsgBoxOKOnly MustSpecifyCustomer ElseIf IsNull(Me![Employee ID]) Then MsgBoxOKOnly MustSpecifySalesPerson ElseIf Not ValidateShipping() Then MsgBoxOKOnly ShippingNotComplete Else If Validation_OrderStatus = Closed_CustomerOrder Then If Not ValidatePaymentInfo() Then MsgBoxOKOnly PaymentInfoNotComplete Exit Function End If End If Dim rsw As New RecordsetWrapper With rsw.GetRecordsetClone(Me.sbfOrderDetails.Form.Recordset) ' Check that we have at least one specified line items If .RecordCount = 0 Then MsgBoxOKOnly OrderDoesNotContainLineItems Else ' Check all that all line items have allocated inventory Dim LineItemCount As Integer Dim Status As OrderItemStatusEnum LineItemCount = 0 While Not .EOF LineItemCount = LineItemCount + 1 Status = Nz(![Status ID], None_OrderItemStatus) If Status <> OnHold_OrderItemStatus And Status <> Invoiced_OrderItemStatus Then MsgBoxOKOnly MustBeAllocatedBeforeInvoicing Exit Function End If rsw.MoveNext Wend ValidateOrder = True End If End With End If End Function
Order List SplitForm
Order List
Image281
#
Order Date
Status
Salesperson
Customer
Ship Date
Shipping
Taxes
Total
Order Subform for Order Details Datasheet (SubForm)
Parent (s):
Product
Qty
Unit Price
Discount
Total Price
Status
Form |
---|
...
|
- Product_ID_AfterUpdate
- Form_Current
- Quantity_AfterUpdate
- Status_Name_DblClick
Option Compare Database Option Explicit
Private Sub Product_ID_AfterUpdate() 'Initialize price and discount for each product change If Not IsNull(Me![Product ID]) Then Me![Quantity] = 0 Me.Quantity.Locked = False Me![Unit Price] = GetListPrice(Me![Product ID]) Me![Discount] = 0 Me![Status ID] = None_OrderItemStatus 'Empty Product records mean user wants to delete line item Else eh.TryToRunCommand acCmdDeleteRecord End If End Sub
Private Sub Form_Current() If Nz(Me![Status ID], None_OrderItemStatus) = Invoiced_OrderItemStatus Then Me.AllowEdits = False Else Me.AllowEdits = True End If End Sub
Private Sub Quantity_AfterUpdate() On Error GoTo ErrorHandler Dim IT As InventoryTransaction Dim PurchaseOrderID As Long Dim SupplierID As Long IT.ProductID = Nz(Me![Product ID], 0) IT.Quantity = Me![Quantity] IT.AllOrNothing = True IT.InventoryID = Nz(Me![Inventory ID], NewInventoryID) 'Request Hold on specified Inventory If Inventory.RequestHold(Me![Order ID], IT) Then Me![Inventory ID] = IT.InventoryID Me![Status ID] = OnHold_OrderItemStatus 'Insufficient Inventory ElseIf Me![Status ID] <> None_OrderItemStatus And Me![Status ID] <> NoStock_OrderItemStatus Then MsgBoxOKOnly InsufficientInventory Me![Quantity] = Me.Quantity.OldValue 'Attempt to create purchase order for back ordered items ElseIf MsgBoxYesNo(NoInventoryCreatePO) Then SupplierID = Inventory.FindProductSupplier(IT.ProductID) 'Create purchase order if we have supplier for this product If SupplierID > 0 Then If PurchaseOrders.Generate(SupplierID, IT.ProductID, Me![Quantity], Me![Order ID], PurchaseOrderID) Then PurchaseOrders.OpenOrder PurchaseOrderID Me![Status ID] = OnOrder_OrderItemStatus Me![Purchase Order ID] = PurchaseOrderID eh.TryToSaveRecord Else Me![Status ID] = NoStock_OrderItemStatus End If 'Could not find a supplier for this product Else MsgBoxOKOnly CannotCreatePO_NoSupplier Me![Status ID] = NoStock_OrderItemStatus End If Else Me![Status ID] = NoStock_OrderItemStatus End If Done: Exit Sub ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("Quantity_AfterUpdate") Then Resume End Sub
Private Sub Status_Name_DblClick(Cancel As Integer) Select Case Me![Status ID] Case NoStock_OrderItemStatus, None_OrderItemStatus Quantity_AfterUpdate Case OnOrder_OrderItemStatus Dim PurchaseOrderID As Long PurchaseOrderID = Nz(Me![Purchase Order ID], 0) If PurchaseOrderID > 0 Then PurchaseOrders.OpenOrder PurchaseOrderID Me.Requery End If Case Invoiced_OrderItemStatus End Select End Sub
Product Category Sales by Month PivotChart (SubForm)
Parent (s):
Order Date:
SumOfQuantity:
Category:
Product Details SingleForm
Auto_Logo0
Go to Product
Standard Cost
Product ID
List Price
Name
Reorder Level
Product Code
Target Level
Category
Default Reorder Quantity
Supplier
Quantity Per Unit
Discontinued
Description
Child22
Order Date
Transaction
Company Name
Quantity
ProductID
Product Sales by Category Chart PivotChart (SubForm)
Parent (s):
Order Date:
Product Name:
Category:
Amount:
Product Sales by Total Revenue Chart PivotChart (SubForm)
Parent (s):
Product Name:
Order Date:
Amount:
Product Sales Qty by Employee Chart PivotChart (SubForm)
Parent (s):
Order Date:
Employee Name
SumOfQuantity:
Product Name:
Product Transactions Subform for Product Details Datasheet (SubForm)
Parent (s):
Order Date
Transaction
Company Name
Quantity
ProductID
Purchase Order Details SingleForm
Auto_Logo0
Status:
BoxOrderHeader
Supplier
Expected Date
Created By:
Creation Date
Submitted By:
Submitted Date
Approved By:
Approved Date
sbfPurchaseDetails
Product
Qty
Unit Cost
Total Price
PO
ID
sbfPurchaseReceiving
Product
Qty
Date Received
Add to Inventory
Payment Type
Payment Date
Notes
Form |
---|
...
|
- GetPurchaseDetailsSubform
- PurchaseContainsLineItems
- Supplier_ID_AfterUpdate
- Supplier_ID_BeforeUpdate
- cmdApprovePurchase_Click
- cmdCancelPurchase_Click
- cmdClose_Click
- cmdSubmitforApproval_Click
- Form_Current
- TabCtlPurchasing_Change
- FRemovePurchaseLineItems
- PurchaseOrder_ContainsPostedInventory
- PurchaseOrderIsValid
- InitFormState
Option Compare Database Option Explicit
Public Function GetPurchaseDetailsSubform() As [Form_Purchases Subform for Purchase Order Details] Set GetPurchaseDetailsSubform = Me.sbfPurchaseDetails.Form End Function
Private Function PurchaseContainsLineItems() As Boolean PurchaseContainsLineItems = Me.GetPurchaseDetailsSubform.RecordsetClone.RecordCount > 0 End Function
Private Sub Supplier_ID_AfterUpdate() Me.GetPurchaseDetailsSubform.Product_ID.Requery Me.[Purchase Details_Page].Enabled = True End Sub
Private Sub Supplier_ID_BeforeUpdate(Cancel As Integer) 'Changing Suppliers with defined line items requires some decisions If PurchaseContainsLineItems() Then If Not MsgBoxYesNo(ChangeSupplierWarning) Then Cancel = True ElseIf PurchaseOrder_ContainsPostedInventory() Then MsgBoxOKOnly CannotRemovePostedItems Cancel = True ElseIf Not FRemovePurchaseLineItems() Then MsgBoxOKOnly ErrorRemovingPurchaseLineItems Cancel = True End If End If End Sub
Private Sub cmdApprovePurchase_Click() 'Cannot approve purchases without line items If Not PurchaseContainsLineItems() Then MsgBoxOKOnly PurchaseHasNoLineItems ElseIf Not Privileges.CanApprovePurchases() Then MsgBoxOKOnly CannotApprovePurchases ElseIf Not PurchaseOrders.MarkApproved(Me![Purchase Order ID]) Then MsgBoxOKOnly PurchaseNotApproved Else Me.Refresh MsgBoxOKOnly PurchaseApproved InitFormState End If End Sub
Private Sub cmdCancelPurchase_Click() If PurchaseOrder_ContainsPostedInventory() Then MsgBoxOKOnly CannotCancelPostedOrder ElseIf MsgBoxYesNo(CancelOrderConfirmPrompt) Then If PurchaseOrders.Delete(Me![Purchase Order ID]) Then MsgBoxOKOnly CancelOrderSuccess eh.TryToGoToRecord acNewRec Else MsgBoxOKOnly CancelOrderFailure End If End If End Sub
Private Sub cmdClose_Click() If PurchaseOrderIsValid() Then eh.TryToCloseObject Else Beep End If End Sub
Private Sub cmdSubmitforApproval_Click() 'Cannot submit purchases without line items If Not PurchaseContainsLineItems() Then MsgBoxOKOnly PurchaseHasNoLineItems Else Me.Submitted_By = GetCurrentUserID() Me.Submitted_Date = Date Me![Status ID] = Submitted_PurchaseOrder eh.TryToSaveRecord 'Refresh joined data MsgBoxOKOnly PurchaseSubmitted InitFormState End If End Sub
Private Sub Form_Current() InitFormState End Sub
Private Sub TabCtlPurchasing_Change() Select Case Me.TabCtlPurchasing.Value Case Me.[Purchase Details_Page].PageIndex Me.[Purchase Details_Page].Requery Case Me.[Payment Information_Page].PageIndex Me.[Inventory Receiving_Page].Requery End Select End Sub
Private Function FRemovePurchaseLineItems() As Boolean 'Don't allow removal for purchases with posted line items If Not PurchaseOrder_ContainsPostedInventory() Then Dim rsw As New RecordsetWrapper With rsw.GetRecordsetClone(Me.GetPurchaseDetailsSubform.Recordset) While Not .EOF If Not ![Posted To Inventory] And IsNull(![Inventory ID]) Then rsw.Delete End If rsw.MoveNext Wend End With Me.GetPurchaseDetailsSubform.Requery FRemovePurchaseLineItems = True End If End Function
Private Function PurchaseOrder_ContainsPostedInventory() As Boolean Dim rsw As New RecordsetWrapper With rsw.GetRecordsetClone(Me.GetPurchaseDetailsSubform.Recordset) While Not .EOF If ![Posted To Inventory] And Not IsNull(![Inventory ID]) Then PurchaseOrder_ContainsPostedInventory = True Exit Function End If rsw.MoveNext Wend End With End Function
Function PurchaseOrderIsValid() As Boolean Dim PurchaseOrderID As Long PurchaseOrderID = Nz(Me![Purchase Order ID], 0) Select Case Me![Status ID] Case New_PurchaseOrder If Not PurchaseContainsLineItems() Then MsgBoxOKOnly PurchaseHasNoLineItems If MsgBoxYesNo(CancelOrderPrompt) Then If PurchaseOrders.Exists(PurchaseOrderID) Then If Not PurchaseOrders.Delete(PurchaseOrderID) Then Exit Function End If End If End If End If Case Submitted_PurchaseOrder Case Approved_PurchaseOrder Case Closed_PurchaseOrder End Select PurchaseOrderIsValid = True End Function
Public Sub InitFormState() Dim Status As PurchaseOrderStatusEnum Me.Supplier_ID.SetFocus Status = Nz(Me![Status ID], New_PurchaseOrder) Me.cmdSubmitforApproval.Enabled = (Status = New_PurchaseOrder) Me.cmdApprovePurchase.Enabled = (Status = Submitted_PurchaseOrder) Me.cmdCancelPurchase.Enabled = (Status <> New_PurchaseOrder) If IsNull(Me![Supplier ID]) Then Me.[Purchase Details_Page].Enabled = False Else Me.[Purchase Details_Page].Enabled = (Status = New_PurchaseOrder) Or (Status = Submitted_PurchaseOrder) End If Me.[Inventory Receiving_Page].Enabled = (Status = Approved_PurchaseOrder) Me.[Payment Information_Page].Enabled = (Status = Approved_PurchaseOrder) Me.AllowEdits = Not (Status = Closed_PurchaseOrder) Me.AllowDeletions = Not (Status = Closed_PurchaseOrder) End Sub
Purchase Order List SplitForm
Auto_Logo0
Purchase Orders
#
Status
Supplier
Total
Submitted By
Submitted
Approved By
Approved
Date Paid
Purchases Subform for Purchase Order Details Datasheet (SubForm)
Parent (s):
Product
Qty
Unit Cost
Total Price
PO
ID
Form |
---|
...
|
...
|
- InitParentState
- Form_AfterInsert
- Form_BeforeUpdate
- Product_ID_AfterUpdate
- Quantity_AfterUpdate
- Quantity_BeforeUpdate
- Unit_Cost_BeforeUpdate
- RemoveCurrentLineItem
Option Compare Database Option Explicit
Sub InitParentState() On Error Resume Next Dim frmParent As [Form_Purchase Order Details] Set frmParent = Me.Parent frmParent.InitFormState End Sub
Private Sub Form_AfterInsert() InitParentState End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer) If IsNull(Me![Unit Cost]) Then MsgBoxOKOnly NeedUnitCost Cancel = True End If End Sub
Private Sub Product_ID_AfterUpdate() ' We interpret this as user wanting to delete purchase item ' Suggested Enhancement: Prevent user from deleting items that have been posted to inventory If IsNull(Me![Product ID]) Then RemoveCurrentLineItem Else Me![Unit Cost] = GetStandardCost(Me![Product ID]) ' Suggested Enhancement: Combine same product iine items End If End Sub
Private Sub Quantity_AfterUpdate() If Me![Quantity] = 0 Then RemoveCurrentLineItem End If End Sub
Private Sub Quantity_BeforeUpdate(Cancel As Integer) If Me![Posted To Inventory] Or Not IsNull(Me![Date Received]) Then MsgBoxOKOnly CannotModifyPurchaseQuantity Cancel = True End If End Sub
Private Sub Unit_Cost_BeforeUpdate(Cancel As Integer) If Me![Posted To Inventory] Or Not IsNull(Me![Date Received]) Then MsgBoxOKOnly CannotModifyPurchasePrice Cancel = True End If End Sub
Private Function RemoveCurrentLineItem() As Boolean RemoveCurrentLineItem = eh.TryToRunCommand(acCmdDeleteRecord) End Function
Receiving Subform for Purchase Order Details Datasheet (SubForm)
Parent (s):
Product
Qty
Date Received
Add to Inventory
Form |
---|
...
|
...
|
- Posted_To_Inventory_AfterUpdate
- Date_Received_AfterUpdate
- Form_Current
- Form_Load
Option Compare Database Option Explicit
Private Sub Posted_To_Inventory_AfterUpdate() On Error GoTo ErrorHandler Dim InventoryID As Long Dim ProductID As Long Dim Quantity As Long ProductID = Nz(Me![Product ID], 0) Quantity = Nz(Me![Quantity], 0) InventoryID = Nz(Me![Inventory ID], 0) 'Posting New Inventory If Me![Posted To Inventory] Then If IsNull(Me![Date Received]) Then Me![Date Received] = Date End If If Inventory.AddPurchase(Me![Purchase Order ID], ProductID, Quantity, InventoryID) Then If InventoryID > 0 Then Me![Inventory ID] = InventoryID Me![Posted To Inventory] = True MsgBoxOKOnly InventoryPostingSuccess End If Else Me![Posted To Inventory] = False MsgBoxOKOnly InventoryPostingFailure End If eh.TryToSaveRecord If Inventory.GetQtyOnBackOrder(ProductID) > 0 Then If MsgBoxYesNo(FillBackOrdersPrompt) Then Inventory.FillBackOrders ProductID End If End If 'Removing Posted Inventory Else If InventoryID > 0 Then Me![Posted To Inventory] = True End If End If Done: Exit Sub ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("Posted_To_Inventory_AfterUpdate") Then Resume End Sub
Private Sub Date_Received_AfterUpdate() If Me![Posted To Inventory] Then Debug.Assert False ElseIf MsgBoxYesNo(PostReceivedProductPrompt) Then Me![Posted To Inventory] = True Posted_To_Inventory_AfterUpdate End If End Sub
Private Sub Form_Current() Me.AllowEdits = Not Me![Posted To Inventory] End Sub
Private Sub Form_Load() Dim rsw As New RecordsetWrapper With rsw.GetRecordsetClone(Me.Recordset) 'Ensure integrity of Inventory postings While Not .EOF If Not IsNull(![Inventory ID]) Then rsw.Edit ![Posted To Inventory] = True rsw.Update End If rsw.MoveNext Wend End With End Sub
Sales Analysis Form SingleForm
Product Name
Employee
Customer Name
Sales
Order Date
Sales Analysis Subform for Home Chart PivotChart (SubForm)
Parent (s):
Country/Region:
Last Name:
First Name:
Shipped Date:
Order ID:
Sale Amount:
Sales Reports Dialog SingleForm
Sales Reports
Select Sales Report
Select Sales Period
Year
Filter Sales Items...
Quarter
Month
Form |
---|
...
|
- PrintReports
- Form_Load
- SetSalesPeriod
- lstSalesPeriod_AfterUpdate
- lstSalesReports_AfterUpdate
- InitFilterItems
- cmdPreview_Click
- cmdPrint_Click
- GetLastOrderDate
Option Compare Database Option Explicit Enum SalesPeriodEnum ByMonth = 1 ByQuarter = 2 ByYear = 3 End Enum
Sub PrintReports(ReportView As AcView) ' This procedure used in Preview_Click and Print_Click Sub procedures. ' Preview or print report selected in the ReportToPrint option group. ' Then close the Print Sales Reports Dialog form. Dim strReportName As String Dim strReportFilter As String Dim lOrderCount As Long ' Determine report filtering If Nz(Me.lstReportFilter) <> "" Then strReportFilter = "([SalesGroupingField] = """ & Me.lstReportFilter & """)" End If ' Determine reporting time frame Select Case Me.lstSalesPeriod Case ByYear strReportName = "Yearly Sales Report" lOrderCount = DCountWrapper("*", "Sales Analysis", "[Year]=" & Me.cbYear) Case ByQuarter strReportName = "Quarterly Sales Report" lOrderCount = DCountWrapper("*", "Sales Analysis", "[Year]=" & Me.cbYear & " AND [Quarter]=" & Me.cbQuarter) Case ByMonth strReportName = "Monthly Sales Report" lOrderCount = DCountWrapper("*", "Sales Analysis", "[Year]=" & Me.cbYear & " AND [Month]=" & Me.cbMonth) End Select If lOrderCount > 0 Then TempVars.Add "Group By", Me.lstSalesReports.Value TempVars.Add "Display", DLookupStringWrapper("[Display]", "Sales Reports", "[Group By]='" & Nz(Me.lstSalesReports) & "'") TempVars.Add "Year", Me.cbYear.Value TempVars.Add "Quarter", Me.cbQuarter.Value TempVars.Add "Month", Me.cbMonth.Value eh.TryToCloseObject DoCmd.OpenReport strReportName, ReportView, , strReportFilter, acWindowNormal Else MsgBoxOKOnly NoSalesInPeriod End If End Sub
Private Sub Form_Load() SetSalesPeriod ByYear InitFilterItems End Sub
Sub SetSalesPeriod(SalesPeriod As SalesPeriodEnum) Me.lstSalesPeriod = SalesPeriod Me.cbQuarter.Enabled = (SalesPeriod = ByQuarter) Me.cbMonth.Enabled = (SalesPeriod = ByMonth) End Sub
Private Sub lstSalesPeriod_AfterUpdate() SetSalesPeriod Me.lstSalesPeriod End Sub
Private Sub lstSalesReports_AfterUpdate() InitFilterItems End Sub
Private Sub InitFilterItems() Me.lstReportFilter.RowSource = DLookupStringWrapper("[Filter Row Source]", "Sales Reports", "[Group By]='" & Nz(Me.lstSalesReports) & "'") Me.lstReportFilter = Null End Sub
Private Sub cmdPreview_Click() PrintReports acViewReport End Sub
Private Sub cmdPrint_Click() PrintReports acViewNormal End Sub
Private Function GetLastOrderDate() As Date GetLastOrderDate = Nz(DMaxWrapper("[Order Date]", "Orders"), Date) End Function
Shipper Details SingleForm
Auto_Logo0
&Go to
Company
First Name
Last Name
Job Title
Business Phone
Mobile Phone
Fax Number
Street
City
State/Province
Zip/Postal Code
Country/Region
E-mail
Web Page
Notes
Primary Contact
Phone Numbers
Address
Shipper List SplitForm
Auto_Logo0
Shipper List
ID
Company
First Name
Last Name
E-mail Address
Business Phone
Job Title
Notes
Home Phone
Mobile Phone
Fax Number
Address
Zip/Postal Code
State/Province
City
Country/Region
Startup Screen SingleForm
Auto_Logo0
Northwind Traders
Welcome to the Northwind Traders sample database. In order to use this sample, click 'Options...' on the Message Bar and select 'Enable this content'. Alternatively, open the database from a Trusted Location.
The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious. No association with any real company, organization, product, domain name, email address, logo, person, places, or events is intended or should be inferred.
Supplier Details SingleForm
Auto_Logo0
&Go to
Company
First Name
Last Name
Job Title
Business Phone
Mobile Phone
Fax Number
Street
City
State/Province
Zip/Postal Code
Country/Region
E-mail
Web Page
Notes
Primary Contact
Phone Numbers
Address
Products subform
ID
Product
Price
Supplier
Quantity Per Unit
Category
Supplier Purchases Subform
Purchase Order ID
Supplier
Purchased Date
Expected Date
Shipping Fee
Taxes
Supplier List SplitForm
Auto_Logo0
Supplier List
ID
Company
First Name
Last Name
E-mail Address
Business Phone
Job Title
Notes
Home Phone
Mobile Phone
Fax Number
Address
Zip/Postal Code
State/Province
City
Country/Region
Supplier Products Subform Datasheet (SubForm)
Parent (s):
ID
Product
Price
Supplier
Quantity Per Unit
Category
Supplier Purchases Subform Datasheet (SubForm)
Parent (s):
Purchase Order ID
Supplier
Purchased Date
Expected Date
Shipping Fee
Taxes
Reports
Customer Address Book Report
Customer Address Book
Contact Name
Address
City
State/Province
Zip/Postal Code
Country/Region
Customer Phone Book Report
Customer Phone Book
Contact Name
Business Phone
Home Phone
Mobile Phone
Employee Address Book Report
Employee Address Book
Employee Name
Address
City
State/Province
Zip/Postal Code
Country/Region
Employee Phone Book Report
Employee Phone Book
Employee Name
Business Phone
Home Phone
Mobile Phone
Invoice Report
Image90
INVOICE
Ship To:
Bill To:
Invoice #
Sales person
Order Date
Customer
Date Shipped
Ship Via
Product ID
Product Name
Quantity
Unit Price
Discount
Price
Monthly Sales Report Report
Monthly Sales Report
Product Category Sales by Month Report
Product Category Sales by Month
Product Category Sales by Month
Order Date:
SumOfQuantity:
Category:
Product Sales by Category Report
Product Sales by Category
Product Sales by Category
Order Date:
Product Name:
Category:
Amount:
Product Sales by Total Revenue Report
Product Sales by Total Revenue
Product Sales by Total Revenue
Product Name:
Order Date:
Amount:
Product Sales Quantity by Employee Report
Product Sales Quantity by Employee
Product Sales Qty by Employee
Order Date:
Employee Name
SumOfQuantity:
Product Name:
Quarterly Sales Report Report
Quarterly Sales Report
Product
Oct
Nov
Dec
Total
Supplier Address Book Report
Supplier Address Book
Contact Name
Address
City
State/Province
Zip/Postal Code
Country/Region
Supplier Phone Book Report
Supplier Phone Book
Contact Name
Business Phone
Home Phone
Mobile Phone
Top Ten Biggest Orders Report
Top 10 Biggest Orders
#
Invoice #
Order Date
Company
Sales Amount
Yearly Sales Report Report
Yeary Sales Report
Product
Q1
Q2
Q3
Q4
Total
Modules
CustomerOrders Module
- CreateInvoice
- IsInvoiced
- PrintInvoice
- SetStatus
- Delete
Option Compare Database Option Explicit Public Enum CustomerOrderStatusEnum New_CustomerOrder = 0 Invoiced_CustomerOrder = 1 Shipped_CustomerOrder = 2 Closed_CustomerOrder = 3 End Enum
Function CreateInvoice(OrderID As Long, Amt As Currency, InvoiceID As Long) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Invoices") Then With rsw.Recordset If Not rsw.AddNew Then Exit Function ![Order ID] = OrderID ![Amount Due] = Amt If rsw.Update Then .Bookmark = .LastModified InvoiceID = ![Invoice ID] CreateInvoice = True End If End With End If End Function
Function IsInvoiced(OrderID As Long) As Boolean IsInvoiced = DCountWrapper("[Invoice ID]", "Invoices", "[Order ID]=" & OrderID) > 0 End Function
Function PrintInvoice(OrderID As Long) As Boolean DoCmd.OpenReport "Invoice", acViewPreview, , "[Order ID]=" & OrderID, acDialog End Function
Function SetStatus(OrderID As Long, Status As CustomerOrderStatusEnum) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Orders", "[Order ID] = " & OrderID) Then With rsw.Recordset If Not .EOF Then .Edit ![Status ID] = Status SetStatus = rsw.Update End If End With End If End Function
Function Delete(OrderID As Long) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Orders", "[Order ID] = " & OrderID) Then Delete = rsw.Delete End If End Function
DomainFunctionWrappers Module
- DomainFunctionWrapper
- DLookupWrapper
- DLookupStringWrapper
- DLookupNumberWrapper
- DCountWrapper
- DMaxWrapper
- DMinWrapper
- DSumWrapper
- DAvgWrapper
Option Compare Database Option Explicit Private Enum DomainFunctionWrapperEnum DLookup_Wrapper DCount_Wrapper DSum_Wrapper DMax_Wrapper DMin_Wrapper DAvg_Wrapper End Enum
Private Function DomainFunctionWrapper(DomainFunction As DomainFunctionWrapperEnum, _ Expr As String, _ Domain As String, _ Optional Criteria As String) As Variant On Error GoTo ErrorHandler Select Case DomainFunction Case DLookup_Wrapper DomainFunctionWrapper = DLookup(Expr, Domain, Criteria) Case DCount_Wrapper DomainFunctionWrapper = DCount(Expr, Domain, Criteria) Case DSum_Wrapper DomainFunctionWrapper = DSum(Expr, Domain, Criteria) Case DMax_Wrapper DomainFunctionWrapper = DMax(Expr, Domain, Criteria) Case DMin_Wrapper DomainFunctionWrapper = DMin(Expr, Domain, Criteria) Case DSum_Wrapper DomainFunctionWrapper = DSum(Expr, Domain, Criteria) Case DAvg_Wrapper DomainFunctionWrapper = DAvg(Expr, Domain, Criteria) Case Else ' Unexpected DomainFunction argument Debug.Assert False End Select Done: Exit Function ErrorHandler: Debug.Print Err.Number & " - " & Err.Description ' Resume statement will be hit when debugging If eh.LogError("DomainFunctionWrapper", _ "DomainFunction = " & DomainFunction, _ "Expr = " & Expr, _ "Domain = " & Domain, _ "Criteria = '" & Criteria & "'") Then Resume End Function
'-------------------------------------------------------- ' DLookupWrapper is just like DLookup only it will trap errors. '-------------------------------------------------------- Public Function DLookupWrapper(Expr As String, Domain As String, Optional Criteria As String) As Variant DLookupWrapper = DomainFunctionWrapper(DLookup_Wrapper, Expr, Domain, Criteria) End Function
'-------------------------------------------------------- ' DLookupStringWrapper is just like DLookup wrapped in an Nz ' This will always return a String. '-------------------------------------------------------- Public Function DLookupStringWrapper(Expr As String, Domain As String, Optional Criteria As String, Optional ValueIfNull As String = "") As String DLookupStringWrapper = Nz(DLookupWrapper(Expr, Domain, Criteria), ValueIfNull) End Function
'-------------------------------------------------------- ' DLookupNumberWrapper is just like DLookup wrapped in ' an Nz that defaults to 0. '-------------------------------------------------------- Public Function DLookupNumberWrapper(Expr As String, Domain As String, Optional Criteria As String, Optional ValueIfNull = 0) As Variant DLookupNumberWrapper = Nz(DLookupWrapper(Expr, Domain, Criteria), ValueIfNull) End Function
'-------------------------------------------------------- ' DCountWrapper is just like DCount only it will trap errors. '-------------------------------------------------------- Public Function DCountWrapper(Expr As String, Domain As String, Optional Criteria As String) As Long DCountWrapper = DomainFunctionWrapper(DCount_Wrapper, Expr, Domain, Criteria) End Function
'-------------------------------------------------------- ' DMaxWrapper is just like DMax only it will trap errors. '-------------------------------------------------------- Public Function DMaxWrapper(Expr As String, Domain As String, Optional Criteria As String) As Long DMaxWrapper = DomainFunctionWrapper(DMax_Wrapper, Expr, Domain, Criteria) End Function
'-------------------------------------------------------- ' DMinWrapper is just like DMin only it will trap errors. '-------------------------------------------------------- Public Function DMinWrapper(Expr As String, Domain As String, Optional Criteria As String) As Long DMinWrapper = DomainFunctionWrapper(DMin_Wrapper, Expr, Domain, Criteria) End Function
'-------------------------------------------------------- ' DSumWrapper is just like DSum only it will trap errors. '-------------------------------------------------------- Public Function DSumWrapper(Expr As String, Domain As String, Optional Criteria As String) As Long DSumWrapper = DomainFunctionWrapper(DSum_Wrapper, Expr, Domain, Criteria) End Function
'-------------------------------------------------------- ' DAvgWrapper is just like DAvg only it will trap errors. '-------------------------------------------------------- Public Function DAvgWrapper(Expr As String, Domain As String, Optional Criteria As String) As Long DAvgWrapper = DomainFunctionWrapper(DAvg_Wrapper, Expr, Domain, Criteria) End Function
ErrorHandling Module
- LogError
- TryToCloseObject
- TryToSaveRecord
- TryToRunCommand
- TryToGoToRecord
Option Compare Database Option Explicit
Public Function LogError(strLocation As String, ParamArray State()) As Boolean Dim strMsg As String Dim strState As String ' Build the error message to display strMsg = Err.Description & " (" & Err.Number & ")" & vbCrLf & vbCrLf & strLocation strState = Join(State, vbCrLf) If strState <> "" Then strMsg = strMsg & vbCrLf & vbCrLf & strState End If ' Display the error MsgBox strMsg, vbCritical ' If debugging is supported, break using Debug.Assert. If DebuggingSupported() Then Debug.Assert False ' Stop code so that you can debug LogError = True ' Step over this line if you don't want to resume End If End Function
Function TryToCloseObject() As Boolean On Error GoTo ErrorHandler DoCmd.Close TryToCloseObject = True Done: Exit Function ErrorHandler: MsgBox Err.Description Resume Done End Function
Function TryToSaveRecord() As Boolean TryToSaveRecord = TryToRunCommand(acCmdSaveRecord) End Function
Function TryToRunCommand(Command As AcCommand) As Boolean On Error GoTo ErrorHandler DoCmd.RunCommand Command TryToRunCommand = True Done: Exit Function ErrorHandler: MsgBox Err.Description Resume Done End Function
Function TryToGoToRecord(Record As AcRecord) As Boolean On Error GoTo ErrorHandler DoCmd.GoToRecord , , Record Done: Exit Function ErrorHandler: MsgBox Err.Description Resume Done End Function
Inventory Module
- NewInventoryID
- AddPurchase
- RemovePurchase
- GetQtyAvailable
- GetQtyOnHand
- GetQtyToReorder
- GetQtyOnBackOrder
- GetInventoryQuantity
- RequestHold
- AddHold
- ModifyHold
- HoldToSold
- RemoveHold
- GetTransaction
- EditTransaction
- DeleteTransaction
- RestockProduct
- FindProductSupplier
- GetRestockingPurchaseOrder
- FillBackOrders
- FillBackOrder
Option Compare Database Option Explicit Public Enum InventoryTransactionTypeEnum Purchase_TransactionType = 1 Sold_TransactionType = 2 Hold_TransactionType = 3 End Enum Type InventoryTransaction ProductID As Long 'Product being added or removed to inventory TransactionType As InventoryTransactionTypeEnum '1=Purchase; 2=Sale; 3=Hold; 4=Waste; Quantity As Long 'Quanitity specifed for purchase, sale, hold, etc. QuantityGranted As Long 'Actual Quanity Granted; may be less than specfied InventoryID As Long 'Inventory Transaction ID returned to the caller AllOrNothing As Boolean 'All or nothing flag for product allocations Comments As String End Type Public Enum OrderItemStatusEnum None_OrderItemStatus = 0 OnHold_OrderItemStatus = 1 Invoiced_OrderItemStatus = 2 Shipped_OrderItemStatus = 3 OnOrder_OrderItemStatus = 4 NoStock_OrderItemStatus = 5 End Enum Private Const m_cNew_InventoryID = -1
Public Property Get NewInventoryID() As Long NewInventoryID = m_cNew_InventoryID End Property
Function AddPurchase(PurchaseOrderID As Long, ProductID As Long, Qty As Long, ByRef InventoryID As Long) As Boolean Dim IT As InventoryTransaction IT.TransactionType = Purchase_TransactionType IT.ProductID = ProductID IT.Quantity = Qty IT.InventoryID = m_cNew_InventoryID If EditTransaction(IT, , PurchaseOrderID) Then AddPurchase = True InventoryID = IT.InventoryID End If End Function
Function RemovePurchase(lInventoryID As Long) MsgBoxOKOnly CannotRemovePostedInventory End Function
Function GetQtyAvailable(ProductID As Long) As Long GetQtyAvailable = GetInventoryQuantity("[Qty Available]", ProductID) End Function
Function GetQtyOnHand(ProductID As Long) As Long GetQtyOnHand = GetInventoryQuantity("[Qty On Hand]", ProductID) End Function
Function GetQtyToReorder(ProductID As Long) As Long GetQtyToReorder = GetInventoryQuantity("[Qty To Reorder]", ProductID) End Function
Function GetQtyOnBackOrder(ProductID As Long) As Long GetQtyOnBackOrder = GetInventoryQuantity("[Qty On Back Order]", ProductID) End Function
Private Function GetInventoryQuantity(FieldName As String, ProductID As Long) As Long GetInventoryQuantity = DLookupNumberWrapper(FieldName, "Inventory", "[Product ID] = " & ProductID) End Function
Function RequestHold(OrderID As Long, IT As InventoryTransaction) As Boolean IT.TransactionType = Hold_TransactionType If (IT.InventoryID = m_cNew_InventoryID) Then RequestHold = AddHold(OrderID, IT) Else RequestHold = ModifyHold(IT) End If End Function
Function AddHold(OrderID As Long, IT As InventoryTransaction) As Boolean Dim QtyAvailable As Long Dim QtyToHold As Long Dim QtyRequested As Long ' Intialize Inventory quantities QtyAvailable = GetQtyAvailable(IT.ProductID) QtyRequested = IT.Quantity QtyToHold = 0 ' Check if we have sufficient Inventory If QtyRequested > QtyAvailable Then If Not IT.AllOrNothing Then QtyToHold = QtyAvailable End If Else QtyToHold = QtyRequested End If ' Execute the Hold If QtyToHold > 0 Then IT.TransactionType = Hold_TransactionType IT.Quantity = QtyToHold AddHold = EditTransaction(IT, OrderID) IT.Quantity = QtyRequested Else IT.QuantityGranted = 0 End If End Function
Function ModifyHold(IT As InventoryTransaction) As Boolean Dim ChangeInQuantity As Long Dim IT_Existing As InventoryTransaction ' Get Information on Previous Hold IT_Existing.InventoryID = IT.InventoryID If GetTransaction(IT_Existing) Then ChangeInQuantity = IT.Quantity - IT_Existing.Quantity ' Determine if we have sufficient Inventory to increase Hold If ChangeInQuantity < 0 Or ChangeInQuantity < GetQtyAvailable(IT.ProductID) Then IT.Quantity = IT.Quantity If EditTransaction(IT) Then IT.QuantityGranted = IT.Quantity ModifyHold = True Else IT.QuantityGranted = IT_Existing.Quantity End If End If End If End Function
Function HoldToSold(InventoryID As Long) As Boolean Dim IT As InventoryTransaction IT.InventoryID = InventoryID If GetTransaction(IT) Then IT.TransactionType = Sold_TransactionType If EditTransaction(IT) Then HoldToSold = True End If End If End Function
Function RemoveHold(InventoryID As Long) As Boolean RemoveHold = DeleteTransaction(InventoryID) End Function
Function GetTransaction(IT As InventoryTransaction) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Inventory Transactions", "[Transaction ID] = " & IT.InventoryID) Then With rsw.Recordset If Not .EOF Then IT.ProductID = ![Product ID] IT.Quantity = ![Quantity] IT.TransactionType = ![Transaction Type] IT.Comments = Nz(![Comments]) GetTransaction = True End If End With End If End Function
Function EditTransaction(IT As InventoryTransaction, Optional CustomerOrderID, Optional PurchaseOrderID) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Inventory Transactions", "[Transaction ID] = " & IT.InventoryID) Then With rsw.Recordset If IT.TransactionType <= 0 Then Exit Function ElseIf IT.InventoryID = m_cNew_InventoryID Then rsw.AddNew ElseIf .EOF Then Exit Function Else rsw.Edit ![Transaction Modified Date] = Now() End If ![Product ID] = IT.ProductID ![Quantity] = IT.Quantity ![Transaction Type] = IT.TransactionType ![Comments] = IIf(IT.Comments = "", Null, IT.Comments) If Not IsMissing(CustomerOrderID) Then ![Customer Order ID] = CustomerOrderID If Not IsMissing(PurchaseOrderID) Then ![Purchase Order ID] = PurchaseOrderID EditTransaction = rsw.Update If IT.InventoryID = m_cNew_InventoryID Then rsw.Recordset.Bookmark = rsw.Recordset.LastModified IT.InventoryID = ![Transaction ID] End If End With End If End Function
Function DeleteTransaction(InventoryID As Long) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Inventory Transactions", "[Transaction ID] = " & InventoryID) Then DeleteTransaction = rsw.Delete End If End Function
Function RestockProduct(ProductID As Long) As Boolean Dim SupplierID As Long Dim QtyToOrder As Long Dim PurchaseOrderID As Long Dim UnitCost As Long QtyToOrder = GetQtyToReorder(ProductID) If QtyToOrder > 0 Then SupplierID = FindProductSupplier(ProductID) If SupplierID > 0 Then ' Generate new Purchase Order if necessary If PurchaseOrderID = 0 Then If Not PurchaseOrders.Create(SupplierID, GetCurrentUserID(), -1, PurchaseOrderID) Then Exit Function End If End If ' Set unit cost to standard cost for product UnitCost = GetStandardCost(Nz(ProductID, 0)) ' Add product line item to Purchase Order If Not PurchaseOrders.CreateLineItem(PurchaseOrderID, ProductID, UnitCost, QtyToOrder) Then Exit Function End If Else ' Suggested Enhancement: Handle case where product does not have a supplier End If End If RestockProduct = True End Function
Function FindProductSupplier(ProductID As Long) As Long FindProductSupplier = DLookupNumberWrapper("[Supplier IDs].Value", "Products", "[ID]=" & ProductID) End Function
Function GetRestockingPurchaseOrder(SupplierID) As Long GetRestockingPurchaseOrder = DLookupNumberWrapper("[Purchase Order ID]", "Purchase Orders", "[Supplier ID]=" & SupplierID & " AND [Status ID] < 2") End Function
Function FillBackOrders(ProductID) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Order Details", "[Product ID] =" & ProductID & " AND [Status ID] = " & OnOrder_OrderItemStatus) Then With rsw.Recordset Dim IT As InventoryTransaction While Not .EOF ' Back Order Products should not be associated with any Inventory at this point If IsNull(![Inventory ID]) Then IT.Quantity = ![Quantity] IT.ProductID = ![Product ID] IT.InventoryID = m_cNew_InventoryID If FillBackOrder(![Order ID], IT) Then .Edit ![Status ID] = OnHold_OrderItemStatus ![Inventory ID] = IT.InventoryID .Update MsgBoxOKOnly FilledBackOrderedProduct, ![Order ID] End If End If rsw.MoveNext Wend End With FillBackOrders = True End If End Function
Function FillBackOrder(OrderID As Long, IT As InventoryTransaction) As Boolean IT.TransactionType = Hold_TransactionType IT.Comments = InsertString(FillBackOrderedProduct, CStr(OrderID)) If GetQtyAvailable(IT.ProductID) >= IT.Quantity Then FillBackOrder = EditTransaction(IT) End If End Function
Privileges Module
- EmployeeHas
- CanApprovePurchases
- IsAdministrator
- GetCurrentUserID
Option Compare Database Option Explicit Public Enum PrivilegeEnum Administrator_Privilege = 1 PurchaseApprovals_Privilege = 2 End Enum
Private Function EmployeeHas(EmployeeID As Long, PrivilegeID As PrivilegeEnum) As Boolean EmployeeHas = DCountWrapper("*", "Employee Privileges", "[Employee ID]=" & EmployeeID & " AND [Privilege ID]=" & PrivilegeID) > 0 End Function
Public Function CanApprovePurchases() As Boolean CanApprovePurchases = EmployeeHas(GetCurrentUserID(), PurchaseApprovals_Privilege) End Function
Public Function IsAdministrator() As Boolean IsAdministrator = EmployeeHas(GetCurrentUserID(), Administrator_Privilege) End Function
Public Function GetCurrentUserID() As Long GetCurrentUserID = Nz(TempVars![CurrentUserID], 0) End Function
PurchaseOrders Module
- Generate
- Create
- CreateLineItem
- OpenOrder
- NewOrder
- Delete
- SetStatus
- GetStatus
- MarkApproved
- MarkSubmitted
- Exists
- GetStandardCost
- GetListPrice
Option Compare Database Option Explicit Public Enum PurchaseOrderStatusEnum New_PurchaseOrder = 0 Submitted_PurchaseOrder = 1 Approved_PurchaseOrder = 2 Closed_PurchaseOrder = 3 End Enum
Function Generate(SupplierID As Long, ProductID As Long, Quantity As Long, OrderID As Long, PurchaseOrderID As Long) As Boolean Dim UnitCost As Long UnitCost = GetStandardCost(Nz(ProductID, 0)) If Create(SupplierID, GetCurrentUserID(), OrderID, PurchaseOrderID) Then Generate = CreateLineItem(PurchaseOrderID, ProductID, UnitCost, Quantity) End If End Function
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
Sub OpenOrder(Optional PurchaseOrderID As Long) If (PurchaseOrderID > 0) Then DoCmd.OpenForm "Purchase Order Details", acNormal, , "[Purchase Order ID]=" & PurchaseOrderID, acFormEdit, acDialog Else DoCmd.OpenForm "Purchase Order Details", acNormal, , , acFormAdd, acDialog End If End Sub
Sub NewOrder() OpenOrder End Sub
Function Delete(PurchaseOrderID As Long) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Purchase Orders", "[Purchase Order ID] = " & PurchaseOrderID) Then Delete = rsw.Delete End If End Function
Private Function SetStatus(PurchaseOrderID As Long, Status As PurchaseOrderStatusEnum) As Boolean Dim rsw As New RecordsetWrapper If rsw.OpenRecordset("Purchase Orders", "[Purchase Order ID] = " & PurchaseOrderID) Then With rsw.Recordset If Not .EOF Then .Edit ![Status ID] = Status Select Case Status Case New_PurchaseOrder ![Creation Date] = Now() ![Created By] = GetCurrentUserID Case Submitted_PurchaseOrder ![Submitted Date] = Now() ![Submitted By] = GetCurrentUserID Case Approved_PurchaseOrder ![Approved Date] = Now() ![Approved By] = GetCurrentUserID End Select SetStatus = rsw.Update End If End With End If End Function
Function GetStatus(PurchaseOrderID) As PurchaseOrderStatusEnum If IsNull(PurchaseOrderID) Then GetStatus = New_PurchaseOrder Else GetStatus = DLookupNumberWrapper("[Status ID]", "Purchase Orders", "[Purchase Order ID] = " & PurchaseOrderID, New_PurchaseOrder) End If End Function
Function MarkApproved(PurchaseOrderID As Long) As Boolean If Not Privileges.CanApprovePurchases() Then Exit Function End If If SetStatus(PurchaseOrderID, Approved_PurchaseOrder) Then MarkApproved = True End If End Function
Function MarkSubmitted(PurchaseOrderID As Long) As Boolean MarkSubmitted = SetStatus(PurchaseOrderID, Submitted_PurchaseOrder) End Function
Function Exists(PurchaseOrderID As Long) As Boolean Exists = Not IsNull(DLookupWrapper("[Purchase Order ID]", "Purchase Orders", "[Purchase Order ID]=" & PurchaseOrderID)) End Function
Function GetStandardCost(lProductID As Long) As Currency GetStandardCost = DLookupNumberWrapper("[Standard Cost]", "Products", "[ID]=" & lProductID) End Function
Function GetListPrice(lProductID As Long) As Currency GetListPrice = DLookupNumberWrapper("[List Price]", "Products", "[ID] = " & lProductID) End Function
RecordsetWrapper Module
- GetRecordsetClone
- OpenRecordset
- Delete
- AddNew
- Edit
- Update
- MoveNext
- CloseRecordset
- Recordset
- Class_Terminate
Option Compare Database Option Explicit Private m_rs As DAO.Recordset2
Public Function GetRecordsetClone(rs As DAO.Recordset2) As DAO.Recordset2 If Not m_rs Is Nothing Then Debug.Assert False ' This is only designed to be used once Else Set m_rs = rs.Clone Set GetRecordsetClone = m_rs End If End Function
Public Function OpenRecordset(Domain As String, _ Optional Criteria As String = "1=1", _ Optional OrderBy As String, _ Optional RecordsetType As DAO.RecordsetTypeEnum = dbOpenDynaset, _ Optional RecordsetOptions As DAO.RecordsetOptionEnum _ ) As Boolean If Not m_rs Is Nothing Then ' Close the recordset so it can be re-used CloseRecordset End If Dim strSQL As String strSQL = "SELECT * FROM [" & Domain & "] WHERE " & Criteria If OrderBy <> "" Then strSQL = strSQL & " ORDER BY " & OrderBy End If On Error GoTo ErrorHandler Set m_rs = CurrentDb.OpenRecordset(strSQL, RecordsetType, RecordsetOptions) OpenRecordset = True Done: Exit Function ErrorHandler: ' verify the private Recordset object was not set Debug.Assert m_rs Is Nothing ' Resume statement will be hit when debugging If eh.LogError("RecordsetWrapper.OpenRecordset", "strSQL = " & Chr(34) & strSQL & Chr(34)) Then Resume End Function
Public Function Delete() As Boolean On Error GoTo ErrorHandler m_rs.Delete Delete = True Done: Exit Function ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("RecordsetWrapper.Delete") Then Resume End Function
Public Function AddNew() As Boolean On Error GoTo ErrorHandler m_rs.AddNew AddNew = True Done: Exit Function ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("RecordsetWrapper.AddNew") Then Resume End Function
Public Function Edit() As Boolean On Error GoTo ErrorHandler m_rs.Edit Edit = True Done: Exit Function ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("RecordsetWrapper.Edit") Then Resume End Function
Public Function Update() As Boolean On Error GoTo ErrorHandler m_rs.Update Update = True Done: Exit Function ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("RecordsetWrapper.Update") Then Resume End Function
Public Function MoveNext() As Boolean On Error GoTo ErrorHandler m_rs.MoveNext MoveNext = True Done: Exit Function ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("RecordsetWrapper.MoveNext") Then Resume End Function
Public Function CloseRecordset() As Boolean On Error GoTo ErrorHandler m_rs.Close CloseRecordset = True Done: Set m_rs = Nothing Exit Function ErrorHandler: ' Resume statement will be hit when debugging If eh.LogError("RecordsetWrapper.CloseRecordset") Then Resume End Function
Public Property Get Recordset() As DAO.Recordset2 Set Recordset = m_rs End Property
Private Sub Class_Terminate() If Not m_rs Is Nothing Then m_rs.Close Set m_rs = Nothing End If End Sub
Utilities Module
- MsgBoxYesNo
- MsgBoxOKOnly
- MsgBoxID
- LoadString
- InsertString
- HasSourceCode
- IsRuntime
- DebuggingSupported
Option Compare Database Option Explicit Public eh As New ErrorHandling Public Enum StringIDEnum AppTitle = 2 CannotRemovePostedInventory = 3 FilledBackOrderedProduct = 4 DiscountedPriceBelowCost = 5 InsufficientInventory = 6 NoInventoryCreatePO = 7 PurchaseOrdersCreated = 8 NoProductsBelowReorderLevels = 9 MustSpecifyCustomer = 10 RestockAllInventory = 11 CannotCreatePO_NoSupplier = 12 PriceBelowCost = 13 WantToContinue = 14 OrderAlreadyInvoiced = 15 OrderDoesNotContainLineItems = 16 MustBeAllocatedBeforeInvoicing = 17 NoSalesInPeriod = 18 RestockSuccess = 19 NoNeedToRestock = 21 RestockingFailed = 22 InvalidLogin = 23 MustFirstSelectReport = 24 ChangeSupplierWarning = 25 RestockingSummary = 26 RestockingError = 27 RestockingDetails = 28 CannotRemovePostedItems = 29 ErrorRemovingPurchaseLineItems = 30 CannotModifyPurchaseQuantity = 31 CannotModifyPurchasePrice = 32 InventoryPostingSuccess = 33 InventoryPostingFailure = 34 FillBackOrdersPrompt = 35 CannotPostNoReceivedDate = 36 PostReceivedProductPrompt = 37 InitializeAppData = 38 MustSpecifyEmployeeName = 39 MustBeLoggedInToApprovePurchase = 40 CannotApprovePurchaseWithoutLineItems = 41 CannotApprovePurchases = 42 PurchaseApproved = 43 PurchaseNotApproved = 44 PurchaseSubmitted = 45 PurchaseNotSubmitted = 46 PurchaseHasNoLineItems = 47 CancelOrderPrompt = 48 CancelOrderConfirmPrompt = 49 CancelOrderSuccess = 100 CannotCancelPostedOrder = 101 CancelOrderFailure = 102 OrderIsNotInvoiced = 103 ShippingNotComplete = 104 CannotShipNotInvoiced = 105 CannotCancelShippedOrder = 106 MustSpecifySalesPerson = 107 OrderMarkedClosed = 108 OrderMustBeShippedToClose = 109 PaymentInfoNotComplete = 110 ErrorAttemptingToRestock = 111 NeedUnitCost = 112 FillBackOrderedProduct = 113 PurchaseGeneratedBasedOnOrder = 114 End Enum
Function MsgBoxYesNo(StringID As StringIDEnum, Optional ByVal strInsert As String) As Boolean MsgBoxYesNo = vbYes = MsgBoxID(StringID, vbYesNo, strInsert) End Function
Sub MsgBoxOKOnly(StringID As StringIDEnum, Optional ByVal strInsert As String) MsgBoxID StringID, vbOKOnly, strInsert End Sub
Function MsgBoxID(StringID As StringIDEnum, Buttons As VbMsgBoxStyle, Optional ByVal strInsert As String) As VbMsgBoxResult MsgBoxID = MsgBox(InsertString(StringID, strInsert), Buttons, LoadString(AppTitle)) End Function
Function LoadString(StringID As StringIDEnum) As String LoadString = DLookupStringWrapper("[String Data]", "Strings", "[String ID]=" & StringID) ' Verify that the specified string was found using DLookupStringWrapper. ' If you hit this breakpoint, verify that the StringID exists in the Strings table. Debug.Assert LoadString <> "" End Function
Function InsertString(StringID As StringIDEnum, strInsert As String) As String InsertString = Replace(LoadString(StringID), "|", strInsert) End Function
Function HasSourceCode() As Boolean On Error Resume Next HasSourceCode = (CurrentDb.Properties("MDE") <> "T") ' Property not found error If Err = 3270 Then HasSourceCode = True On Error GoTo 0 End Function
Function IsRuntime() As Boolean IsRuntime = SysCmd(acSysCmdRuntime) End Function
Function DebuggingSupported() As Boolean DebuggingSupported = HasSourceCode() And Not IsRuntime() End Function