Catalog_TableOfContents
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| TocTitle | Short Text | 255 | Yes | No |
| TocPage | Integer | 2 | Yes | No |
Indexes
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | TocTitle | Yes | Yes |
| TocPage | TocPage | No | No |
Documentation generated September 01, 2026 at 2:33 PM Eastern Daylight Time
Scan time: 37.9 seconds
Source database: C:\Temp\NorthwindTradersPlus.accdb
Application starting point: opens frmStartup via AutoExec macro. AutoExec opens this form when the database starts.
Likely landing form: frmOrderList via modStartup.Startup Strong inference. This form is opened unconditionally by the startup routine and is likely the form users see after startup processing finishes.
No sensitive literals were redacted. This does not prove that the database contains no credentials or secrets.
These are review prompts based on static analysis. Dynamic Access references may not be visible.
| Level | Finding | Object | Detail |
|---|---|---|---|
| Info | No detected references | qryMaxStockTakeDate | This may be intentional or referenced dynamically; review before removing it. |
| Info | No detected references | qryOrders_MostRecent_Customer | This may be intentional or referenced dynamically; review before removing it. |
| Info | No detected references | qryOrders_MostRecent_Employee | This may be intentional or referenced dynamically; review before removing it. |
| Info | No detected references | qryOrders_MostRecent_ModifiedOn | This may be intentional or referenced dynamically; review before removing it. |
| Info | No detected references | qrySales_SalesRep | This may be intentional or referenced dynamically; review before removing it. |
| Info | No detected references | qryVendors | This may be intentional or referenced dynamically; review before removing it. |
Shows detected calls between documented VBA procedures in forms and standard modules. Calls made dynamically, through a string, or through an Access macro may not appear.
Calls: None detected
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.LogErrorToFile
Called by: frmAbout.cmdClose_Click, frmAdmin.cmdDeleteTestData_Click, frmAdmin.cmdInternetOrders_Click, frmAdmin.cmdPrivileges_Click, frmAdmin.cmdProductCategories_Click, frmAdmin.cmdRelationshipsDiagram_Click, frmAdmin.cmdResetDates_Click, frmAdmin.cmdStrings_Click, frmAdmin.cmdSystemSettings_Click, frmAdmin.Form_Open, frmAdmin.UpdateSubLabels, frmCompanyDetail.cboCompanyTypeID_AfterUpdate, frmCompanyDetail.cboCompanyTypeID_BeforeUpdate, frmCompanyDetail.cmdAdd_Click, frmCompanyDetail.cmdCancel_Click, frmCompanyDetail.cmdClickToMap_Click, frmCompanyDetail.cmdDeleteCompany_Click, frmCompanyDetail.cmdEmail_Click, frmCompanyDetail.cmdSave_Click, frmCompanyDetail.cmdShowFilter_Click, frmCompanyDetail.CompanyCantBeDeleted, frmCompanyDetail.CompanyConfirmDelete, frmCompanyDetail.CompanyIsActive, frmCompanyDetail.Form_AfterDelConfirm, frmCompanyDetail.Form_AfterInsert, frmCompanyDetail.Form_AfterUpdate, frmCompanyDetail.Form_BeforeDelConfirm, frmCompanyDetail.Form_BeforeUpdate, frmCompanyDetail.Form_Current, frmCompanyDetail.Form_Delete, frmCompanyDetail.Form_Load, frmCompanyDetail.Form_Open, frmCompanyDetail.ManageFormOptions, frmCompanyDetail.txtBusinessPhone_Click, frmCompanyDetail.txtWebsite_DblClick, frmCompanyList.cmdAddNew_Click, frmCompanyList.cmdShowFilter_Click, frmCompanyList.cmdShowHideFields_Click, frmCompanyList.Form_Open, frmCompanyList.fraFilter_AfterUpdate, frmCompanyList.Open_frmCompanyDetail, frmCompanyList.txtCompanyID_Click, frmCredentials.cmdAddMe_Click, frmCredentials.cmdExit_Click, frmCredentials.Form_BeforeUpdate, frmCredentials.Form_Load, frmEmployeeList.cboSupervisorID_Enter, frmEmployeeList.cboSupervisorID_NotInList, frmEmployeeList.cmdEmailEmployee_Click, frmEmployeeList.cmdNewEmployee_Click, frmEmployeeList.EmployeeCanBeDeleted, frmEmployeeList.Form_AfterDelConfirm, frmEmployeeList.Form_AfterInsert, frmEmployeeList.Form_AfterUpdate, frmEmployeeList.Form_BeforeDelConfirm, frmEmployeeList.Form_BeforeUpdate, frmEmployeeList.Form_Current, frmEmployeeList.Form_Delete, frmEmployeeList.RequeryEmployeeList, frmEmployeeTitles.Form_Open, frmGenericDialog.cmdCancelClose_Click, frmGenericDialog.cmdOK_Click, frmGenericDialog.Form_Load, frmLogin.AutoLogin_chk_AfterUpdate, frmLogin.cmdLogin_Click, frmLogin.Form_Load, frmLogin.Form_Unload, frmNorthwindFeatures.txtHelpKeywords_Click, frmOrderDetails.AllInvoiceLineItemsHaveStatus, frmOrderDetails.cmdAddOrder_Click, frmOrderDetails.cmdCloseOrder_Click, frmOrderDetails.cmdCreateInvoice_Click, frmOrderDetails.cmdDeleteOrder_Click, frmOrderDetails.cmdPrintInvoice_Click, frmOrderDetails.cmdReceivePayment_Click, frmOrderDetails.cmdShipOrder_Click, frmOrderDetails.CustomerID_AfterUpdate, frmOrderDetails.Form_AfterInsert, frmOrderDetails.Form_AfterUpdate, frmOrderDetails.Form_BeforeDelConfirm, frmOrderDetails.Form_BeforeInsert, frmOrderDetails.Form_BeforeUpdate, frmOrderDetails.Form_Close, frmOrderDetails.Form_Current, frmOrderDetails.Form_Delete, frmOrderDetails.Form_Load, frmOrderDetails.Form_Open, frmOrderDetails.LockControls, frmOrderDetails.PaidFieldsFilledOut, frmOrderDetails.SetFormStatus, frmOrderDetails.SetLineItemsStatus, frmOrderDetails.sfrmOrderLineItems_Exit, frmOrderDetails.ShippingFeeFilledOut, frmOrderDetails.ShippingFieldsFilledOut, frmOrderList.cmdAddOrder_Click, frmOrderList.cmdShowFilter_Click, frmOrderList.Form_Open, frmOrderList.fraFilter_AfterUpdate, frmOrderList.OrderID_Click, frmProductDetail.CalculateLevels, frmProductDetail.cboFindProduct_AfterUpdate, frmProductDetail.cboProductCategoryID_AfterUpdate, frmProductDetail.chkDiscontinued_AfterUpdate, frmProductDetail.cmdAddProduct_Click, frmProductDetail.cmdDeleteProduct_Click, frmProductDetail.cmdReorderProduct_Click, frmProductDetail.ControlStates, frmProductDetail.Form_Activate, frmProductDetail.Form_AfterDelConfirm, frmProductDetail.Form_AfterInsert, frmProductDetail.Form_AfterUpdate, frmProductDetail.Form_BeforeUpdate, frmProductDetail.Form_Close, frmProductDetail.Form_Current, frmProductDetail.Form_Delete, frmProductDetail.Form_Load, frmProductDetail.imgHelp_Click, frmProductDetail.SetProductCode, frmProductDetail.tabProducts_Change, frmProductDetail.txtTargetLevel_AfterUpdate, frmProductList.cmdAddProduct_Click, frmProductList.cmdExport_Click, frmProductList.ProductID_Click, frmPurchaseOrderDetails.AllocatePurchaseOrder, frmPurchaseOrderDetails.cmdAddNostock_Click, frmPurchaseOrderDetails.cmdAddPO_Click, frmPurchaseOrderDetails.cmdApprovePO_Click, frmPurchaseOrderDetails.cmdClosePO_Click, frmPurchaseOrderDetails.cmdDeletePO_Click, frmPurchaseOrderDetails.cmdReceivePO_Click, frmPurchaseOrderDetails.cmdSubmitPO_Click, frmPurchaseOrderDetails.Form_AfterInsert, frmPurchaseOrderDetails.Form_AfterUpdate, frmPurchaseOrderDetails.Form_BeforeInsert, frmPurchaseOrderDetails.Form_BeforeUpdate, frmPurchaseOrderDetails.Form_Close, frmPurchaseOrderDetails.Form_Current, frmPurchaseOrderDetails.Form_Delete, frmPurchaseOrderDetails.Form_Load, frmPurchaseOrderDetails.Form_Open, frmPurchaseOrderDetails.LockControls, frmPurchaseOrderDetails.PoCloseFieldsFilledOut, frmPurchaseOrderDetails.SetWorkflowLabelColors, frmPurchaseOrderDetails.VendorID_AfterUpdate, frmPurchaseOrderDetails.VendorID_BeforeUpdate, frmPurchaseOrderList.cmdAddPO_Click, frmPurchaseOrderList.Form_Open, frmPurchaseOrderList.PurchaseOrderID_Click, frmReports.cmdEmployeeEmailList_Click, frmReports.cmdEmployeePhoneList_Click, frmReports.cmdFallCatalog_Click, frmReports.cmdPreviewReport_Click, frmReports.cmdSalesByemployeeReport_Click, frmReports.cmdSalesByProductReportMonthly_Click, frmReports.cmdSalesByProductReportQuarterly_Click, frmReports.Form_Close, frmReports.Form_Open, frmReports.ReportFormInitialization, frmSelectVendorDialog.cmdCancel_Click, frmSelectVendorDialog.cmdOK_Click, frmSelectVendorDialog.Form_Load, frmSelectVendorDialog.lstVendor_DblClick, frmWelcome.cmdGetStarted_Click, frmWelcome.Form_Close, frmWelcome.Form_Open, sfrmAdmin_DeleteTestData.cmdRemoveTestData_Click, sfrmAdmin_InternetOrders.cmdCreate_Click, sfrmAdmin_InternetOrders.txtCount_BeforeUpdate, sfrmAdmin_ResetDates.cmdResetDates_Click, sfrmAdmin_Strings.Form_AfterDelConfirm, sfrmAdmin_Strings.Form_AfterInsert, sfrmAdmin_SystemSettings.Form_AfterDelConfirm, sfrmAdmin_SystemSettings.Form_AfterInsert, sfrmCompanyDetail_Contacts.Form_AfterUpdate, sfrmCompanyDetail_Contacts.Form_BeforeUpdate, sfrmCompanyDetail_Contacts.txtPrimaryPhone_Click, sfrmCompanyDetail_Contacts.txtSecondaryPhone_Click, sfrmCompanyDetail_CustomerOrders.Detail_DblClick, sfrmCompanyDetail_CustomerOrders.OpenForm_frmOrderDetails, sfrmCompanyDetail_ShipperOrders.Detail_DblClick, sfrmCompanyDetail_ShipperOrders.OpenForm_frmOrderDetails, sfrmCompanyDetail_VendorPurchaseOrders.Detail_DblClick, sfrmCompanyDetail_VendorPurchaseOrders.OpenForm_frmPurchaseOrderDetails, sfrmEmployee_Privileges.Form_AfterDelConfirm, sfrmEmployee_Privileges.Form_AfterInsert, sfrmEmployee_Privileges.Form_Open, sfrmEmployee_Privileges.frmLoadedAsSubform, sfrmOrderLineItems.cboProductCategories_AfterUpdate, sfrmOrderLineItems.Form_AfterDelConfirm, sfrmOrderLineItems.Form_AfterUpdate, sfrmOrderLineItems.Form_BeforeDelConfirm, sfrmOrderLineItems.Form_BeforeInsert, sfrmOrderLineItems.Form_BeforeUpdate, sfrmOrderLineItems.Form_Current, sfrmOrderLineItems.Form_Delete, sfrmOrderLineItems.Form_Error, sfrmOrderLineItems.ProductCategoryName_GotFocus, sfrmOrderLineItems.ProductID_AfterUpdate, sfrmOrderLineItems.ProductID_GotFocus, sfrmOrderLineItems.ProductName_DblClick, sfrmOrderLineItems.ProductName_GotFocus, sfrmOrderLineItems.ReallocateInventory, sfrmOrderLineItems.SetOrderDetailStatus, sfrmOrders_MostRecent_ByEmployee.OrderID_Click, sfrmProductCategories.cmdAdd_Click, sfrmProductCategories.cmdDelete_Click, sfrmProductCategories.Form_AfterInsert, sfrmProductCategories.Form_Current, sfrmProductCategories.Form_Delete, sfrmProductCategories.lstCategory_AfterUpdate, sfrmProductCategories.txtProductCategoryCode_BeforeUpdate, sfrmProductDetail_Orders.txtOrderID_Click, sfrmProductDetail_PurchaseOrders.txtPOID_Click, sfrmProductDetail_StockTake.Form_AfterInsert, sfrmProductDetail_StockTake.Form_AfterUpdate, sfrmProductDetail_StockTake.Form_BeforeUpdate, sfrmProductDetail_StockTake.Form_Current, sfrmProductDetail_StockTake.QuantityOnHand_AfterUpdate, sfrmProductDetail_StockTake.QuantityOnHand_BeforeUpdate, sfrmProductDetail_StockTake.RequeryQuantities, sfrmProductDetail_Vendors.Form_BeforeUpdate, sfrmProductDetail_Vendors.txtVendorID_Click, sfrmPurchaseOrderLineItems.Form_BeforeUpdate, sfrmPurchaseOrderLineItems.Form_Current, sfrmPurchaseOrderLineItems.Form_Error, sfrmPurchaseOrderLineItems.ProductID_AfterUpdate, sfrmPurchaseOrderLineItems.PurchaseOrderDetailID_Click, sfrmPurchaseOrderLineItems.ValidateLineItem, clsErrorHandler.ErrorHandlerExample, clsErrorHandler.ErrorHandlerExample_EventProcedure, modCompanies.GetRandomCustomerID, modCompanies.GetTaxStatusID, modDAO.GetRandomPkValue, modDAO.HasDataMacro, modDebug.DumpTempVars, modDebug.NotImplemented, modFiles.StringToFile, modForms.ControlCurrentView, modForms.ControlDefaultView, modForms.IsFormOpen, modForms.RequeryListForms, modForms.RequeryProductList, modGlobal.AddToMRU, modGlobal.Get_EmployeeFNLN, modGlobal.Get_UserID, modGlobal.Get_UserID_ForWindowsUser, modGlobal.GetNorthwindAddress, modGlobal.GetWindowsUserName, modGlobal.InitializeUser, modGlobal.OneTimeProcessing, modGlobal.RecordModifiedString, modGlobal.RemoveFromMRU, modGlobal.SetCtrlCurrencyFormat, modGlobal.ToAccessDate, modInventory.AllocateInventory, modInventory.OrderQuantity_ByStatus, modInventory.ProductAllocated, modInventory.ProductAvailable, modInventory.ProductBought, modInventory.ProductLastStockTakeDate, modInventory.ProductLastStockTakeQuantity, modInventory.ProductNoStock, modInventory.ProductOnOrder, modInventory.ProductReorderQuantity, modInventory.ProductSold, modInventory.ProductToSell, modMath.GetRandom, modMath.MaxValue, modOrders.CloseAllOrderDetailsForms, modOrders.CloseOrderDetailsForm, modOrders.CreateRandomOrders, modOrders.GetRandomProductID, modOrders.OpenOrderDetailsForm, modOrders.SetDatesToCurrent, modPurchaseOrders.AddPurchaseOrderDetail, modPurchaseOrders.CloseAllPurchaseOrderDetailsForms, modPurchaseOrders.ClosePurchaseOrderDetailsForm, modPurchaseOrders.OpenPurchaseOrderDetailsForm, modPurchaseOrders.ReorderProduct, modReportParameters.reportParameterEndDate, modReportParameters.reportParameterStartDate, modRibbonCallback.ActivateTab, modRibbonCallback.cmdAbout_OnAction, modRibbonCallback.cmdAddOrder_OnAction, modRibbonCallback.cmdAddPurchaseOrder_OnAction, modRibbonCallback.cmdAdmin_OnAction, modRibbonCallback.cmdCustomers_OnAction, modRibbonCallback.cmdEmployees_OnAction, modRibbonCallback.cmdExitApplication_OnAction, modRibbonCallback.cmdExportToExcel_OnAction, modRibbonCallback.cmdFeatures_OnAction, modRibbonCallback.cmdLearn_OnAction, modRibbonCallback.cmdNorthwindDocumentation_OnAction, modRibbonCallback.cmdOrders_OnAction, modRibbonCallback.cmdProducts_OnAction, modRibbonCallback.cmdPurchaseOrders_OnAction, modRibbonCallback.cmdReports_OnAction, modRibbonCallback.ddMRU_GetItemCount, modRibbonCallback.ddMRU_GetItemID, modRibbonCallback.ddMRU_GetItemLabel, modRibbonCallback.ddMRU_OnAction, modRibbonCallback.ddMRU_OnChange, modRibbonCallback.gReportOptions_GetVisible, modRibbonCallback.Ribbon_RefreshMRU, modRibbonCallback.Ribbon_ShowReportsGroup, modSecurity.HasPrivilege, modStartup.CloseAllForms, modStartup.CloseAllReports, modStartup.GetSystemSetting, modStartup.GetUserSetting, modStartup.SaveSystemSetting, modStartup.SaveUserSetting, modStartup.SetAppTitle, modStartup.Startup, modStrings.GetString, modStrings.StringFormat, modStrings.StringFormatSQL, modStrings.StringToDictionary, modTableDataMacros.AddDataMacros, modTableDataMacros.GetAuditFieldsUserName, modValidation.HighlightControl, modValidation.HighlightInvalidControls, modValidation.IsValidForm, modValidation.ValidateForm
Calls: None detected
Called by: clsErrorHandler.HandleError
Calls: clsErrorHandler.HandleError, modCompanies.GetRandomCustomerID, modDAO.GetRandomPkValue
Called by: modCompanies.GetRandomCustomerID, modOrders.CreateRandomOrders
Calls: clsErrorHandler.HandleError, modCompanies.GetTaxStatusID
Called by: modCompanies.GetTaxStatusID, modOrders.CreateRandomOrders
Calls: clsErrorHandler.HandleError, modDAO.GetRandomPkValue, modMath.GetRandom
Called by: modCompanies.GetRandomCustomerID, modDAO.GetRandomPkValue, modOrders.GetRandomProductID
Calls: clsErrorHandler.HandleError, modDAO.HasDataMacro, modStrings.StringFormatSQL
Called by: modDAO.HasDataMacro, modTableDataMacros.AddDataMacros
Calls: modDAO.HasField
Called by: modDAO.HasField, modTableDataMacros.AddDataMacros
Calls: modDAO.HasProperty
Called by: modDAO.HasProperty, modValidation.HighlightControl
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: modFiles.FileExists
Called by: frmReports.cmdPreviewReport_Click, modFiles.FileExists
Calls: clsErrorHandler.HandleError
Called by: modTableDataMacros.AddDataMacros
Calls: clsErrorHandler.HandleError, modForms.ControlCurrentView
Called by: modForms.ControlCurrentView, modValidation.HighlightControl, modValidation.ValidateForm_RemoveHighlights
Calls: clsErrorHandler.HandleError, modForms.ControlDefaultView
Called by: modForms.ControlDefaultView, modValidation.HighlightControl, modValidation.ValidateForm_RemoveHighlights
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen
Called by: frmCompanyDetail.cboCompanyTypeID_BeforeUpdate, frmCompanyDetail.cmdShowFilter_Click, frmCompanyDetail.CompanyCantBeDeleted, frmCompanyDetail.CompanyConfirmDelete, frmCompanyDetail.Form_AfterDelConfirm, frmCompanyDetail.Form_AfterInsert, frmCompanyList.cmdShowFilter_Click, frmCompanyList.Open_frmCompanyDetail, frmEmployeeList.EmployeeCanBeDeleted, frmOrderList.cmdShowFilter_Click, frmProductDetail.cmdReorderProduct_Click, frmProductList.cmdAddProduct_Click, frmPurchaseOrderDetails.cmdDeletePO_Click, frmPurchaseOrderDetails.Form_AfterUpdate, sfrmProductDetail_StockTake.RequeryQuantities, sfrmProductDetail_Vendors.txtVendorID_Click, modForms.IsFormOpen, modForms.RequeryListForms, modForms.RequeryProductList, modReportParameters.reportParameterEndDate, modReportParameters.reportParameterStartDate
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen
Called by: frmOrderDetails.Form_Close, frmProductDetail.Form_Close, frmPurchaseOrderDetails.Form_Close
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen
Called by: frmProductDetail.cmdDeleteProduct_Click, frmProductDetail.cmdReorderProduct_Click, frmProductDetail.Form_AfterDelConfirm, frmProductDetail.Form_AfterInsert, frmProductDetail.Form_AfterUpdate, sfrmProductDetail_StockTake.RequeryQuantities
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modGlobal.Get_UserID, modRibbonCallback.Ribbon_RefreshMRU, modStrings.StringFormatSQL
Called by: frmOrderDetails.Form_AfterInsert, frmOrderDetails.Form_Load, frmProductDetail.cmdReorderProduct_Click, frmPurchaseOrderDetails.Form_AfterInsert, frmPurchaseOrderDetails.Form_Load, modOrders.CreateRandomOrders
Calls: modGlobal.g_dbApp
Called by: frmCompanyDetail.Form_Delete, frmOrderDetails.SetLineItemsStatus, frmProductDetail.cmdDeleteProduct_Click, frmPurchaseOrderDetails.AllocatePurchaseOrder, frmPurchaseOrderDetails.cmdAddNostock_Click, frmPurchaseOrderDetails.cmdReceivePO_Click, frmPurchaseOrderDetails.VendorID_BeforeUpdate, sfrmAdmin_DeleteTestData.cmdRemoveTestData_Click, sfrmPurchaseOrderLineItems.ValidateLineItem, modGlobal.AddToMRU, modGlobal.g_dbApp, modGlobal.GetNorthwindAddress, modGlobal.RemoveFromMRU, modInventory.AllocateInventory, modInventory.ProductLastStockTakeDate, modStartup.SaveSystemSetting, modStartup.SaveUserSetting, modTableDataMacros.AddDataMacros
Calls: clsErrorHandler.HandleError, modGlobal.Get_EmployeeFNLN
Called by: sfrmProductDetail_Vendors.Form_BeforeUpdate, modGlobal.Get_EmployeeFNLN, modStartup.SetAppTitle
Calls: clsErrorHandler.HandleError, modGlobal.Get_UserID
Called by: frmLogin.Form_Load, frmOrderDetails.Form_BeforeInsert, frmOrderList.fraFilter_AfterUpdate, frmPurchaseOrderDetails.cmdApprovePO_Click, frmPurchaseOrderDetails.cmdSubmitPO_Click, sfrmProductDetail_Vendors.Form_BeforeUpdate, modGlobal.AddToMRU, modGlobal.Get_UserID, modSecurity.HasPrivilege, modStartup.SetAppTitle, modTableDataMacros.GetAuditFieldsUserName
Calls: clsErrorHandler.HandleError, modGlobal.Get_UserID_ForWindowsUser, modGlobal.GetWindowsUserName, modStrings.StringFormatSQL
Called by: frmLogin.Form_Load, modGlobal.Get_UserID_ForWindowsUser
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modGlobal.GetNorthwindAddress, modStrings.StringFormat
Called by: modGlobal.GetNorthwindAddress
Calls: clsErrorHandler.HandleError, modGlobal.GetWindowsUserName
Called by: frmCredentials.Form_Load, frmEmployeeList.cmdEmailEmployee_Click, modGlobal.Get_UserID_ForWindowsUser, modGlobal.GetWindowsUserName, modGlobal.InitializeUser, modTableDataMacros.GetAuditFieldsUserName
Calls: None detected
Called by: modGlobal.OneTimeProcessing
Calls: clsErrorHandler.HandleError, modGlobal.GetWindowsUserName, modStartup.GetUserSetting, modStrings.StringFormatSQL
Called by: modStartup.Startup
Calls: clsErrorHandler.HandleError, modGlobal.HiddenAndSystemObjectsWorkaround, modGlobal.SetCtrlCurrencyFormat, modOrders.SetDatesToCurrent, modStartup.GetSystemSetting, modStartup.SaveSystemSetting, modTableDataMacros.AddDataMacros
Called by: modStartup.Startup
Calls: clsErrorHandler.HandleError, modGlobal.RecordModifiedString
Called by: modGlobal.RecordModifiedString
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modRibbonCallback.Ribbon_RefreshMRU, modStrings.StringFormatSQL
Called by: frmEmployeeList.EmployeeCanBeDeleted, frmOrderDetails.Form_Delete, frmProductDetail.Form_Delete, frmPurchaseOrderDetails.Form_Delete
Calls: clsErrorHandler.HandleError
Called by: modGlobal.OneTimeProcessing
Calls: clsErrorHandler.HandleError, modGlobal.ToAccessDate
Called by: modGlobal.ToAccessDate, modInventory.ProductLastStockTakeQuantity, modStartup.SaveSystemSetting, modStrings.StringFormatSQL
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modInventory.ProductAvailable, modInventory.ProductOnOrder, modStrings.StringFormatSQL
Called by: frmOrderDetails.Form_Delete, frmPurchaseOrderDetails.AllocatePurchaseOrder, sfrmOrderLineItems.Form_AfterDelConfirm, sfrmOrderLineItems.ReallocateInventory, sfrmProductDetail_StockTake.Form_AfterUpdate, modOrders.CreateRandomOrders
Calls: clsErrorHandler.HandleError, modInventory.OrderQuantity_ByStatus, modStrings.StringFormatSQL
Called by: modInventory.OrderQuantity_ByStatus, modInventory.ProductAllocated, modInventory.ProductNoStock
Calls: clsErrorHandler.HandleError, modInventory.OrderQuantity_ByStatus, modInventory.ProductAllocated
Called by: frmProductDetail.CalculateLevels, modInventory.ProductAllocated, modInventory.ProductToSell
Calls: clsErrorHandler.HandleError, modInventory.ProductAvailable, modInventory.ProductBought, modInventory.ProductLastStockTakeDate, modInventory.ProductLastStockTakeQuantity, modInventory.ProductSold
Called by: sfrmOrderLineItems.SetOrderDetailStatus, sfrmProductDetail_StockTake.QuantityOnHand_AfterUpdate, sfrmProductDetail_StockTake.QuantityOnHand_BeforeUpdate, modInventory.AllocateInventory, modInventory.ProductAvailable, modOrders.CreateRandomOrders
Calls: clsErrorHandler.HandleError, modInventory.ProductBought, modStrings.StringFormatSQL
Called by: modInventory.ProductAvailable, modInventory.ProductBought, modInventory.ProductToSell
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modInventory.ProductLastStockTakeDate, modStrings.StringFormatSQL
Called by: frmProductDetail.CalculateLevels, modInventory.ProductAvailable, modInventory.ProductLastStockTakeDate, modInventory.ProductLastStockTakeQuantity, modInventory.ProductToSell
Calls: clsErrorHandler.HandleError, modGlobal.ToAccessDate, modInventory.ProductLastStockTakeDate, modInventory.ProductLastStockTakeQuantity, modStrings.StringFormatSQL
Called by: modInventory.ProductAvailable, modInventory.ProductLastStockTakeQuantity, modInventory.ProductToSell
Calls: clsErrorHandler.HandleError, modInventory.OrderQuantity_ByStatus, modInventory.ProductNoStock
Called by: frmProductDetail.CalculateLevels, modInventory.ProductNoStock, modInventory.ProductReorderQuantity
Calls: clsErrorHandler.HandleError, modInventory.ProductOnOrder, modStrings.StringFormatSQL
Called by: frmProductDetail.CalculateLevels, modInventory.AllocateInventory, modInventory.ProductOnOrder, modInventory.ProductReorderQuantity
Calls: clsErrorHandler.HandleError, modInventory.ProductNoStock, modInventory.ProductOnOrder, modInventory.ProductReorderQuantity, modInventory.ProductToSell
Called by: frmProductDetail.CalculateLevels, sfrmPurchaseOrderLineItems.ProductID_AfterUpdate, modInventory.ProductReorderQuantity
Calls: clsErrorHandler.HandleError, modInventory.ProductSold, modStrings.StringFormatSQL
Called by: modInventory.ProductAvailable, modInventory.ProductSold, modInventory.ProductToSell
Calls: clsErrorHandler.HandleError, modInventory.ProductAllocated, modInventory.ProductBought, modInventory.ProductLastStockTakeDate, modInventory.ProductLastStockTakeQuantity, modInventory.ProductSold, modInventory.ProductToSell
Called by: frmProductDetail.CalculateLevels, sfrmPurchaseOrderLineItems.ValidateLineItem, modInventory.ProductReorderQuantity, modInventory.ProductToSell
Calls: clsErrorHandler.HandleError, modMath.GetRandom
Called by: modDAO.GetRandomPkValue, modMath.GetRandom, modOrders.CreateRandomOrders
Calls: clsErrorHandler.HandleError, modMath.MaxValue
Called by: modMath.MaxValue
Calls: None detected
Called by: modNorthwindPlusPlanning.RunOrderAvailabilityPlanning
Calls: None detected
Called by: modNorthwindPlusPlanning.RunOrderAvailabilityPlanning
Calls: None detected
Called by: modNorthwindPlusPlanning.RunOrderAvailabilityPlanning
Calls: modNorthwindPlusPlanning.BuildFulfillmentPlan, modNorthwindPlusPlanning.ClearExistingFulfillmentPlan, modNorthwindPlusPlanning.OpenAvailabilityReport, modNorthwindPlusPlanning.ValidateOrderForPlanning
Called by: frmOrderDetails.cmdCheckAvailability_Click
Calls: modNorthwindPlusPlanning.ValidateOrderForPlanning
Called by: modNorthwindPlusPlanning.RunOrderAvailabilityPlanning, modNorthwindPlusPlanning.ValidateOrderForPlanning
Calls: modNorthwindPlusSetup.SaveQuery
Called by: modNorthwindPlusSetup.InstallNorthwindPlus
Calls: modNorthwindPlusSetup.TableExists
Called by: modNorthwindPlusSetup.InstallNorthwindPlus
Calls: modNorthwindPlusSetup.CreateNorthwindPlusQueries, modNorthwindPlusSetup.CreateNorthwindPlusTables, modNorthwindPlusSetup.SeedMockProductionCapacity
Called by: None detected
Calls: None detected
Calls: None detected
Called by: modNorthwindPlusSetup.InstallNorthwindPlus
Calls: modNorthwindPlusSetup.TableExists
Called by: modNorthwindPlusSetup.CreateNorthwindPlusTables, modNorthwindPlusSetup.TableExists
Calls: clsErrorHandler.HandleError
Called by: modStartup.Finish
Calls: clsErrorHandler.HandleError
Called by: frmOrderDetails.Form_Close
Calls: clsErrorHandler.HandleError, modCompanies.GetRandomCustomerID, modCompanies.GetTaxStatusID, modGlobal.AddToMRU, modInventory.AllocateInventory, modInventory.ProductAvailable, modMath.GetRandom, modOrders.GetRandomProductID, modStartup.GetSystemSetting
Called by: sfrmAdmin_InternetOrders.cmdCreate_Click
Calls: clsErrorHandler.HandleError, modDAO.GetRandomPkValue, modOrders.GetRandomProductID
Called by: modOrders.CreateRandomOrders, modOrders.GetRandomProductID
Calls: clsErrorHandler.HandleError
Called by: frmOrderList.cmdAddOrder_Click, sfrmCompanyDetail_CustomerOrders.OpenForm_frmOrderDetails, sfrmCompanyDetail_ShipperOrders.OpenForm_frmOrderDetails, sfrmOrders_MostRecent_ByEmployee.OrderID_Click, sfrmProductDetail_Orders.txtOrderID_Click, modRibbonCallback.cmdAddOrder_OnAction, modRibbonCallback.ddMRU_OnAction
Calls: None detected
Called by: frmOrderList.OrderID_Click
Calls: clsErrorHandler.HandleError, modStrings.StringFormat
Called by: sfrmAdmin_ResetDates.cmdResetDates_Click, modGlobal.OneTimeProcessing
Calls: clsErrorHandler.HandleError, modPurchaseOrders.AddPurchaseOrderDetail, modStrings.StringFormatSQL
Called by: frmProductDetail.cmdReorderProduct_Click, modPurchaseOrders.AddPurchaseOrderDetail, modPurchaseOrders.ReorderProduct
Calls: clsErrorHandler.HandleError
Called by: modStartup.Finish
Calls: clsErrorHandler.HandleError
Called by: frmPurchaseOrderDetails.Form_Close
Calls: clsErrorHandler.HandleError
Called by: frmProductDetail.cmdReorderProduct_Click, frmPurchaseOrderList.cmdAddPO_Click, frmPurchaseOrderList.PurchaseOrderID_Click, sfrmCompanyDetail_VendorPurchaseOrders.OpenForm_frmPurchaseOrderDetails, sfrmProductDetail_PurchaseOrders.txtPOID_Click, modRibbonCallback.cmdAddPurchaseOrder_OnAction, modRibbonCallback.ddMRU_OnAction
Calls: clsErrorHandler.HandleError, modPurchaseOrders.AddPurchaseOrderDetail, modPurchaseOrders.ReorderProduct, modStrings.StringFormat
Called by: frmProductDetail.cmdReorderProduct_Click, modPurchaseOrders.ReorderProduct
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modReportParameters.reportParameterEndDate
Called by: modReportParameters.reportParameterEndDate
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modReportParameters.reportParameterStartDate
Called by: modReportParameters.reportParameterStartDate
Calls: clsErrorHandler.HandleError, modRibbonCallback.ActivateTab
Called by: modRibbonCallback.ActivateTab, modRibbonCallback.ribbonLoaded
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modPurchaseOrders.OpenPurchaseOrderDetailsForm
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStartup.Finish
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.StringFormat
Called by: None detected
Calls: None detected
Called by: None detected
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsForm, modPurchaseOrders.OpenPurchaseOrderDetailsForm
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: sfrmAdmin_InternetOrders.cmdCreate_Click, modGlobal.AddToMRU, modGlobal.RemoveFromMRU
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: None detected
Called by: modStartup.Finish
Calls: modRibbonCallback.ActivateTab
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.Get_UserID, modSecurity.HasPrivilege
Called by: frmPurchaseOrderDetails.cmdApprovePO_Click, modSecurity.HasPrivilege
Calls: clsErrorHandler.HandleError
Called by: modStartup.Finish
Calls: clsErrorHandler.HandleError
Called by: modStartup.Finish
Calls: modOrders.CloseAllOrderDetailsForms, modPurchaseOrders.CloseAllPurchaseOrderDetailsForms, modRibbonCallback.RibbonFinish, modStartup.CloseAllForms, modStartup.CloseAllReports
Calls: clsErrorHandler.HandleError, modStartup.GetSystemSetting
Called by: frmAdmin.UpdateSubLabels, frmOrderDetails.Form_BeforeInsert, frmWelcome.Form_Open, modGlobal.OneTimeProcessing, modOrders.CreateRandomOrders, modStartup.GetSystemSetting, modStartup.Startup
Calls: clsErrorHandler.HandleError, modStartup.GetUserSetting
Called by: frmLogin.Form_Load, modGlobal.InitializeUser, modStartup.GetUserSetting
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modGlobal.ToAccessDate, modStrings.StringFormatSQL
Called by: frmWelcome.Form_Close, modGlobal.OneTimeProcessing
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modStrings.StringFormatSQL
Called by: frmLogin.AutoLogin_chk_AfterUpdate
Calls: clsErrorHandler.HandleError, modGlobal.Get_EmployeeFNLN, modGlobal.Get_UserID
Called by: frmCredentials.cmdAddMe_Click, frmLogin.cmdLogin_Click, frmLogin.Form_Load, modStartup.Startup
Calls: clsErrorHandler.HandleError, modGlobal.InitializeUser, modGlobal.OneTimeProcessing, modStartup.GetSystemSetting, modStartup.SetAppTitle
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString, modStrings.StringFormat
Called by: frmCompanyDetail.cboCompanyTypeID_BeforeUpdate, frmCompanyDetail.cmdAdd_Click, frmCompanyDetail.CompanyCantBeDeleted, frmCompanyDetail.Form_BeforeUpdate, frmCompanyList.Open_frmCompanyDetail, frmEmployeeList.cboSupervisorID_NotInList, frmEmployeeList.EmployeeCanBeDeleted, frmEmployeeList.Form_BeforeDelConfirm, frmLogin.Form_Load, frmOrderDetails.cmdAddOrder_Click, frmOrderDetails.cmdCloseOrder_Click, frmOrderDetails.cmdCreateInvoice_Click, frmOrderDetails.cmdDeleteOrder_Click, frmOrderDetails.cmdReceivePayment_Click, frmOrderDetails.cmdShipOrder_Click, frmOrderDetails.Form_Delete, frmOrderDetails.PaidFieldsFilledOut, frmOrderDetails.sfrmOrderLineItems_Enter, frmOrderDetails.ShippingFieldsFilledOut, frmOrderList.fraFilter_AfterUpdate, frmProductDetail.cmdDeleteProduct_Click, frmPurchaseOrderDetails.cmdAddPO_Click, frmPurchaseOrderDetails.cmdApprovePO_Click, frmPurchaseOrderDetails.cmdClosePO_Click, frmPurchaseOrderDetails.cmdDeletePO_Click, frmPurchaseOrderDetails.cmdReceivePO_Click, frmPurchaseOrderDetails.cmdSubmitPO_Click, frmPurchaseOrderDetails.PoCloseFieldsFilledOut, frmPurchaseOrderDetails.VendorID_BeforeUpdate, sfrmAdmin_InternetOrders.cmdCreate_Click, sfrmAdmin_InternetOrders.txtCount_BeforeUpdate, sfrmOrderLineItems.Form_Delete, sfrmOrderLineItems.Form_Error, sfrmProductCategories.cmdDelete_Click, sfrmProductDetail_Vendors.txtVendorID_Click, sfrmPurchaseOrderLineItems.ValidateLineItem, modStrings.GetString, modValidation.ValidateForm
Calls: clsErrorHandler.HandleError, modStrings.StringFormat
Called by: frmCompanyDetail.cboCompanyTypeID_BeforeUpdate, frmCompanyDetail.cmdShowFilter_Click, frmCompanyDetail.CompanyCantBeDeleted, frmCompanyDetail.CompanyConfirmDelete, frmCompanyList.cmdShowFilter_Click, frmEmployeeList.EmployeeCanBeDeleted, frmOrderList.cmdShowFilter_Click, sfrmProductDetail_StockTake.QuantityOnHand_BeforeUpdate, sfrmProductDetail_Vendors.txtVendorID_Click, modGlobal.GetNorthwindAddress, modOrders.SetDatesToCurrent, modPurchaseOrders.ReorderProduct, modRibbonCallback.ddMRU_GetItemLabel, modStrings.GetString, modStrings.StringFormat, modStrings.StringFormatSQL
Calls: clsErrorHandler.HandleError, modGlobal.ToAccessDate, modStrings.StringFormat, modStrings.StringFormatSQL
Called by: frmAdmin.UpdateSubLabels, frmCompanyDetail.CompanyIsActive, frmCompanyDetail.Form_Delete, frmEmployeeList.cmdEmailEmployee_Click, frmEmployeeList.EmployeeCanBeDeleted, frmOrderDetails.SetLineItemsStatus, frmOrderList.fraFilter_AfterUpdate, frmProductDetail.cmdReorderProduct_Click, frmPurchaseOrderDetails.cmdAddNostock_Click, frmPurchaseOrderDetails.cmdReceivePO_Click, modDAO.HasDataMacro, modGlobal.AddToMRU, modGlobal.Get_UserID_ForWindowsUser, modGlobal.InitializeUser, modGlobal.RemoveFromMRU, modInventory.AllocateInventory, modInventory.OrderQuantity_ByStatus, modInventory.ProductBought, modInventory.ProductLastStockTakeDate, modInventory.ProductLastStockTakeQuantity, modInventory.ProductOnOrder, modInventory.ProductSold, modPurchaseOrders.AddPurchaseOrderDetail, modStartup.SaveSystemSetting, modStartup.SaveUserSetting, modStrings.StringFormatSQL
Calls: clsErrorHandler.HandleError, modStrings.StringToDictionary
Called by: frmCompanyDetail.Form_Load, frmEmployeeTitles.Form_Open, frmGenericDialog.Form_Load, frmOrderDetails.Form_Load, frmPurchaseOrderDetails.Form_Load, modStrings.StringToDictionary
Calls: clsErrorHandler.HandleError, modDAO.HasDataMacro, modDAO.HasField, modFiles.StringToFile, modGlobal.g_dbApp
Called by: modGlobal.OneTimeProcessing
Calls: clsErrorHandler.HandleError, modGlobal.Get_UserID, modGlobal.GetWindowsUserName, modTableDataMacros.GetAuditFieldsUserName
Called by: modTableDataMacros.GetAuditFieldsUserName
Calls: clsErrorHandler.HandleError, modDAO.HasProperty, modForms.ControlCurrentView, modForms.ControlDefaultView
Called by: frmOrderDetails.PaidFieldsFilledOut, frmOrderDetails.ShippingFeeFilledOut, frmOrderDetails.ShippingFieldsFilledOut, frmPurchaseOrderDetails.PoCloseFieldsFilledOut, modValidation.HighlightInvalidControls
Calls: clsErrorHandler.HandleError, modValidation.HighlightControl, modValidation.IsBoundToRequiredField
Called by: modValidation.ValidateForm
Calls: modValidation.IsBoundToRequiredField
Called by: modValidation.HighlightInvalidControls, modValidation.IsBoundToRequiredField, modValidation.IsValidForm
Calls: clsErrorHandler.HandleError, modValidation.IsBoundToRequiredField, modValidation.IsValidForm
Called by: modValidation.IsValidForm, modValidation.ValidateForm
Calls: clsErrorHandler.HandleError, modStrings.GetString, modValidation.HighlightInvalidControls, modValidation.IsValidForm, modValidation.ValidateForm
Called by: frmCompanyDetail.cmdSave_Click, frmCompanyDetail.Form_BeforeUpdate, frmCredentials.Form_BeforeUpdate, frmEmployeeList.Form_BeforeUpdate, frmOrderDetails.Form_BeforeUpdate, frmProductDetail.Form_BeforeUpdate, frmPurchaseOrderDetails.Form_BeforeUpdate, sfrmCompanyDetail_Contacts.Form_BeforeUpdate, sfrmOrderLineItems.Form_BeforeUpdate, sfrmProductDetail_StockTake.Form_BeforeUpdate, sfrmPurchaseOrderLineItems.Form_BeforeUpdate, modValidation.ValidateForm
Calls: modForms.ControlCurrentView, modForms.ControlDefaultView
Called by: frmCompanyDetail.cmdSave_Click, frmCompanyDetail.Form_AfterUpdate, frmCompanyDetail.Form_Current, frmEmployeeList.Form_AfterUpdate, frmEmployeeList.Form_Current, frmOrderDetails.Form_AfterUpdate, frmOrderDetails.Form_BeforeUpdate, frmOrderDetails.Form_Current, frmOrderDetails.sfrmOrderLineItems_Exit, frmProductDetail.ControlStates, frmPurchaseOrderDetails.Form_AfterUpdate, frmPurchaseOrderDetails.Form_BeforeUpdate, frmPurchaseOrderDetails.Form_Current, sfrmCompanyDetail_Contacts.Form_AfterUpdate, sfrmOrderLineItems.Form_AfterUpdate, sfrmOrderLineItems.Form_Current, sfrmProductDetail_StockTake.Form_AfterUpdate, sfrmProductDetail_StockTake.Form_Current, sfrmPurchaseOrderLineItems.Form_Current
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmAdmin.UpdateSubLabels, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStartup.GetSystemSetting, modStrings.StringFormatSQL
Called by: frmAdmin.Form_Open, sfrmAdmin_InternetOrders.cmdCreate_Click, sfrmEmployee_Privileges.Form_AfterDelConfirm, sfrmEmployee_Privileges.Form_AfterInsert
Calls: frmCompanyDetail.ManageFormOptions, clsErrorHandler.HandleError
Called by: None detected
Calls: frmCompanyDetail.CompanyIsActive, clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.GetString, modStrings.StringFormat
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.StringFormat
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.GetString, modStrings.StringFormat
Called by: frmCompanyDetail.Form_Delete
Calls: frmCompanyDetail.CompanyConfirmDelete, clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.StringFormat
Called by: frmCompanyDetail.CompanyConfirmDelete, frmCompanyDetail.Form_Delete
Calls: frmCompanyDetail.CompanyIsActive, clsErrorHandler.HandleError, modStrings.StringFormatSQL
Called by: frmCompanyDetail.cboCompanyTypeID_BeforeUpdate, frmCompanyDetail.CompanyIsActive, frmCompanyDetail.Form_Delete
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString, modValidation.ValidateForm
Called by: None detected
Calls: frmCompanyDetail.ManageFormOptions, clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: frmCompanyDetail.CompanyCantBeDeleted, frmCompanyDetail.CompanyConfirmDelete, frmCompanyDetail.CompanyIsActive, clsErrorHandler.HandleError, modGlobal.g_dbApp, modStrings.StringFormatSQL
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.StringToDictionary
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: frmCompanyDetail.cboCompanyTypeID_AfterUpdate, frmCompanyDetail.Form_Current
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmCompanyList.Open_frmCompanyDetail, clsErrorHandler.HandleError
Called by: None detected
Calls: None detected
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.StringFormat
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.GetString
Called by: frmCompanyList.cmdAddNew_Click, frmCompanyList.txtCompanyID_Click
Calls: frmCompanyList.Open_frmCompanyDetail, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStartup.SetAppTitle
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.GetWindowsUserName
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.GetWindowsUserName, modStrings.StringFormatSQL
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmEmployeeList.EmployeeCanBeDeleted, clsErrorHandler.HandleError, modForms.IsFormOpen, modGlobal.RemoveFromMRU, modStrings.GetString, modStrings.StringFormat, modStrings.StringFormatSQL
Called by: frmEmployeeList.EmployeeCanBeDeleted, frmEmployeeList.Form_Delete
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmEmployeeList.RequeryEmployeeList, clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: frmEmployeeList.EmployeeCanBeDeleted, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: frmEmployeeList.Form_AfterUpdate
Calls: clsErrorHandler.HandleError, modStrings.StringToDictionary
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.StringToDictionary
Called by: None detected
Calls: clsErrorHandler.HandleError, modStartup.SaveUserSetting
Called by: None detected
Calls: clsErrorHandler.HandleError, modStartup.SetAppTitle
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.Get_UserID, modGlobal.Get_UserID_ForWindowsUser, modStartup.GetUserSetting, modStartup.SetAppTitle, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmOrderDetails.AllInvoiceLineItemsHaveStatus, clsErrorHandler.HandleError
Called by: frmOrderDetails.AllInvoiceLineItemsHaveStatus, frmOrderDetails.cmdCreateInvoice_Click
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: modNorthwindPlusPlanning.RunOrderAvailabilityPlanning
Called by: None detected
Calls: frmOrderDetails.SetFormStatus, clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: frmOrderDetails.AllInvoiceLineItemsHaveStatus, frmOrderDetails.SetFormStatus, frmOrderDetails.SetLineItemsStatus, frmOrderDetails.ShippingFeeFilledOut, clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmOrderDetails.PaidFieldsFilledOut, frmOrderDetails.SetFormStatus, clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: frmOrderDetails.SetFormStatus, frmOrderDetails.SetLineItemsStatus, frmOrderDetails.ShippingFieldsFilledOut, clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.AddToMRU
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.Get_UserID, modStartup.GetSystemSetting
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.RequeryListForms, modOrders.CloseOrderDetailsForm
Called by: None detected
Calls: frmOrderDetails.LockControls, frmOrderDetails.SetFormStatus, clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.RemoveFromMRU, modInventory.AllocateInventory, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.AddToMRU, modStrings.StringToDictionary
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: frmOrderDetails.Form_Current, frmOrderDetails.SetFormStatus
Calls: frmOrderDetails.PaidFieldsFilledOut, clsErrorHandler.HandleError, modStrings.GetString, modValidation.HighlightControl
Called by: frmOrderDetails.cmdReceivePayment_Click, frmOrderDetails.PaidFieldsFilledOut
Calls: frmOrderDetails.LockControls, clsErrorHandler.HandleError
Called by: frmOrderDetails.cmdCloseOrder_Click, frmOrderDetails.cmdCreateInvoice_Click, frmOrderDetails.cmdReceivePayment_Click, frmOrderDetails.cmdShipOrder_Click, frmOrderDetails.Form_Current
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modStrings.StringFormatSQL
Called by: frmOrderDetails.cmdCreateInvoice_Click, frmOrderDetails.cmdShipOrder_Click
Calls: modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: frmOrderDetails.ShippingFeeFilledOut, clsErrorHandler.HandleError, modValidation.HighlightControl
Called by: frmOrderDetails.cmdCreateInvoice_Click, frmOrderDetails.ShippingFeeFilledOut
Calls: frmOrderDetails.ShippingFieldsFilledOut, clsErrorHandler.HandleError, modStrings.GetString, modValidation.HighlightControl
Called by: frmOrderDetails.cmdShipOrder_Click, frmOrderDetails.ShippingFieldsFilledOut
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.StringFormat
Called by: None detected
Calls: frmOrderList.fraFilter_AfterUpdate, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.Get_UserID, modStrings.GetString, modStrings.StringFormatSQL
Called by: frmOrderList.Form_Open
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsFormNew
Called by: None detected
Calls: clsErrorHandler.HandleError, modInventory.ProductAllocated, modInventory.ProductLastStockTakeDate, modInventory.ProductNoStock, modInventory.ProductOnOrder, modInventory.ProductReorderQuantity, modInventory.ProductToSell
Called by: frmProductDetail.ControlStates
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError
Called by: None detected
Calls: frmProductDetail.SetProductCode, clsErrorHandler.HandleError
Called by: None detected
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.RequeryProductList, modGlobal.g_dbApp, modStrings.GetString
Called by: None detected
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError, modForms.IsFormOpen, modForms.RequeryProductList, modGlobal.AddToMRU, modPurchaseOrders.AddPurchaseOrderDetail, modPurchaseOrders.OpenPurchaseOrderDetailsForm, modPurchaseOrders.ReorderProduct, modStrings.StringFormatSQL
Called by: None detected
Calls: frmProductDetail.CalculateLevels, clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: frmProductDetail.cboFindProduct_AfterUpdate, frmProductDetail.chkDiscontinued_AfterUpdate, frmProductDetail.cmdReorderProduct_Click, frmProductDetail.Form_Activate, frmProductDetail.Form_AfterInsert, frmProductDetail.Form_AfterUpdate, frmProductDetail.Form_Current, frmProductDetail.txtTargetLevel_AfterUpdate, sfrmProductDetail_StockTake.RequeryQuantities
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.RequeryProductList
Called by: None detected
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError, modForms.RequeryProductList
Called by: None detected
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError, modForms.RequeryProductList
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.RequeryListForms
Called by: None detected
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.RemoveFromMRU
Called by: None detected
Calls: frmProductDetail.tabProducts_Change, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: frmProductDetail.cboProductCategoryID_AfterUpdate
Calls: clsErrorHandler.HandleError
Called by: frmProductDetail.Form_Load
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modInventory.AllocateInventory
Called by: frmPurchaseOrderDetails.cmdApprovePO_Click, frmPurchaseOrderDetails.cmdReceivePO_Click
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modStrings.StringFormatSQL
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: frmPurchaseOrderDetails.AllocatePurchaseOrder, frmPurchaseOrderDetails.SetWorkflowLabelColors, clsErrorHandler.HandleError, modGlobal.Get_UserID, modSecurity.HasPrivilege, modStrings.GetString
Called by: None detected
Calls: frmPurchaseOrderDetails.PoCloseFieldsFilledOut, frmPurchaseOrderDetails.SetWorkflowLabelColors, clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.GetString
Called by: None detected
Calls: frmPurchaseOrderDetails.AllocatePurchaseOrder, frmPurchaseOrderDetails.SetWorkflowLabelColors, clsErrorHandler.HandleError, modGlobal.g_dbApp, modStrings.GetString, modStrings.StringFormatSQL
Called by: None detected
Calls: frmPurchaseOrderDetails.SetWorkflowLabelColors, clsErrorHandler.HandleError, modGlobal.Get_UserID, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.AddToMRU
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.RequeryListForms, modPurchaseOrders.ClosePurchaseOrderDetailsForm
Called by: None detected
Calls: frmPurchaseOrderDetails.LockControls, frmPurchaseOrderDetails.SetWorkflowLabelColors, clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.RemoveFromMRU
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.AddToMRU, modStrings.StringToDictionary
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: frmPurchaseOrderDetails.Form_Current, frmPurchaseOrderDetails.SetWorkflowLabelColors
Calls: frmPurchaseOrderDetails.PoCloseFieldsFilledOut, clsErrorHandler.HandleError, modStrings.GetString, modValidation.HighlightControl
Called by: frmPurchaseOrderDetails.cmdClosePO_Click, frmPurchaseOrderDetails.PoCloseFieldsFilledOut
Calls: frmPurchaseOrderDetails.LockControls, clsErrorHandler.HandleError
Called by: frmPurchaseOrderDetails.cmdApprovePO_Click, frmPurchaseOrderDetails.cmdClosePO_Click, frmPurchaseOrderDetails.cmdReceivePO_Click, frmPurchaseOrderDetails.cmdSubmitPO_Click, frmPurchaseOrderDetails.Form_Current
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modPurchaseOrders.OpenPurchaseOrderDetailsForm
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modPurchaseOrders.OpenPurchaseOrderDetailsForm
Called by: None detected
Calls: frmReports.ReportFormInitialization, clsErrorHandler.HandleError
Called by: None detected
Calls: frmReports.ReportFormInitialization, clsErrorHandler.HandleError
Called by: None detected
Calls: frmReports.ReportFormInitialization, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modFiles.FileExists
Called by: None detected
Calls: frmReports.ReportFormInitialization, clsErrorHandler.HandleError
Called by: frmReports.Form_Open
Calls: frmReports.ReportFormInitialization, clsErrorHandler.HandleError
Called by: None detected
Calls: frmReports.ReportFormInitialization, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmReports.cmdSalesByemployeeReport_Click, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: frmReports.cmdEmployeeEmailList_Click, frmReports.cmdEmployeePhoneList_Click, frmReports.cmdFallCatalog_Click, frmReports.cmdSalesByemployeeReport_Click, frmReports.cmdSalesByProductReportMonthly_Click, frmReports.cmdSalesByProductReportQuarterly_Click
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: frmSelectVendorDialog.lstVendor_DblClick
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: frmSelectVendorDialog.cmdOK_Click, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStartup.SaveSystemSetting
Called by: None detected
Calls: clsErrorHandler.HandleError, modStartup.GetSystemSetting
Called by: None detected
Calls: clsErrorHandler.HandleError, modGlobal.g_dbApp
Called by: None detected
Calls: frmAdmin.UpdateSubLabels, clsErrorHandler.HandleError, modOrders.CreateRandomOrders, modRibbonCallback.Ribbon_RefreshMRU, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modOrders.SetDatesToCurrent
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: sfrmCompanyDetail_CustomerOrders.OpenForm_frmOrderDetails, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsForm
Calls: sfrmCompanyDetail_ShipperOrders.OpenForm_frmOrderDetails, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsForm
Calls: sfrmCompanyDetail_VendorPurchaseOrders.OpenForm_frmPurchaseOrderDetails, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modPurchaseOrders.OpenPurchaseOrderDetailsForm
Called by: sfrmCompanyDetail_VendorPurchaseOrders.Detail_DblClick
Calls: frmAdmin.UpdateSubLabels, sfrmEmployee_Privileges.frmLoadedAsSubform, clsErrorHandler.HandleError
Called by: None detected
Calls: frmAdmin.UpdateSubLabels, sfrmEmployee_Privileges.frmLoadedAsSubform, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: sfrmEmployee_Privileges.frmLoadedAsSubform, clsErrorHandler.HandleError
Called by: sfrmEmployee_Privileges.Form_AfterDelConfirm, sfrmEmployee_Privileges.Form_AfterInsert, sfrmEmployee_Privileges.frmLoadedAsSubform
Calls: sfrmOrderLineItems.ProductID_AfterUpdate, clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modInventory.AllocateInventory
Called by: None detected
Calls: sfrmOrderLineItems.ReallocateInventory, clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: sfrmOrderLineItems.SetOrderDetailStatus, clsErrorHandler.HandleError, modValidation.ValidateForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: sfrmOrderLineItems.cboProductCategories_AfterUpdate
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modInventory.AllocateInventory
Called by: sfrmOrderLineItems.Form_AfterUpdate
Calls: clsErrorHandler.HandleError, modInventory.ProductAvailable
Called by: sfrmOrderLineItems.Form_BeforeUpdate
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsForm
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modStrings.GetString
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modOrders.OpenOrderDetailsForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modPurchaseOrders.OpenPurchaseOrderDetailsForm
Called by: None detected
Calls: sfrmProductDetail_StockTake.RequeryQuantities, clsErrorHandler.HandleError
Called by: None detected
Calls: sfrmProductDetail_StockTake.RequeryQuantities, clsErrorHandler.HandleError, modInventory.AllocateInventory, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError, modInventory.ProductAvailable
Called by: None detected
Calls: clsErrorHandler.HandleError, modInventory.ProductAvailable, modStrings.StringFormat
Called by: None detected
Calls: frmProductDetail.ControlStates, clsErrorHandler.HandleError, modForms.IsFormOpen, modForms.RequeryProductList
Called by: sfrmProductDetail_StockTake.Form_AfterInsert, sfrmProductDetail_StockTake.Form_AfterUpdate
Calls: clsErrorHandler.HandleError, modGlobal.Get_EmployeeFNLN, modGlobal.Get_UserID
Called by: None detected
Calls: clsErrorHandler.HandleError, modForms.IsFormOpen, modStrings.GetString, modStrings.StringFormat
Called by: None detected
Calls: sfrmPurchaseOrderLineItems.ValidateLineItem, clsErrorHandler.HandleError, modValidation.ValidateForm
Called by: None detected
Calls: clsErrorHandler.HandleError, modValidation.ValidateForm_RemoveHighlights
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: clsErrorHandler.HandleError, modInventory.ProductReorderQuantity
Called by: None detected
Calls: clsErrorHandler.HandleError
Called by: None detected
Calls: sfrmPurchaseOrderLineItems.ValidateLineItem, clsErrorHandler.HandleError, modGlobal.g_dbApp, modInventory.ProductToSell, modStrings.GetString
Called by: sfrmPurchaseOrderLineItems.Form_BeforeUpdate, sfrmPurchaseOrderLineItems.ValidateLineItem
Every documented table, query, form, report, macro, and module is included. Lines indicate detected references; click a node to open it here, or Ctrl+click to open its documentation in a new tab. Type to search similar names, then press Enter to focus on an exact object and its direct connections.
Press Enter after typing an exact name to focus on that object and its direct connections.Search for an object to see queries, forms, reports, or modules that reference it.
Press Search (or Enter) to refresh the results.Choose a wireframe map link to trace that action.
Detected from the saved scan. Calls or object names built dynamically at runtime may not appear.
Tables, their fields, indexes, and linked-table details.
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| TocTitle | Short Text | 255 | Yes | No |
| TocPage | Integer | 2 | Yes | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | TocTitle | Yes | Yes |
| TocPage | TocPage | No | No |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| CompanyID | Long Integer | 4 | No | No |
| CompanyName | Short Text | 50 | Yes | No |
| CompanyTypeID | Long Integer | 4 | Yes | No |
| BusinessPhone | Short Text | 20 | No | No |
| Address | Short Text | 255 | Yes | No |
| City | Short Text | 255 | Yes | No |
| StateAbbrev | Short Text | 2 | Yes | No |
| Zip | Short Text | 10 | Yes | No |
| Website | Long Text | No | No | |
| Notes | Long Text | No | No | |
| StandardTaxStatusID | Byte | 1 | Yes | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| CompanyTypesCompanies | CompanyTypeID | No | No |
| CustomerName | CompanyName, CompanyTypeID | No | Yes |
| New_CompanyTypesCompanies | CompanyTypeID | No | No |
| New_New_CompanyTypesCompanies | CompanyTypeID | No | No |
| New_New_StatesCompanies | StateAbbrev | No | No |
| New_New_TaxStatusCompanies | StandardTaxStatusID | No | No |
| New_StatesCompanies | StateAbbrev | No | No |
| New_TaxStatusCompanies | StandardTaxStatusID | No | No |
| PrimaryKey | CompanyID | Yes | Yes |
| StatesCompanies | StateAbbrev | No | No |
| TaxStatusCompanies | StandardTaxStatusID | No | No |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| CompanyTypeID | Long Integer | 4 | No | No |
| CompanyType | Short Text | 50 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| CompanyType | CompanyType | No | Yes |
| PrimaryKey | CompanyTypeID | Yes | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ContactID | Long Integer | 4 | No | No |
| CompanyID | Long Integer | 4 | Yes | No |
| LastName | Short Text | 30 | Yes | No |
| FirstName | Short Text | 20 | Yes | No |
| EmailAddress | Short Text | 255 | No | No |
| JobTitle | Short Text | 50 | Yes | No |
| PrimaryPhone | Short Text | 20 | No | No |
| SecondaryPhone | Short Text | 20 | No | No |
| Notes | Long Text | No | No | |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| CompaniesContacts | CompanyID | No | No |
| New_CompaniesContacts | CompanyID | No | No |
| New_New_CompaniesContacts | CompanyID | No | No |
| PrimaryKey | ContactID | Yes | Yes |
| uidxCompanyFNLN | CompanyID, FirstName, LastName | No | Yes |
| uidxCompanyLNFN | CompanyID, LastName, FirstName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| EmployeePrivilegeID | Long Integer | 4 | No | No |
| EmployeeID | Long Integer | 4 | Yes | No |
| PrivilegeID | Long Integer | 4 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| EmployeesEmployeePrivileges | EmployeeID | No | No |
| New_EmployeesEmployeePrivileges | EmployeeID | No | No |
| New_New_EmployeesEmployeePrivileges | EmployeeID | No | No |
| New_New_PrivilegesEmployeePrivileges | PrivilegeID | No | No |
| New_PrivilegesEmployeePrivileges | PrivilegeID | No | No |
| PrimaryKey | EmployeePrivilegeID | Yes | Yes |
| PrivilegeID | PrivilegeID | No | No |
| PrivilegesEmployeePrivileges | PrivilegeID | No | No |
| UniqueIdx | EmployeePrivilegeID, PrivilegeID | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| EmployeeID | Long Integer | 4 | No | No |
| FirstName | Short Text | 20 | Yes | No |
| LastName | Short Text | 30 | Yes | No |
| EmailAddress | Short Text | 255 | No | No |
| JobTitle | Short Text | 50 | Yes | No |
| PrimaryPhone | Short Text | 20 | No | No |
| SecondaryPhone | Short Text | 20 | No | No |
| Title | Short Text | 20 | No | No |
| Notes | Long Text | No | No | |
| Attachments | Type 101 | 4 | No | No |
| SupervisorID | Long Integer | 4 | No | No |
| WindowsUserName | Short Text | 50 | No | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| EmployeesEmployees | SupervisorID | No | No |
| New_EmployeesEmployees | SupervisorID | No | No |
| New_New_EmployeesEmployees | SupervisorID | No | No |
| New_New_SalutationsEmployees | Title | No | No |
| New_SalutationsEmployees | Title | No | No |
| PrimaryKey | EmployeeID | Yes | Yes |
| SalutationsEmployees | Title | No | No |
| uidxFNLN | FirstName, LastName | No | Yes |
| uidxLNFN | LastName, FirstName | No | Yes |
| WindowsUserName | WindowsUserName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ID | Long Integer | 4 | No | No |
| SectionNo | Integer | 2 | Yes | No |
| SectionText | Long Text | No | Yes |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | ID | Yes | Yes |
| SectionNo | SectionNo | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| MRU_ID | Long Integer | 4 | No | No |
| EmployeeID | Long Integer | 4 | Yes | No |
| TableName | Short Text | 50 | Yes | No |
| PKValue | Long Integer | 4 | Yes | No |
| DateAdded | Date/Time | 8 | Yes | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| EmployeesMRU | EmployeeID | No | No |
| New_EmployeesMRU | EmployeeID | No | No |
| New_New_EmployeesMRU | EmployeeID | No | No |
| PrimaryKey | MRU_ID | Yes | Yes |
| SortIdx | EmployeeID, DateAdded | No | Yes |
| UniqueIdx | EmployeeID, TableName, PKValue | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| NorthwindFeaturesID | Long Integer | 4 | No | No |
| ItemName | Short Text | 255 | Yes | No |
| Description | Short Text | 255 | No | No |
| Navigation | Short Text | 255 | Yes | No |
| LearnMore | Long Text | No | No | |
| HelpKeywords | Short Text | 255 | No | No |
| OpenMethod | Long Integer | 4 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | NorthwindFeaturesID | Yes | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| FulfillmentPlanID | Long Integer | 4 | No | No |
| OrderID | Long Integer | 4 | Yes | No |
| ProductID | Long Integer | 4 | Yes | No |
| RequiredQuantity | Long Integer | 4 | Yes | No |
| QuantityOnHand | Long Integer | 4 | Yes | No |
| PlannedProduction | Long Integer | 4 | Yes | No |
| AvailableToPromise | Long Integer | 4 | Yes | No |
| ShortageQuantity | Long Integer | 4 | Yes | No |
| PromiseDate | Date/Time | 8 | No | No |
| PlanStatus | Short Text | 30 | Yes | No |
| CreatedOn | Date/Time | 8 | Yes | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| IX_NWPFulfillmentPlan_Order | OrderID | No | No |
| PK_NWPFulfillmentPlan | FulfillmentPlanID | Yes | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ProductionCapacityID | Long Integer | 4 | No | No |
| ProductID | Long Integer | 4 | Yes | No |
| ProductionDate | Date/Time | 8 | Yes | No |
| CapacityUnits | Long Integer | 4 | Yes | No |
| PlanningNote | Short Text | 255 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| IX_NWPProductionCapacity_ProductDate | ProductID, ProductionDate | No | No |
| PK_NWPProductionCapacity | ProductionCapacityID | Yes | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| OrderDetailID | Long Integer | 4 | No | No |
| OrderID | Long Integer | 4 | Yes | No |
| ProductID | Long Integer | 4 | Yes | No |
| Quantity | Integer | 2 | Yes | No |
| UnitPrice | Currency | 8 | Yes | No |
| Discount | Single | 4 | No | No |
| OrderDetailStatusID | Long Integer | 4 | Yes | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| New_New_OrderDetailsStatusOrderDetails | OrderDetailStatusID | No | No |
| New_New_OrdersOrderDetails | OrderID | No | No |
| New_New_ProductsOrderDetails | ProductID | No | No |
| New_OrderDetailsStatusOrderDetails | OrderDetailStatusID | No | No |
| New_OrdersOrderDetails | OrderID | No | No |
| New_ProductsOrderDetails | ProductID | No | No |
| OrderDetailsStatusOrderDetails | OrderDetailStatusID | No | No |
| OrdersOrderDetails | OrderID | No | No |
| PrimaryKey | OrderDetailID | Yes | Yes |
| ProductID | ProductID | No | No |
| ProductsOrderDetails | ProductID | No | No |
| StatusID | OrderDetailStatusID | No | No |
| uidxOrderID_ProductID | OrderID, ProductID | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| OrderDetailStatusID | Long Integer | 4 | No | No |
| OrderDetailStatusName | Short Text | 50 | Yes | No |
| SortOrder | Byte | 1 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | OrderDetailStatusID | Yes | Yes |
| SortOrder | SortOrder | No | Yes |
| StatusName | OrderDetailStatusName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| OrderID | Long Integer | 4 | No | No |
| EmployeeID | Long Integer | 4 | Yes | No |
| CustomerID | Long Integer | 4 | Yes | No |
| OrderDate | Date/Time | 8 | Yes | No |
| InvoiceDate | Date/Time | 8 | No | No |
| ShippedDate | Date/Time | 8 | No | No |
| ShipperID | Long Integer | 4 | No | No |
| ShippingFee | Currency | 8 | No | No |
| TaxRate | Single | 4 | Yes | No |
| TaxStatusID | Byte | 1 | Yes | No |
| PaymentMethod | Short Text | 50 | No | No |
| PaidDate | Date/Time | 8 | No | No |
| Notes | Long Text | No | No | |
| OrderStatusID | Long Integer | 4 | Yes | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| CompaniesOrders | CustomerID | No | No |
| CompaniesOrders1 | ShipperID | No | No |
| EmployeesOrders | EmployeeID | No | No |
| New_CompaniesOrders | CustomerID | No | No |
| New_CompaniesOrders1 | ShipperID | No | No |
| New_EmployeesOrders | EmployeeID | No | No |
| New_New_CompaniesOrders | CustomerID | No | No |
| New_New_CompaniesOrders1 | ShipperID | No | No |
| New_New_EmployeesOrders | EmployeeID | No | No |
| New_New_OrdersStatusOrders | OrderStatusID | No | No |
| New_New_TaxStatusOrders | TaxStatusID | No | No |
| New_OrdersStatusOrders | OrderStatusID | No | No |
| New_TaxStatusOrders | TaxStatusID | No | No |
| OrderDate | OrderDate | No | No |
| OrdersStatusOrders | OrderStatusID | No | No |
| PrimaryKey | OrderID | Yes | Yes |
| TaxStatusOrders | TaxStatusID | No | No |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| OrderStatusID | Long Integer | 4 | No | No |
| OrderStatusCode | Short Text | 5 | Yes | No |
| OrderStatusName | Short Text | 50 | Yes | No |
| SortOrder | Byte | 1 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | OrderStatusID | Yes | Yes |
| SortOrder | SortOrder | No | Yes |
| StatusCode | OrderStatusCode | No | Yes |
| StatusName | OrderStatusName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| PrivilegeID | Long Integer | 4 | No | No |
| PrivilegeName | Short Text | 50 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | PrivilegeID | Yes | Yes |
| PrivilegeName | PrivilegeName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ProductCategoryID | Long Integer | 4 | No | No |
| ProductCategoryName | Short Text | 255 | Yes | No |
| ProductCategoryCode | Short Text | 3 | Yes | No |
| ProductCategoryDesc | Short Text | 255 | No | No |
| ProductCategoryImage | Type 101 | 4 | No | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | ProductCategoryID | Yes | Yes |
| ProductCategory | ProductCategoryName | No | Yes |
| ProductCategoryCode | ProductCategoryCode | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ProductID | Long Integer | 4 | No | No |
| ProductCode | Short Text | 20 | Yes | No |
| ProductName | Short Text | 50 | Yes | No |
| ProductDescription | Long Text | No | No | |
| StandardUnitCost | Currency | 8 | Yes | No |
| UnitPrice | Currency | 8 | Yes | No |
| ReorderLevel | Integer | 2 | No | No |
| TargetLevel | Integer | 2 | No | No |
| QuantityPerUnit | Short Text | 50 | No | No |
| Discontinued | Yes/No | 1 | Yes | No |
| MinimumReorderQuantity | Integer | 2 | No | No |
| ProductCategoryID | Long Integer | 4 | Yes | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| New_New_ProductCategories_NEWProducts | ProductCategoryID | No | No |
| New_ProductCategories_NEWProducts | ProductCategoryID | No | No |
| PrimaryKey | ProductID | Yes | Yes |
| ProductCategories_NEWProducts | ProductCategoryID | No | No |
| ProductCode | ProductCode | No | Yes |
| ProductName | ProductName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ProductVendorID | Long Integer | 4 | No | No |
| ProductID | Long Integer | 4 | Yes | No |
| VendorID | Long Integer | 4 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| CompaniesProductVendors | VendorID | No | No |
| New_CompaniesProductVendors | VendorID | No | No |
| New_New_CompaniesProductVendors | VendorID | No | No |
| New_New_ProductsProductVendors | ProductID | No | No |
| New_ProductsProductVendors | ProductID | No | No |
| PrimaryKey | ProductVendorID | Yes | Yes |
| ProductsProductVendors | ProductID | No | No |
| UniqueIdx | ProductID, VendorID | No | Yes |
| VendorID | VendorID | No | No |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| PurchaseOrderDetailID | Long Integer | 4 | No | No |
| PurchaseOrderID | Long Integer | 4 | Yes | No |
| ProductID | Long Integer | 4 | Yes | No |
| Quantity | Integer | 2 | Yes | No |
| UnitCost | Currency | 8 | Yes | No |
| ReceivedDate | Date/Time | 8 | No | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| New_New_ProductsPurchaseOrderDetails | ProductID | No | No |
| New_New_PurchaseOrdersPurchaseOrderDetails | PurchaseOrderID | No | No |
| New_ProductsPurchaseOrderDetails | ProductID | No | No |
| New_PurchaseOrdersPurchaseOrderDetails | PurchaseOrderID | No | No |
| PrimaryKey | PurchaseOrderDetailID | Yes | Yes |
| ProductsPurchaseOrderDetails | ProductID | No | No |
| PurchaseOrdersPurchaseOrderDetails | PurchaseOrderID | No | No |
| uidxPurchaseOrderID_ProductID | PurchaseOrderID, ProductID | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| PurchaseOrderID | Long Integer | 4 | No | No |
| VendorID | Long Integer | 4 | Yes | No |
| SubmittedByID | Long Integer | 4 | No | No |
| SubmittedDate | Date/Time | 8 | No | No |
| ApprovedByID | Long Integer | 4 | No | No |
| ApprovedDate | Date/Time | 8 | No | No |
| StatusID | Long Integer | 4 | Yes | No |
| ReceivedDate | Date/Time | 8 | No | No |
| ShippingFee | Currency | 8 | No | No |
| TaxAmount | Currency | 8 | No | No |
| PaymentDate | Date/Time | 8 | No | No |
| PaymentAmount | Currency | 8 | No | No |
| PaymentMethod | Short Text | 50 | No | No |
| Notes | Long Text | No | No | |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| CompaniesPurchaseOrders | VendorID | No | No |
| EmployeesPurchaseOrders1 | ApprovedByID | No | No |
| EmployeesPurchaseOrders2 | SubmittedByID | No | No |
| New_CompaniesPurchaseOrders | VendorID | No | No |
| New_EmployeesPurchaseOrders1 | ApprovedByID | No | No |
| New_EmployeesPurchaseOrders2 | SubmittedByID | No | No |
| New_New_CompaniesPurchaseOrders | VendorID | No | No |
| New_New_EmployeesPurchaseOrders1 | ApprovedByID | No | No |
| New_New_EmployeesPurchaseOrders2 | SubmittedByID | No | No |
| New_New_PurchaseOrdersStatusPurchaseOrders | StatusID | No | No |
| New_PurchaseOrdersStatusPurchaseOrders | StatusID | No | No |
| PrimaryKey | PurchaseOrderID | Yes | Yes |
| PurchaseOrdersStatusPurchaseOrders | StatusID | No | No |
| StatusCode | StatusID | No | No |
| SubmittedDate | SubmittedDate | No | No |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| StatusID | Long Integer | 4 | No | No |
| StatusName | Short Text | 50 | Yes | No |
| SortOrder | Byte | 1 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | StatusID | Yes | Yes |
| SortOrder | SortOrder | No | Yes |
| StatusName | StatusName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| StateAbbrev | Short Text | 2 | Yes | No |
| StateName | Short Text | 50 | Yes | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | StateAbbrev | Yes | Yes |
| StateName | StateName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| StockTakeID | Long Integer | 4 | No | No |
| StockTakeDate | Date/Time | 8 | Yes | No |
| ProductID | Long Integer | 4 | Yes | No |
| QuantityOnHand | Integer | 2 | Yes | No |
| ExpectedQuantity | Long Integer | 4 | No | No |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| New_New_ProductsStockTake | ProductID | No | No |
| New_ProductsStockTake | ProductID | No | No |
| PrimaryKey | StockTakeID | Yes | Yes |
| ProductsStockTake | ProductID | No | No |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| StringID | Long Integer | 4 | No | No |
| StringData | Long Text | Yes | No | |
| AddedBy | Short Text | 255 | No | No |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | No |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | StringID | Yes | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| SettingID | Long Integer | 4 | No | No |
| SettingName | Short Text | 50 | Yes | No |
| SettingValue | Short Text | 255 | No | No |
| Notes | Short Text | 255 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | SettingID | Yes | Yes |
| SettingName | SettingName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| TaxStatusID | Byte | 1 | Yes | No |
| TaxStatus | Short Text | 50 | Yes | No |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | TaxStatusID | Yes | Yes |
| TaxStatus | TaxStatus | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| Title | Short Text | 20 | Yes | Yes |
| AddedBy | Short Text | 255 | No | Yes |
| AddedOn | Date/Time | 8 | No | No |
| ModifiedBy | Short Text | 255 | No | Yes |
| ModifiedOn | Date/Time | 8 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | Title | Yes | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| SettingID | Long Integer | 4 | No | No |
| SettingName | Short Text | 50 | Yes | No |
| SettingValue | Short Text | 255 | No | No |
| Notes | Short Text | 255 | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | SettingID | Yes | Yes |
| SettingName | SettingName | No | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ID | Long Integer | 4 | No | No |
| RibbonName | Short Text | 255 | No | No |
| RibbonXML | Long Text | No | No |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | ID | Yes | Yes |
| Field | Data type | Size | Required | Zero-length text |
|---|---|---|---|---|
| ID | Long Integer | 4 | No | No |
| Welcome | Long Text | No | No | |
| Learn | Long Text | No | No | |
| DataMacro | Long Text | No | Yes |
| Name | Fields | Primary | Unique |
|---|---|---|---|
| PrimaryKey | ID | Yes | Yes |
Saved query SQL, dependencies, and an optional visual query-designer view.
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT CompanyTypes.CompanyTypeID, CompanyTypes.CompanyType FROM CompanyTypes ORDER BY CompanyTypes.CompanyType;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Companies.CompanyID, Companies.CompanyName FROM Companies WHERE (((Companies.CompanyTypeID)=1)) ORDER BY Companies.CompanyName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT qryEmployees.EmployeeID, qryEmployees.FullNameFNLN FROM qryEmployees ORDER BY qryEmployees.FullNameFNLN;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT OrderDetailStatus.OrderDetailStatusID, OrderDetailStatus.OrderDetailStatusName FROM OrderDetailStatus ORDER BY OrderDetailStatus.SortOrder;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT OrderStatus.OrderStatusID, OrderStatus.OrderStatusName FROM OrderStatus ORDER BY OrderStatus.SortOrder;
Union query: Access exposes this query in SQL view. The design grid below summarizes the first SELECT branch; all branches remain available in the SQL.
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
select distinct 1 as theClause, 0 as ProductCategoryID, "<All>" as ProductCategoryName FROM ProductCategories UNION ALL SELECT 2 as theClause, ProductCategories.ProductCategoryID, ProductCategories.ProductCategoryName FROM ProductCategories ORDER BY theClause, ProductCategoryName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT ProductCategories.ProductCategoryID, ProductCategories.ProductCategoryName FROM ProductCategories ORDER BY ProductCategories.ProductCategoryName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Products.ProductID, Products.ProductName, Products.UnitPrice, Products.ProductCategoryID FROM Products WHERE (((Products.ProductCategoryID)=[Form]![cboProductCategories])) ORDER BY Products.ProductName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Products.ProductID, Products.ProductName, Products.UnitPrice, Products.ProductCategoryID FROM Products ORDER BY Products.ProductName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Products.ProductID = ProductVendors.ProductID (1 → ∞)
SELECT Products.ProductID, Products.ProductName, Products.StandardUnitCost FROM Products INNER JOIN ProductVendors ON Products.ProductID = ProductVendors.ProductID WHERE (((ProductVendors.VendorID)=[Parent]![VendorID])) ORDER BY Products.ProductName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Companies.CompanyID, Companies.CompanyName FROM Companies WHERE (((Companies.CompanyTypeID)=2)) ORDER BY Companies.CompanyName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT States.StateAbbrev, States.StateName FROM States ORDER BY States.StateName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT TaxStatus.TaxStatusID, TaxStatus.TaxStatus FROM TaxStatus ORDER BY TaxStatus.TaxStatusID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Companies.CompanyID, Companies.CompanyName FROM Companies WHERE (((Companies.CompanyTypeID)=3)) ORDER BY Companies.CompanyName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Companies.*, [Address] & Space(2) & [City] & ", " & [StateAbbrev] & Space(2) & [Zip] AS BusinessAddress FROM Companies ORDER BY Companies.CompanyName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: CompanyTypes.CompanyTypeID = Companies.CompanyTypeID (1 → ∞); INNER JOIN: TaxStatus.TaxStatusID = Companies.StandardTaxStatusID (1 → ∞)
SELECT Companies.CompanyID, Companies.CompanyName, CompanyTypes.CompanyType, Companies.BusinessPhone, Companies.Address, Companies.City, Companies.StateAbbrev, Companies.Zip, Companies.Website, Companies.Notes, TaxStatus.TaxStatus, Companies.AddedBy, Companies.AddedOn, Companies.ModifiedBy, Companies.ModifiedOn, [Address] & Space(2) & [City] & ", " & [StateAbbrev] & Space(2) & [Zip] AS BusinessAddress, Companies.CompanyTypeID, Companies.StandardTaxStatusID FROM TaxStatus INNER JOIN (CompanyTypes INNER JOIN Companies ON CompanyTypes.CompanyTypeID = Companies.CompanyTypeID) ON TaxStatus.TaxStatusID = Companies.StandardTaxStatusID ORDER BY Companies.CompanyName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Contacts.* FROM Contacts ORDER BY Contacts.LastName, Contacts.FirstName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Orders.EmployeeID = qrycboEmployees.EmployeeID; LEFT JOIN: Orders.ShipperID = qrycboShippers.CompanyID; LEFT JOIN: Orders.OrderID = qryOrderTotal.OrderID; INNER JOIN: Orders.OrderStatusID = qrycboOrderStatus.OrderStatusID
SELECT Orders.OrderID, Orders.EmployeeID, Orders.CustomerID AS myCompanyID, Orders.OrderDate, Orders.ShippedDate, Orders.ShipperID, Orders.ShippingFee, Orders.TaxRate, Orders.TaxStatusID, Orders.PaymentMethod, Orders.PaidDate, Orders.Notes, Orders.OrderStatusID, Orders.AddedBy, Orders.AddedOn, Orders.ModifiedBy, Orders.ModifiedOn, qrycboEmployees.FullNameFNLN AS EmployeeName, qrycboShippers.CompanyName AS ShipperName, qryOrderTotal.OrderTotal, qrycboOrderStatus.OrderStatusName FROM (((Orders INNER JOIN qrycboEmployees ON Orders.EmployeeID = qrycboEmployees.EmployeeID) LEFT JOIN qrycboShippers ON Orders.ShipperID = qrycboShippers.CompanyID) LEFT JOIN qryOrderTotal ON Orders.OrderID = qryOrderTotal.OrderID) INNER JOIN qrycboOrderStatus ON Orders.OrderStatusID = qrycboOrderStatus.OrderStatusID ORDER BY Orders.OrderID DESC;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Companies.* FROM Companies WHERE (((Companies.CompanyTypeID)=1));
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT qryEmployees.EmployeeID, qryEmployees.FirstName, qryEmployees.LastName, qryEmployees.EmailAddress, qryEmployees.JobTitle, qryEmployees.WindowsUserName, qryEmployees.FullNameFNLN AS FullName FROM qryEmployees;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Employees.EmployeeID = EmployeePrivileges.EmployeeID (1 → ∞)
SELECT EmployeePrivileges.* FROM Employees INNER JOIN EmployeePrivileges ON Employees.EmployeeID = EmployeePrivileges.EmployeeID ORDER BY Employees.FirstName, Employees.LastName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Employees.*, [FirstName] & " " & [LastName] AS FullNameFNLN, [LastName] & ", " & [FirstName] AS FullNameLNFN FROM Employees ORDER BY [LastName] & ", " & [FirstName];
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT qryEmployees.EmployeeID, qryEmployees.fullnamefnln AS Supervisor FROM qryEmployees WHERE (((qryEmployees.EmployeeID)<>[Forms]![frmEmployeeList]![EmployeeID]));
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: qryCustomers.CompanyID = Orders.CustomerID; INNER JOIN: qryEmployees.EmployeeID = Orders.EmployeeID; INNER JOIN: Orders.OrderID = OrderDetails.OrderID (1 → ∞); INNER JOIN: Products.ProductID = OrderDetails.ProductID (1 → ∞)
SELECT qryCustomers.CompanyName, qryCustomers.Address, qryCustomers.City, qryCustomers.StateAbbrev, qryCustomers.Zip, Orders.*, qryEmployees.FullNameFNLN AS SalesPerson, OrderDetails.ProductID, OrderDetails.Quantity, OrderDetails.UnitPrice, OrderDetails.Discount, Products.ProductCode, Products.ProductName FROM Products INNER JOIN ((qryEmployees INNER JOIN (qryCustomers INNER JOIN Orders ON qryCustomers.CompanyID = Orders.CustomerID) ON qryEmployees.EmployeeID = Orders.EmployeeID) INNER JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID) ON Products.ProductID = OrderDetails.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT StockTake.ProductID, Max(StockTake.StockTakeDate) AS MaxOfStockTakeDate FROM StockTake GROUP BY StockTake.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT MRU.* FROM MRU WHERE (((MRU.EmployeeID)=Get_UserID())) ORDER BY MRU.MRU_ID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: LEFT JOIN: Products.ProductID = LatestStock.ProductID; LEFT JOIN: Products.ProductID = Planned.ProductID
SELECT Products.ProductID, Products.ProductCode, Products.ProductName, Nz(LatestStock.QuantityOnHand, 0) AS QuantityOnHand, Nz(Planned.PlannedProduction, 0) AS PlannedProduction, Nz(LatestStock.QuantityOnHand, 0) + Nz(Planned.PlannedProduction, 0) AS AvailableToPromise, Planned.FirstProductionDate FROM (Products LEFT JOIN qryNWP_LatestStock AS LatestStock ON Products.ProductID = LatestStock.ProductID) LEFT JOIN qryNWP_PlannedProduction AS Planned ON Products.ProductID = Planned.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Demand.ProductID = Availability.ProductID
Action output: NWPFulfillmentPlan
PARAMETERS [pOrderID] Long; INSERT INTO NWPFulfillmentPlan ( OrderID, ProductID, RequiredQuantity, QuantityOnHand, PlannedProduction, AvailableToPromise, ShortageQuantity, PromiseDate, PlanStatus, CreatedOn ) SELECT Demand.OrderID, Demand.ProductID, Demand.RequiredQuantity, Availability.QuantityOnHand, Availability.PlannedProduction, Availability.AvailableToPromise, IIf(Availability.AvailableToPromise < Demand.RequiredQuantity, Demand.RequiredQuantity - Availability.AvailableToPromise, 0) AS ShortageQuantity, IIf(Availability.AvailableToPromise >= Demand.RequiredQuantity, Date(), Availability.FirstProductionDate) AS PromiseDate, IIf(Availability.AvailableToPromise >= Demand.RequiredQuantity, 'Available now', IIf(Availability.PlannedProduction > 0, 'Planned production', 'Shortage')) AS PlanStatus, Now() FROM qryNWP_OrderDemand AS Demand INNER JOIN qryNWP_AvailableToPromise AS Availability ON Demand.ProductID = Availability.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT StockTake.ProductID, StockTake.QuantityOnHand FROM StockTake INNER JOIN (SELECT ProductID, Max(StockTakeDate) AS LatestStockTakeDate FROM StockTake GROUP BY ProductID) AS Latest ON (StockTake.StockTakeDate = Latest.LatestStockTakeDate) AND (StockTake.ProductID = Latest.ProductID);
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Plan.ProductID = Products.ProductID
SELECT Plan.OrderID, Products.ProductCode, Products.ProductName, Plan.RequiredQuantity, Plan.QuantityOnHand, Plan.PlannedProduction, Plan.AvailableToPromise, Plan.ShortageQuantity, Plan.PromiseDate, Plan.PlanStatus FROM NWPFulfillmentPlan AS Plan INNER JOIN Products ON Plan.ProductID = Products.ProductID ORDER BY Plan.OrderID, Products.ProductName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
PARAMETERS [pOrderID] Long; SELECT OrderDetails.OrderID, OrderDetails.ProductID, Sum(OrderDetails.Quantity) AS RequiredQuantity FROM OrderDetails WHERE OrderDetails.OrderID = [pOrderID] GROUP BY OrderDetails.OrderID, OrderDetails.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT ProductID, Sum(CapacityUnits) AS PlannedProduction, Min(ProductionDate) AS FirstProductionDate FROM NWPProductionCapacity WHERE ProductionDate >= Date() GROUP BY ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: OrderStatus.OrderStatusID = Orders.OrderStatusID (1 → ∞)
SELECT Orders.*, OrderStatus.OrderStatusName FROM OrderStatus INNER JOIN Orders ON OrderStatus.OrderStatusID = Orders.OrderStatusID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: ProductCategories.ProductCategoryID = Products.ProductCategoryID (1 → ∞); INNER JOIN: Products.ProductID = OrderDetails.ProductID (1 → ∞)
SELECT OrderDetails.*, Products.ProductName, Products.ProductCategoryID, ProductCategories.ProductCategoryName FROM (ProductCategories INNER JOIN Products ON ProductCategories.ProductCategoryID = Products.ProductCategoryID) INNER JOIN OrderDetails ON Products.ProductID = OrderDetails.ProductID ORDER BY OrderDetails.OrderDetailID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: qryCustomers.CompanyID = Orders.CustomerID; INNER JOIN: Orders.OrderID = qryOrderTotal.OrderID; INNER JOIN: qrycboEmployees.EmployeeID = Orders.EmployeeID; LEFT JOIN: Orders.OrderID = qryOrderList_DetailStatus.OrderID; LEFT JOIN: OrderStatus.OrderStatusID = Orders.OrderStatusID (1 → ∞)
SELECT Orders.*, qrycboEmployees.FullNameFNLN, qryCustomers.CompanyName, qryOrderTotal.OrderTotal, OrderStatus.OrderStatusName, qryOrderList_DetailStatus.OrderDetailStatusName, DateValue([OrderDate]) AS OrderDateOnly FROM OrderStatus INNER JOIN ((qrycboEmployees INNER JOIN ((qryCustomers INNER JOIN Orders ON qryCustomers.CompanyID = Orders.CustomerID) INNER JOIN qryOrderTotal ON Orders.OrderID = qryOrderTotal.OrderID) ON qrycboEmployees.EmployeeID = Orders.EmployeeID) LEFT JOIN qryOrderList_DetailStatus ON Orders.OrderID = qryOrderList_DetailStatus.OrderID) ON OrderStatus.OrderStatusID = Orders.OrderStatusID ORDER BY Orders.OrderID DESC;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: qryOrderList_DetailStatus_Lowest.MinOfSortOrder = OrderDetailStatus.SortOrder
SELECT qryOrderList_DetailStatus_Lowest.OrderID, OrderDetailStatus.OrderDetailStatusName FROM qryOrderList_DetailStatus_Lowest INNER JOIN OrderDetailStatus ON qryOrderList_DetailStatus_Lowest.MinOfSortOrder = OrderDetailStatus.SortOrder;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: OrderDetailStatus.OrderDetailStatusID = OrderDetails.OrderDetailStatusID (1 → ∞)
SELECT OrderDetails.OrderID, Min(OrderDetailStatus.SortOrder) AS MinOfSortOrder FROM OrderDetailStatus INNER JOIN OrderDetails ON OrderDetailStatus.OrderDetailStatusID = OrderDetails.OrderDetailStatusID GROUP BY OrderDetails.OrderID ORDER BY OrderDetails.OrderID, Min(OrderDetailStatus.SortOrder);
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT TOP 20 qryOrderList.* FROM qryOrderList;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT qryOrderList.* FROM qryOrderList WHERE (((qryOrderList.CustomerID)=[Parent]![Parent]![CustomerID])) ORDER BY qryOrderList.OrderDate DESC;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT qryOrderList.* FROM qryOrderList WHERE (((qryOrderList.EmployeeID)=[Parent].[EmployeeID])) ORDER BY qryOrderList.OrderDate DESC;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT qryOrderList.* FROM qryOrderList ORDER BY qryOrderList.ModifiedOn DESC;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: LEFT JOIN: Orders.OrderID = OrderDetails.OrderID (1 → ∞)
SELECT Orders.OrderID, Sum([Quantity]*(1-[Discount])*[UnitPrice]) AS OrderTotal FROM Orders LEFT JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID GROUP BY Orders.OrderID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: PurchaseOrders.PurchaseOrderID = PurchaseOrderDetails.PurchaseOrderID (1 → ∞)
SELECT PurchaseOrders.StatusID, PurchaseOrderDetails.ProductID, Sum(PurchaseOrderDetails.Quantity) AS Quantity FROM PurchaseOrders INNER JOIN PurchaseOrderDetails ON PurchaseOrders.PurchaseOrderID = PurchaseOrderDetails.PurchaseOrderID GROUP BY PurchaseOrders.StatusID, PurchaseOrderDetails.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Privileges.PrivilegeID, Privileges.PrivilegeName FROM [Privileges] ORDER BY Privileges.PrivilegeName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT ProductCategories.ProductCategoryID, ProductCategories.ProductCategoryName, ProductCategories.ProductCategoryCode, ProductCategories.ProductCategoryDesc, ProductCategories.ProductCategoryImage, ProductCategories.AddedBy, ProductCategories.AddedOn, ProductCategories.ModifiedBy, ProductCategories.ModifiedOn FROM ProductCategories;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Products.ProductID, Products.ProductCode, Products.ProductName, Products.ProductDescription, Products.StandardUnitCost, Products.UnitPrice, Products.ReorderLevel, Products.TargetLevel, Products.QuantityPerUnit, Products.Discontinued, Products.MinimumReorderQuantity, Products.ProductCategoryID, Products.AddedBy, Products.AddedOn, Products.ModifiedBy, Products.ModifiedOn FROM Products;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: ProductCategories.ProductCategoryID = Products.ProductCategoryID (1 → ∞)
SELECT Products.ProductID, ProductCategories.ProductCategoryName, Products.ProductCode, Products.ProductName, Products.ProductDescription, Products.StandardUnitCost, ProductNoStock([Products].[ProductID]) AS NoStock, ProductAllocated([Products].[ProductID]) AS Allocated, ProductToSell([Products].[ProductID]) AS ToSell, ProductOnOrder([Products].[ProductID]) AS QuantityOnOrder, Products.MinimumReorderQuantity, Products.UnitPrice, Products.ReorderLevel, Products.TargetLevel, Products.QuantityPerUnit, Products.Discontinued, Products.ProductCategoryID, Products.AddedBy, Products.AddedOn, Products.ModifiedBy, Products.ModifiedOn FROM ProductCategories INNER JOIN Products ON ProductCategories.ProductCategoryID = Products.ProductCategoryID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Products.ProductID AS [Product ID], Products.ProductCode AS [Product Code], Products.ProductName AS Product, CDbl(ProductAllocated([Products].[ProductID])) AS [Allocated Inventory], ProductToSell([Products].[ProductID]) AS [Inventory To Sell], ProductOnOrder([Products].[ProductID]) AS [Qty On Order], Products.ReorderLevel AS [Reorder Level], Products.TargetLevel AS [Target Level], Products.MinimumReorderQuantity AS [Min Reorder Qty], Products.Discontinued FROM Products ORDER BY Products.ProductName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: OrderDetailStatus.OrderDetailStatusID = OrderDetails.OrderDetailStatusID (1 → ∞); INNER JOIN: Orders.OrderID = OrderDetails.OrderID (1 → ∞); INNER JOIN: OrderStatus.OrderStatusID = Orders.OrderStatusID (1 → ∞); INNER JOIN: Products.ProductID = OrderDetails.ProductID (1 → ∞)
SELECT OrderDetails.OrderID, OrderDetails.ProductID, Orders.OrderDate, OrderDetails.Quantity, OrderDetails.UnitPrice, [OrderDetails].[Quantity]*[OrderDetails].[UnitPrice] AS ExtendedPrice, OrderStatus.OrderStatusName AS OrderStatus, OrderDetailStatus.OrderDetailStatusName AS ProductStatus FROM Products INNER JOIN (OrderStatus INNER JOIN (Orders INNER JOIN (OrderDetailStatus INNER JOIN OrderDetails ON OrderDetailStatus.OrderDetailStatusID = OrderDetails.OrderDetailStatusID) ON Orders.OrderID = OrderDetails.OrderID) ON OrderStatus.OrderStatusID = Orders.OrderStatusID) ON Products.ProductID = OrderDetails.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Companies.CompanyID = PurchaseOrders.VendorID (1 → ∞); INNER JOIN: Products.ProductID = PurchaseOrderDetails.ProductID (1 → ∞); INNER JOIN: PurchaseOrders.PurchaseOrderID = PurchaseOrderDetails.PurchaseOrderID (1 → ∞); INNER JOIN: PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID (1 → ∞)
SELECT Products.ProductID, PurchaseOrderDetails.PurchaseOrderID, PurchaseOrderStatus.StatusID, PurchaseOrderStatus.StatusName, PurchaseOrderStatus.SortOrder, PurchaseOrderDetails.Quantity, PurchaseOrderDetails.UnitCost, [Quantity]*[UnitCost] AS ExtendedCost, Companies.CompanyName, PurchaseOrders.SubmittedDate, PurchaseOrderDetails.ReceivedDate FROM PurchaseOrderStatus RIGHT JOIN ((Companies INNER JOIN PurchaseOrders ON Companies.CompanyID = PurchaseOrders.VendorID) INNER JOIN (Products INNER JOIN PurchaseOrderDetails ON Products.ProductID = PurchaseOrderDetails.ProductID) ON PurchaseOrders.PurchaseOrderID = PurchaseOrderDetails.PurchaseOrderID) ON PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID ORDER BY PurchaseOrderStatus.SortOrder, PurchaseOrders.SubmittedDate;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT ProductVendors.ProductVendorID, ProductVendors.ProductID, ProductVendors.VendorID, ProductVendors.AddedBy, ProductVendors.AddedOn, ProductVendors.ModifiedBy, ProductVendors.ModifiedOn FROM ProductVendors;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: LEFT JOIN: PurchaseOrders.SubmittedByID = qryEmployees.EmployeeID; LEFT JOIN: PurchaseOrders.ApprovedByID = qryEmployees_1.EmployeeID; LEFT JOIN: PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID (1 → ∞)
SELECT PurchaseOrders.*, PurchaseOrderStatus.StatusName, qryEmployees.FullNameFNLN AS SubmittedBy, qryEmployees_1.FullNameFNLN AS ApprovedBy FROM PurchaseOrderStatus INNER JOIN ((PurchaseOrders LEFT JOIN qryEmployees ON PurchaseOrders.SubmittedByID = qryEmployees.EmployeeID) LEFT JOIN qryEmployees AS qryEmployees_1 ON PurchaseOrders.ApprovedByID = qryEmployees_1.EmployeeID) ON PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: LEFT JOIN: PurchaseOrders.PurchaseOrderID = PurchaseOrderDetails.PurchaseOrderID (1 → ∞)
SELECT PurchaseOrders.PurchaseOrderID, Sum([Quantity]*[UnitCost]) AS ExtendedCost FROM PurchaseOrders LEFT JOIN PurchaseOrderDetails ON PurchaseOrders.PurchaseOrderID = PurchaseOrderDetails.PurchaseOrderID GROUP BY PurchaseOrders.PurchaseOrderID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT PurchaseOrderDetails.* FROM PurchaseOrderDetails ORDER BY PurchaseOrderDetails.PurchaseOrderDetailID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: qrycboVendors.CompanyID = PurchaseOrders.VendorID; INNER JOIN: PurchaseOrders.PurchaseOrderID = qryPurchaseOrderCost.PurchaseOrderID; INNER JOIN: qrycboEmployees-Submitted.EmployeeID = PurchaseOrders.SubmittedByID; INNER JOIN: qrycboEmployees-Approved.EmployeeID = PurchaseOrders.ApprovedByID; INNER JOIN: PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID (1 → ∞)
SELECT PurchaseOrders.PurchaseOrderID, PurchaseOrderStatus.StatusName, qrycboVendors.CompanyName, Nz([qryPurchaseOrderCost].[ExtendedCost])+Nz([PurchaseOrders].[ShippingFee])+Nz([PurchaseOrders].[TaxAmount]) AS TotalCost, [qrycboEmployees-Submitted].FullNameFNLN AS Submitter, PurchaseOrders.SubmittedDate, [qrycboEmployees-Approved].FullNameFNLN AS Approver, PurchaseOrders.ApprovedDate, PurchaseOrders.PaymentDate FROM PurchaseOrderStatus INNER JOIN (qrycboEmployees AS [qrycboEmployees-Approved] RIGHT JOIN (qrycboEmployees AS [qrycboEmployees-Submitted] RIGHT JOIN ((qrycboVendors INNER JOIN PurchaseOrders ON qrycboVendors.CompanyID = PurchaseOrders.VendorID) INNER JOIN qryPurchaseOrderCost ON PurchaseOrders.PurchaseOrderID = qryPurchaseOrderCost.PurchaseOrderID) ON [qrycboEmployees-Submitted].EmployeeID = PurchaseOrders.SubmittedByID) ON [qrycboEmployees-Approved].EmployeeID = PurchaseOrders.ApprovedByID) ON PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID ORDER BY PurchaseOrders.PurchaseOrderID DESC;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Employees.EmployeeID, [Employees].[FirstName] & " " & [Employees].[LastName] AS FullNameFNLN, Employees.EmailAddress FROM Employees ORDER BY [Employees].[FirstName] & " " & [Employees].[LastName];
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Employees.EmployeeID, [employees].[FirstName] & " " & [employees].[LastName] AS FullNameFNLN, Employees.PrimaryPhone, Employees.SecondaryPhone, Left([FirstName],1) AS EmailGroup FROM Employees ORDER BY [employees].[FirstName] & " " & [employees].[LastName];
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: LEFT JOIN: Products.ProductID = qryTotalSalesByProduct.ProductID; LEFT JOIN: ProductCategories.ProductCategoryID = Products.ProductCategoryID (1 → ∞)
SELECT ProductCategories.ProductCategoryID, ProductCategories.ProductCategoryName, ProductCategories.ProductCategoryCode, Products.ProductName, Products.ProductID, Products.QuantityPerUnit, Products.UnitPrice, qryTotalSalesByProduct.TotalSales, ProductCategories.ProductCategoryDesc, ProductCategories.ProductCategoryImage FROM ProductCategories INNER JOIN (Products LEFT JOIN qryTotalSalesByProduct ON Products.ProductID = qryTotalSalesByProduct.ProductID) ON ProductCategories.ProductCategoryID = Products.ProductCategoryID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: qryOrderTotal.OrderID = Orders.OrderID; INNER JOIN: Employees.EmployeeID = Orders.EmployeeID (1 → ∞)
SELECT Orders.EmployeeID, Sum(qryOrderTotal.OrderTotal) AS OrderTotal, [Employees].[FirstName] & " " & [Employees].[LastName] AS FullNameFNLN, Format([OrderDate],"mmm-yyyy") AS MonthYear, Format([OrderDate],"yyyy-mm") AS MonthYearSort FROM Employees INNER JOIN (qryOrderTotal INNER JOIN Orders ON qryOrderTotal.OrderID = Orders.OrderID) ON Employees.EmployeeID = Orders.EmployeeID WHERE (((Orders.OrderDate) Between reportParameterStartDate() And reportParameterEndDate())) GROUP BY Orders.EmployeeID, [Employees].[FirstName] & " " & [Employees].[LastName], Format([OrderDate],"mmm-yyyy"), Format([OrderDate],"yyyy-mm");
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Orders.OrderID = OrderDetails.OrderID (1 → ∞); INNER JOIN: Products.ProductID = OrderDetails.ProductID (1 → ∞)
SELECT Products.ProductName, Products.ProductID, Format([OrderDate],"mmm-yyyy") AS MonthYear, Format([OrderDate],"yyyy-mm") AS MonthYearSort, Sum([OrderDetails].[Quantity]*(1-[OrderDetails].[Discount])*[OrderDetails].[UnitPrice]) AS OrderTotal FROM Products INNER JOIN (Orders INNER JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID) ON Products.ProductID = OrderDetails.ProductID WHERE (((Orders.OrderDate) Between reportParameterStartDate() And reportParameterEndDate())) GROUP BY Products.ProductName, Products.ProductID, Format([OrderDate],"mmm-yyyy"), Format([OrderDate],"yyyy-mm");
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Orders.OrderID = OrderDetails.OrderID (1 → ∞); INNER JOIN: Products.ProductID = OrderDetails.ProductID (1 → ∞)
SELECT Products.ProductName, Products.ProductID, Format([OrderDate],"q-yyyy") AS QuarterYear, Sum([OrderDetails].[Quantity]*(1-[OrderDetails].[Discount])*[OrderDetails].[UnitPrice]) AS OrderTotal FROM Products INNER JOIN (Orders INNER JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID) ON Products.ProductID = OrderDetails.ProductID WHERE (((Orders.OrderDate) Between reportParameterStartDate() And reportParameterEndDate())) GROUP BY Products.ProductName, Products.ProductID, Format([OrderDate],"q-yyyy");
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Employees.EmployeeID = Orders.EmployeeID (1 → ∞); INNER JOIN: Orders.OrderID = OrderDetails.OrderID (1 → ∞)
SELECT Sum([Quantity]*[UnitPrice]) AS OrderTotal, Employees.FullNameFNLN AS Expr1 FROM (Employees INNER JOIN Orders ON Employees.EmployeeID = Orders.EmployeeID) INNER JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID WHERE (((Year([OrderDate]))=Year(Date()))) GROUP BY Employees.FullNameFNLN;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: Orders.EmployeeID = qrycboEmployees.EmployeeID; INNER JOIN: Orders.OrderID = qryOrderTotal.OrderID; INNER JOIN: Orders.CustomerID = qrycboCustomers.CompanyID; INNER JOIN: OrderStatus.OrderStatusID = Orders.OrderStatusID (1 → ∞)
SELECT Orders.OrderID, qrycboEmployees.FullNameFNLN AS EmployeeFNLN, Orders.OrderDate, qryOrderTotal.OrderTotal, OrderStatus.OrderStatusName, Orders.CustomerID, Orders.ShipperID AS myCompanyID, qrycboCustomers.CompanyName AS CustomerName FROM OrderStatus INNER JOIN (((Orders INNER JOIN qrycboEmployees ON Orders.EmployeeID = qrycboEmployees.EmployeeID) INNER JOIN qryOrderTotal ON Orders.OrderID = qryOrderTotal.OrderID) INNER JOIN qrycboCustomers ON Orders.CustomerID = qrycboCustomers.CompanyID) ON OrderStatus.OrderStatusID = Orders.OrderStatusID ORDER BY Orders.OrderID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Companies.* FROM Companies WHERE (((Companies.CompanyTypeID)=2));
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT StockTake.StockTakeID, StockTake.StockTakeDate, StockTake.ProductID, StockTake.QuantityOnHand, StockTake.ExpectedQuantity FROM StockTake;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Strings.StringID, Strings.StringData FROM Strings ORDER BY Strings.StringID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT SystemSettings.* FROM SystemSettings ORDER BY SystemSettings.SettingName;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Titles.Title FROM Titles;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT OrderDetails.ProductID, Sum([Quantity]*(1-[Discount])*[UnitPrice]) AS TotalSales FROM OrderDetails GROUP BY OrderDetails.ProductID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
Detected joins: INNER JOIN: PurchaseOrders.SubmittedByID = SumbittedBy.EmployeeID; LEFT JOIN: PurchaseOrders.ApprovedByID = ApprovedBy.EmployeeID; LEFT JOIN: PurchaseOrders.PurchaseOrderID = qryPurchaseOrderCost.PurchaseOrderID; LEFT JOIN: PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID (1 → ∞)
SELECT PurchaseOrders.VendorID AS myCompanyID, PurchaseOrders.PurchaseOrderID, PurchaseOrders.SubmittedByID, PurchaseOrders.SubmittedDate, PurchaseOrders.ApprovedByID, PurchaseOrders.ApprovedDate, PurchaseOrders.StatusID, PurchaseOrders.ReceivedDate, PurchaseOrders.ShippingFee, PurchaseOrders.TaxAmount, PurchaseOrders.PaymentDate, PurchaseOrders.PaymentAmount, PurchaseOrders.PaymentMethod, PurchaseOrders.Notes, PurchaseOrders.AddedBy, PurchaseOrders.AddedOn, PurchaseOrders.ModifiedBy, PurchaseOrders.ModifiedOn, SumbittedBy.FullNameFNLN AS SubmittedBy, ApprovedBy.FullNameFNLN AS ApprovedBy, PurchaseOrderStatus.StatusName, qryPurchaseOrderCost.ExtendedCost FROM PurchaseOrderStatus INNER JOIN (((PurchaseOrders INNER JOIN qrycboEmployees AS SumbittedBy ON PurchaseOrders.SubmittedByID = SumbittedBy.EmployeeID) LEFT JOIN qrycboEmployees AS ApprovedBy ON PurchaseOrders.ApprovedByID = ApprovedBy.EmployeeID) LEFT JOIN qryPurchaseOrderCost ON PurchaseOrders.PurchaseOrderID = qryPurchaseOrderCost.PurchaseOrderID) ON PurchaseOrderStatus.StatusID = PurchaseOrders.StatusID;
Scroll source boxes to see their fields. Lines show inner joins; arrows show outer joins. The join-condition list below gives the exact matching fields. Complex expressions remain available in the SQL below.
SELECT Companies.* FROM Companies WHERE (((Companies.CompanyTypeID)=3));
Documented relationships and their linked fields.
Companies → Contacts
CompanyID → CompanyID
Companies → Orders
CompanyID → CustomerID
Companies → Orders
CompanyID → ShipperID
Companies → ProductVendors
CompanyID → VendorID
Companies → PurchaseOrders
CompanyID → VendorID
CompanyTypes → Companies
CompanyTypeID → CompanyTypeID
Employees → EmployeePrivileges
EmployeeID → EmployeeID
Employees → Employees
EmployeeID → SupervisorID
Employees → MRU
EmployeeID → EmployeeID
Employees → Orders
EmployeeID → EmployeeID
Employees → PurchaseOrders
EmployeeID → ApprovedByID
Employees → PurchaseOrders
EmployeeID → SubmittedByID
OrderDetailStatus → OrderDetails
OrderDetailStatusID → OrderDetailStatusID
Orders → OrderDetails
OrderID → OrderID
OrderStatus → Orders
OrderStatusID → OrderStatusID
Privileges → EmployeePrivileges
PrivilegeID → PrivilegeID
ProductCategories → Products
ProductCategoryID → ProductCategoryID
Products → OrderDetails
ProductID → ProductID
Products → ProductVendors
ProductID → ProductID
Products → PurchaseOrderDetails
ProductID → ProductID
Products → StockTake
ProductID → ProductID
PurchaseOrders → PurchaseOrderDetails
PurchaseOrderID → PurchaseOrderID
PurchaseOrderStatus → PurchaseOrders
StatusID → StatusID
Titles → Employees
Title → Title
States → Companies
StateAbbrev → StateAbbrev
TaxStatus → Companies
TaxStatusID → StandardTaxStatusID
TaxStatus → Orders
TaxStatusID → TaxStatusID
Form settings, controls, labels, event handlers, and interactive layouts.
Record source: No record source
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Title | |||||
| boxHeaderControls | Rectangle | ||||||
| chkDiscontinued | Check box | Discontinued | |||||
| cmdAddOrder | Command button | Header Button | |||||
| cmdCreateInvoice | Command button | Workflow Button | |||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/40c61470-c7c4-4fdb-9f90-d9af2a807c7a | ||||
| Command198 | Command button | Header Button | |||||
| ctlInventorySubform | Subform/Subreport | ||||||
| ctlOrderSubform | Subform/Subreport | ||||||
| ctlPOSubform | Subform/Subreport | ||||||
| ctlVendorSubform | Subform/Subreport | ||||||
| CustomerID | Combo box | qrycboCustomers | |||||
| imgNorthwindTradersLogo | Image | ||||||
| Label15 | Label | Combobox | |||||
| Label152 | Label | TIP: Use Shift+F2 for Zoom window | |||||
| Label200 | Label | Hyperlink Textbox | |||||
| Label48 | Label | MultiLine Text | |||||
| Label9 | Label | Textbox | |||||
| lblDiscontinued | Label | Discontinued | |||||
| lblOrderLineItems | Label | SubTitle | |||||
| Notes | Text box | Notes | |||||
| OrderID | Text box | ||||||
| pgInventory | Page | Stock Takes | |||||
| pgOrders | Page | Customer Orders | |||||
| PgPurchaseOrders | Page | Purchase Orders | |||||
| pgVendors | Page | Product Vendors | |||||
| tabProducts | Tab control | ||||||
| Text199 | Text box | OrderID | |||||
| txtModified | Text box |
Record source: No record source
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Title0 | Label | About Northwind Dev Edition | ||||
| Box254 | Rectangle | |||||
| Box255 | Rectangle | |||||
| Box256 | Rectangle | |||||
| Box257 | Rectangle | |||||
| Box258 | Rectangle | |||||
| Box259 | Rectangle | |||||
| cmdClose | Command button | Close | Click: cmdClose_Click | |||
| imgNorthwindTradersLogo | Image | |||||
| lblVersion | Label | Release Date Sep-2025; Version 2.5 | ||||
| txtAbout | Text box | =GetString(41) |
Private Sub cmdClose_Click() 10 On Error GoTo Err_Handler 20 DoCmd.Close acForm, Me.Name Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdClose_Click", True 50 Resume Exit_Handler End Sub
Record source: No record source
Has VBA module
Events — OnOpen: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Box35 | Rectangle | |||||
| Box41 | Rectangle | |||||
| Box44 | Rectangle | |||||
| Box47 | Rectangle | |||||
| Box58 | Rectangle | |||||
| Box61 | Rectangle | |||||
| Box66 | Rectangle | |||||
| Box70 | Rectangle | |||||
| cmdDeleteTestData | Command button | Delete Test Data | Click: cmdDeleteTestData_Click | |||
| cmdInternetOrders | Command button | Internet Orders | Click: cmdInternetOrders_Click | |||
| cmdPrivileges | Command button | Privileges | Click: cmdPrivileges_Click | |||
| cmdProductCategories | Command button | Product Categories | Click: cmdProductCategories_Click | |||
| cmdRelationshipsDiagram | Command button | Relationships Diagram | ||||
| cmdResetDates | Command button | Reset Dates | Click: cmdResetDates_Click | |||
| cmdStrings | Command button | Strings | Click: cmdStrings_Click | |||
| cmdSystemSettings | Command button | System Settings | Click: cmdSystemSettings_Click | |||
| Label69 | Label | Table Maintenance | ||||
| Label72 | Label | |||||
| lblEmployeesSub | Label | |||||
| lblInternetOrdersSub | Label | Last 30 days: 0 | ||||
| lblPrivilegesSub | Label | Count: 1 | ||||
| lblResetDatesSub | Label | Last Reset: 12/17/2022 | ||||
| lblStringsSub | Label | Count: 46 | ||||
| lblSystemSettingsSub | Label | Count: 4 | ||||
| sfrmAdmin | Subform/Subreport |
Private Sub cmdDeleteTestData_Click()
10 On Error GoTo Err_Handler
' _AXL:<?xml version="1.0" encoding="UTF-16" standalone="no"?>
' <UserInterfaceMacro For="cmdPrivileges" Event="OnClick" xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><Statements><Action Name="SetValue"><Argument Name="Item
' _AXL:">[sfrmAdmin].[SourceObject]</Argument><Argument Name="Expression">"sfrmEmployee_Privileges"</Argument></Action></Statements></UserInterfaceMacro>
20 sfrmAdmin.SourceObject = "sfrmAdmin_DeleteTestData"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdDeleteTestData_Click", True
50 Resume Exit_Handler
End Sub
'This module was created by converting Macro Code (see design ribbon far right)
'The comments inside the module were created by the conversion process
'We added the error handling
'------------------------------------------------------------
' cmdInternetOrders_Click
'
'------------------------------------------------------------Private Sub cmdInternetOrders_Click()
10 On Error GoTo Err_Handler
' _AXL:<?xml version="1.0" encoding="UTF-16" standalone="no"?>
' <UserInterfaceMacro For="cmdSystemSettings" xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><Statements><Action Name="SetValue"><Argument Name="Item">[sfrmAdmin
' _AXL:].[SourceObject]</Argument><Argument Name="Expression">"sfrmAdmin_SystemSettings"</Argument></Action></Statements></UserInterfaceMacro>
20 sfrmAdmin.SourceObject = "sfrmAdmin_InternetOrders"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdInternetOrders_Click", True
50 Resume Exit_Handler
End Sub
'This module was created by converting Macro Code (see design ribbon far right)
'The comments inside the module were created by the conversion process
'We added the error handling
'------------------------------------------------------------
' cmdPrivileges_Click
'
'------------------------------------------------------------Private Sub cmdPrivileges_Click()
10 On Error GoTo Err_Handler
' _AXL:<?xml version="1.0" encoding="UTF-16" standalone="no"?>
' <UserInterfaceMacro For="cmdStrings" Event="OnClick" xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><Statements><Action Name="SetValue"><Argument Name="Item">[
' _AXL:sfrmAdmin].[SourceObject]</Argument><Argument Name="Expression">"sfrmAdmin_Strings"</Argument></Action></Statements></UserInterfaceMacro>
20 sfrmAdmin.SourceObject = "sfrmEmployee_Privileges"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdPrivileges_Click", True
50 Resume Exit_Handler
End SubPrivate Sub cmdProductCategories_Click() 10 On Error GoTo Err_Handler 20 Me.sfrmAdmin.SourceObject = "sfrmProductCategories" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdProductCategories_Click", True 50 Resume Exit_Handler End Sub
Private Sub cmdRelationshipsDiagram_Click()
10 On Error GoTo Err_Handler
Dim strMsg As String
20 strMsg = "At the time of release of this template, the ACCDT process which creates the Access Template, does not preserve the layout of the Relationships window. " & _
"We included this report so you can see it laid out as was intended."
30 MsgBox strMsg, vbInformation
40 DoCmd.OpenReport "rptRelationshipsWindow", acViewReport
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "cmdRelationshipsDiagram_Click", True
70 Resume Exit_Handler
End Sub
'This module was created by converting Macro Code (see design ribbon far right)
'The comments inside the module were created by the conversion process
'We added the error handling
'------------------------------------------------------------
' cmdResetDates_Click
'
'------------------------------------------------------------Private Sub cmdResetDates_Click()
10 On Error GoTo Err_Handler
' _AXL:<?xml version="1.0" encoding="UTF-16" standalone="no"?>
' <UserInterfaceMacro For="cmdInternetOrders" xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><Statements><Action Name="SetValue"><Argument Name="Item">[sfrmAdmin
' _AXL:].[SourceObject]</Argument><Argument Name="Expression">"sfrmAdmin_InternetOrders"</Argument></Action></Statements></UserInterfaceMacro>
20 sfrmAdmin.SourceObject = "sfrmAdmin_ResetDates"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdResetDates_Click", True
50 Resume Exit_Handler
End Sub
'This module was created by converting Macro Code (see design ribbon far right)
'The comments inside the module were created by the conversion process
'We added the error handling
'------------------------------------------------------------
' cmdStrings_Click
'
'------------------------------------------------------------Private Sub cmdStrings_Click()
10 On Error GoTo Err_Handler
' _AXL:<?xml version="1.0" encoding="UTF-16" standalone="no"?>
' <UserInterfaceMacro For="cmdResetDates" xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><Statements><Action Name="SetValue"><Argument Name="Item">[sfrmAdmin].[S
' _AXL:ourceObject]</Argument><Argument Name="Expression">"sfrmAdmin_ResetDates"</Argument></Action></Statements></UserInterfaceMacro>
20 sfrmAdmin.SourceObject = "sfrmAdmin_Strings"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdStrings_Click", True
50 Resume Exit_Handler
End Sub
'This module was created by converting Macro Code (see design ribbon far right)
'The comments inside the module were created by the conversion process
'We added the error handling
'------------------------------------------------------------
' cmdSystemSettings_Click
'
'------------------------------------------------------------Private Sub cmdSystemSettings_Click() 10 On Error GoTo Err_Handler 20 sfrmAdmin.SourceObject = "sfrmAdmin_SystemSettings" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdSystemSettings_Click", True 50 Resume Exit_Handler End Sub
Private Sub Form_Open(Cancel As Integer) 10 On Error GoTo Err_Handler 20 UpdateSubLabels Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_Open", True 50 Resume Exit_Handler End Sub 'NOTE: ' Public so the various subforms can update these labels as well.
Public Sub UpdateSubLabels()
10 On Error GoTo Err_Handler
20 Me.lblSystemSettingsSub.Caption = "Count: " & DCount("*", "SystemSettings")
30 Me.lblInternetOrdersSub.Caption = "Last 30 days: " & DCount("*", "Orders", StringFormatSQL("EmployeeID = {0} and OrderDate > {1}", INTERNET_SALES_EMPLOYEEID, DateAdd("d", -30, Date)))
40 Me.lblResetDatesSub.Caption = "Last Reset: " & GetSystemSetting(ssLastResetDate)
50 Me.lblStringsSub.Caption = "Count: " & DCount("*", "Strings")
60 Me.lblPrivilegesSub.Caption = "Count: " & DCount("*", "Privileges")
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "UpdateSubLabels"
90 Resume Exit_Handler
End SubRecord source: qryCompanies
Has VBA module
Events — OnOpen: [Event Procedure], OnLoad: [Event Procedure], OnCurrent: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Default value | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|---|
| boxHeaderControls | Rectangle | |||||||
| cboCompanyTypeID | Combo box | CompanyTypeID | 1 | qrycboCompanyType | ||||
| cboStandardTaxStatusID | Combo box | StandardTaxStatusID | qrycboTaxStatus | |||||
| cboState | Combo box | StateAbbrev | qrycboStates | |||||
| cmdAdd | Command button | Add | Click: cmdAdd_Click | |||||
| cmdCancel | Command button | Cancel | Click: cmdCancel_Click | |||||
| cmdClickToMap | Command button | Map | Click: cmdClickToMap_Click | |||||
| cmdDeleteCompany | Command button | Delete Company | Click: cmdDeleteCompany_Click | |||||
| cmdEmail | Command button | Email Company List | Click: cmdEmail_Click | |||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/9b03e070-1710-4cb8-9dcd-3208e84180d4 | |||||
| cmdSave | Command button | Save | Click: cmdSave_Click | |||||
| cmdShowFilter | Command button | Show Filter | Click: cmdShowFilter_Click | |||||
| imgHelp | Image | |||||||
| imgLogo | Image | |||||||
| lblBusinessPhone | Label | Phone | ||||||
| lblCity | Label | City | ||||||
| lblCompanyID | Label | CompanyID | ||||||
| lblCompanyName | Label | Company | ||||||
| lblCompanyTypeID | Label | Type | ||||||
| lblNotes | Label | Notes (Rich Text) | ||||||
| lblsfrmCompanyDetail_Contact | Label | Contacts | ||||||
| lblsfrmOrders | Label | Orders | ||||||
| lblState | Label | State | ||||||
| lblTaxStatus | Label | Tax Status | ||||||
| lbltxtAddress | Label | Address | ||||||
| lblWebsite | Label | Website | ||||||
| lblWebsiteTip | Label | TIP: Right Click to Edit the Hyperlink | ||||||
| lblZip | Label | Zip | ||||||
| lblZoomTip | Label | TIP: Use Shift+F2 for Zoom window | ||||||
| sfrmCompanyDetail_Contacts | Subform/Subreport | sfrmCompanyDetail_Contacts | ||||||
| sfrmOrders | Subform/Subreport | sfrmCompanyDetail_CustomerOrders | ||||||
| txtAddress | Text box | Address | ||||||
| txtBusinessPhone | Text box | BusinessPhone | Click: txtBusinessPhone_Click | |||||
| txtCity | Text box | City | ||||||
| txtCompanyID | Text box | CompanyID | ||||||
| txtCompanyName | Text box | CompanyName | ||||||
| txtCompanyType | Text box | =[cboCompanyTypeID].[Column](1) | ||||||
| txtHeaderCompanyName | Text box | =[CompanyName] | "KimsCompany" | |||||
| txtModified | Text box | =RecordModifiedString([AddedBy],[AddedOn],[ModifiedBy],[ModifiedOn]) | ||||||
| txtNotes | Text box | Notes | ||||||
| txtWebsite | Text box | Website | Double-click: txtWebsite_DblClick | |||||
| txtZip | Text box | Zip |
Private Sub cboCompanyTypeID_AfterUpdate() 10 On Error GoTo Err_Handler 20 ManageFormOptions Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cboCompanyTypeID_AfterUpdate", True 50 Resume Exit_Handler End Sub
Private Sub cboCompanyTypeID_BeforeUpdate(Cancel As Integer)
10 On Error GoTo Err_Handler
Dim strDlgMsg As String
Dim strOpenArgs As String
'BUSINESS RULE:
' If the Company has any existing Orders, Purchase Orders, or Product Vendors
' the user cannot change the Company Type
20 If CompanyIsActive = True Or m_lngVendorProductCount > 0 Then
' strDlgMsg = "You can not change the Company Type if the Company has<br />" & _
' " Customer Orders (" & m_lngCustomerOrderCount & ") <br />" & _
' " Shipper Orders (" & m_lngShipperOrderCount & ") <br />" & _
' " Vendor Purchase Orders (" & m_lngVendorPurchaseOrderCount & ") <br />" & _
' " Vendor Products (" & m_lngVendorProductCount & ") <br />"
30 strDlgMsg = GetString(sCompanyDelete_CompanyTypeChange, "change the Company Type", m_lngCustomerOrderCount, m_lngShipperOrderCount, m_lngVendorPurchaseOrderCount, "Vendor Products (" & m_lngVendorProductCount & ")")
40 strOpenArgs = StringFormat("Header={0}&Message={1}&Actions={2}&FormCaption={3}", "Company Type Change Not Allowed", strDlgMsg, "vbOK", m_strMsgCaption)
50 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
60 If IsFormOpen("frmGenericDialog") Then
70 DoCmd.Close acForm, "frmGenericDialog", acSaveNo
80 End If
90 Me.cboCompanyTypeID.Undo
100 Cancel = True
110 End If
Exit_Handler:
120 Exit Sub
Err_Handler:
130 clsErrorHandler.HandleError Me.Name, "cboCompanyTypeID_BeforeUpdate", True
140 Resume Exit_Handler
End SubPrivate Sub cmdAdd_Click() 10 On Error GoTo Err_Handler 20 If Me.NewRecord Then 30 MsgBox GetString(sAlreadyOnNewRecord), vbInformation 40 Else 50 RunCommand acCmdRecordsGoToNew 60 End If Exit_Handler: 70 Exit Sub Err_Handler: 80 clsErrorHandler.HandleError Me.Name, "cmdAdd_Click", True 90 Resume Exit_Handler End Sub
Private Sub cmdCancel_Click()
10 On Error GoTo Err_Handler
20 If m_lngCalledFromID = 0 Then
'Add Company was requested by frmCompanyList
30 DoCmd.Close acForm, Me.Name
40 Else
50 If Not IsNull(Me.CompanyID) Then
60 If Me.Dirty Then
70 Me.Undo
80 End If
90 End If
100 DoCmd.SearchForRecord acDataForm, Me.Name, acFirst, "CompanyID = " & m_lngCalledFromID
110 End If
Exit_Handler:
120 Exit Sub
Err_Handler:
130 clsErrorHandler.HandleError Me.Name, "cmdCancel_Click", True
140 Resume Exit_Handler
End SubPrivate Sub cmdClickToMap_Click()
10 On Error GoTo Err_Handler
Dim strBusinessAddress As String
'Concatenate the Address into a single string to pass to the mapping function
20 strBusinessAddress = Me.[Address] & Space(2) & Me.[City] & ", " & Me.[StateAbbrev] & Space(2) & Me.[Zip]
30 Application.FollowHyperlink "http://maps.live.com/default.aspx?where1=" & strBusinessAddress
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "cmdClickToMap_Click", True
60 Resume Exit_Handler
End SubPrivate Sub cmdDeleteCompany_Click()
'Companies can be deleted two ways
' 1) User clicks on the Delete Company button (this code executes)
' 2) User clicks on the record selector (grey vertical bar on the lfst side of the screen)
' and then hits the Delete key and the Form_Delete event fires
'
'When this code executes the RunCommand acCmdDeleteRecord
' the Form_Delete event executes same as option 2
'
'All logic for validating the delete request will be found in the Form_Delete event
10 On Error Resume Next
20 RunCommand acCmdDeleteRecord
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdDeleteCompany_Click"
50 Resume Exit_Handler
End SubPrivate Sub cmdEmail_Click() 10 On Error GoTo Err_Handler 20 DoCmd.RunCommand acCmdSend Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdEmail_Click", True 50 Resume Exit_Handler End Sub
Private Sub cmdSave_Click()
10 On Error GoTo Err_Handler
Dim Cancel As Integer '
'If you use DoCmd.RunCommand acCmdSaveRecord it will ALWAYS attempt a save
'DoCmd.RunCommand acCmdSaveRecord
'If you use Me.Dirty, it will ONLY attempt a save if there is something to save
20 Cancel = ValidateForm(Me)
30 If Not Cancel Then
'The form is valid. Save it.
40 If Me.Dirty Then Me.Dirty = False
50 ValidateForm_RemoveHighlights Me
60 End If
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "cmdSave_Click", True
90 Resume Exit_Handler
End SubPrivate Sub cmdShowFilter_Click()
10 On Error GoTo Err_Handler
Dim strOpenArgs As String
Dim strFilter As String
20 If Me.Form.FilterOn = True Then
30 strFilter = Me.Form.Filter
40 strFilter = Replace(strFilter, "[Lookup_cboCompanyTypeID].", "")
50 strFilter = Replace(strFilter, "[Lookup_cboState].", "")
60 strFilter = Replace(strFilter, "[Lookup_cboStandardTaxStatusID].", "")
70 strFilter = Replace(strFilter, "[qryCompanies].", "")
80 strOpenArgs = StringFormat("Header={0}&Message={1}&Actions={2}&FormCaption={3}", "Form Filter", strFilter, "vbOK", m_strMsgCaption)
90 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
100 If IsFormOpen("frmGenericDialog") Then
110 DoCmd.Close acForm, "frmGenericDialog", acSaveNo
120 End If
130 Else
140 MsgBox "This form has not been filtered.", vbOKOnly Or vbInformation
150 End If
Exit_Handler:
160 Exit Sub
Err_Handler:
170 clsErrorHandler.HandleError Me.Name, "cmdShowFilter_Click", True
180 Resume Exit_Handler
End SubPrivate Sub CompanyCantBeDeleted()
10 On Error GoTo Err_Handler
Dim strDlgMsg As String
Dim strOpenArgs As String
20 strDlgMsg = GetString(sCompanyDelete_CompanyTypeChange, "delete the Company", m_lngCustomerOrderCount, m_lngShipperOrderCount, m_lngVendorPurchaseOrderCount, "")
30 strOpenArgs = StringFormat("Header={0}&Message={1}&Actions={2}&FormCaption={3}", "Company Delete Not Allowed", strDlgMsg, "vbOK", m_strMsgCaption)
40 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
50 If IsFormOpen("frmGenericDialog") Then
60 DoCmd.Close acForm, "frmGenericDialog", acSaveNo
70 End If
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError Me.Name, "CompanyCantBeDeleted"
100 Resume Exit_Handler
End SubPrivate Function CompanyConfirmDelete() As Boolean
10 On Error GoTo Err_Handler
Dim strDlgMsg As String
Dim strOpenArgs As String
20 If m_lngCompanyContactCount > 0 Or m_lngVendorProductCount > 0 Then
'Confirm the Users intention to delete if they have Contacts or are a Product Vendor
30 strDlgMsg = "If you delete the Company any <br />" & _
" Contacts (" & m_lngCompanyContactCount & ")or Product Vendors (" & m_lngVendorProductCount & ") will be deleted.<br /><br />" & _
"Is this OK?"
40 strOpenArgs = StringFormat("Header={0}&Message={1}&FormCaption={2}&Actions={3}", "Confirm Delete", strDlgMsg, m_strMsgCaption, "vbOKCancel")
50 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
60 Else
'Confirm the Users intention to delete
70 strDlgMsg = "Are you sure you want to delete this Company?"
80 strOpenArgs = StringFormat("Header={0}&Message={1}&FormCaption={2}&Actions={3}", _
"Confirm Delete", strDlgMsg, m_strMsgCaption, "vbYesNo")
90 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
100 End If
110 If IsFormOpen("frmGenericDialog") Then
'User Clicked OKAY
120 CompanyConfirmDelete = True
130 DoCmd.Close acForm, "frmGenericDialog", acSaveNo
140 Else
150 CompanyConfirmDelete = False
160 End If
Exit_Handler:
170 Exit Function
Err_Handler:
180 clsErrorHandler.HandleError Me.Name, "CompanyConfirmDelete"
190 Resume Exit_Handler
End FunctionPrivate Function CompanyIsActive() As Boolean
10 On Error GoTo Err_Handler
Dim lngCount As Long
'BUSINESS RULE:
'Check All Foreign Key Relationships
'A Company Is Active it they have Orders or Purchase Orders
'We wont check Contacts or Product Vendors, because we can
' delete those for the end user if there are no Orders or Purchase Orders
' We count these so we know if we need to delete them
20 m_lngCompanyContactCount = DCount("*", "Contacts", StringFormatSQL("CompanyID={0}", Me.CompanyID))
30 m_lngCustomerOrderCount = DCount("*", "Orders", StringFormatSQL("CustomerID={0}", Me.CompanyID))
40 m_lngShipperOrderCount = DCount("*", "Orders", StringFormatSQL("ShipperID={0}", Me.CompanyID))
50 m_lngVendorPurchaseOrderCount = DCount("*", "PurchaseOrders", StringFormatSQL("VendorID={0}", Me.CompanyID))
60 m_lngVendorProductCount = DCount("*", "ProductVendors", StringFormatSQL("VendorID={0}", Me.CompanyID))
'Get the Count of Active Orders or Purchase Orders
70 lngCount = m_lngCustomerOrderCount + m_lngShipperOrderCount + m_lngVendorPurchaseOrderCount
80 If lngCount > 0 Then
90 CompanyIsActive = True
100 Else
110 CompanyIsActive = False
120 End If
Exit_Handler:
130 Exit Function
Err_Handler:
140 clsErrorHandler.HandleError Me.Name, "CompanyIsActive"
150 Resume Exit_Handler
End FunctionPrivate Sub Form_AfterDelConfirm(Status As Integer)
10 On Error GoTo Err_Handler
20 Select Case Status
Case acDeleteOK
30 MsgBox "Deleted!", vbInformation Or vbOKOnly
40 If IsFormOpen("frmCompanyList") = True Then
50 Forms("frmCompanyList").Requery
60 End If
70 End Select
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError Me.Name, "Form_AfterDelConfirm", True
100 Resume Exit_Handler
End SubPrivate Sub Form_AfterInsert()
10 On Error GoTo Err_Handler
20 If IsFormOpen("frmCompanyList") = True Then
30 Forms("frmCompanyList").Requery
40 Me.SetFocus
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True
80 Resume Exit_Handler
End SubPrivate Sub Form_AfterUpdate()
10 On Error GoTo Err_Handler
'In case there are any left over
20 ValidateForm_RemoveHighlights Me
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True
50 Resume Exit_Handler
End SubPrivate Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
10 On Error GoTo Err_Handler
'https://docs.microsoft.com/previous-versions/office/developer/office-2003/aa211249(v=office.11)
'The link above is for Access 2003 but how this event works has not changed
'and this document gives a good explanation
'Access will ask the User to confirm the Delete action
'We want to Display our own message box - not the default one
'To do that we set the response to acDataErrContinue
20 Response = acDataErrContinue
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "Form_BeforeDelConfirm", True
50 Resume Exit_Handler
End SubPrivate Sub Form_BeforeUpdate(Cancel As Integer)
10 On Error GoTo Err_Handler
'This is an example where the business rules are such that saving a record needs to be confirmed.
20 If MsgBox(GetString(sDoYouWantToSaveYourChanges), vbQuestion Or vbYesNo, "Save Your Changes?") = vbNo Then
30 Me.Undo
40 Else
50 Cancel = ValidateForm(Me)
60 End If
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True
90 Resume Exit_Handler
End SubPrivate Sub Form_Current()
10 On Error GoTo Err_Handler
20 If Not Me.NewRecord Then m_lngCalledFromID = Me.CompanyID
30 ManageFormOptions
'In case there are any left over
40 ValidateForm_RemoveHighlights Me
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "Form_Current", True
70 Resume Exit_Handler
End SubPrivate Sub Form_Delete(Cancel As Integer)
10 On Error GoTo Err_Handler
Dim strSQL As String
'BUSINESS RULE:
' If the Company has any existing Orders or Purchase Orders
' the User can not delete the Company
20 If CompanyIsActive = True Then
30 CompanyCantBeDeleted
40 Cancel = True
50 GoTo Exit_Handler
60 End If
'Confirm the User Delete Request
70 If CompanyConfirmDelete Then
80 If m_lngCompanyContactCount > 0 Then
90 strSQL = StringFormatSQL("Delete from Contacts where CompanyID = {0}", Me.txtCompanyID.Value)
100 g_dbApp().Execute strSQL, dbFailOnError
110 End If
120 If m_lngVendorProductCount > 0 Then
130 strSQL = StringFormatSQL("Delete from ProductVendors where VendorID = {0}", Me.txtCompanyID.Value)
140 g_dbApp().Execute strSQL, dbFailOnError
150 End If
160 Else
170 Cancel = True
180 Exit Sub
190 End If
Exit_Handler:
200 Exit Sub
Err_Handler:
210 clsErrorHandler.HandleError Me.Name, "Form_Delete", True
220 Resume Exit_Handler
End Sub
'==================================================================
'Using the Calling Form Filter
'==================================================================
'
'The form frmCompanyList is rich with opportunities
' to filter the Companies in Northwind.
'
'There is an option group at the top of the form to
' filter the results by the type of Company
'
'The user can right click in any field to access
' a variety built in filtering options and
' multiple columns can be filtered
'
'Once the data has been filtered to the subset
' the user wants to review, double click
' anywhere in frmCompanyList to open this form
'
'Open this form with only the records which match
' the subset created in frmCompanyList
'
'To achieve that we are using the filter from
' frmCompanyList
'
'But it's not that simple. The data on
' frmCompanyList is denormalized and the
' data on this form is not (so we can do data entry)
'
'If the filter from frmCompanyList looks like this
'
' ([CompanyType]<>"Vendor" Or [CompanyType] IS Null)
'
' and the field CompanyType is not in the table Company
' (CompanyTypeID is) how can we use the filter passed in?
'
'Look at the query for this form and you will see how
' we got the fields we needed to be able to apply the
' filter and kept the query updateable
'
'==================================================================Private Sub Form_Load()
10 On Error GoTo Err_Handler
Dim dict As Scripting.Dictionary
Dim key As Variant
Dim lngOpenArgCompanyID As Long
Dim strOpenArgAction As String
Dim strOpenArgCompanyName As String
Dim strOpenArgCompanyTypeID As String
Dim strOpenArgPassedFilter As String
Dim strFormWhere As String
'===================================================================================================
'NOTE:
'Often, we need to take different actions depending on the circumstances
'For example, If a first time Customer give a 10% discount
'This type of programming is referred to as Branching or Conditional Execution.
'
'This form provided the opportunity to demonstrate 4 different
' approaches to Branching or Conditional Execution
'===================================================================================================
'Parse OpenArgs
'Split the String created by frmCompanyList into Key Value Pairs
'Key Value Pairs are a set of two data items - a KEY and a VALUE
'To see how the string is broken into the Key Value Pairs look at
' StringToDictionary function in Northwind
'Option 1 - Case Statement
' Populate the correct variable based on the KEY
'https://docs.microsoft.com/office/vba/Language/Reference/User-Interface-Help/select-case-statement
'Initialize the module level variable
20 m_lngCalledFromID = 0 'Indicates List Form
30 m_strMsgCaption = "Message from Company"
40 If IsNull(Me.OpenArgs) Then
'Form is opened without any specific instructions in OpenArgs.
50 Else
'Parse Open Args into a Dictionary Object
60 Set dict = StringToDictionary(Me.OpenArgs)
'Loop thru the Dictionary object
70 For Each key In dict.Keys
80 Select Case key
Case "Action"
90 strOpenArgAction = dict.Item(key)
100 Case "CompanyName"
110 strOpenArgCompanyName = dict.Item(key)
120 Case "CompanyTypeID"
130 strOpenArgCompanyTypeID = dict.Item(key)
140 Case "CompanyID"
150 lngOpenArgCompanyID = dict.Item(key)
160 Case "PassedFilter"
170 strOpenArgPassedFilter = dict.Item(key)
180 Case "[frmOrderDetails]![CustomerID]" 'Opened from the OrderDetails form, entering a new company in the dropdown.
190 strOpenArgCompanyName = dict.Item(key)
200 strOpenArgAction = "Add"
210 End Select
220 Next key
230 Set dict = Nothing
240 End If
'Process In This Order. Don't switch these options around.
'Option 2 - Nested If Else
' Build mFormWhere
'https://docs.microsoft.com/office/vba/Language/Concepts/Getting-Started/using-ifthenelse-statements
250 If Len(strOpenArgCompanyTypeID) > 0 Then
260 If Len(strOpenArgCompanyTypeID) = 1 Then
270 Me.cboCompanyTypeID.DefaultValue = strOpenArgCompanyTypeID
280 strFormWhere = "CompanyTypeID = " & strOpenArgCompanyTypeID
290 Else
300 strFormWhere = "CompanyTypeID " & strOpenArgCompanyTypeID
310 End If
320 End If
'Option 3 - ElseIf
'https://docs.microsoft.com/office/vba/Language/Concepts/Getting-Started/using-ifthenelse-statements
'See the comment Using the Parent Form Filter at the top of this module
330 If Len(strOpenArgPassedFilter) > 0 Then
340 Me.Filter = strOpenArgPassedFilter
350 Me.FilterOn = True
360 ElseIf Len(strFormWhere) > 0 Then
370 Me.Filter = strFormWhere 'No Passed Filter use strFormWhere
380 Me.FilterOn = True
390 Else
400 Me.FilterOn = False
410 End If
'Option 4 - Nested If Else and ElseIF
'https://docs.microsoft.com/office/vba/Language/Concepts/Getting-Started/using-ifthenelse-statements
420 If Len(strOpenArgAction) > 0 Then
430 If strOpenArgAction = "Add" Then
440 DoCmd.GoToRecord acDataForm, Me.Name, acNewRec
450 If Len(strOpenArgCompanyName) > 0 Then
460 Me.txtCompanyName = strOpenArgCompanyName
470 End If
480 Else
'The provided Action is unexpected
'Tell the user this has happened
490 MsgBox "An unknown action has been requested. " & vbCrLf & vbCrLf & "Please let IT know this has happened and that action is : " & strOpenArgAction, vbOKOnly Or vbCritical, "Contact IT"
500 End If
510 ElseIf Len(lngOpenArgCompanyID) > 0 Then
520 DoCmd.SearchForRecord acDataForm, Me.Name, acFirst, "CompanyID = " & lngOpenArgCompanyID
530 m_lngCalledFromID = lngOpenArgCompanyID
540 End If
Exit_Handler:
550 Exit Sub
Err_Handler:
560 clsErrorHandler.HandleError Me.Name, "Form_Load", True
570 Resume Exit_Handler
End SubPrivate Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
'Clean up anything left by a previous session
'In order to have the clear the filter, you need 2 lines of code as shown below, and they must happen in this order.
'https://stackoverflow.com/questions/59954653/vba-ms-access-remove-form-filter
20 Me.FilterOn = False
30 Me.Filter = ""
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "Form_Open", True
60 Resume Exit_Handler
End SubPrivate Sub ManageFormOptions()
10 On Error GoTo Err_Handler
20 With Me
30 .sfrmOrders.SourceObject = ""
40 .Caption = .txtCompanyType.Value
'Set the subform in the upper right section based on Company Type
50 Select Case .cboCompanyTypeID.Value
Case enumCompanyType.ctCustomer
60 .sfrmOrders.SourceObject = "sfrmCompanyDetail_CustomerOrders"
70 .lblsfrmOrders.Caption = "Orders"
80 Case enumCompanyType.ctShipper
90 .sfrmOrders.SourceObject = "sfrmCompanyDetail_ShipperOrders"
100 .lblsfrmOrders.Caption = "Orders Shipped"
110 Case enumCompanyType.ctVendor
120 .sfrmOrders.SourceObject = "sfrmCompanyDetail_VendorPurchaseOrders"
130 .lblsfrmOrders.Caption = "Purchase Orders"
140 Case enumCompanyType.ctNorthwind
150 .sfrmOrders.SourceObject = "" 'Northwind itself does not place orders.
160 .lblsfrmOrders.Caption = ""
170 Case Else
180 Debug.Assert False 'Unexpected company type is not yet implemented.
190 End Select
200 End With
Exit_Handler:
210 Exit Sub
Err_Handler:
220 clsErrorHandler.HandleError Me.Name, "ManageFormOptions"
230 Resume Exit_Handler
End SubPrivate Sub txtBusinessPhone_Click()
10 On Error GoTo Err_Handler
'If the Phone has not been populated yet
'position the cursor to the beginning of the field no matter where the user clicked
20 If Len(Me.txtBusinessPhone) = 0 Then
30 Me.txtBusinessPhone.SelStart = 0
40 End If
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "txtBusinessPhone_Click", True
70 Resume Exit_Handler
End SubPrivate Sub txtWebsite_DblClick(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Application.FollowHyperlink Me.txtWebsite Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "txtWebsite_DblClick", True 50 Resume Exit_Handler End Sub
Record source: qryCompanyList
Has VBA module
Events — OnOpen: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Default value | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Companies | ||||||
| BoxCaptions | Rectangle | |||||||
| cmdAddNew | Command button | Add Company | Click: cmdAddNew_Click | |||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/9b03e070-1710-4cb8-9dcd-3208e84180d4 | |||||
| cmdLabelWizard | Command button | Create Labels | Click: cmdLabelWizard_Click | |||||
| cmdShowFilter | Command button | Show Filter | Click: cmdShowFilter_Click | |||||
| cmdShowHideFields | Command button | Show/Hide Fields | Click: cmdShowHideFields_Click | |||||
| CompanyType | Text box | CompanyType | Double-click: =Open_frmCompanyDetail("") | |||||
| EmptyCell205 | Empty cell | |||||||
| EmptyCell213 | Empty cell | |||||||
| EmptyCell221 | Empty cell | |||||||
| EmptyCell229 | Empty cell | |||||||
| fraFilter | Option group | 0 | ||||||
| imgNorthwindTradersLogo | Image | |||||||
| Label126 | Label | All | ||||||
| Label128 | Label | Customers | ||||||
| Label130 | Label | Shippers | ||||||
| Label132 | Label | Vendors | ||||||
| Label62 | Label | CompanyType | ||||||
| Label77 | Label | TaxStatus | ||||||
| lblAddedBy | Label | Added By | ||||||
| lblAddedOn | Label | Added On | ||||||
| lblAddress | Label | Address | ||||||
| lblBusinessAddress | Label | Business Address | ||||||
| lblBusinessPhone | Label | Business Phone | ||||||
| lblCity | Label | City | ||||||
| lblCompanyID | Label | ID | ||||||
| lblCompanyName | Label | Customer Name | ||||||
| lblFilterBy | Label | Filter By | ||||||
| lblModifiedBy | Label | Modified By | ||||||
| lblModifiedOn | Label | Modified On | ||||||
| lblNotes | Label | Notes | ||||||
| lblState | Label | State | ||||||
| lblWebsite | Label | Website | ||||||
| lblZip | Label | Zip | ||||||
| Option125 | Option button | |||||||
| Option127 | Option button | |||||||
| Option129 | Option button | |||||||
| Option131 | Option button | |||||||
| TaxStatus | Text box | TaxStatus | Double-click: =Open_frmCompanyDetail("") | |||||
| txtAddedBy | Text box | AddedBy | Double-click: =Open_frmCompanyDetail("") | |||||
| txtAddedOn | Text box | AddedOn | Double-click: =Open_frmCompanyDetail("") | |||||
| txtAddress | Text box | Address | Double-click: =Open_frmCompanyDetail("") | |||||
| txtBusinessAddress | Text box | BusinessAddress | Double-click: =Open_frmCompanyDetail("") | |||||
| txtBusinessPhone | Text box | BusinessPhone | Double-click: =Open_frmCompanyDetail("") | |||||
| txtCity | Text box | City | Double-click: =Open_frmCompanyDetail("") | |||||
| txtCompanyID | Text box | CompanyID | Click: txtCompanyID_Click | |||||
| txtCompanyName | Text box | CompanyName | Double-click: =Open_frmCompanyDetail("") | |||||
| txtModifiedBy | Text box | ModifiedBy | ||||||
| txtModifiedOn | Text box | ModifiedOn | Double-click: =Open_frmCompanyDetail("") | |||||
| txtNotes | Text box | Notes | Double-click: =Open_frmCompanyDetail("") | |||||
| txtState | Text box | StateAbbrev | Double-click: =Open_frmCompanyDetail("") | |||||
| txtWebsite | Text box | Website | ||||||
| txtZip | Text box | Zip | Double-click: =Open_frmCompanyDetail("") |
Private Sub cmdAddNew_Click()
10 On Error GoTo Err_Handler
'Pass acNewRec in the OpenArgs to the form frmCompanyDetail
'so it knows you want to add a new record
20 Open_frmCompanyDetail "Add"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdAddNew_Click", True
50 Resume Exit_Handler
End SubPrivate Sub cmdLabelWizard_Click() 10 On Error Resume Next 20 DoCmd.RunCommand acCmdNewObjectLabelsReport End Sub
Private Sub cmdShowFilter_Click()
10 On Error GoTo Err_Handler
Dim strOpenArgs As String
20 If Me.Form.FilterOn = False Then
30 MsgBox "This form has not been filtered.", vbOKOnly Or vbInformation
40 Else
'OpenArgs uses Replace function to make the filter more readable for humans.
50 strOpenArgs = StringFormat("Header={0}&Message={1}", "Form Filter", Replace(Me.Form.Filter, "[qryCompanyList].", ""))
60 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
70 If IsFormOpen("frmGenericDialog") Then
80 DoCmd.Close acForm, "frmGenericDialog", acSaveNo
90 End If
100 End If
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "cmdShowFilter_Click", True
130 Resume Exit_Handler
End SubPrivate Sub cmdShowHideFields_Click() 10 On Error GoTo Err_Handler 20 DoCmd.RunCommand acCmdUnhideColumns Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdShowHideFields_Click", True 50 Resume Exit_Handler End Sub
Private Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
Dim ctl As Access.control
'Clean up anything left by a previous session
20 Me.Auto_Header0.Caption = "Companies"
'In order to have the change to the filter stick
' you need to set the FilterOn property to false
'https://stackoverflow.com/questions/59954653/vba-ms-access-remove-form-filter
30 Me.FilterOn = False
40 Me.Filter = ""
'The list cannot be edited, but the Filter should still be accessible, so Me.AllowEdits is no good.
50 On Error Resume Next 'Not every type of control has a Locked property.
60 For Each ctl In Me.Controls
70 ctl.Locked = (TypeName(ctl) = "TextBox")
80 Next ctl
90 On Error GoTo Err_Handler
Exit_Handler:
100 Exit Sub
Err_Handler:
110 clsErrorHandler.HandleError Me.Name, "Form_Open", True
120 Resume Exit_Handler
130 Resume
End SubPrivate Sub fraFilter_AfterUpdate()
10 On Error GoTo Err_Handler
20 With Me
30 Select Case .fraFilter
Case enumCompanyType.ctCustomer
40 .Filter = "CompanyTypeID = " & Me.fraFilter
50 .FilterOn = True
60 .Auto_Header0.Caption = "Customers"
70 .NavigationCaption = "Customers"
80 Case enumCompanyType.ctShipper
90 .Filter = "CompanyTypeID = " & Me.fraFilter
100 .FilterOn = True
110 .Auto_Header0.Caption = "Shippers"
120 .NavigationCaption = "Shippers"
130 Case enumCompanyType.ctVendor
140 .Filter = "CompanyTypeID = " & Me.fraFilter
150 .FilterOn = True
160 .Auto_Header0.Caption = "Vendors"
170 .NavigationCaption = "Vendors"
180 Case Else
190 .FilterOn = False
200 .Filter = ""
210 .Auto_Header0.Caption = "Companies"
220 .NavigationCaption = "Companies"
230 End Select
240 End With
Exit_Handler:
250 Exit Sub
Err_Handler:
260 clsErrorHandler.HandleError Me.Name, "fraFilter_AfterUpdate", True
270 Resume Exit_Handler
End Sub
'We want to pass multiple parameters to frmCompanyDetail via
' the forms OpenArgs property
'To do that we need to pass a string which can be parsed by frmCompanyDetail
'
'To learn more about OpenArgs or Search For Record follow the link below
'https://docs.microsoft.com/office/vba/api/Access.Form.OpenArgs
'https://docs.microsoft.com/office/vba/api/access.docmd.searchforrecord
'Public Function Open_frmCompanyDetail(ByVal strAction As String)
10 On Error GoTo Err_Handler
Dim varOpenArgs As Variant
Dim strOpenArgAction As String
Dim strOpenArgCompanyTypeID As String
Dim strOpenArgCompanyID As String
Dim strOpenArgPassedFilter As String
20 If IsFormOpen("frmCompanyDetail") Then
30 MsgBox GetString(sFormAlreadyOpen, Forms!frmCompanyDetail.Caption), vbOKOnly Or vbInformation, "Already Open"
40 GoTo Exit_Handler
50 End If
'First we will create the string for each parameter individually
60 If Len(strAction) > 0 Then
70 strOpenArgAction = "Action=" & strAction
80 Else
90 strOpenArgCompanyID = "CompanyID=" & Me.txtCompanyID
100 End If
110 If Me.fraFilter > 0 Then
120 strOpenArgCompanyTypeID = "CompanyTypeID=" & Me.fraFilter
130 End If
140 If Me.FilterOn Then
150 strOpenArgPassedFilter = Me.Filter
'Remove the query name ([qryCompanyList].) which appears in the string
'so the filter can be applied based only on field names in frmCompanyDetail
160 strOpenArgPassedFilter = "PassedFilter=" & Replace(strOpenArgPassedFilter, "[qryCompanyList].", "")
170 Else
180 strOpenArgPassedFilter = ""
190 End If
'Secondly we will concatenate the strings above
'into a single sting to pass in the OpenArgs parameter of the docmd.Open form event
'***************************************************************
'Using this place holder in the varOpenArgs string
' varOpenArgs = "OpenBy=frmCompanyList"
' eliminates the need to continously check
' if we are setting or concatenating to varOpenArgs
' Now we know we are always concatenating
'
' WHAT WE DONT NEED TO DO FOR EACH POTENTIAL PARAMTER
'***************************************************************
' If Len(varOpenArgs) = 0 then
' varOpenArgs = xyz
' Else
' varOpenArgs = varOpenArgs & "&" & xyz
' end if
'***************************************************************
200 varOpenArgs = "OpenBy=frmCompanyList" 'Place holder
210 If Len(strOpenArgAction) > 0 Then
220 varOpenArgs = varOpenArgs & "&" & strOpenArgAction
230 End If
240 If Len(strOpenArgCompanyID) > 0 Then
250 varOpenArgs = varOpenArgs & "&" & strOpenArgCompanyID
260 End If
270 If Len(strOpenArgCompanyTypeID) > 0 Then
280 varOpenArgs = varOpenArgs & "&" & strOpenArgCompanyTypeID
290 End If
'Concatenate this last incase it has formatting which interfers
'with the parameter creation in frmCompanyDetail
300 If Len(strOpenArgPassedFilter) > 0 Then
310 varOpenArgs = varOpenArgs & "&" & strOpenArgPassedFilter
320 End If
330 DoCmd.OpenForm "frmCompanyDetail", acNormal, , , acFormEdit, acWindowNormal, varOpenArgs
Exit_Handler:
340 Exit Function
Err_Handler:
350 clsErrorHandler.HandleError Me.Name, "Open_frmCompanyDetail", True
360 Resume Exit_Handler
End FunctionPrivate Sub txtCompanyID_Click() 10 On Error GoTo Err_Handler 20 Open_frmCompanyDetail "" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "txtCompanyID_Click", True 50 Resume Exit_Handler End Sub
Record source: qryEmployeeLogin
Has VBA module
Events — OnLoad: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Title0 | Label | Welcome! | ||||
| Box254 | Rectangle | |||||
| Box255 | Rectangle | |||||
| Box256 | Rectangle | |||||
| Box257 | Rectangle | |||||
| Box258 | Rectangle | |||||
| Box259 | Rectangle | |||||
| cmdAddMe | Command button | Add Me | Click: cmdAddMe_Click | |||
| cmdExit | Command button | Exit | Click: cmdExit_Click | |||
| EmployeeID | Text box | EmployeeID | ||||
| FirstName | Text box | FirstName | ||||
| imgNorthwindTradersLogo | Image | |||||
| JobTitle | Text box | JobTitle | ||||
| LastName | Text box | LastName | ||||
| lblEmployeeID | Label | EmployeeID | ||||
| lblFirstName | Label | First Name | ||||
| lblInstructions | Label | We would like to make you a member of the Northwind team. Please enter a name and job title at the company, so we can personalize your experience. This information never leaves the building, but if you like that better: John / Doe / Racecar Driver would work just fine. | ||||
| lblJobTitle | Label | Job Title | ||||
| lblLastName | Label | Last Name | ||||
| WindowsUserName | Text box | WindowsUserName |
Public Property Get UserID() As Long 10 UserID = m_UserID End Property
Private Sub cmdAddMe_Click()
10 On Error GoTo Err_Handler
20 RunCommand acCmdSaveRecord
30 m_UserID = Me.EmployeeID.Value
'You can log in to the application as any Employee
'Let the user know who they have logged in as
40 modStartup.SetAppTitle True
50 Me.Visible = False 'Do not close the form. Allow caller to inspect properties.
Exit_Handler:
60 Exit Sub
Err_Handler:
70 If Err.Number = 3021 Then ' 3021 = No current record. The form is not valid. Validator has already shown error message.
80 Resume Exit_Handler
90 ElseIf Err.Number = 3022 Then ' 3022 = The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate entries and try again.
100 Err.Description = "This FirstName + LastName combination already exists. Please enter a different name."
110 ElseIf Err.Number = 2046 Then ' 2046 = The command or action 'SaveRecord' isn't available now.
120 Err.Description = "This record cannot be saved as-is. Does this FirstName + LastName combination already exist?"
130 End If
140 clsErrorHandler.HandleError Me.Name, "cmdAddMe_Click"
150 Resume Exit_Handler
160 Resume
End SubPrivate Sub cmdExit_Click() 10 On Error GoTo Err_Handler 20 If Me.Dirty Then 30 Me.Undo 40 End If 50 DoCmd.Close acForm, Me.Name 60 DoCmd.Quit acQuitSaveAll Exit_Handler: 70 Exit Sub Err_Handler: 80 clsErrorHandler.HandleError Me.Name, "cmdExit_Click", True 90 Resume Exit_Handler End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 50 Resume Exit_Handler End Sub
Private Sub Form_Load()
10 On Error GoTo Err_Handler
Dim strUserName As String
20 strUserName = GetWindowsUserName()
'this value will be used to find the user in the future
30 Me.WindowsUserName = strUserName
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "Form_Load", True
60 Resume Exit_Handler
End SubRecord source: qryEmployees
Order by: [qryEmployees].[LastName], [qryEmployees].[FirstName] DESC · Has VBA module
Events — OnCurrent: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Northwind Employees | |||||
| BoxCaptions | Rectangle | ||||||
| cboSupervisorID | Combo box | SupervisorID | qryEmployeeSupervisor | ||||
| cboTitle | Combo box | Title | qryTitle | ||||
| cmdEmailEmployee | Command button | Click: cmdEmailEmployee_Click | |||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/57007c0d-7fc1-4dfc-a050-f0e5e014706b | ||||
| cmdNewEmployee | Command button | Add Employee | Click: cmdNewEmployee_Click | ||||
| imgEmployeePicture | Attachment | Attachments | |||||
| imgNorthwindTradersLogo | Image | ||||||
| lblEmailAddress | Label | Email Address | |||||
| lblEmployeeID | Label | ID | |||||
| lblEmployeePicture | Label | Picture | |||||
| lblFirstName | Label | First Name | |||||
| lblJobTitle | Label | Job Title | |||||
| lblLastName | Label | Last Name | |||||
| lblNotes | Label | Notes | |||||
| lblPrimaryPhone | Label | Primary Phone | |||||
| lblRecentOrders | Label | Recent Orders for Steven Thorpe | |||||
| lblSecondaryPhone | Label | Secondary Phone | |||||
| lblSuperVisor | Label | Supervisor | |||||
| lblTitle | Label | Title | |||||
| lblWindowsUserName | Label | Windows User Name | |||||
| sfrmEmployeeOrders | Subform/Subreport | sfrmOrders_MostRecent_ByEmployee | |||||
| txtEmailAddress | Text box | EmailAddress | |||||
| txtEmployeeID EmployeeID | Text box | =Right("00000" & [EmployeeID],5) | |||||
| txtFirstName | Text box | FirstName | |||||
| txtJobTitle | Text box | JobTitle | |||||
| txtLastName | Text box | LastName | |||||
| txtModified | Text box | =RecordModifiedString([AddedBy],[AddedOn],[ModifiedBy],[ModifiedOn]) | |||||
| txtNotes | Text box | Notes | |||||
| txtPrimaryPhone | Text box | PrimaryPhone | |||||
| txtSecondaryPhone | Text box | SecondaryPhone | |||||
| txtWindowsUserName | Text box | WindowsUserName |
Private Sub cboSupervisorID_Enter()
10 On Error GoTo Err_Handler
'In order to limit the list of Employees who can be assigned as supervisors
'the combo box is filtered to exclude the current employee's EmployeeID
'This rowsource must be refreshed for each record when it becomes current
20 Me.cboSupervisorID.Requery
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cboSupervisorID_Enter", True
50 Resume Exit_Handler
End SubPrivate Sub cboSupervisorID_NotInList(NewData As String, Response As Integer)
10 On Error GoTo Err_Handler
'We need to do two things
'Suppress the default error message from Acess and replace it with a custom message
'Allow the user to add a new employee record for the person who will become the new supervisor.
20 Response = acDataErrContinue
30 With Me
40 .cboSupervisorID.Undo
50 If MsgBox(GetString(sNewEmployee, NewData), vbExclamation Or vbOKCancel, "Add " & NewData & "?") = vbOK Then
60 .Dirty = False
70 .Recordset.AddNew
80 End If
90 End With
Exit_Handler:
100 Exit Sub
Err_Handler:
110 clsErrorHandler.HandleError Me.Name, "cboSupervisorID_NotInList", True
120 Resume Exit_Handler
End SubPrivate Sub cmdEmailEmployee_Click()
10 On Error GoTo Err_Handler
Dim strSender As String
Dim strWindowsUserName As String
20 strWindowsUserName = GetWindowsUserName()
30 strSender = DLookup("FirstName", "Employees", StringFormatSQL("Employees.WindowsUserName = {0}", strWindowsUserName))
40 strSender = vbCrLf & vbCrLf & vbCrLf & strSender & " " & DLookup("LastName", "Employees", StringFormatSQL("Employees.WindowsUserName = {0}", strWindowsUserName))
50 DoCmd.SendObject ObjectType:=acSendNoObject, To:=Nz(Me.EmailAddress, ""), Subject:="NorthWind Traders: ", MessageText:=strSender, editMessage:=True
Exit_Handler:
60 Exit Sub
Err_Handler:
70 If Err <> 2296 Then 'Error 2296 indicates the email password is invalid; the message can't be sent.
80 clsErrorHandler.HandleError Me.Name, "cmdEmailEmployee_Click"
90 End If
100 Resume Exit_Handler
End SubPrivate Sub cmdNewEmployee_Click() 10 On Error GoTo Err_Handler 20 If Not Me.NewRecord Then DoCmd.GoToRecord record:=acNewRec Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdNewEmployee_Click", True 50 Resume Exit_Handler End Sub 'RETURNS ' True if the employee can be deleted (no child records exist in four related tables); False otherwise. 'NOTE: ' This is a private function, used only in this form
Private Function EmployeeCanBeDeleted(ByVal lngEmployeeID As Long) As Boolean
10 On Error GoTo Err_Handler
Dim blnReturn As Boolean
Dim lngEmployeeOrders As Long
Dim lngEmployeeSupervisor As Long
Dim lngEmployeePrivileges As Long
Dim lngEmployeePurchaseOrders As Long
Dim sCantDeleteResponse As String
Dim strOpenArgs As String
Dim strMsgCaption As String
20 blnReturn = True
30 strMsgCaption = "Message from Employees"
40 With Me
50 lngEmployeeOrders = DCount("OrderID", "Orders", StringFormatSQL("EmployeeID ={0}", lngEmployeeID))
60 lngEmployeeSupervisor = DCount("EmployeeID", "Employees", StringFormatSQL("SupervisorID ={0}", lngEmployeeID))
70 lngEmployeePrivileges = DCount("EmployeeID", "EmployeePrivileges", StringFormatSQL("EmployeeID ={0}", lngEmployeeID))
80 lngEmployeePurchaseOrders = DCount("PurchaseOrderID", "PurchaseOrders", StringFormatSQL("SubmittedByID ={0}", lngEmployeeID))
90 If lngEmployeeOrders > 0 Then
100 sCantDeleteResponse = GetString(sEmployeeRestraints, .FullNameFNLN, "has Orders (" & lngEmployeeOrders & ").", "Employees with orders can not be deleted")
110 End If
120 If lngEmployeePurchaseOrders > 0 Then
130 sCantDeleteResponse = sCantDeleteResponse & vbCrLf & vbCrLf & GetString(sEmployeeRestraints, .FullNameFNLN, "has Purchase Orders (" & lngEmployeePurchaseOrders & ").", "Employees with purchase orders can not be deleted")
140 End If
150 If lngEmployeeSupervisor > 0 Then
160 sCantDeleteResponse = sCantDeleteResponse & vbCrLf & vbCrLf & GetString(sEmployeeRestraints, .FullNameFNLN, "is a Supervisor.", "Employees supervising other employees can not be deleted <br /> until their employees are reassigned")
170 End If
180 If lngEmployeePrivileges > 0 Then
190 sCantDeleteResponse = sCantDeleteResponse & vbCrLf & vbCrLf & GetString(sEmployeeRestraints, .FullNameFNLN, "has elevated Privileges.", "Employees with elevated privileges can not be deleted <br /> until those privileges are revoked")
200 End If
210 blnReturn = (lngEmployeeOrders + lngEmployeeSupervisor + lngEmployeePrivileges + lngEmployeePurchaseOrders = 0)
220 If blnReturn = True Then
' It's safe to remove any of this Employee's records from MRU if there are no supporting records in other tables.
230 RemoveFromMRU "Orders", Nz(DLookup("PkValue", "MRU", "EmployeeID = " & lngEmployeeID), 0)
240 RemoveFromMRU "PurchaseOrders", Nz(DLookup("PkValue", "MRU", "EmployeeID = " & lngEmployeeID), 0)
' Capture the current employee's name for the deletion confirmation message box
' If multiple employees are deleted in bulk, append all names
250 TempVars.Add Name:="EmployeeToDelete", Value:=TempVars!EmployeeToDelete & Chr(13) & Me.FullNameFNLN.Value
260 Else
270 sCantDeleteResponse = Left(sCantDeleteResponse, Len(sCantDeleteResponse) - 6) 'Remove the trailing <br />
280 strOpenArgs = StringFormat("Header={0}&Message={1}&Actions={2}&FormCaption={3}", "Employee Delete Not Allowed", sCantDeleteResponse, "vbOK", strMsgCaption)
290 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
'Defensive programming: currently the dialog would be closed in this case, but that behavior could conceivably be changed.
300 If IsFormOpen("frmGenericDialog") Then
310 DoCmd.Close acForm, "frmGenericDialog", acSaveNo
320 End If
330 End If
340 End With
350 EmployeeCanBeDeleted = blnReturn
Exit_Handler:
360 Exit Function
Err_Handler:
370 clsErrorHandler.HandleError Me.Name, "EmployeeCanBeDeleted"
380 Resume Exit_Handler
End FunctionPrivate Sub Form_AfterDelConfirm(Status As Integer) 10 On Error GoTo Err_Handler 20 Me.cmdNewEmployee.Visible = Not Me.NewRecord Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterDelConfirm", True 50 Resume Exit_Handler End Sub
Private Sub Form_AfterInsert()
10 On Error GoTo Err_Handler
Dim lngNewEmployeeID As Long
20 With Me
30 lngNewEmployeeID = .EmployeeID
40 DoCmd.OpenForm FormName:="sfrmEmployee_Privileges", _
View:=acNormal, _
WhereCondition:="EmployeeID = " & lngNewEmployeeID, _
DataMode:=acFormAdd, _
WindowMode:=acDialog, _
OpenArgs:=lngNewEmployeeID
50 End With
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True
80 Resume Exit_Handler
End SubPrivate Sub Form_AfterUpdate() 10 On Error GoTo Err_Handler 20 Call RequeryEmployeeList(Me.EmployeeID) 30 ValidateForm_RemoveHighlights Me Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True 60 Resume Exit_Handler End Sub
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
10 On Error GoTo Err_Handler
' TempVars!EmployeeToDelete returns the correctly identified employee or employees in the confirmation messagebox
20 If MsgBox(GetString(sDeleteEmployee, TempVars!EmployeeToDelete), vbQuestion Or vbYesNo, "Delete Employee?") = vbNo Then
30 Cancel = True
40 End If
50 TempVars.Add Name:="EmployeeToDelete", Value:=""
60 Response = acDataErrContinue
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "Form_BeforeDelConfirm", True
90 Resume Exit_Handler
End SubPrivate Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 50 Resume Exit_Handler End Sub
Private Sub Form_Current() 10 On Error GoTo Err_Handler 20 ValidateForm_RemoveHighlights Me 30 With Me 40 .cmdNewEmployee.Visible = Not .NewRecord 50 .cboSupervisorID.Requery 60 .lblRecentOrders.Caption = "Recent Orders for " & .FullNameFNLN 70 End With Exit_Handler: 80 Exit Sub Err_Handler: 90 clsErrorHandler.HandleError Me.Name, "Form_Current", True 100 Resume Exit_Handler End Sub
Private Sub Form_Delete(Cancel As Integer)
10 On Error GoTo Err_Handler
'Before allowing an employee to be deleted, confirm that there are no child records in one of the four child record tables
'Also replace the default Access error message with a custom message if the employee can't be deleted
20 Cancel = Not EmployeeCanBeDeleted(Me.EmployeeID)
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "Form_Delete", True
50 Resume Exit_Handler
End Sub
'PURPOSE:
' Requery the form and go back to the record we were on (otherwise we would be on record 1).Private Sub RequeryEmployeeList(ByVal lngEmployeeID As Long)
10 On Error GoTo Err_Handler
Dim rst As DAO.Recordset
20 With Me
30 .Requery
40 Set rst = .RecordsetClone
50 rst.FindFirst "EmployeeID = " & lngEmployeeID
60 .Bookmark = rst.Bookmark
70 End With
80 Set rst = Nothing
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError Me.Name, "RequeryEmployeeList"
110 Resume Exit_Handler
End SubRecord source: Titles
Has VBA module
Events — OnOpen: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Titles | ||||
| imgHelp | Image | |||||
| Label0 | Label | Title | ||||
| Title | Text box | Title |
Private Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
Dim dict As Scripting.Dictionary
20 Set dict = StringToDictionary(Me.OpenArgs)
30 If Not Me.NewRecord Then RunCommand acCmdRecordsGoToNew
40 Me.Title = dict("[frmEmployeeList]![cboTitle]")
50 Set dict = Nothing
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "Form_Open", True
80 Resume Exit_Handler
End SubRecord source: No record source
Has VBA module
Events — OnLoad: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Generic Dialog | ||||
| Box8 | Rectangle | |||||
| BoxCaptions | Rectangle | |||||
| cmdCancelClose | Command button | Cancel | Click: cmdCancelClose_Click | |||
| cmdOK | Command button | OK | Click: cmdOK_Click | |||
| imgHelp | Image | |||||
| txtMessage | Text box |
Private Sub cmdCancelClose_Click()
10 On Error GoTo Err_Handler
'If we close the form the calling form will know the User clicked Cancel
20 DoCmd.Close acForm, Me.Name, acSaveNo
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdCancelClose_Click", True
50 Resume Exit_Handler
End SubPrivate Sub cmdOK_Click()
10 On Error GoTo Err_Handler
'If we make the form invisible the calling form know the User clicked OK.
20 Me.Visible = False
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "cmdOK_Click", True
50 Resume Exit_Handler
End SubPrivate Sub Form_Load()
10 On Error GoTo Err_Handler
Dim dict As Scripting.Dictionary
Dim key As Variant
Dim strActions As String
Dim strFormCaption As String
Dim strHeader As String
Dim strMsg As String
'Set default values for the variables above
20 strActions = "None"
30 strFormCaption = "Message from Northwind"
40 strHeader = "No Message Provided"
50 strMsg = "Please let the IT team know what happened."
' ==============================================================================
' Passing Multiple values in via the OpenArgs property
' ==============================================================================
' One approach is to pass the values in a string using a delimiter (for example | ).
' The opened form uses the Split() function to break the values apart (see frmSelectVendorDialog).
' This approach requires passing the values in the order expected by the opened form.
' If there 3 optional values you will need pass those in as well even if you have only the last value ( ||| )
'
' Another approach is to use Key/Value pairs and the Scripting.Dictionary object to parse them.
' A benefit of this approach is the values are identified by the KEY portion of the pair not the
' Ordinal position - so the order of the values is no longer important.
' The NW function StringToDictionary handles the parsing of the Key/Value pairs for you.
60 If Nz(Me.OpenArgs, "") > "" Then
70 Set dict = StringToDictionary(Me.OpenArgs)
80 For Each key In dict.Keys
90 Select Case key
Case "FormCaption"
100 strFormCaption = dict.Item(key)
110 Case "Header"
120 strHeader = dict.Item(key)
130 Case "Message"
140 strMsg = dict.Item(key)
150 Case "Actions"
160 strActions = dict.Item(key)
170 End Select
180 Next key
190 End If
200 With Me
210 .Caption = strFormCaption
220 .Auto_Header0.Caption = strHeader
230 .txtMessage = Trim$(strMsg)
240 If strActions = "None" Then
250 .cmdCancelClose.Visible = True
260 .cmdCancelClose.Caption = "&Close"
270 .cmdOK.Visible = False
280 ElseIf strActions = "vbOKCancel" Then
290 .cmdCancelClose.Visible = True
300 .cmdCancelClose.Caption = "&Cancel"
310 .cmdOK.Visible = True
320 .cmdOK.Caption = "&OK"
330 ElseIf strActions = "vbYesNo" Then
340 .cmdCancelClose.Visible = True
350 .cmdCancelClose.Caption = "&No"
360 .cmdOK.Visible = True
370 .cmdOK.Caption = "&Yes"
380 Else
'A value was sent that we don't recognize
390 .cmdCancelClose.Visible = True
400 .cmdCancelClose.Caption = "&Close"
410 .cmdOK.Visible = False
420 End If
430 End With
440 With Me.txtMessage
'Cause the vertical scroll bar to appear in case
'the message exceeds the current size of the control
450 .SetFocus
460 .SelStart = 0
470 End With
Exit_Handler:
480 Set dict = Nothing
490 Exit Sub
Err_Handler:
500 clsErrorHandler.HandleError Me.Name, "Form_Load"
510 Resume Exit_Handler
End SubRecord source: No record source
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Box1 | Rectangle | ||||||
| Box70 | Rectangle | ||||||
| cmdAccessForum | Command button | Access Forum | Address: https://answers.microsoft.com/en-us/msoffice/forum/msoffice_access | ||||
| cmdFeedback | Command button | Access Tech Community | Address: https://techcommunity.microsoft.com/t5/access/ct-p/Access_Cat | ||||
| cmdLearnMoreAboutAccess | Command button | Learn more about Access | Address: https://support.microsoft.com/en-us/office/access-video-training-a5ffb1ef-4cc4-4d79-a862-e2dda6ef38e6 | ||||
| cmdOpenReport | Command button | Preview Report | Click: [Embedded Macro] | ||||
| EdgeBrowser2 | Edge browser control | ="https://support.office.com/f1/topic/a685f382-e246-4f55-888f-52e4766868f8" | |||||
| imgNorthwindTradersCommunity | Image | ||||||
| imgNorthwindTradersFeedback | Image | ||||||
| imgNorthwindTradersVideo | Image | Address: https://support.microsoft.com/topic/32eb79d2-bede-4ea4-b575-0714ca8dc1e2 | |||||
| lblAccessTraining | Label | Access Online Training | |||||
| lblFeedback | Label | Access Community | |||||
| lblHyperLink | Label | View Learn document in your browser | Address: https://support.office.com/f1/topic/a685f382-e246-4f55-888f-52e4766868f8 | ||||
| lblReportandLink | Label | This form uses the new (as of 2023) Edge Browser control, which is not available in older versions of Access. For those, please click the button to open an Access report with the same content. You may also use the hyperlink to view the Learn Document online. | |||||
| lblWelcomeVideo | Label | Welcome Video |
Record source: No record source
Has VBA module
Events — OnLoad: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Default value | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Auto_Title0 | Label | Northwind Login | |||||
| AutoLogin_chk | Check box | False | |||||
| AutoLogin_lbl | Label | Don't show me this again - automatically log me in | |||||
| Box254 | Rectangle | ||||||
| Box255 | Rectangle | ||||||
| Box256 | Rectangle | ||||||
| Box56 | Rectangle | ||||||
| Box57 | Rectangle | ||||||
| Box58 | Rectangle | ||||||
| cboEmployee | Combo box | [TempVars]![UserID] | qrycboEmployees | ||||
| cboEmployee_Label | Label | Select Employee: | |||||
| cmdLogin | Command button | Login | Click: cmdLogin_Click | ||||
| Disclaimer | Label | 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. | |||||
| imgNorthwindTradersLogo | Image |
Public Property Get UserID() As Long 10 UserID = m_UserID End Property
Private Sub AutoLogin_chk_AfterUpdate() 10 On Error GoTo Err_Handler 20 SaveUserSetting usAutoLogin, Me.AutoLogin_chk Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "AutoLogin_chk_AfterUpdate", True 50 Resume Exit_Handler End Sub
Private Sub cmdLogin_Click()
10 On Error GoTo Err_Handler
20 If IsNull(Me.cboEmployee.Value) Then
30 MsgBox "You must select a user to login as. Please select someone now.", vbOKOnly Or vbExclamation, "Select a Login"
40 Me.cboEmployee.SetFocus
50 Me.cboEmployee.Dropdown
60 m_bolLoginClicked = False
70 Exit Sub
80 End If
'This lets us know the user clicked on the Login button
'If you look at the forms Unload event below you will see why we need to know this
90 m_bolLoginClicked = True
100 m_UserID = Me.cboEmployee.Value
'You can log in to the application as any Employee
'Let the user know who they have logged in as
110 modStartup.SetAppTitle True
120 Me.Visible = False 'Do not close the form. Allow caller to inspect properties.
Exit_Handler:
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError Me.Name, "cmdLogin_Click", True
150 Resume Exit_Handler
End SubPrivate Sub Form_Load()
10 On Error GoTo Err_Handler
Dim bolAutoLogIn As Boolean
Dim lngUserID As Long
20 bolAutoLogIn = False
30 Me.Disclaimer.Caption = GetString(sDisclaimer)
40 bolAutoLogIn = GetUserSetting(enumUserSettings.usAutoLogin)
50 Me.AutoLogin_chk.Value = bolAutoLogIn
60 lngUserID = Get_UserID()
70 Me.cboEmployee = lngUserID
80 If lngUserID = 0 Then
' The function has told us there is no User selected at this time
' our business rule says to focus on the default log in
90 m_UserID = DEFAULT_LOGIN_ID
100 Me.AutoLogin_chk.Visible = False
110 ElseIf lngUserID = Get_UserID_ForWindowsUser Then
120 Me.AutoLogin_chk.Visible = True
130 Else
140 Me.AutoLogin_chk.Visible = False
150 End If
160 m_bolLoginClicked = False
170 modStartup.SetAppTitle False
Exit_Handler:
180 Exit Sub
Err_Handler:
190 clsErrorHandler.HandleError Me.Name, "Form_Load", True
200 Resume Exit_Handler
End SubPrivate Sub Form_Unload(Cancel As Integer)
10 On Error GoTo Err_Handler
20 If m_bolLoginClicked = False Then
30 If MsgBox("Do you want to close " & g_strAppName & "?", vbYesNo Or vbExclamation, "Select a Login") = vbNo Then
40 Me.cboEmployee.SetFocus
50 Cancel = True
60 Else
70 Me.Application.Quit acQuitSaveNone
80 End If
90 End If
Exit_Handler:
100 Exit Sub
Err_Handler:
110 clsErrorHandler.HandleError Me.Name, "Form_Unload", True
120 Resume Exit_Handler
End SubRecord source: NorthwindFeatures
Order by: [NorthwindFeatures].[ItemName] · Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Northwind Features | ||||
| BoxCaptions | Rectangle | |||||
| imgNorthwindTradersLogo | Image | |||||
| Label161 | Label | Item Name | ||||
| Label162 | Label | Description | ||||
| Label163 | Label | Navigation (from Main Menu) | ||||
| Label165 | Label | Click for In-App Help | ||||
| Label166 | Label | OpenMethod | ||||
| lblOnlineHelp | Label | Click for On-Line Help | ||||
| OpenMethod | Text box | OpenMethod | ||||
| txtDescription | Text box | Description | ||||
| txtHelpKeywords | Text box | HelpKeywords | Click: txtHelpKeywords_Click | |||
| txtItemName | Text box | ItemName | ||||
| txtLearnMore | Text box | LearnMore | ||||
| txtNavigation | Text box | Navigation |
Private Sub txtHelpKeywords_Click()
10 On Error GoTo Err_Handler
Dim strHyperlink As String
'Exit if the field is blank to avoid error
20 If Nz(Me.txtHelpKeywords, "") = "" Then GoTo Exit_Handler
30 Select Case Me.OpenMethod
Case enumNorthwindFeaturesOpenMethod.nfInPageHelp
40 Application.Assistance.SearchHelp Me.txtHelpKeywords
50 Case enumNorthwindFeaturesOpenMethod.nfFollowHyperlink
'The field in table is defined as a hyperlink
' and we want it to be a hyperlink so if
' the field is shown and the user clicks on it the webpage will open
' See: txtLearnMore_Click()
'
'The field type of hyperlink coantains pound signs (#) at the beginning and the end
' we need to remove those to access the webpage from here
60 strHyperlink = Replace(CStr(Me.txtLearnMore), "#", "")
70 Application.FollowHyperlink strHyperlink
80 End Select
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError Me.Name, "txtHelpKeywords_Click", True
110 Resume Exit_Handler
End SubRecord source: qryOrder
Has VBA module
Events — OnOpen: [Event Procedure], OnLoad: [Event Procedure], OnCurrent: [Event Procedure], OnClose: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Order | |||||
| boxHeaderControls | Rectangle | ||||||
| cmdAddOrder | Command button | Add Order | Click: cmdAddOrder_Click | ||||
| cmdCheckAvailability | Command button | Check Stock Availability | Click: cmdCheckAvailability_Click | ||||
| cmdCloseOrder | Command button | 4: Close Order | Click: cmdCloseOrder_Click | ||||
| cmdCreateInvoice | Command button | 1: Create Invoice | Click: cmdCreateInvoice_Click | ||||
| cmdDeleteOrder | Command button | Delete Order | Click: cmdDeleteOrder_Click | ||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/40c61470-c7c4-4fdb-9f90-d9af2a807c7a | ||||
| cmdPrintInvoice | Command button | Print Invoice | Click: cmdPrintInvoice_Click | ||||
| cmdReceivePayment | Command button | 3: Receive Payment | Click: cmdReceivePayment_Click | ||||
| cmdShipOrder | Command button | 2: Ship Order | Click: cmdShipOrder_Click | ||||
| Command198 | Command button | Command198 | |||||
| CustomerID | Combo box | CustomerID | qrycboCustomers | ||||
| EmployeeID | Combo box | EmployeeID | qrycboEmployees | ||||
| imgNorthwindTradersLogo | Image | ||||||
| InvoiceDate | Text box | InvoiceDate | |||||
| Label12 | Label | Order Date | |||||
| Label15 | Label | Customer | |||||
| Label152 | Label | TIP: Use Shift+F2 for Zoom window | |||||
| Label155 | Label | Order Status | |||||
| Label160 | Label | 2: Shipper | |||||
| Label161 | Label | 1: Shipping Fee | |||||
| Label162 | Label | Tax Rate | |||||
| Label163 | Label | Tax Status | |||||
| Label164 | Label | Tax Amount | |||||
| Label165 | Label | 3: Payment Method | |||||
| Label167 | Label | Total | |||||
| Label18 | Label | 2: Shipped Date | |||||
| Label196 | Label | 1: Invoice Date | |||||
| Label21 | Label | 3: Paid Date | |||||
| Label48 | Label | Notes | |||||
| Label6 | Label | Employee | |||||
| Label9 | Label | Order ID | |||||
| lblOrderLineItems | Label | Order Line Items | |||||
| lblWorkflow | Label | -------------------------- Workflow ------------------------------------ | |||||
| Notes | Text box | Notes | |||||
| OrderDate | Text box | OrderDate | |||||
| OrderID | Text box | OrderID | |||||
| OrderStatusID | Text box | OrderStatusID | |||||
| OrderStatusName | Text box | OrderStatusName | |||||
| PaidDate | Text box | PaidDate | |||||
| PaymentMethod | Combo box | PaymentMethod | Credit Card;Check;Cash | ||||
| sfrmOrderLineItems | Subform/Subreport | sfrmOrderLineItems | |||||
| ShippedDate | Text box | ShippedDate | |||||
| ShipperID | Combo box | ShipperID | qrycboShippers | ||||
| ShippingFee | Text box | ShippingFee | |||||
| TaxRate | Text box | TaxRate | |||||
| TaxStatusID | Combo box | TaxStatusID | qrycboTaxStatus | ||||
| txtModified | Text box | =RecordModifiedString([AddedBy],[AddedOn],[ModifiedBy],[ModifiedOn]) | |||||
| txtTaxAmount | Text box | =IIf([TaxStatusID]=1,[TaxRate]*[sfrmOrderLineItems].[Form].[txtSubTotal],0) | |||||
| txtTotal | Text box | =[sfrmOrderLineItems].[Form].[txtSubTotal]+[txtTaxAmount]+Nz([ShippingFee]) |
Private Function AllInvoiceLineItemsHaveStatus(ByVal ods As enumOrderDetailStatus) As Boolean
10 On Error GoTo Err_Handler
Dim blnReturn As Boolean
20 With Me.sfrmOrderLineItems.Form.RecordsetClone 'This "With" construct has the advantage it automatically cleans up the Recordset object after it ends. And it saves typing.
30 If .RecordCount = 0 Then
40 blnReturn = True
50 Else
60 .MoveFirst
70 blnReturn = True 'Optimistic.
80 Do While Not .EOF
90 If !OrderDetailStatusID <> ods Then
'Different status found. No point in continuing.
100 blnReturn = False
110 Exit Do
120 End If
130 .MoveNext
140 Loop
150 End If
160 End With
170 AllInvoiceLineItemsHaveStatus = blnReturn
Exit_Handler:
180 Exit Function
Err_Handler:
190 clsErrorHandler.HandleError Me.Name, "AllInvoiceLineItemsHaveStatus"
200 Resume Exit_Handler
End FunctionPrivate Sub cmdAddOrder_Click() 10 On Error GoTo Err_Handler 20 If Me.NewRecord Then 30 MsgBox GetString(sAlreadyOnNewRecord), vbInformation 40 Else 50 RunCommand acCmdRecordsGoToNew 60 End If Exit_Handler: 70 Exit Sub Err_Handler: 80 clsErrorHandler.HandleError Me.Name, "cmdAddOrder_Click", True 90 Resume Exit_Handler End Sub
Private Sub cmdCheckAvailability_Click()
If Me.Dirty Then Me.Dirty = False
RunOrderAvailabilityPlanning Nz(Me!OrderID, 0)
End SubPrivate Sub cmdCloseOrder_Click() 10 On Error GoTo Err_Handler 20 If Me.NewRecord Then 30 MsgBox GetString(sOptionNotAvailable_NewRecord), vbExclamation 40 Else 50 If Me.OrderStatusID = enumOrderStatus.osPaid Then 60 RunCommand acCmdSaveRecord 70 If MsgBox(GetString(enumStrings.sOrderClosed), vbYesNo Or vbQuestion) = vbYes Then 80 Me.OrderStatusID = enumOrderStatus.osClosed 90 RunCommand acCmdSaveRecord 'Save record, so Requery below will pick up the new value. 100 SetFormStatus 110 End If 120 Else 130 MsgBox GetString(enumStrings.sOrderMustBePaid), vbExclamation 140 End If 150 End If Exit_Handler: 160 Exit Sub Err_Handler: 170 clsErrorHandler.HandleError Me.Name, "cmdCloseOrder_Click", True 180 Resume Exit_Handler End Sub
Private Sub cmdCreateInvoice_Click()
10 On Error GoTo Err_Handler
20 If Me.NewRecord Then
30 MsgBox GetString(sOptionNotAvailable_NewRecord), vbExclamation
40 Else
50 RunCommand acCmdSaveRecord 'The report should pick up saved values.
'BUSINESS RULE: Only "New" orders can be invoiced.
60 If Me.OrderStatusID = enumOrderStatus.osNew Then
'BUSINESS RULE: An order must have at least one line item.
70 If DCount("*", "OrderDetails", "OrderID = " & Me.OrderID) = 0 Then
80 MsgBox GetString(sOneLineItem), vbExclamation
90 Else
'BUSINESS RULE: all order line items must be allocated, so we can invoice all at once. No partial invoices.
100 If AllInvoiceLineItemsHaveStatus(enumOrderDetailStatus.odsAllocated) Then
110 If ShippingFeeFilledOut() Then
120 DoCmd.OpenReport "rptInvoice", acViewPreview, WhereCondition:="OrderID = " & Me.OrderID
130 If Me.OrderStatusID = enumOrderStatus.osNew Then
140 Me.OrderStatusID = enumOrderStatus.osInvoiced
150 Me.InvoiceDate = Now()
160 Me.cmdPrintInvoice.Visible = True
'Set the status of invoiced line items.
170 SetLineItemsStatus enumOrderDetailStatus.odsInvoiced
180 Else
'Status has already advanced from New, and user prints another invoice. No status change needed.
190 End If
'Some controls got new values. Save again. We would not want user to hit Cancel and undo those changes.
'This won't work, since the report has focus. RunCommand acCmdSaveRecord
200 Me.Dirty = False
210 SetFormStatus
220 Else
230 MsgBox "Shipping Fee is required for the invoice.", vbExclamation
240 End If
250 Else
260 MsgBox GetString(sOrderAllocated), vbExclamation
270 End If
280 End If
290 Else
300 MsgBox GetString(sNewOrderInvoice), vbExclamation
310 End If
320 End If
Exit_Handler:
330 Exit Sub
Err_Handler:
340 clsErrorHandler.HandleError Me.Name, "cmdCreateInvoice_Click", True
350 Resume Exit_Handler
End SubPrivate Sub cmdDeleteOrder_Click()
10 On Error GoTo Err_Handler
'BUSINESS RULE: Orders can be Deleted until they are shipped.
20 If IsNull(Me.OrderID) Then 'Alternatively can test for Me.NewRecord.
30 MsgBox "This is a new order. There is nothing to delete.", vbInformation
40 Else
50 If Me.OrderStatusID = enumOrderStatus.osNew Or Me.OrderStatusID = enumOrderStatus.osInvoiced Then
60 RunCommand acCmdDeleteRecord
70 Else
80 MsgBox GetString(enumStrings.sOrderCannotDelete), vbExclamation
90 End If
100 End If
Exit_Handler:
110 Exit Sub
Err_Handler:
120 If Err.Number = 3021 Then ' 3021 = No current record.
'This happens when choosing No when prompted to delete the order, and the event is cancelled. Just ignore it and run the next line of code.
130 Resume Next
140 End If
150 clsErrorHandler.HandleError Me.Name, "cmdDeleteOrder_Click"
160 Resume Exit_Handler
170 Resume
End SubPrivate Sub cmdPrintInvoice_Click() 10 On Error GoTo Err_Handler 20 DoCmd.OpenReport "rptInvoice", acViewPreview, WhereCondition:="OrderID = " & Me.OrderID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdPrintInvoice_Click", True 50 Resume Exit_Handler End Sub
Private Sub cmdReceivePayment_Click()
10 On Error GoTo Err_Handler
20 If Me.NewRecord Then
30 MsgBox GetString(sOptionNotAvailable_NewRecord), vbExclamation
40 Else
'BUSINESS RULE: order must be shipped before it can be paid.
50 If Me.OrderStatusID = enumOrderStatus.osShipped Then
60 If PaidFieldsFilledOut() Then
70 Me.OrderStatusID = enumOrderStatus.osPaid
80 RunCommand acCmdSaveRecord 'This will trigger Form_BeforeUpdate where we will do additional validation.
90 SetFormStatus
100 End If
110 Else
120 MsgBox GetString(sOrderMustBeShippedBeforePaid), vbExclamation
130 End If
140 End If
Exit_Handler:
150 Exit Sub
Err_Handler:
160 clsErrorHandler.HandleError Me.Name, "cmdReceivePayment_Click", True
170 Resume Exit_Handler
End SubPrivate Sub cmdShipOrder_Click()
10 On Error GoTo Err_Handler
20 If Me.NewRecord Then
30 MsgBox GetString(sOptionNotAvailable_NewRecord), vbExclamation
40 Else
'BUSINESS RULE: order must be invoiced before it can be shipped.
50 If Me.OrderStatusID = enumOrderStatus.osInvoiced Then
60 If ShippingFieldsFilledOut() Then
70 Me.OrderStatusID = enumOrderStatus.osShipped
80 RunCommand acCmdSaveRecord 'This will trigger Form_BeforeUpdate where we will do additional validation.
'Set line items to shipped.
90 SetLineItemsStatus enumOrderDetailStatus.odsShipped
100 SetFormStatus
110 End If
120 Else
130 MsgBox GetString(sOrderMustBeInvoiced), vbExclamation
140 End If
150 End If
Exit_Handler:
160 Exit Sub
Err_Handler:
170 clsErrorHandler.HandleError Me.Name, "cmdShipOrder_Click", True
180 Resume Exit_Handler
End SubPrivate Sub CustomerID_AfterUpdate()
10 On Error GoTo Err_Handler
'Set default value for tax status.
20 Me.TaxStatusID = DLookup("StandardTaxStatusID", "Companies", "CompanyID = " & Me.CustomerID)
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "CustomerID_AfterUpdate", True
50 Resume Exit_Handler
End SubPrivate Sub Form_AfterInsert() 10 On Error GoTo Err_Handler 20 AddToMRU "Orders", Me.OrderID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True 50 Resume Exit_Handler End Sub
Private Sub Form_AfterUpdate() 10 On Error GoTo Err_Handler 20 ValidateForm_RemoveHighlights Me Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True 50 Resume Exit_Handler End Sub
Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer) 10 On Error GoTo Err_Handler 20 Response = acDataErrContinue Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_BeforeDelConfirm", True 50 Resume Exit_Handler End Sub
Private Sub Form_BeforeInsert(Cancel As Integer)
10 On Error GoTo Err_Handler
'Set initial values for new record. Fires when the first character is entered into a new record.
20 Me.EmployeeID = Get_UserID()
30 Me.TaxRate = GetSystemSetting(ssTaxRate)
40 Me.OrderStatusID = enumOrderStatus.osNew
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "Form_BeforeInsert", True
70 Resume Exit_Handler
End SubPrivate Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) 30 If Not Cancel Then 40 ValidateForm_RemoveHighlights Me 50 End If Exit_Handler: 60 Exit Sub Err_Handler: 70 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 80 Resume Exit_Handler End Sub
Private Sub Form_Close()
10 On Error GoTo Err_Handler
20 CloseOrderDetailsForm Me
'Refresh Open List Forms
30 RequeryListForms
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "Form_Close", True
60 Resume Exit_Handler
End SubPrivate Sub Form_Current()
10 On Error GoTo Err_Handler
20 ValidateForm_RemoveHighlights Me 'Needed if user canceled a new record with yellow highlights on the form.
30 SetFormStatus
40 Me.Caption = "Order " & Me.OrderID 'Show the orderID in the caption, so several instances can easily be distinguished.
'This is too severe. Need to set Locked property on a per-control basis and depends on OrderStatus.
' This is not implemented
' Me.AllowEdits = (Me.OrderStatusID = enumOrderStatus.osNew)
50 LockControls
'ALTERNATIVE SYNTAX for .AllowAdditions = (Me.OrderStatusID = enumOrderStatus.osNew):
'If Me.OrderStatusID = enumOrderStatus.osNew Then .AllowAdditions = True Else .AllowAdditions = False
'or
'.AllowAdditions = IIf(Me.OrderStatusID = enumOrderStatus.osNew, True, False)
60 If Me.NewRecord Then
70 With Me.sfrmOrderLineItems.Form
80 .AllowAdditions = True
90 .AllowEdits = True
100 .AllowDeletions = True
110 End With
120 Me.cmdPrintInvoice.Visible = False
130 Else
140 With Me.sfrmOrderLineItems.Form
150 .AllowAdditions = (Me.OrderStatusID = enumOrderStatus.osNew)
160 .AllowEdits = .AllowAdditions
170 .AllowDeletions = .AllowAdditions
180 End With
190 Me.cmdPrintInvoice.Visible = (Me.OrderStatusID <> enumOrderStatus.osNew)
200 End If
Exit_Handler:
210 Exit Sub
Err_Handler:
220 clsErrorHandler.HandleError Me.Name, "Form_Current", True
230 Resume Exit_Handler
End SubPrivate Sub Form_Delete(Cancel As Integer)
10 On Error GoTo Err_Handler
Dim lngProductID As Long
20 If MsgBox(GetString(enumStrings.sDeleteRecord, "order"), vbYesNo Or vbQuestion) = vbYes Then
30 lngProductID = 0
'Delete of the Order causes a cascading delete of order line items
'We want to delete each line item so we can reallocate inventory for each product
'before the cascading delete happens
40 With Me.sfrmOrderLineItems.Form.RecordsetClone
50 If .RecordCount > 0 Then
60 .MoveFirst
70 While Not .EOF
80 lngProductID = !ProductID
90 .Delete
100 AllocateInventory lngProductID
110 .MoveNext
120 Wend
130 End If
140 End With
150 RemoveFromMRU "Orders", Me.OrderID
160 Else
170 Cancel = True
180 End If
Exit_Handler:
190 Exit Sub
Err_Handler:
200 clsErrorHandler.HandleError Me.Name, "Form_Delete", True
210 Resume Exit_Handler
End SubPrivate Sub Form_Load()
10 On Error GoTo Err_Handler
Dim dict As Scripting.Dictionary
20 If IsNull(TempVars!OpenArgs) Then
'New record.
30 If Not Me.NewRecord Then RunCommand acCmdRecordsGoToNew
40 Else
'TempVars!OpenArgs holds the OrderID to be displayed. Format: "OrderID=123"
50 Set dict = StringToDictionary(TempVars!OpenArgs)
'Although this code works perfectly, it is not a best practice. As the number of records grows (and Orders will be the fastest growing),
'it is better to open a single record.
' 'Use the recordsetclone to select the record with the requested OrderID.
' 'Note that "with me.recordsetclone" automatically cleans up the temporary objects at "end with".
' With Me.RecordsetClone
' .FindFirst "OrderID = " & dict("OrderID")
' Debug.Assert Not .NoMatch 'If this asserts, the orderID we just clicked on is not in the current recordsource.
' Me.Bookmark = .Bookmark 'The bookmark technique selects the current record.
' End With
'Open a single record.
60 Me.RecordSource = "select * from qryOrder where OrderID = " & dict("OrderID")
70 TempVars!OpenArgs = Null
80 Set dict = Nothing
90 If Not Me.NewRecord Then AddToMRU "Orders", Me.OrderID
100 End If
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "Form_Load", True
130 Resume Exit_Handler
End SubPrivate Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
'For multi-instance forms, Form_Open is too soon to process OpenArgs and set the current record. Postpone until Form_Load.
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError Me.Name, "Form_Open", True
40 Resume Exit_Handler
End Sub
'PURPOSE:
' Based on order status, lock controls that can no longer be edited because that would be illogical. E.g. you cannot change the Order date after the order has been created.
' These are the business rules for Northwind; in another company some fields may remain editable longer.Private Sub LockControls()
10 On Error GoTo Err_Handler
Dim varControls As Variant 'The Array function returns a variant containing an array.
Dim v As Variant
20 varControls = Array() 'Initialize, so it is no longer empty. Without this,error 13 = Type mismatch will occur when looping over varControls.
'List the controls that should be locked for each status. Some controls like OrderID and TaxAmount can be omitted because they cannot be edited.
30 Select Case Me.OrderStatusID
Case enumOrderStatus.osNew
40 varControls = Array("OrderID", "CustomerID", "EmployeeID", "OrderStatusName", "OrderDate", "InvoiceDate", "ShippedDate", "ShipperID", "PaymentMethod", "PaidDate", "txtTaxAmount", "txtTotal")
50 Case osInvoiced
60 varControls = Array("OrderID", "CustomerID", "EmployeeID", "OrderStatusName", "OrderDate", "InvoiceDate", "ShippingFee", "PaymentMethod", "PaidDate", "TaxRate", "TaxStatusID", "txtTaxAmount", "txtTotal")
70 Case osShipped
80 varControls = Array("OrderID", "CustomerID", "EmployeeID", "OrderStatusName", "OrderDate", "InvoiceDate", "ShippedDate", "ShipperID", "ShippingFee", "TaxRate", "TaxStatusID", "txtTaxAmount", "txtTotal")
90 Case osPaid
100 varControls = Array("OrderID", "CustomerID", "EmployeeID", "OrderStatusName", "OrderDate", "InvoiceDate", "ShippedDate", "ShipperID", "ShippingFee", "PaymentMethod", "PaidDate", "TaxRate", "TaxStatusID", "txtTaxAmount", "txtTotal")
110 Case osClosed
120 varControls = Array("OrderID", "CustomerID", "EmployeeID", "Notes", "OrderStatusName", "OrderDate", "InvoiceDate", "ShippedDate", "ShipperID", "ShippingFee", "PaymentMethod", "PaidDate", "TaxRate", "TaxStatusID", "txtTaxAmount", "txtTotal")
130 Case Else
140 If IsNull(Me.OrderStatusID) Then 'NOTE: You cannot have a Case Null, because comparisons with Null are Null, not True/False.
150 varControls = Array("OrderID", "OrderStatusName", "OrderDate", "InvoiceDate", "ShippedDate", "ShipperID", "PaymentMethod", "PaidDate", "txtTaxAmount", "txtTotal")
160 Else
170 Debug.Assert False 'Unexpected order status.
180 End If
190 End Select
'Initialize Locked property to False for all controls.
200 On Error Resume Next 'Not all controls have an Enabled Property
210 For Each v In Me.Controls
220 v.Locked = False
230 v.Enabled = True
240 v.BackShade = 100 '100 means no shading.
250 Next v
260 On Error GoTo Err_Handler 'Back to normal error handler.
'Set Locked property to True for the controls in the array.
270 For Each v In varControls
280 Me.Controls(v).Locked = True
290 Me.Controls(v).Enabled = False
300 Me.Controls(v).BackShade = 95 '95 means Darker 5%
310 Next v
Exit_Handler:
320 Exit Sub
Err_Handler:
330 clsErrorHandler.HandleError Me.Name, "Form_Open", True
340 Resume Exit_Handler
End SubPrivate Function PaidFieldsFilledOut() As Boolean
10 On Error GoTo Err_Handler
Dim blnIsValid As Boolean
20 blnIsValid = True 'Optimistic.
30 If IsNull(Me.PaymentMethod) Then
40 blnIsValid = False
50 HighlightControl Me.PaymentMethod
60 End If
70 If IsNull(Me.PaidDate) Then
80 blnIsValid = False
90 HighlightControl Me.PaidDate
100 End If
110 If Not blnIsValid Then
120 MsgBox GetString(sRequiredFields_Paid), vbExclamation
130 End If
140 PaidFieldsFilledOut = blnIsValid
Exit_Handler:
150 Exit Function
Err_Handler:
160 clsErrorHandler.HandleError Me.Name, "PaidFieldsFilledOut"
170 Resume Exit_Handler
End Function
'PURPOSE:
' Set form and control properties based on current status.Private Sub SetFormStatus()
10 On Error GoTo Err_Handler
20 If Me.NewRecord Then
30 With Me.sfrmOrderLineItems.Form
40 .AllowAdditions = True
50 .AllowEdits = True
60 .AllowDeletions = True
70 End With
80 Me.cmdPrintInvoice.Visible = False
90 Else
100 With Me.sfrmOrderLineItems.Form
110 .AllowAdditions = (Me.OrderStatusID = enumOrderStatus.osNew)
120 .AllowEdits = .AllowAdditions
130 .AllowDeletions = .AllowAdditions
140 End With
150 Me.cmdPrintInvoice.Visible = (Me.OrderStatusID <> enumOrderStatus.osNew)
160 End If
'Initialize workflow button colors. Alternatively we could set RGB values, but we want to support Themes.
170 Me.cmdCreateInvoice.ForeShade = 95 '95 means Darker 5%
180 Me.cmdShipOrder.ForeShade = 95
190 Me.cmdReceivePayment.ForeShade = 95
200 Me.cmdCloseOrder.ForeShade = 95
210 If Me.NewRecord Then
'Nothing more to do. OrderStatusID is null.
220 Else
230 LockControls
240 If Me.OrderStatusID = enumOrderStatus.osNew Then GoTo Exit_Handler
250 Me.cmdCreateInvoice.ForeShade = 70 '70 means Darker 30%
260 If Me.OrderStatusID = enumOrderStatus.osInvoiced Then GoTo Exit_Handler
270 Me.cmdShipOrder.ForeShade = 70
280 If Me.OrderStatusID = enumOrderStatus.osShipped Then GoTo Exit_Handler
290 Me.cmdReceivePayment.ForeShade = 70
300 If Me.OrderStatusID = enumOrderStatus.osPaid Then GoTo Exit_Handler
310 Me.cmdCloseOrder.ForeShade = 70
320 End If
Exit_Handler:
330 Exit Sub
Err_Handler:
340 clsErrorHandler.HandleError Me.Name, "SetFormStatus"
350 Resume Exit_Handler
End SubPrivate Sub SetLineItemsStatus(ByVal ods As enumOrderDetailStatus)
10 On Error GoTo Err_Handler
Dim sql As String
20 sql = StringFormatSQL("update OrderDetails set OrderDetailStatusID = {0} where OrderID = {1};", ods, Me.OrderID)
30 g_dbApp().Execute sql, dbFailOnError
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "SetLineItemsStatus"
60 Resume Exit_Handler
End SubPrivate Sub sfrmOrderLineItems_Enter()
'It doesn't make sense to allow user to (begin to) enter a Child row while the Parent row is not saved, due to Referential integrity. This also prevents a possible bug with subforms and recordsetclones that MSFT has not yet fixed (as of Oct-2023).
'10 If IsNull(Me.sfrmOrderLineItems.Form.OrderID) Then
'20 MsgBox GetString(sOrderBeforeOrderLineItems), vbExclamation
'30 Me.CustomerID.SetFocus
'40 End If
10 If Me.NewRecord Then
20 MsgBox GetString(sOrderBeforeOrderLineItems), vbExclamation
30 Me.CustomerID.SetFocus
40 End If
End SubPrivate Sub sfrmOrderLineItems_Exit(Cancel As Integer) 10 On Error GoTo Err_Handler 20 ValidateForm_RemoveHighlights Me.sfrmOrderLineItems.Form Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "sfrmOrderLineItems_Exit", True 50 Resume Exit_Handler End Sub
Private Function ShippingFeeFilledOut() As Boolean
10 On Error GoTo Err_Handler
Dim blnIsValid As Boolean
20 blnIsValid = True 'Optimistic.
30 If IsNull(Me.ShippingFee) Then
40 blnIsValid = False
50 HighlightControl Me.ShippingFee
60 End If
70 ShippingFeeFilledOut = blnIsValid
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError Me.Name, "ShippingFeeFilledOut"
100 Resume Exit_Handler
End FunctionPrivate Function ShippingFieldsFilledOut() As Boolean
10 On Error GoTo Err_Handler
Dim blnIsValid As Boolean
20 blnIsValid = True 'Optimistic.
30 If IsNull(Me.ShippedDate) Then
40 blnIsValid = False
50 HighlightControl Me.ShippedDate
60 End If
70 If IsNull(Me.ShipperID) Then
80 blnIsValid = False
90 HighlightControl Me.ShipperID
100 End If
110 If IsNull(Me.ShippingFee) Then
120 blnIsValid = False
130 HighlightControl Me.ShippingFee
140 End If
150 If Not blnIsValid Then
160 MsgBox GetString(sRequiredFields_Shipping), vbExclamation
170 End If
180 ShippingFieldsFilledOut = blnIsValid
Exit_Handler:
190 Exit Function
Err_Handler:
200 clsErrorHandler.HandleError Me.Name, "ShippingFieldsFilledOut"
210 Resume Exit_Handler
End FunctionRecord source: qryOrderList
Filter: OrderStatusID <> 1 · Order by: [qryOrderList].[OrderDetailStatusName], [qryOrderList].[OrderStatusName] · Has VBA module
Events — OnOpen: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Default value | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Orders | ||||||
| boxHeaderControls | Rectangle | |||||||
| cmdAddOrder | Command button | Add Order | Click: cmdAddOrder_Click | |||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/40c61470-c7c4-4fdb-9f90-d9af2a807c7a | |||||
| cmdShowFilter | Command button | Show Filter | Click: cmdShowFilter_Click | |||||
| CompanyName | Text box | CompanyName | ||||||
| fraFilter | Option group | 1 | ||||||
| FullName | Text box | FullNameFNLN | ||||||
| imgNorthwindTradersLogo | Image | |||||||
| Label0 | Label | # | ||||||
| Label1 | Label | Employee | ||||||
| Label11 | Label | Paid Date | ||||||
| Label12 | Label | Status | ||||||
| Label124 | Label | Sum: | ||||||
| Label126 | Label | Count: | ||||||
| Label129 | Label | All Orders | ||||||
| Label2 | Label | Customer | ||||||
| Label3 | Label | Order Date | ||||||
| Label4 | Label | Shipped Date | ||||||
| Label66 | Label | Open Orders | ||||||
| Label68 | Label | Recent Orders | ||||||
| Label70 | Label | My Orders | ||||||
| Label8 | Label | Order Total | ||||||
| lblFilterBY | Label | Filter by: | ||||||
| lblOrderDetailStatusName | Label | Detail Status | ||||||
| Option128 | Option button | |||||||
| Option65 | Option button | |||||||
| Option67 | Option button | |||||||
| Option69 | Option button | |||||||
| OrderDateOnly | Text box | OrderDateOnly | ||||||
| OrderDetailStatusName | Text box | OrderDetailStatusName | ||||||
| OrderID | Text box | OrderID | Click: OrderID_Click | |||||
| OrderTotal | Text box | OrderTotal | ||||||
| PaidDate | Text box | PaidDate | ||||||
| ShippedDate | Text box | ShippedDate | ||||||
| StatusName | Text box | OrderStatusName | ||||||
| Text125 | Text box | =Count([OrderID]) | ||||||
| txtSumOrderTotal | Text box | =Sum([OrderTotal]) |
Private Sub cmdAddOrder_Click() 10 On Error GoTo Err_Handler 20 OpenOrderDetailsForm Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdAddOrder_Click", True 50 Resume Exit_Handler End Sub
Private Sub cmdShowFilter_Click()
10 On Error GoTo Err_Handler
Dim strOpenArgs As String
20 If Me.Form.FilterOn = False Then
30 MsgBox "This form has not been filtered.", vbOKOnly Or vbInformation
40 Else
'OpenArgs uses Replace function to make the filter more readable for humans.
50 strOpenArgs = StringFormat("Header={0}&Message={1}", "Form Filter", Replace(Me.Form.Filter, "[qryOrderList].", ""))
60 DoCmd.OpenForm "frmGenericDialog", acNormal, , , acFormReadOnly, acDialog, strOpenArgs
70 If IsFormOpen("frmGenericDialog") Then
80 DoCmd.Close acForm, "frmGenericDialog", acSaveNo
90 End If
100 End If
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "cmdShowFilter_Click", True
130 Resume Exit_Handler
End SubPrivate Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
'Clean up anything left by a previous session
20 Me.FilterOn = False
30 Me.Filter = ""
'Apply the filter for the default value of the fraFilter group box.
40 fraFilter_AfterUpdate
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "Form_Open", True
70 Resume Exit_Handler
End SubPrivate Sub fraFilter_AfterUpdate()
10 On Error GoTo Err_Handler
20 Select Case Me.fraFilter
Case 1 '1=Open Orders
30 Me.Filter = "OrderStatusID <> 1" 'Open orders are all except in Status=1=Closed.
40 Case 2 '2=Recent Orders
50 Me.Filter = StringFormatSQL("OrderDate >= {0}", DateAdd("d", -30, Date))
60 Case 3 '3=My Orders
70 Me.Filter = "EmployeeID = " & Get_UserID()
80 Case 4 '4=All Orders
90 Me.Filter = ""
100 End Select
110 Me.FilterOn = True 'This turns the filter on.
120 If Me.fraFilter = 2 And Me.RecordsetClone.RecordCount = 0 Then
130 MsgBox GetString(sNoRecentOrders), vbInformation
140 End If
Exit_Handler:
150 Exit Sub
Err_Handler:
160 clsErrorHandler.HandleError Me.Name, "fraFilter_AfterUpdate", True
170 Resume Exit_Handler
180 Resume
End SubPrivate Sub OrderID_Click() 10 On Error GoTo Err_Handler 20 OpenOrderDetailsFormNew Me.OrderID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "OrderID_Click", True 50 Resume Exit_Handler End Sub
Record source: qryProductDetail
Filter: ProductID = 1 · Has VBA module
Events — OnLoad: [Event Procedure], OnCurrent: [Event Procedure], OnClose: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Default value | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|---|
| Auto_Header0 | Text box | =IIf(Nz([ProductID],0)>0,"Product: " & [ProductName],"New Product") | ||||||
| boxHeaderControls | Rectangle | |||||||
| cboFindProduct | Combo box | SELECT qryProductDetail.ProductID, qryProductDetail.ProductName FROM qryProductDetail ORDER BY qryProductDetail.ProductName; | ||||||
| cboProductCategoryID | Combo box | ProductCategoryID | qrycboProductCategory | |||||
| chkDiscontinued | Check box | Discontinued | ||||||
| cmdAddProduct | Command button | Add Product | Click: cmdAddProduct_Click | |||||
| cmdDeleteProduct | Command button | Delete Product | Click: cmdDeleteProduct_Click | |||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/5f829aa2-41df-4e0a-bab4-5a8036ae741c | |||||
| cmdReorderProduct | Command button | Reorder Product | Click: cmdReorderProduct_Click | |||||
| ctlInventorySubform | Subform/Subreport | |||||||
| ctlOrderSubform | Subform/Subreport | |||||||
| ctlPOSubform | Subform/Subreport | |||||||
| ctlVendorSubform | Subform/Subreport | sfrmProductDetail_Vendors | ||||||
| EmptyCell228 | Empty cell | |||||||
| EmptyCell339 | Empty cell | |||||||
| EmptyCell340 | Empty cell | |||||||
| EmptyCell351 | Empty cell | |||||||
| imgNorthwindTradersLogo | Image | |||||||
| Label176 | Label | Product Code | ||||||
| Label177 | Label | Product Name | ||||||
| Label178 | Label | Product Description | ||||||
| Label179 | Label | Unit Price | ||||||
| Label215 | Label | Unit Cost | ||||||
| Label232 | Label | Reorder Level | ||||||
| Label233 | Label | Target Level | ||||||
| Label234 | Label | Qty Per Unit | ||||||
| Label236 | Label | Min Reorder Qty | ||||||
| Label237 | Label | Product Category | ||||||
| Label343 | Label | Product ID | ||||||
| lblDiscontinued | Label | Discontinued | ||||||
| lblFindProduct | Label | Go to Product: | ||||||
| lblQtyAllocated | Label | Qty Allocated | ||||||
| lblQtyAvailable | Label | Qty Avail. to Sell | ||||||
| lblQtyNoStock | Label | Qty No Stock | ||||||
| lblQtyOnOrder | Label | Qty on Order | ||||||
| lblQtyToReorder | Label | Qty to Reorder | ||||||
| lblZoomTip | Label | TIP: Use Shift+F2 for Zoom window | ||||||
| pgInventory | Page | Stock Takes | ||||||
| pgOrders | Page | Customer Orders | ||||||
| PgPurchaseOrders | Page | Purchase Orders | ||||||
| pgVendors | Page | Product Vendors | ||||||
| tabProducts | Tab control | |||||||
| txtMinimumReorderQuantity | Text box | MinimumReorderQuantity | ||||||
| txtModified | Text box | =RecordModifiedString([AddedBy],[AddedOn],[ModifiedBy],[ModifiedOn]) | ||||||
| txtProductCode | Text box | ProductCode | ||||||
| txtProductDescription | Text box | ProductDescription | ||||||
| txtProductID | Text box | ProductID | ||||||
| txtProductName | Text box | ProductName | ||||||
| txtQtyAllocated | Text box | 0 | ||||||
| txtQtyAvailable | Text box | 0 | ||||||
| txtQtyNoStock | Text box | 0 | ||||||
| txtQtyOnOrder | Text box | 0 | ||||||
| txtQtyToReorder | Text box | 0 | ||||||
| txtQuantityPerUnit | Text box | QuantityPerUnit | ||||||
| txtReorderLevel | Text box | ReorderLevel | ||||||
| txtStandardUnitCost | Text box | StandardUnitCost | ||||||
| txtTargetLevel | Text box | TargetLevel | ||||||
| txtUnitPrice | Text box | UnitPrice |
Public Sub CalculateLevels()
10 On Error GoTo Err_Handler
Dim dtLastStockTake As Date
20 If Me.NewRecord Then GoTo Exit_Handler
30 Me.txtQtyAvailable = ProductToSell(Me.ProductID)
40 Me.txtQtyNoStock = ProductNoStock(Me.ProductID)
50 dtLastStockTake = ProductLastStockTakeDate(Me.ProductID)
60 Me.txtQtyAllocated = ProductAllocated(Me.ProductID)
70 Me.txtQtyOnOrder = ProductOnOrder(Me.ProductID)
80 Me.txtQtyToReorder = ProductReorderQuantity(Me.ProductID)
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError Me.Name, "CalculateLevels"
110 Resume Exit_Handler
End SubPrivate Sub cboFindProduct_AfterUpdate()
10 On Error GoTo Err_Handler
Dim lngProductID As Long
20 lngProductID = Me.cboFindProduct
'Remove the filter because the recordset is searched as filtered
30 If Me.FilterOn Then Me.FilterOn = False
40 Me.DataEntry = False
50 DoCmd.SearchForRecord acDataForm, Me.Name, acFirst, "[ProductID] = " & lngProductID
'============UI Option==============
'Reset Product selection combo
'Comment if the selected product should remain visible in the combo
60 Me.cboFindProduct = ""
'===================================
70 ControlStates
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError Me.Name, "cboFindProduct_AfterUpdate", True
100 Resume Exit_Handler
End SubPrivate Sub cboProductCategoryID_AfterUpdate() 10 On Error GoTo Err_Handler 20 SetProductCode Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cboProductCategoryID_AfterUpdate", True 50 Resume Exit_Handler End Sub
Private Sub chkDiscontinued_AfterUpdate() 10 On Error GoTo Err_Handler 20 ControlStates Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "chkDiscontinued_AfterUpdate", True 50 Resume Exit_Handler End Sub
Private Sub cmdAddProduct_Click() 10 On Error GoTo Err_Handler 20 DoCmd.GoToRecord , "", acNewRec Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdAddProduct_Click", True 50 Resume Exit_Handler End Sub
Private Sub cmdDeleteProduct_Click()
10 On Error GoTo Err_Handler
Dim strMessage As String
20 strMessage = ""
'Check if related records will prevent deleting this Product
30 Select Case True
Case DCount("OrderID", "OrderDetails", "ProductID = " & Me.ProductID) > 0
40 strMessage = "Order"
50 Case DCount("PurchaseOrderDetailID", "PurchaseOrderDetails", "ProductID = " & Me.ProductID) > 0
60 strMessage = "Purchase Order"
70 End Select
80 If strMessage > "" Then
'================Equivalent Syntax==============================
' Two methods of generating a message box
' The first is default: Building the messagebox message
' The second uses the custom Function GetString in conjunction
' with the Enumeration enumStrings.
'Method 1
' MsgBox "Product '" & Me.ProductName & "' cannot be deleted because it has a related " _
' & strMessage & " record.", vbExclamation or vbOKOnly, "Cannot Delete"
'Method 2
90 MsgBox GetString(enumStrings.sCannotDelete, "Product", Me.ProductName, strMessage) _
, vbExclamation Or vbOKOnly, "Cannot Delete"
'===============================================================
100 GoTo Exit_Handler
110 End If
'Delete child records in Companies (Vendors) and StockTake (Inventory) first
'====================Equivalent Syntax==========================
120 g_dbApp().Execute "DELETE * FROM StockTake WHERE ProductID = " & Me.ProductID & ";", dbFailOnError
' DoCmd.RunSQL "DELETE * FROM StockTake WHERE ProductID = " & Me.ProductID & ";"
' ================================================================
'================Equivalent Syntax==============================
130 g_dbApp().Execute "DELETE * FROM ProductVendors WHERE ProductID = " & Me.ProductID & ";", dbFailOnError
' DoCmd.RunSQL "DELETE * FROM ProductVendors WHERE ProductID = " & Me.ProductID & ";"
'===============================================================
140 If Not Form.NewRecord Then
150 Me.Refresh
160 DoCmd.RunCommand acCmdDeleteRecord
170 DoCmd.RunCommand acCmdRemoveFilterSort
180 Me.cboFindProduct.Requery
190 RequeryProductList
200 Else
210 Me.Undo
220 End If
Exit_Handler:
230 Exit Sub
Err_Handler:
240 clsErrorHandler.HandleError Me.Name, "cmdDeleteProduct_Click", True
250 Resume Exit_Handler
End SubPrivate Sub cmdReorderProduct_Click()
10 On Error GoTo Err_Handler
Dim varRelatedID As Variant
Dim lngTargetPOID As Long
Dim lngVendorID As Long
Dim aryVendor() As String
Dim strInputBox As String
Dim strWhere As String
Dim intOrderQuantity As Integer
Dim lngTargetLineID As Long
20 If Me.NewRecord And Me.Dirty = False Then GoTo Exit_Handler
30 If Me.Dirty Then
'====================Equivalent Syntax==========================
40 Me.Dirty = False
' DoCmd.RunCommand acCmdSaveRecord
'===============================================================
50 End If
'Check if an Order for this Product is outstanding.
60 If Me.txtQtyOnOrder <> 0 Then
70 strWhere = StringFormatSQL("ProductID = {0} AND StatusID in ({1},{2},{3})", Me.ProductID _
, enumPurchaseOrderStatus.posApprove _
, enumPurchaseOrderStatus.posNew _
, enumPurchaseOrderStatus.posSubmitted)
80 varRelatedID = DLookup("PurchaseOrderID", "qryProductPurchaseOrder", strWhere)
90 If Nz(varRelatedID, 0) > 0 Then
'Open frmPurchaseOrders and go to the outstanding Order
100 OpenPurchaseOrderDetailsForm varRelatedID
110 GoTo Exit_Handler
120 End If
130 End If
'Check if this product has at least one vendor defined before allowing a purchase order.
'The Purchase Order Line items subform requires a pre-defined vendor for each product
140 varRelatedID = DLookup("Count(ProductVendorID) & ""|"" & First(VendorID)", "ProductVendors", "ProductID = " & Me.ProductID)
150 If Nz(varRelatedID, 0) = "0|" Then
'Prompt user to enter a Vendor
160 MsgBox "At least one product vendor must be defined for this product before a purchase order can be created.", _
vbExclamation Or vbOKOnly, "Vendor Required"
'Set focus on the Product Vendors tab
170 Me.tabProducts.Pages.Item("pgVendors").SetFocus
180 GoTo Exit_Handler
190 Else
200 aryVendor = Split(varRelatedID, "|")
210 End If
220 If aryVendor(0) = 1 Then 'If we counted a single vendor, we don't have to prompt for a vendor choice
230 lngVendorID = aryVendor(1)
240 Else
'Prompt user to choose a vendor from multiple possible vendors
'====================Equivalent Syntax=========================
250 DoCmd.OpenForm "frmSelectVendorDialog", , , , , acDialog, "Vendor Required|Select a Vendor|" & Me.ProductID
' DoCmd.OpenForm FormName:="frmSelectVendorDialog", WindowMode:=acDialog, OpenArgs:="Vendor Required|Select a Vendor|" & Me.ProductID
'===============================================================
260 If IsFormOpen("frmSelectVendorDialog") Then
270 lngVendorID = Form_frmSelectVendorDialog.lstVendor
'====================Equivalent Syntax=========================
280 DoCmd.Close acForm, "frmSelectVendorDialog" 'Note the explicit naming of the form to be closed. Without it, the active form is closed which may not always be what you want.
' DoCmd.Close ObjectType:=acForm, ObjectName:="frmSelectVendorDialog"
'===============================================================
290 Else
'User cancelled.
300 GoTo Exit_Handler
310 End If
320 End If
'Reorder Quantity: txtQtyReorder > txtMinimumOrderQuantity > prompt user for quantity
330 If Me.txtQtyToReorder = 0 Then
340 intOrderQuantity = Nz(Me.txtMinimumReorderQuantity, 0)
350 If intOrderQuantity = 0 Then
360 strInputBox = InputBox("Specify order quantity:", "Quantity", 0)
370 If strInputBox = "" Then GoTo Exit_Handler 'User clicked Cancel.
380 intOrderQuantity = CInt(strInputBox)
390 End If
400 If intOrderQuantity = 0 Then GoTo Exit_Handler
410 Else
420 intOrderQuantity = Me.txtQtyToReorder
430 End If
'Check if there's a Purchase Order in "New" status for the Vendor. If so, we'll append to that. DMin will get the oldest PO.
440 varRelatedID = DMin("PurchaseOrderID", "PurchaseOrders" _
, StringFormatSQL("VendorID = {0} AND StatusID = {1}" _
, lngVendorID, enumPurchaseOrderStatus.posNew))
450 If Nz(varRelatedID, 0) > 0 Then
'Append a new line item to the existing purchase order
460 lngTargetPOID = varRelatedID
470 lngTargetLineID = AddPurchaseOrderDetail(lngTargetPOID, Me.ProductID, intOrderQuantity, Me.StandardUnitCost)
480 Else
'Create the new Purchase Order
490 lngTargetPOID = ReorderProduct(Me.ProductID, lngVendorID, intOrderQuantity, Me.StandardUnitCost)
500 End If
'If no new Purchase Order, fail the procedure and exit
510 If lngTargetPOID = 0 Then
520 MsgBox "Reorder Failed.", vbExclamation Or vbOKOnly, "Reorder Fail"
530 GoTo Exit_Handler
540 End If
'Requery the Quantities and set control formats accordingly
550 ControlStates
'Set focus on the Purchase Orders tab and requery its subform to reflect the new Purchase Order
560 Me.tabProducts.Pages.Item("pgPurchaseOrders").SetFocus
570 Me.ctlPOSubform.Form.Requery
580 OpenPurchaseOrderDetailsForm lngTargetPOID
590 AddToMRU "PurchaseOrders", lngTargetPOID
'Update PO list form if loaded
'=================Equivalent Syntax=============================
600 If IsFormOpen("frmPurchaseOrderList") Then 'This option is a custom function
' or
' If SysCmd(acSysCmdGetObjectState, acForm, "frmPurchaseOrderList") <> 0 Then
' or
' If CurrentProject.AllForms("frmPurchaseOrderList").IsLoaded Then
'===============================================================
610 Forms!frmPurchaseOrderList.Requery
620 End If
'If the Product List is loaded, requery to reflect the "on order" quantity.
630 RequeryProductList
Exit_Handler:
640 Exit Sub
Err_Handler:
650 Select Case Err.Number
Case 2186, 91, 13 '2186=error on switching to design view; 91, 13=User cleared input box value or cancelled it
660 Resume Exit_Handler
670 Case Else
680 clsErrorHandler.HandleError Me.Name, "cmdReorderProduct_Click"
690 Resume Exit_Handler
700 End Select
710 Resume
End Sub
'PURPOSE:
' Sets UI statesPublic Sub ControlStates()
10 On Error GoTo Err_Handler
20 If Me.NewRecord Then
30 Me.cmdDeleteProduct.Visible = False
40 Me.cmdReorderProduct.Visible = False
50 Me.Caption = "New Product"
'Ensure focus is not on pgOrders or PgPurchaseOrders, before making them not visible
60 Me.txtProductName.SetFocus
70 Me.pgOrders.Visible = False
80 Me.PgPurchaseOrders.Visible = False
'===============================================================
'resolves "ghost" tab display of Orders & Purchase Orders
90 Me.txtProductName.SetFocus
100 Me.tabProducts.Visible = False
110 Me.tabProducts.Visible = True
'===============================================================
'Zero out the calculated fields
120 Me.txtQtyAllocated = 0
130 Me.txtQtyAvailable = 0
140 Me.txtQtyToReorder = 0
150 Me.txtQtyOnOrder = 0
160 Me.txtQtyToReorder.ForeColor = Me.txtQtyAvailable.ForeColor
170 Me.lblQtyToReorder.ForeColor = Me.lblQtyAvailable.ForeColor
180 Me.txtQtyToReorder.FontBold = False
190 Me.lblQtyToReorder.FontBold = False
200 Else
'Populate the inventory level text boxes
210 CalculateLevels
220 Me.cmdDeleteProduct.Visible = True
230 Me.cmdReorderProduct.Visible = True
240 Me.Caption = "Product: " & Me.ProductName
250 Me.pgOrders.Visible = True
260 Me.PgPurchaseOrders.Visible = True
'Set formatting of inventory level text boxes
270 If Me.txtQtyToReorder > 0 And Me.chkDiscontinued = False Then
280 Me.txtQtyToReorder.ForeColor = vbRed
290 Me.lblQtyToReorder.ForeColor = vbRed
300 Me.txtQtyToReorder.FontBold = True
310 Me.lblQtyToReorder.FontBold = True
320 Else
330 Me.txtQtyToReorder.ForeColor = Me.txtQtyAvailable.ForeColor
340 Me.lblQtyToReorder.ForeColor = Me.lblQtyAvailable.ForeColor
350 Me.txtQtyToReorder.FontBold = False
360 Me.lblQtyToReorder.FontBold = False
370 End If
380 End If
'Display the Discontinued checbox's label in red if the product is discontinued
390 If Me.chkDiscontinued = True Then
400 Me.cmdReorderProduct.Visible = False
410 Me.lblDiscontinued.BackColor = vbRed
420 Me.lblDiscontinued.ForeColor = vbWhite
430 Else
440 Me.cmdReorderProduct.Visible = Not Me.NewRecord
450 Me.lblDiscontinued.BackColor = vbWhite
460 Me.lblDiscontinued.ForeColor = RGB(89, 89, 89)
470 End If
480 ValidateForm_RemoveHighlights Me 'Needed if user canceled a new record with yellow highlights on the form.
Exit_Handler:
490 Exit Sub
Err_Handler:
500 clsErrorHandler.HandleError Me.Name, "ControlStates"
510 Resume Exit_Handler
End SubPrivate Sub Form_Activate()
10 On Error GoTo Err_Handler
20 If Not Me.NewRecord Then
'refresh counts that might have been altered on another form
30 ControlStates
40 Me.ctlOrderSubform.Requery
50 Me.ctlPOSubform.Requery
60 End If
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "Form_Activate", True
90 Resume Exit_Handler
End SubPrivate Sub Form_AfterDelConfirm(Status As Integer)
10 On Error GoTo Err_Handler
20 Me.cboFindProduct.Requery
'If the Products list is loaded, update it
30 RequeryProductList
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "Form_AfterDelConfirm", True
60 Resume Exit_Handler
End SubPrivate Sub Form_AfterInsert()
10 On Error GoTo Err_Handler
20 Me.cboFindProduct.Requery
'Set control formatting and calculated quantities
30 ControlStates
'If the Products list is loaded, update it so the new record will show.
40 RequeryProductList
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True
70 Resume Exit_Handler
End SubPrivate Sub Form_AfterUpdate() 10 On Error GoTo Err_Handler 20 RequeryProductList 30 ControlStates Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True 60 Resume Exit_Handler End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) 30 If Me.txtStandardUnitCost <= 0 Then 40 MsgBox "Standard Unit Cost must be > 0", vbOKOnly Or vbExclamation, "Cost Required" 50 Cancel = True 60 Me.txtStandardUnitCost.SetFocus 70 End If Exit_Handler: 80 Exit Sub Err_Handler: 90 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 100 Resume Exit_Handler End Sub
Private Sub Form_Close()
10 On Error GoTo Err_Handler
'clear the tab subform source objects to enable lazy loading
20 Me.ctlOrderSubform.SourceObject = ""
30 Me.ctlInventorySubform.SourceObject = ""
40 Me.ctlVendorSubform.SourceObject = ""
50 Me.ctlPOSubform.SourceObject = ""
'Refresh any open list forms
60 RequeryListForms
Exit_Handler:
70 Exit Sub
Err_Handler:
80 If Err.Number = 2467 Then '2467 = Error switching to design view
'do nothing
90 Else
100 clsErrorHandler.HandleError Me.Name, "Form_Close"
110 End If
120 Resume Exit_Handler
End SubPrivate Sub Form_Current() 10 On Error GoTo Err_Handler 20 ControlStates Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_Current", True 50 Resume Exit_Handler End Sub
Private Sub Form_Delete(Cancel As Integer) 10 On Error GoTo Err_Handler 20 RemoveFromMRU "Products", Me.ProductID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_Delete", True 50 Resume Exit_Handler End Sub
Private Sub Form_Load()
10 On Error GoTo Err_Handler
'Forces the subform to load in the first visible tab
'This allows the tab order to be changed without causing errors due to late binding.
20 tabProducts_Change
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "Form_Load", True
50 Resume Exit_Handler
End SubPrivate Sub imgHelp_Click()
10 On Error GoTo Err_Handler
' Application.FollowHyperlink ("<>")
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError Me.Name, "imgHelp_Click", True
40 Resume Exit_Handler
End SubPrivate Sub SetProductCode()
10 On Error GoTo Err_Handler
Dim varPrefix As Variant
20 If Nz(Me.ProductID, 0) = 0 Then GoTo Exit_Handler
30 If Nz(Me.cboProductCategoryID, 0) > 0 Then
40 varPrefix = DLookup("ProductCategoryCode", "ProductCategories", "ProductCategoryID = " & Me.cboProductCategoryID)
50 Me.txtProductCode = "NWT" & varPrefix & "-" & Me.ProductID
60 End If
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "SetProductCode"
90 Resume Exit_Handler
End SubPrivate Sub tabProducts_Change()
10 On Error GoTo Err_Handler
'Late Binding:
'Setting the source object for the subform only when the tab is selected by the user
'can improve form performance. This is called Late Binding.
20 Select Case tabProducts.Pages.Item(tabProducts.Value).Name
Case "pgInventory"
30 If Me.ctlInventorySubform.SourceObject = "" Then Me.ctlInventorySubform.SourceObject = "sfrmProductDetail_StockTake"
40 Case "PgOrders"
50 If Me.ctlOrderSubform.SourceObject = "" Then Me.ctlOrderSubform.SourceObject = "sfrmProductDetail_Orders"
60 Case "PgPurchaseOrders"
70 If Me.ctlPOSubform.SourceObject = "" Then Me.ctlPOSubform.SourceObject = "sfrmProductDetail_PurchaseOrders"
80 Case "pgVendors"
90 If Me.ctlVendorSubform.SourceObject = "" Then Me.ctlVendorSubform.SourceObject = "sfrmProductDetail_Vendors"
100 End Select
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "tabProducts_Change", True
130 Resume Exit_Handler
End SubPrivate Sub txtTargetLevel_AfterUpdate()
10 On Error GoTo Err_Handler
20 If Not Me.NewRecord Then
'Save the record
'====================Equivalent Syntax==========================
30 Me.Dirty = False
' DoCmd.RunCommand acCmdSaveRecord 'note that this (docmd) syntax will err in break (debug) mode
'===============================================================
'Re-calculate inventory levels and adjust control formatting accordingly
40 ControlStates
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "txtTargetLevel_AfterUpdate", True
80 Resume Exit_Handler
End SubRecord source: qryProductList
Filter: ([qryProductList].[ProductName]="Almonds") · Order by: [qryProductList].[ProductName], [qryProductList].[ProductID] · Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Allocated | Text box | Allocated | |||||
| Auto_Header0 | Label | Products | |||||
| BoxCaptions | Rectangle | ||||||
| cmdAddProduct | Command button | Add Product | Click: cmdAddProduct_Click | ||||
| cmdExport | Command button | Export to Excel | Click: cmdExport_Click | ||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/5f829aa2-41df-4e0a-bab4-5a8036ae741c | ||||
| Discontinued | Check box | Discontinued | |||||
| imgNorthwindTradersLogo | Image | ||||||
| Label0 | Label | Product ID | |||||
| Label1 | Label | Product Code | |||||
| Label10 | Label | Min. Reorder Qty | |||||
| Label170 | Label | Available | |||||
| Label196 | Label | Qty On Order | |||||
| Label2 | Label | Product | |||||
| Label290 | Label | No Stock | |||||
| Label6 | Label | Reorder Level | |||||
| Label7 | Label | Target Level | |||||
| Label9 | Label | Discontinued | |||||
| lblAllocated | Label | Allocated | |||||
| MinimumReorderQuantity | Text box | MinimumReorderQuantity | |||||
| NoStock | Text box | NoStock | |||||
| ProductCode | Text box | ProductCode | |||||
| ProductID | Text box | ProductID | Click: ProductID_Click | ||||
| ProductName | Text box | ProductName | |||||
| QuantityOnOrder | Text box | QuantityOnOrder | |||||
| ReorderLevel | Text box | ReorderLevel | |||||
| TargetLevel | Text box | TargetLevel | |||||
| ToSell | Text box | ToSell |
Private Sub cmdAddProduct_Click()
10 On Error GoTo Err_Handler
Dim strForm As String
20 strForm = "frmProductDetail"
'Check if frmProductDetail is already open. If so, navigate it to a new record
'=================Equivalent Syntax=============================
30 If IsFormOpen(strForm) Then 'This option is a custom function
' or
' If SysCmd(acSysCmdGetObjectState, acForm, strForm) <> 0 Then
' or
' If CurrentProject.AllForms(strForm).IsLoaded Then
'===============================================================
40 Forms(strForm).SetFocus
50 DoCmd.GoToRecord acForm, strForm, acNewRec
60 Else
'=====================Equivalent Syntax=========================
70 DoCmd.OpenForm strForm, , , , acFormAdd
' DoCmd.OpenForm FormName:=strForm, DataMode:=acFormAdd
'===============================================================
80 End If
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError Me.Name, "cmdAddProduct_Click", True
110 Resume Exit_Handler
End SubPrivate Sub cmdExport_Click()
10 On Error GoTo Err_Handler
Dim strFilePath As String
'set path to the same location as Northwind
20 strFilePath = CurrentProject.Path & "\Northwind Products.xlsx"
30 DoCmd.OutputTo acOutputQuery, "qryProductList_Export", acFormatXLSX, strFilePath
40 Application.FollowHyperlink strFilePath
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "cmdExport_Click", True
70 Resume Exit_Handler
End SubPrivate Sub ProductID_Click()
10 On Error GoTo Err_Handler
'=====================Equivalent Syntax=========================
20 DoCmd.OpenForm "frmProductDetail", , , "ProductID = " & Me.ProductID
' DoCmd.OpenForm FormName:="frmProductDetail", WhereCondition:="ProductID = " & Me.ProductID
'===============================================================
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "ProductID_Click", True
50 Resume Exit_Handler
End SubRecord source: qryPurchaseOrder
Has VBA module
Events — OnOpen: [Event Procedure], OnLoad: [Event Procedure], OnCurrent: [Event Procedure], OnClose: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| ApprovedBy | Text box | ApprovedBy | |||||
| ApprovedByID | Text box | ApprovedByID | |||||
| ApprovedDate | Text box | ApprovedDate | |||||
| Auto_Header0 | Label | Purchase Order | |||||
| boxHeaderControls | Rectangle | ||||||
| cmdAddNostock | Command button | Add Reorder Items | Click: cmdAddNostock_Click | ||||
| cmdAddPO | Command button | Add PO | Click: cmdAddPO_Click | ||||
| cmdApprovePO | Command button | 2: Approve PO | Click: cmdApprovePO_Click | ||||
| cmdClosePO | Command button | 4: Close PO | Click: cmdClosePO_Click | ||||
| cmdDeletePO | Command button | Delete PO | Click: cmdDeletePO_Click | ||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/74482757-0b12-4639-beae-b8905f0f3ca9 | ||||
| cmdReceivePO | Command button | 3: Receive PO | Click: cmdReceivePO_Click | ||||
| cmdSubmitPO | Command button | 1: Submit PO | Click: cmdSubmitPO_Click | ||||
| imgNorthwindTradersLogo | Image | ||||||
| Label12 | Label | Submitted Date | |||||
| Label15 | Label | Vendor | |||||
| Label152 | Label | TIP: Use Shift+F2 for Zoom window | |||||
| Label155 | Label | PO Status | |||||
| Label161 | Label | 4: Shipping Fee | |||||
| Label164 | Label | Tax Amount | |||||
| Label165 | Label | 4: Payment Method | |||||
| Label167 | Label | Total | |||||
| Label169 | Label | Approved Date | |||||
| Label171 | Label | Approved By | |||||
| Label175 | Label | Received Date | |||||
| Label21 | Label | Payment Date | |||||
| Label48 | Label | Notes | |||||
| Label6 | Label | Submitted By | |||||
| Label9 | Label | Purchase Order ID | |||||
| lblWorkflow | Label | -------------------------- Workflow ------------------------------------ | |||||
| Notes | Text box | Notes | |||||
| PaymentAmount | Text box | PaymentAmount | |||||
| PaymentDate | Text box | PaymentDate | |||||
| PaymentMethod | Combo box | PaymentMethod | Credit Card;Check;Cash | ||||
| PurchaseOrderID | Text box | PurchaseOrderID | |||||
| ReceivedDate | Text box | ReceivedDate | |||||
| sfrmPurchaseOrderLineItems | Subform/Subreport | sfrmPurchaseOrderLineItems | |||||
| ShippingFee | Text box | ShippingFee | |||||
| StatusID | Text box | StatusID | |||||
| StatusName | Text box | StatusName | |||||
| SubmittedBy | Text box | SubmittedBy | |||||
| SubmittedByID | Text box | SubmittedByID | |||||
| SubmittedDate | Text box | SubmittedDate | |||||
| TaxAmount | Text box | TaxAmount | |||||
| txtModified | Text box | =RecordModifiedString([AddedBy],[AddedOn],[ModifiedBy],[ModifiedOn]) | |||||
| txtTaxAmount | Text box | =[txtTaxRate]*[sfrmPurchaseOrderLineItems].[Form].[txtSubTotal] | |||||
| txtTaxRate | Text box | =GetSystemSetting(6) | |||||
| txtTotal | Text box | =[sfrmPurchaseOrderLineItems].[Form].[txtSubTotal]+[txtTaxAmount]+Nz([ShippingFee]) | |||||
| VendorID | Combo box | VendorID | qrycboVendors |
Private Sub AllocatePurchaseOrder(ByVal lngPurchaseOrderID As Long)
10 On Error GoTo Err_Handler
Dim rsPO As DAO.Recordset
Dim intPOQty As Integer
Dim sql As String
'Since update queries quickly became not updatable, we will use recordsets.
20 sql = "select * from PurchaseOrderDetails where PurchaseOrderID = " & lngPurchaseOrderID
30 Set rsPO = g_dbApp().OpenRecordset(sql, dbOpenSnapshot)
40 While Not rsPO.EOF 'Loop over the line items of this PO.
50 intPOQty = rsPO!Quantity
60 AllocateInventory rsPO!ProductID
70 rsPO.MoveNext
80 Wend
90 rsPO.Close
100 Set rsPO = Nothing
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "AllocatePurchaseOrder"
130 Resume Exit_Handler
End Sub
'PURPOSE: cmdAddNostock_Click
' Add all products supplied by this vendor, not already on the Purchase Order,
' with a status of NO Stock on Order Details; saving the user from having to remember
' and enter every item they want to order from the vendor.
'FINDING ITEMS WITH NO STOCK FOR THE VENDOR NOT ON THIS PO:
' The SQL statement below could have been done via a query.
' We chose not to do that in order to highlight some of the benefits of the StringFormatSQL function
' and this provides an opportunity to document/explain what we needed to do and how we accomplished that
'IF THIS WERE A QUERY:
' 1) In order to explain what needs to be done (aka document),
' we would have placed the following statements in the "properties" property of the query
' and hope that
' a)you would right click on the query to see if we put anything there
' or
' b) you chose the navigation pane option to View By --> Details
'
' 2) There are two parameters required by the Query; PurchaseOrderID and VendorID
' We would have created tempVars or public functions which can be accessed
' by the query to pass the parameters and populated them before executing the query
'
' Using StringFormatSQL means we don't need to do either of these,
' and StringFormatSQL makes sure the parameters are formatted correctly;
' i.e. dates have the # before and after a date value, and strings are enclosed in double quotes.
'FINDING THE No Stock ORDER DETAILS FOR THE VENDOR:
'
' WHERE (((Products.ProductID) Not In (Select ProductID from PurchaseOrderDetails Where PurchaseOrderID = {1}))
'++ Determine which Products are NOT on the Order
'
' AND ((ProductVendors.VendorID)={2})
'++ Select Only Products this Vendor supplies
'
' AND ((ProductNoStock([Products].[ProductID]))>0))
'++ Call the function ProductNoStock to ensure there is at least one OrderDetail with a status of NoStock for the Product
'UTILIZING PRE-BUILT CALCULATIONS:
' This query utilizes two pre-built calculations - meaning calculations done via a public function
' 1) ReorderQuantity
' 2) ProductNoStock
'
' Those functions were created for use on the Product Detail form.
' At the time they were created this task was not in the requirements; it came much later.
' It is a best practice to create functions for all calculations.
' This ensures that all parts of an application that need the calculation, always do it the same way
' You can find all places in the application where the calculation is used
' and if a change is needed to the calculation, you can evaluate if all places it is used need to be changed
' and if not create a new function for the new calculation.Private Sub cmdAddNostock_Click()
10 On Error GoTo Err_Handler
Dim strSQL As String
20 If Me.NewRecord Then
30 MsgBox "Please first create the main purchase order record. Then this button can add all No Stock line items.", vbInformation
40 Else
50 strSQL = "INSERT INTO PurchaseOrderDetails (PurchaseOrderID, ProductID, Quantity, UnitCost) " & _
"SELECT {0} AS POrderID, Products.ProductID, ProductReorderQuantity([Products].[ProductID]) AS ProductReorderQuantity, Products.StandardUnitCost " & _
"FROM Products INNER JOIN ProductVendors ON Products.ProductID = ProductVendors.ProductID " & _
"WHERE (((Products.ProductID) Not In (Select ProductID from PurchaseOrderDetails Where PurchaseOrderID = {0})) AND (ProductVendors.VendorID = {1}) AND ((ProductNoStock([Products].[ProductID])) > 0));"
60 strSQL = StringFormatSQL(strSQL, Me.PurchaseOrderID, Me.VendorID)
70 g_dbApp().Execute strSQL, dbFailOnError
'Requery vs Refresh
'https://support.microsoft.com/office/refresh-or-requery-data-76e8c8b5-b8b4-49eb-a7d5-a472e742366c
'Refresh does not take into account **ADDED or DELETED** records
'Requery will take into account all **ADDED, UPDATED and DELETED**
80 Me.sfrmPurchaseOrderLineItems.Requery
90 End If
Exit_Handler:
100 Exit Sub
Err_Handler:
110 clsErrorHandler.HandleError Me.Name, "cmdAddNostock_Click", True
120 Resume Exit_Handler
End Sub
'NOTE:
' This form does not prevent the form and subform from being edited after that has become illogical (or illegal).
' Refer to frmOrderDetails.SetFormStatus for a way to implement it.Private Sub cmdAddPO_Click() 10 On Error GoTo Err_Handler 20 If Me.NewRecord Then 30 MsgBox GetString(sAlreadyOnNewRecord), vbInformation 40 Else 50 RunCommand acCmdRecordsGoToNew 60 End If Exit_Handler: 70 Exit Sub Err_Handler: 80 clsErrorHandler.HandleError Me.Name, "cmdAddPO_Click", True 90 Resume Exit_Handler End Sub
Private Sub cmdApprovePO_Click()
10 On Error GoTo Err_Handler
'PO must already have been submitted.
20 If Me.StatusID = enumPurchaseOrderStatus.posSubmitted Then
'Check if user has privilege to approve POs.
30 If HasPrivilege(enumPrivileges.pApprovePO) Then
40 Me.ApprovedByID = Get_UserID()
50 Me.ApprovedDate = Now
60 Me.StatusID = enumPurchaseOrderStatus.posApprove
70 Me.Dirty = False 'Save the record.
80 AllocatePurchaseOrder Me.PurchaseOrderID
90 SetWorkflowLabelColors
100 MsgBox GetString(sNewStatusSet), vbInformation
110 Else
120 MsgBox GetString(sNoPrivilege, "Approve PO"), vbExclamation
130 End If
140 Else
150 MsgBox GetString(sPOMustBeSubmitted), vbExclamation
160 End If
'NOTE: implicitly the PO is now sent to Vendor, and we are waiting to receive it.
Exit_Handler:
170 Exit Sub
Err_Handler:
180 clsErrorHandler.HandleError Me.Name, "cmdApprovePO_Click", True
190 Resume Exit_Handler
End SubPrivate Sub cmdClosePO_Click() 10 On Error GoTo Err_Handler 20 If Me.StatusID = enumPurchaseOrderStatus.posReceived Then 30 If PoCloseFieldsFilledOut() Then 40 Me.PaymentDate = Now 50 Me.TaxAmount = Me.txtTaxAmount 60 Me.PaymentAmount = Me.txtTotal 70 Me.StatusID = enumPurchaseOrderStatus.posClosed 80 Me.Dirty = False 90 SetWorkflowLabelColors 100 MsgBox GetString(sNewStatusSet), vbInformation 110 End If 120 Else 130 MsgBox GetString(sPOMustBeReceived), vbExclamation 140 End If Exit_Handler: 150 Exit Sub Err_Handler: 160 clsErrorHandler.HandleError Me.Name, "cmdClosePO_Click", True 170 Resume Exit_Handler End Sub 'NOTE: ' We allow deletion only for New and Submitted. If you change this business rule, be aware you will need to adjust Inventory along the same lines as when deleting an order or orderlineitem.
Private Sub cmdDeletePO_Click()
10 On Error GoTo Err_Handler
20 If Me.StatusID = enumPurchaseOrderStatus.posNew Or Me.StatusID = enumPurchaseOrderStatus.posSubmitted Then
'The relationship between PurchaseOrders and PurchaseOrderDetails has cascade delete, so all we need to do is delete the parent record.
30 RunCommand acCmdDeleteRecord
40 If IsFormOpen("frmPurchaseOrderList") Then Forms!frmPurchaseOrderList.Requery
50 Else
60 MsgBox GetString(sPOCannotDelete), vbExclamation
70 End If
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError Me.Name, "cmdDeletePO_Click", True
100 Resume Exit_Handler
End SubPrivate Sub cmdReceivePO_Click()
10 On Error GoTo Err_Handler
Dim sql As String
20 If Me.StatusID = enumPurchaseOrderStatus.posApprove Then
30 If MsgBox(GetString(sPostToInventory), vbQuestion Or vbYesNo) = vbYes Then
'The entire PO has been delivered. Allocate product to orders that are waiting for it, and put the rest in inventory.
40 Me.ReceivedDate = Now
50 Me.StatusID = enumPurchaseOrderStatus.posReceived
60 Me.Dirty = False 'Save the record.
'Set PO line items ReceivedDate to full date/time. Important for inventory calculations.
70 sql = StringFormatSQL("update PurchaseOrderDetails set ReceivedDate = {0} where PurchaseOrderID = {1};", Now(), Me.PurchaseOrderID)
80 g_dbApp().Execute sql, dbFailOnError
90 SetWorkflowLabelColors
100 MsgBox GetString(sNewStatusSet), vbInformation
110 AllocatePurchaseOrder Me.PurchaseOrderID
120 End If
130 Else
140 MsgBox GetString(sPOMustBeApproved), vbExclamation
150 End If
Exit_Handler:
160 Exit Sub
Err_Handler:
170 clsErrorHandler.HandleError Me.Name, "cmdReceivePO_Click", True
180 Resume Exit_Handler
End SubPrivate Sub cmdSubmitPO_Click() 10 On Error GoTo Err_Handler 20 If Me.StatusID = enumPurchaseOrderStatus.posNew Then 30 Me.SubmittedByID = Get_UserID() 40 Me.SubmittedDate = Now 50 Me.StatusID = enumPurchaseOrderStatus.posSubmitted 60 Me.Dirty = False 'Save the record. 70 SetWorkflowLabelColors 80 MsgBox GetString(sNewStatusSet), vbInformation 90 Else 100 MsgBox GetString(sPOMustBeNew), vbExclamation 110 End If Exit_Handler: 120 Exit Sub Err_Handler: 130 clsErrorHandler.HandleError Me.Name, "cmdSubmitPO_Click", True 140 Resume Exit_Handler End Sub
Private Sub Form_AfterInsert() 10 On Error GoTo Err_Handler 20 AddToMRU "PurchaseOrders", Me.PurchaseOrderID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True 50 Resume Exit_Handler End Sub
Private Sub Form_AfterUpdate()
10 On Error GoTo Err_Handler
20 ValidateForm_RemoveHighlights Me
30 If IsFormOpen("frmPurchaseOrderList") Then Forms!frmPurchaseOrderList.Requery
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True
60 Resume Exit_Handler
End SubPrivate Sub Form_BeforeInsert(Cancel As Integer)
10 On Error GoTo Err_Handler
'Set initial values for new record. Fires when the first character is entered into a new record.
20 Me.StatusID = enumPurchaseOrderStatus.posNew
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "Form_BeforeInsert", True
50 Resume Exit_Handler
End SubPrivate Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) 30 If Not Cancel Then 40 ValidateForm_RemoveHighlights Me 50 End If Exit_Handler: 60 Exit Sub Err_Handler: 70 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 80 Resume Exit_Handler End Sub
Private Sub Form_Close() 10 On Error GoTo Err_Handler 20 ClosePurchaseOrderDetailsForm Me 30 RequeryListForms Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "Form_Close", True 60 Resume Exit_Handler End Sub
Private Sub Form_Current()
10 On Error GoTo Err_Handler
20 ValidateForm_RemoveHighlights Me 'Needed if user canceled a new record with yellow highlights on the form.
30 Me.Caption = "Purchase Order " & Me.PurchaseOrderID 'Show the PurchaseOrderID in the caption, so several instances can easily be distinguised.
40 LockControls
50 SetWorkflowLabelColors
'Allow edits based on order status
60 If Me.NewRecord Then
70 With Me.sfrmPurchaseOrderLineItems.Form
80 .AllowAdditions = True
90 .AllowEdits = True
100 .AllowDeletions = True
110 End With
120 Else
130 With Me.sfrmPurchaseOrderLineItems.Form
140 .AllowAdditions = (Me.StatusID = enumPurchaseOrderStatus.posNew)
150 .AllowEdits = .AllowAdditions
160 .AllowDeletions = .AllowAdditions
170 End With
180 End If
Exit_Handler:
190 Exit Sub
Err_Handler:
200 clsErrorHandler.HandleError Me.Name, "Form_Current", True
210 Resume Exit_Handler
End SubPrivate Sub Form_Delete(Cancel As Integer) 10 On Error GoTo Err_Handler 20 RemoveFromMRU "PurchaseOrders", Me.PurchaseOrderID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_Delete", True 50 Resume Exit_Handler End Sub
Private Sub Form_Load()
10 On Error GoTo Err_Handler
Dim dict As Scripting.Dictionary
20 If IsNull(TempVars!OpenArgs) Then
'New record.
30 If Not Me.NewRecord Then RunCommand acCmdRecordsGoToNew
40 Else
'TempVars!OpenArgs holds the OrderID to be displayed. Format: "OrderID=123"
50 Set dict = StringToDictionary(TempVars!OpenArgs)
'Use the recordsetclone technique to select the record with the requested PurchaseOrderID.
'Note that "with me.recordsetclone" automatically cleans up the temporary objects at "End With".
'Alternatively you can assign a RecordSource that has only 1 record. See frmOrderDetails.
60 With Me.RecordsetClone
70 .FindFirst "PurchaseOrderID = " & dict("PurchaseOrderID")
80 Debug.Assert Not .NoMatch 'If this asserts, the orderID we just clicked on is not in the current recordsource.
90 Me.Bookmark = .Bookmark
100 End With
110 TempVars!OpenArgs = Null
120 Set dict = Nothing
130 If Not Me.NewRecord Then AddToMRU "PurchaseOrders", Me.PurchaseOrderID
140 End If
Exit_Handler:
150 Exit Sub
Err_Handler:
160 clsErrorHandler.HandleError Me.Name, "Form_Load", True
170 Resume Exit_Handler
End SubPrivate Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
'For multi-instance forms, Form_Open is too soon to process OpenArgs and set the current record. Postpone until Form_Load.
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError Me.Name, "Form_Open", True
40 Resume Exit_Handler
End Sub
'PURPOSE:
' Based on order status, lock controls that can no longer be edited because that would be illogical. E.g. you cannot change the Order date after the order has been created.
' These are the business rules for Northwind; in another company some fields may remain editable longer.Private Sub LockControls()
10 On Error GoTo Err_Handler
Dim varControls As Variant 'The Array function returns a variant containing an array.
Dim v As Variant
20 varControls = Array() 'Initialize, so it is no longer empty.
'List the controls that should be locked for each status. Some controls like OrderID and TaxAmount can be omitted because they cannot be edited.
30 Select Case Me.StatusID
Case enumPurchaseOrderStatus.posNew
40 varControls = Array("PurchaseOrderID", "VendorID", "StatusName", "SubmittedBy", "SubmittedDate", "ApprovedBy", "ApprovedDate", "ReceivedDate", "PaymentMethod", "ShippingFee", "txtTaxAmount", "txtTotal", "PaymentDate")
50 Case posSubmitted
60 varControls = Array("PurchaseOrderID", "VendorID", "StatusName", "SubmittedBy", "SubmittedDate", "ApprovedBy", "ApprovedDate", "ReceivedDate", "PaymentMethod", "ShippingFee", "txtTaxAmount", "txtTotal", "PaymentDate")
70 Case posApprove
80 varControls = Array("PurchaseOrderID", "VendorID", "StatusName", "SubmittedBy", "SubmittedDate", "ApprovedBy", "ApprovedDate", "PaymentMethod", "ShippingFee", "txtTaxAmount", "txtTotal", "PaymentDate")
90 Case posReceived
100 varControls = Array("PurchaseOrderID", "VendorID", "StatusName", "SubmittedBy", "SubmittedDate", "ApprovedBy", "ApprovedDate", "ReceivedDate", "txtTaxAmount", "txtTotal", "PaymentDate")
110 Case posClosed
120 varControls = Array("PurchaseOrderID", "VendorID", "Notes", "StatusName", "SubmittedBy", "SubmittedDate", "ApprovedBy", "ApprovedDate", "ReceivedDate", "PaymentMethod", "ShippingFee", "txtTaxAmount", "txtTotal", "PaymentDate")
130 Me.AllowEdits = False
140 Case Else
150 If IsNull(Me.StatusID) Then 'NOTE: You cannot have a Case Null, because comparisons with Null are Null, not True/False.
160 varControls = Array("PurchaseOrderID", "StatusName", "SubmittedBy", "SubmittedDate", "ApprovedBy", "ApprovedDate", "ReceivedDate", "PaymentMethod", "ShippingFee", "txtTaxAmount", "txtTotal", "PaymentDate")
170 Else
180 Debug.Assert False 'Unexpected order status.
190 End If
200 End Select
'Initialize Locked property to False for all controls.
210 On Error Resume Next 'Not all controls have an Enabled Property
220 For Each v In Me.Controls
230 v.Locked = False
240 v.Enabled = True
250 v.BackShade = 100 '100 means no shading.
260 Next v
270 On Error GoTo Err_Handler 'Back to normal error handler.
'Set Locked property to True for the controls in the array.
280 For Each v In varControls
290 Me.Controls(v).Locked = True
300 Me.Controls(v).Enabled = False
310 Me.Controls(v).BackShade = 95 '95 means Darker 5%
320 Next v
Exit_Handler:
330 Exit Sub
Err_Handler:
340 clsErrorHandler.HandleError Me.Name, "PoCloseFieldsFilledOut"
350 Resume Exit_Handler
End Sub
'PURPOSE:
' Check if all fields for the Close PO status have been filled out.Private Function PoCloseFieldsFilledOut() As Boolean
10 On Error GoTo Err_Handler
Dim blnIsValid As Boolean
20 blnIsValid = True 'Optimistic.
30 If IsNull(Me.ShippingFee) Then
40 blnIsValid = False
50 HighlightControl Me.ShippingFee
60 End If
70 If IsNull(Me.PaymentMethod) Then
80 blnIsValid = False
90 HighlightControl Me.PaymentMethod
100 End If
110 If Not blnIsValid Then
120 MsgBox GetString(sRequiredFields_PO_Close), vbExclamation
130 End If
140 PoCloseFieldsFilledOut = blnIsValid
Exit_Handler:
150 Exit Function
Err_Handler:
160 clsErrorHandler.HandleError Me.Name, "PoCloseFieldsFilledOut"
170 Resume Exit_Handler
End Function
' PURPOSE:
' Set the foreground color of the 4 workflow labels in the form header.Private Sub SetWorkflowLabelColors()
10 On Error GoTo Err_Handler
'Initialize. Alternatively we could set RGB values, but we want to support Themes.
20 Me.cmdSubmitPO.ForeShade = 95 '95 means Darker 5%
30 Me.cmdApprovePO.ForeShade = 95
40 Me.cmdReceivePO.ForeShade = 95
50 Me.cmdClosePO.ForeShade = 95
60 If Me.NewRecord Then
'Nothing more to do. StatusID is null.
70 Else
80 LockControls
90 If Me.StatusID = enumPurchaseOrderStatus.posNew Then GoTo Exit_Handler
100 Me.cmdSubmitPO.ForeShade = 70 '70 means Darker 30%
110 If Me.StatusID = enumPurchaseOrderStatus.posSubmitted Then GoTo Exit_Handler
120 Me.cmdApprovePO.ForeShade = 70
130 If Me.StatusID = enumPurchaseOrderStatus.posApprove Then GoTo Exit_Handler
140 Me.cmdReceivePO.ForeShade = 70
150 If Me.StatusID = enumPurchaseOrderStatus.posReceived Then GoTo Exit_Handler
160 Me.cmdClosePO.ForeShade = 70
170 End If
Exit_Handler:
180 Exit Sub
Err_Handler:
190 clsErrorHandler.HandleError Me.Name, "SetWorkflowLabelColors"
200 Resume Exit_Handler
End SubPrivate Sub VendorID_AfterUpdate() 10 On Error GoTo Err_Handler 20 Me.sfrmPurchaseOrderLineItems.Requery 30 Me.sfrmPurchaseOrderLineItems.Form.ProductID.Requery Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "VendorID_AfterUpdate", True 60 Resume Exit_Handler End Sub
Private Sub VendorID_BeforeUpdate(Cancel As Integer)
10 On Error GoTo Err_Handler
20 If IsNull(Me.VendorID.OldValue) Then
'Changing the value from Null to a number should not trigger the prompt about changing vendors.
30 Else
40 If MsgBox(GetString(sChangingVendor), vbYesNo Or vbQuestion) = vbYes Then
50 g_dbApp().Execute "delete * from PurchaseOrderDetails where PurchaseOrderID = " & Me.PurchaseOrderID, dbFailOnError
60 Else
70 Cancel = True
80 End If
90 End If
Exit_Handler:
100 Exit Sub
Err_Handler:
110 clsErrorHandler.HandleError Me.Name, "VendorID_BeforeUpdate", True
120 Resume Exit_Handler
End SubRecord source: qryPurchaseOrderList
Order by: [qryPurchaseOrderList].[PurchaseOrderID] DESC, [qryPurchaseOrderList].[ApprovedDate] DESC, [qryPurchaseOrderList].[TotalCost] · Has VBA module
Events — OnOpen: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| ApprovedDate | Text box | ApprovedDate | |||||
| Approver | Text box | Approver | |||||
| Auto_Header0 | Label | Purchase Orders | |||||
| boxHeaderControls | Rectangle | ||||||
| cmdAddPO | Command button | Add PO | Click: cmdAddPO_Click | ||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/74482757-0b12-4639-beae-b8905f0f3ca9 | ||||
| CompanyName | Text box | CompanyName | |||||
| imgNorthwindTradersLogo | Image | ||||||
| Label0 | Label | # | |||||
| Label1 | Label | Status | |||||
| Label11 | Label | Paid Date | |||||
| Label124 | Label | Sum: | |||||
| Label126 | Label | Count: | |||||
| Label128 | Label | Submitted By | |||||
| Label131 | Label | Approved | |||||
| Label132 | Label | Approved By | |||||
| Label2 | Label | Vendor | |||||
| Label3 | Label | Submitted | |||||
| Label8 | Label | Total | |||||
| PaymentDate | Text box | PaymentDate | |||||
| PurchaseOrderID | Text box | PurchaseOrderID | Click: PurchaseOrderID_Click | ||||
| StatusName | Text box | StatusName | |||||
| SubmittedDate | Text box | SubmittedDate | |||||
| Submitter | Text box | Submitter | |||||
| Text125 | Text box | =Count([PurchaseOrderID]) | |||||
| TotalCost | Text box | TotalCost | |||||
| txtSumTotalCost | Text box | =Sum([TotalCost]) |
Private Sub cmdAddPO_Click() 10 On Error GoTo Err_Handler 20 OpenPurchaseOrderDetailsForm Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdAddPO_Click", True 50 Resume Exit_Handler End Sub
Private Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
'Clean up anything left by a previous session
20 Me.FilterOn = False
30 Me.Filter = ""
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError Me.Name, "Form_Open", True
60 Resume Exit_Handler
End SubPrivate Sub PurchaseOrderID_Click() 10 On Error GoTo Err_Handler 20 OpenPurchaseOrderDetailsForm Me.PurchaseOrderID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "PurchaseOrderID_Click", True 50 Resume Exit_Handler End Sub
Record source: No record source
Has VBA module
Events — OnOpen: [Event Procedure], OnClose: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Box25 | Rectangle | ||||||
| boxCriteria | Rectangle | ||||||
| boxEmployeeEmailList | Rectangle | ||||||
| boxEmployeePhoneList | Rectangle | ||||||
| boxFormHeader | Rectangle | ||||||
| boxMonthlySalesperEmployee | Rectangle | ||||||
| boxMonthlySalesPerProduct | Rectangle | ||||||
| boxQuarterlySalesPerProduct | Rectangle | ||||||
| cmdEmployeeEmailList | Command button | Employee Email List | Click: cmdEmployeeEmailList_Click | ||||
| cmdEmployeePhoneList | Command button | Employee Phone List | Click: cmdEmployeePhoneList_Click | ||||
| cmdFallCatalog | Command button | Fall Catalog | Click: cmdFallCatalog_Click | ||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/1f9feed8-d8cd-44ed-932e-637ac795a7e2 | ||||
| cmdPreviewReport | Command button | Preview | Click: cmdPreviewReport_Click | ||||
| cmdSalesByEmployeeReport | Command button | Monthly Orders per Employee | |||||
| cmdSalesByProductReportMonthly | Command button | Monthly Orders per Product | |||||
| cmdSalesByProductReportQuarterly | Command button | Quarterly Orders per Product | |||||
| lblEndDate | Label | End Date | |||||
| lblReportCriteria | Label | Enter Criteria | |||||
| lblReportFormHeader | Label | Select Report | |||||
| lblSelectedReport | Label | Selected Report: | |||||
| lblSelectedReportName | Label | Monthly Sales per Employee | |||||
| lblStartDate | Label | Start Date | |||||
| txtEndDate | Text box | ||||||
| txtStartDate | Text box |
Private Sub cmdEmployeeEmailList_Click() 10 On Error GoTo Err_Handler 20 Call ReportFormInitialization(False) 30 TempVars.Add "ReportName", "rptEmployeeEmailList" Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "cmdEmployeeEmailList_Click", True 60 Resume Exit_Handler End Sub
Private Sub cmdEmployeePhoneList_Click() 10 On Error GoTo Err_Handler 20 Call ReportFormInitialization(False) 30 TempVars.Add "ReportName", "rptEmployeePhoneList" Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "cmdEmployeePhoneList_Click", True 60 Resume Exit_Handler End Sub 'NOTE: ' The hardest part of this report is generating the table of contents (ToC). Page numbers will change as more data is added. ' This requires the report to be rendered fully. ' Sending the report to a PDF will update the table of contents. ' The print preview includes an OpenArgs which is used to turn off the deletion of the table contents records
Private Sub cmdFallCatalog_Click() 10 On Error GoTo Err_Handler 20 Call ReportFormInitialization(False) 30 TempVars.Add "ReportName", "rptProductCatalog" 40 TempVars.Add "ReportView", acViewPreview Exit_Handler: 50 Exit Sub Err_Handler: 60 clsErrorHandler.HandleError Me.Name, "cmdFallCatalog_Click", True 70 Resume Exit_Handler End Sub
Private Sub cmdPreviewReport_Click()
10 On Error GoTo Err_Handler
Dim strPath As String 'this is the directory of the application to send the pdf
20 If TempVars!ReportName = "rptProductCatalog" Then
'Special processing for this report.
'get the path of the current application and construct the path to the PDF file.
30 strPath = Left(CurrentDb.Name, InStrRev(CurrentDb.Name, "\"))
40 strPath = strPath & TempVars!ReportName & ".pdf" 'this is the name of the sacrificial PDF that will be deleted
50 If FileExists(strPath) Then
60 Kill strPath
70 End If
'Run the report for the first time, to create the ToC.
80 TempVars.Add "GenerateToC", True
90 DoCmd.OutputTo ObjectType:=acOutputReport, ObjectName:=TempVars!ReportName, OutputFormat:=acFormatPDF, OutputFile:=strPath
100 TempVars!GenerateToC = False
110 End If
120 If IsNull(TempVars!ReportView) Then TempVars!ReportView = acViewPreview
130 DoCmd.OpenReport TempVars!ReportName, TempVars!ReportView, "", "", acNormal
Exit_Handler:
140 Exit Sub
Err_Handler:
150 clsErrorHandler.HandleError Me.Name, "cmdPreviewReport_Click", True
160 Resume Exit_Handler
End SubPrivate Sub cmdSalesByemployeeReport_Click() 10 On Error GoTo Err_Handler 20 Call ReportFormInitialization(True) 30 TempVars.Add "ReportName", "rptSalesByEmployee" 40 TempVars.Add "ReportView", acViewReport 'This report must be opened in Report View, so user can filter it. Exit_Handler: 50 Exit Sub Err_Handler: 60 clsErrorHandler.HandleError Me.Name, "cmdSalesByemployeeReport_Click", True 70 Resume Exit_Handler End Sub
Private Sub cmdSalesByProductReportMonthly_Click() 10 On Error GoTo Err_Handler 20 Call ReportFormInitialization(True) 30 TempVars.Add "ReportName", "rptSalesByProduct" Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "cmdSalesByProductReportMonthly_Click", True 60 Resume Exit_Handler End Sub
Private Sub cmdSalesByProductReportQuarterly_Click() 10 On Error GoTo Err_Handler 20 Call ReportFormInitialization(True) 30 TempVars.Add "ReportName", "rptSalesByProductQuarterly" Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "cmdSalesByProductReportQuarterly_Click", True 60 Resume Exit_Handler End Sub
Private Sub Form_Close() 10 On Error GoTo Err_Handler 20 TempVars.Remove "ReportView" 30 TempVars.Remove "ReportName" Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "Form_Close", True 60 Resume Exit_Handler End Sub
Private Sub Form_Open(Cancel As Integer)
10 On Error GoTo Err_Handler
' Set default report name to the first report.
20 Me.SetFocus 'Prepare for Screen.ActiveControl later on in ReportFormInitialization.
30 Me.cmdSalesByEmployeeReport.SetFocus 'Prepare for Screen.ActiveControl later on in ReportFormInitialization.
40 cmdSalesByemployeeReport_Click 'Init this form by doing the same thing as if user clicked the first report button.
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "Form_Open", True
70 Resume Exit_Handler
End Sub
'PURPOSE:
' If blnEnableCriteria is true, show the date range criteria controls and set default date values.
'NOTE:
' If you add other criteria controls, you must add to this code.Private Sub ReportFormInitialization(ByVal blnEnableCriteria As Boolean)
10 On Error GoTo Err_Handler
Dim dtMaxOrderDate As Date
20 dtMaxOrderDate = DateValue(DMax("OrderDate", "Orders")) 'Set the date range relative to the max order date.
30 With Me
40 .txtStartDate.Enabled = blnEnableCriteria
50 .txtStartDate.Visible = blnEnableCriteria
60 .txtStartDate = IIf(blnEnableCriteria = True, DateAdd("m", -3, DateValue(dtMaxOrderDate)), Null)
70 .txtEndDate.Enabled = blnEnableCriteria
80 .txtEndDate.Visible = blnEnableCriteria
90 .txtEndDate = IIf(blnEnableCriteria = True, dtMaxOrderDate, Null)
100 .lblSelectedReportName.Caption = Screen.ActiveControl.Caption 'Will throw Error 2474 at startup time, when there is no focus yet.
110 End With
Exit_Handler:
120 Exit Sub
Err_Handler:
130 clsErrorHandler.HandleError Me.Name, "ReportFormInitialization"
140 Resume Exit_Handler
End SubRecord source: No record source
Has VBA module
Events — OnLoad: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Generic Dialog | ||||
| Box8 | Rectangle | |||||
| BoxCaptions | Rectangle | |||||
| cmdCancel | Command button | Cancel | Click: cmdCancel_Click | |||
| cmdOK | Command button | OK | Click: cmdOK_Click | |||
| imgNorthwindTradersLogo | Image | |||||
| lstVendor | List box | SELECT ProductVendors.VendorID, Companies.CompanyName, ProductVendors.ProductID FROM Companies INNER JOIN ProductVendors ON Companies.CompanyID = ProductVendors.VendorID WHERE (((ProductVendors.ProductID)=[Forms]![frmSelectVendorDialog]![txtProductID])) ORDER BY Companies.CompanyName; | Double-click: lstVendor_DblClick | |||
| txtMessage | Text box | |||||
| txtProductID | Text box |
Private Sub cmdCancel_Click() 10 On Error GoTo Err_Handler 20 DoCmd.Close acForm, Me.Name Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdCancel_Click", True 50 Resume Exit_Handler End Sub
Private Sub cmdOK_Click() 10 On Error GoTo Err_Handler 20 If Me.lstVendor.Value > 0 Then 30 Me.Visible = False 40 Else 50 Beep 60 Me.txtMessage.ForeColor = vbRed 70 Me.txtMessage = "Select a Vendor, then OK (or Cancel)" 80 Me.lstVendor.SetFocus 90 End If Exit_Handler: 100 Exit Sub Err_Handler: 110 clsErrorHandler.HandleError Me.Name, "cmdOK_Click", True 120 Resume Exit_Handler End Sub
Private Sub Form_Load()
10 On Error GoTo Err_Handler
'==================================================================
' OpenArgs: <Dialog header caption>|<Message or prompt>|ProductID
' ALTERNATE IMPLEMENTATION: use StringToDictionary
'==================================================================
Dim arArgs() As String
20 If Nz(Me.OpenArgs, "") > "" Then
30 arArgs = Split(Me.OpenArgs, "|")
40 Me.Auto_Header0.Caption = arArgs(0)
50 Me.txtMessage = arArgs(1)
60 Me.txtProductID = arArgs(2)
70 Me.lstVendor.Requery
80 End If
90 Me.Visible = True
100 Me.Modal = True
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "Form_Load", True
130 Resume Exit_Handler
End SubPrivate Sub lstVendor_DblClick(Cancel As Integer) 10 On Error GoTo Err_Handler 20 cmdOK_Click Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "lstVendor_DblClick", True 50 Resume Exit_Handler End Sub
Record source: No record source
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Box11 | Rectangle | |||||
| Box12 | Rectangle | |||||
| Box13 | Rectangle | |||||
| Box254 | Rectangle | |||||
| Box255 | Rectangle | |||||
| Box256 | Rectangle | |||||
| imgNorthwindTradersLogo | Image | |||||
| Title | Label | Northwind Traders | ||||
| Welcome | Label | Welcome to the Northwind Traders sample database. In order to use this sample, click 'Enable Content' on the Message Bar. Alternatively, open the database from a Trusted Location. |
Record source: Welcome
Has VBA module
Events — OnOpen: [Event Procedure], OnClose: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| Auto_Title0 | Label | Welcome to the Northwind Developer Edition! | |||||
| Box64 | Rectangle | ||||||
| Box69 | Rectangle | ||||||
| Box71 | Rectangle | ||||||
| chkShowWelcome | Check box | ||||||
| cmdGetStarted | Command button | Continue | Click: cmdGetStarted_Click | ||||
| cmdWatchThisIntro | Command button | Address: https://support.microsoft.com/topic/32eb79d2-bede-4ea4-b575-0714ca8dc1e2 | |||||
| imgNorthwindTradersLogo | Image | ||||||
| imgNorthwindTradersVideo | Image | ||||||
| Label83 | Label | After watching, click Continue to login | |||||
| Label84 | Label | This version of Northwind was designed for Access 2019 and better (32- and 64-bit), though it may work with older versions. | |||||
| lblCallToAction | Label | Please watch this short video. We promise, it will be well worth it! | |||||
| lblShowWelcome | Label | Show Welcome when this database is opened | |||||
| lblVideo | Label | Northwind Developer Video | |||||
| txtWelcome | Text box | Welcome |
Private Sub cmdGetStarted_Click() 10 On Error GoTo Err_Handler 20 DoCmd.Close acForm, Me.Name Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdGetStarted_Click", True 50 Resume Exit_Handler End Sub
Private Sub Form_Close()
10 On Error GoTo Err_Handler
'Save the value of the checkbox to the SystemSettings table.
20 SaveSystemSetting ssShowWelcome, IIf(Me.chkShowWelcome, -1, 0) 'Ensure this works in international scenarios.
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError Me.Name, "Form_Close", True
50 Resume Exit_Handler
End SubPrivate Sub Form_Open(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Me.chkShowWelcome = GetSystemSetting(ssShowWelcome) Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_Open", True 50 Resume Exit_Handler End Sub
Record source: No record source
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Remove Test Data | ||||
| cmdRemoveTestData | Command button | Remove Test Data | Click: cmdRemoveTestData_Click | |||
| imgNorthwindTradersLogo | Image | |||||
| Label47 | Label | This page is used to remove most test data. Not exactly all data, because some Employees are used in code, and Statuses must have these values. |
Private Sub cmdRemoveTestData_Click()
10 On Error GoTo Err_Handler
Const MAX_COMPANYID As Long = 13
Const MAX_PRODUCTID As Long = 43
Const MAX_EMPLOYEEID As Long = 10
Const MAX_CONTACTID As Long = 16
Dim sql As String
20 If MsgBox("This will permanently delete most data. Are you sure? You might want to first make a backup.", vbQuestion Or vbYesNo) = vbYes Then
30 sql = "delete * from MRU;"
40 g_dbApp().Execute sql, dbFailOnError
50 sql = "delete * from Contacts where ContactID > " & MAX_CONTACTID
60 g_dbApp().Execute sql, dbFailOnError
'Delete all orders and their order details.
70 sql = "delete * from OrderDetails where OrderID in (select OrderID from Orders where EmployeeID > " & MAX_EMPLOYEEID & ");"
80 g_dbApp().Execute sql, dbFailOnError
90 sql = "delete * from OrderDetails where OrderID in (select OrderID from Orders where CustomerID > " & MAX_COMPANYID & ");"
100 g_dbApp().Execute sql, dbFailOnError
110 sql = "delete * from OrderDetails where ProductID > " & MAX_PRODUCTID
120 g_dbApp().Execute sql, dbFailOnError
130 sql = "delete * from Orders where EmployeeID > " & MAX_EMPLOYEEID
140 g_dbApp().Execute sql, dbFailOnError
150 sql = "delete * from Orders where CustomerID > " & MAX_COMPANYID
160 g_dbApp().Execute sql, dbFailOnError
170 sql = "delete * from PurchaseOrderDetails where PurchaseOrderID in (select PurchaseOrderID from PurchaseOrders where SubmittedByID > " & MAX_EMPLOYEEID & ");"
180 g_dbApp().Execute sql, dbFailOnError
190 sql = "delete * from PurchaseOrderDetails where PurchaseOrderID in (select PurchaseOrderID from PurchaseOrders where ApprovedByID > " & MAX_EMPLOYEEID & ");"
200 g_dbApp().Execute sql, dbFailOnError
210 sql = "delete * from PurchaseOrderDetails where PurchaseOrderID in (select PurchaseOrderID from PurchaseOrders where VendorID > " & MAX_COMPANYID & ");"
220 g_dbApp().Execute sql, dbFailOnError
230 sql = "delete * from PurchaseOrderDetails where ProductID > " & MAX_PRODUCTID
240 g_dbApp().Execute sql, dbFailOnError
250 sql = "delete * from PurchaseOrders where SubmittedByID > " & MAX_EMPLOYEEID
260 g_dbApp().Execute sql, dbFailOnError
270 sql = "delete * from PurchaseOrders where ApprovedByID > " & MAX_EMPLOYEEID
280 g_dbApp().Execute sql, dbFailOnError
290 sql = "delete * from PurchaseOrders where VendorID > " & MAX_COMPANYID
300 g_dbApp().Execute sql, dbFailOnError
310 sql = "delete * from Companies where CompanyID > " & MAX_COMPANYID
320 g_dbApp().Execute sql, dbFailOnError
330 sql = "delete * from StockTake where ProductID > " & MAX_PRODUCTID
340 g_dbApp().Execute sql, dbFailOnError
350 sql = "delete * from ProductVendors where ProductID > " & MAX_PRODUCTID
360 g_dbApp().Execute sql, dbFailOnError
370 sql = "delete * from Products where ProductID > " & MAX_PRODUCTID
380 g_dbApp().Execute sql, dbFailOnError
390 sql = "delete * from EmployeePrivileges where EmployeeID > " & MAX_EMPLOYEEID
400 g_dbApp().Execute sql, dbFailOnError
410 sql = "delete * from Employees where EmployeeID > " & MAX_EMPLOYEEID
420 g_dbApp().Execute sql, dbFailOnError
430 sql = "update SystemSettings set SettingValue = -1 where SettingName = 'ShowWelcome'"
440 g_dbApp().Execute sql, dbFailOnError
450 sql = "update UserSettings set SettingValue = 0 where SettingName = 'AutoLogin'"
460 g_dbApp().Execute sql, dbFailOnError
470 MsgBox "Data Deleted. You may want to close and re-open the application.", vbInformation
480 End If
Exit_Handler:
490 Exit Sub
Err_Handler:
500 clsErrorHandler.HandleError Me.Name, "cmdRemoveTestData_Click", True
510 Resume Exit_Handler
520 Resume
End SubRecord source: qrySystemSettings
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Internet Orders | ||||
| cmdCreate | Command button | Create | Click: cmdCreate_Click | |||
| imgNorthwindTradersLogo | Image | |||||
| Label119 | Label | (1-5) | ||||
| Label47 | Label | This page is used to simulate Internet Orders being added to the database. The button invokes VBA code that creates random orders. | ||||
| Label59 | Label | Number of orders | ||||
| txtCount | Text box |
Private Sub cmdCreate_Click()
10 On Error GoTo Err_Handler
'Validation
20 If IsNull(Me.txtCount) Then
30 MsgBox GetString(sNumberBetween, MinCount, MaxCount), vbExclamation
40 Else
50 CreateRandomOrders Me.txtCount
60 Me.Parent.UpdateSubLabels
70 Ribbon_RefreshMRU
80 MsgBox "Orders created. Refresh the Order List form to see them.", vbInformation
90 End If
Exit_Handler:
100 Exit Sub
Err_Handler:
110 clsErrorHandler.HandleError Me.Name, "cmdCreate_Click", True
120 Resume Exit_Handler
End SubPrivate Sub txtCount_BeforeUpdate(Cancel As Integer)
10 On Error GoTo Err_Handler
'Validation
20 If IsNull(Me.txtCount) Or Me.txtCount < MinCount Or Me.txtCount > MaxCount Then
30 MsgBox GetString(sNumberBetween, MinCount, MaxCount), vbExclamation
40 Cancel = True 'Prevents the user from exiting the textbox with this bad value.
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "txtCount_BeforeUpdate", True
80 Resume Exit_Handler
End SubRecord source: qrySystemSettings
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Reset Dates | ||||
| cmdResetDates | Command button | Reset Dates | Click: cmdResetDates_Click | |||
| imgNorthwindTradersLogo | Image | |||||
| Label47 | Label | This page is used to reset date fields relative to today. Many users like to work with current dates. The button invokes VBA code that updates several date fields, such as Order Date. |
Private Sub cmdResetDates_Click() 10 On Error GoTo Err_Handler 20 SetDatesToCurrent 30 MsgBox "Done. Reopen your forms to see the new dates.", vbInformation Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "cmdResetDates_Click", True 60 Resume Exit_Handler End Sub
Record source: qryStrings
Filter: ([qryStrings].[StringData] Like "*employee*") · Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Strings | ||||
| boxHeaderControls | Rectangle | |||||
| imgNorthwindTradersLogo | Image | |||||
| Label0 | Label | # | ||||
| Label1 | Label | String Data | ||||
| StringData | Text box | StringData | ||||
| StringID | Text box | StringID |
Private Sub Form_AfterDelConfirm(Status As Integer)
10 On Error GoTo Err_Handler
'Not needed; form does not allow deletions. Me.Parent.UpdateSubLabels
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError Me.Name, "Form_AfterDelConfirm", True
40 Resume Exit_Handler
End SubPrivate Sub Form_AfterInsert()
10 On Error GoTo Err_Handler
'Not needed; form does not allow additions. Me.Parent.UpdateSubLabels
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True
40 Resume Exit_Handler
End SubRecord source: qrySystemSettings
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | System Settings | ||||
| boxHeaderControls | Rectangle | |||||
| imgNorthwindTradersLogo | Image | |||||
| Label0 | Label | # | ||||
| Label1 | Label | Setting Name | ||||
| Label2 | Label | Setting Value | ||||
| Label3 | Label | Notes | ||||
| Notes | Text box | Notes | ||||
| SettingID | Text box | SettingID | ||||
| SettingName | Text box | SettingName | ||||
| SettingValue | Text box | SettingValue |
Private Sub Form_AfterDelConfirm(Status As Integer)
10 On Error GoTo Err_Handler
'Not needed; form does not allow deletions. Me.Parent.UpdateSubLabels
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError Me.Name, "Form_AfterDelConfirm", True
40 Resume Exit_Handler
End SubPrivate Sub Form_AfterInsert()
10 On Error GoTo Err_Handler
'Not needed; form does not allow additions. Me.Parent.UpdateSubLabels
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True
40 Resume Exit_Handler
End SubRecord source: qryContacts
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| lblAddedBy | Label | Added By | ||||
| lblAddedOn | Label | Added On | ||||
| lblContactID | Label | ID | ||||
| lblEmailAddress | Label | |||||
| lblFirstName | Label | First Name * | ||||
| lblJobTitle | Label | Job Title * | ||||
| lblLastName | Label | Last Name * | ||||
| lblModifeidOn | Label | Modified On | ||||
| lblModifiedBy | Label | Modified By | ||||
| lblNotes | Label | Notes | ||||
| lblPrimaryPhone | Label | Primary Phone | ||||
| lblSecondaryPhone | Label | Secondary Phone | ||||
| txtAddedBy | Text box | AddedBy | ||||
| txtAddedOn | Text box | AddedOn | ||||
| txtContactID | Text box | ContactID | ||||
| txtEmailAddress | Text box | EmailAddress | ||||
| txtFirstName | Text box | FirstName | ||||
| txtJobTitle | Text box | JobTitle | ||||
| txtLastName | Text box | LastName | ||||
| txtModifiedBy | Text box | ModifiedBy | ||||
| txtModifiedOn | Text box | ModifiedOn | ||||
| txtNotes | Text box | Notes | ||||
| txtPrimaryPhone | Text box | PrimaryPhone | Click: txtPrimaryPhone_Click | |||
| txtSecondaryPhone | Text box | SecondaryPhone | Click: txtSecondaryPhone_Click |
Private Sub Form_AfterUpdate() 10 On Error GoTo Err_Handler 20 ValidateForm_RemoveHighlights Me Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True 50 Resume Exit_Handler End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 50 Resume Exit_Handler End Sub
Private Sub txtPrimaryPhone_Click()
10 On Error GoTo Err_Handler
'If the Phone has not been populated yet
'postion the cursor to the beginning of the field
'no matter where the user clicked in the field
20 If Len(Me.txtPrimaryPhone) = 0 Then
30 Me.txtPrimaryPhone.SelStart = 0
40 End If
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "txtPrimaryPhone_Click", True
70 Resume Exit_Handler
End SubPrivate Sub txtSecondaryPhone_Click()
10 On Error GoTo Err_Handler
'If the Phone has not been populated yet
'postion the cursor to the beginning of the field
'no matter where the user clicked in the field
20 If Len(Me.txtSecondaryPhone) = 0 Then
30 Me.txtSecondaryPhone.SelStart = 0
40 End If
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "txtSecondaryPhone_Click", True
70 Resume Exit_Handler
End SubRecord source: qryCustomerOrderList
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| lblEmployeeName | Label | Employee | ||||
| lblOrderCount | Label | Order Count | ||||
| lblOrderDate | Label | Order Date | ||||
| lblOrderID | Label | # | ||||
| lblOrderTotal | Label | Order Total | ||||
| lblShipperName | Label | Shipper | ||||
| lblStatusName | Label | Status | ||||
| txtEmployeeFNLN | Text box | EmployeeName | Double-click: =OpenForm_frmOrderDetails() | |||
| txtOrderCount | Text box | =Count(*) | ||||
| txtOrderDate | Text box | OrderDate | Double-click: =OpenForm_frmOrderDetails() | |||
| txtOrderID | Text box | OrderID | Click: =OpenForm_frmOrderDetails() | |||
| txtOrderStatusName | Text box | OrderStatusName | Double-click: =OpenForm_frmOrderDetails() | |||
| txtOrderTotal | Text box | OrderTotal | Double-click: =OpenForm_frmOrderDetails() | |||
| txtShipperName | Text box | ShipperName | Double-click: =OpenForm_frmOrderDetails() |
Private Sub Detail_DblClick(Cancel As Integer) 10 On Error GoTo Err_Handler 20 OpenForm_frmOrderDetails Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Detail_DblClick" 50 Resume Exit_Handler End Sub
Public Function OpenForm_frmOrderDetails() 10 On Error GoTo Err_Handler 20 OpenOrderDetailsForm Me.OrderID Exit_Handler: 30 Exit Function Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "OpenForm_frmOrderDetails", True 50 Resume Exit_Handler End Function
Record source: qryShipperOrderList
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| lblCustomerName | Label | Customer | ||||
| lblFullNameFNLN | Label | Employee | ||||
| lblOrderCount | Label | Order Count | ||||
| lblOrderDate | Label | Order Date | ||||
| lblOrderID | Label | # | ||||
| lblStatusName | Label | Status | ||||
| lbltxtOrderTotal | Label | Order Total | ||||
| txtCustomerName | Text box | CustomerName | Double-click: =OpenForm_frmOrderDetails() | |||
| txtEmployeeFNLN | Text box | EmployeeFNLN | Double-click: =OpenForm_frmOrderDetails() | |||
| txtOrderCount | Text box | =Count(*) | ||||
| txtOrderDate | Text box | OrderDate | Double-click: =OpenForm_frmOrderDetails() | |||
| txtOrderID | Text box | OrderID | Click: =OpenForm_frmOrderDetails() | |||
| txtOrderStatusName | Text box | OrderStatusName | Double-click: =OpenForm_frmOrderDetails() | |||
| txtOrderTotal | Text box | OrderTotal | Double-click: =OpenForm_frmOrderDetails() |
Private Sub Detail_DblClick(Cancel As Integer) 10 On Error GoTo Err_Handler 20 OpenForm_frmOrderDetails Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Detail_DblClick" 50 Resume Exit_Handler End Sub
Public Function OpenForm_frmOrderDetails() 10 On Error GoTo Err_Handler 20 OpenOrderDetailsForm Me.OrderID Exit_Handler: 30 Exit Function Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "OpenForm_frmOrderDetails", True 50 Resume Exit_Handler End Function
Record source: qryVendorPurchaseOrderList
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| ApprovedBy | Text box | ApprovedBy | Double-click: =OpenForm_frmPurchaseOrderDetails() | |||
| ApprovedDate | Text box | ApprovedDate | Double-click: =OpenForm_frmPurchaseOrderDetails() | |||
| Label0 | Label | # | ||||
| Label184 | Label | Submitted By | ||||
| Label191 | Label | Approved By | ||||
| Label198 | Label | Status | ||||
| Label3 | Label | Submitted | ||||
| Label5 | Label | Approved | ||||
| Label8 | Label | Received | ||||
| lblOrderCount | Label | Order Count | ||||
| ReceivedDate | Text box | ReceivedDate | Double-click: =OpenForm_frmPurchaseOrderDetails() | |||
| StatusName | Text box | StatusName | Double-click: =OpenForm_frmPurchaseOrderDetails() | |||
| SubmittedBy | Text box | SubmittedBy | Double-click: =OpenForm_frmPurchaseOrderDetails() | |||
| SubmittedDate | Text box | SubmittedDate | Double-click: =OpenForm_frmPurchaseOrderDetails() | |||
| txtOrderCount | Text box | =Count(*) | ||||
| txtPurchaseOrderID | Text box | PurchaseOrderID | Click: =OpenForm_frmPurchaseOrderDetails() |
Private Sub Detail_DblClick(Cancel As Integer) 10 On Error GoTo Err_Handler 20 OpenForm_frmPurchaseOrderDetails Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Detail_DblClick" 50 Resume Exit_Handler End Sub
Public Function OpenForm_frmPurchaseOrderDetails() 10 On Error GoTo Err_Handler 20 OpenPurchaseOrderDetailsForm Me.PurchaseOrderID Exit_Handler: 30 Exit Function Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "OpenForm_frmPurchaseOrderDetails", True 50 Resume Exit_Handler End Function
Record source: qryEmployeePrivileges
Filter: EmployeeID = 26 · Has VBA module
Events — OnOpen: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Privileges | ||||
| boxHeaderControls | Rectangle | |||||
| cboEmployeeID | Combo box | EmployeeID | qrycboEmployees | |||
| cboPrivilegeID | Combo box | PrivilegeID | qryPrivileges | |||
| EmployeePrivilegeID | Text box | EmployeePrivilegeID | ||||
| imgNorthwindTradersLogo | Image | |||||
| Label0 | Label | # | ||||
| Label1 | Label | Employee | ||||
| Label2 | Label | Privilege |
Private Sub Form_AfterDelConfirm(Status As Integer) 10 On Error GoTo Err_Handler 20 If frmLoadedAsSubform Then Me.Parent.UpdateSubLabels Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterDelConfirm", True 50 Resume Exit_Handler End Sub
Private Sub Form_AfterInsert() 10 On Error GoTo Err_Handler 20 If frmLoadedAsSubform Then Me.Parent.UpdateSubLabels Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True 50 Resume Exit_Handler End Sub
Private Sub Form_Open(Cancel As Integer) 10 On Error GoTo Err_Handler 20 With Me 30 If Nz(.OpenArgs, 0) > 0 Then 40 DoCmd.MoveSize Right:=TWIPS_PER_INCH * 3, down:=TWIPS_PER_INCH * 3, Width:=TWIPS_PER_INCH * 4.5, Height:=TWIPS_PER_INCH * 4.5 50 .cboEmployeeID.DefaultValue = .OpenArgs 60 End If 70 End With Exit_Handler: 80 Exit Sub Err_Handler: 90 clsErrorHandler.HandleError Me.Name, "Form_Open", True 100 Resume Exit_Handler End Sub
Private Function frmLoadedAsSubform() As Boolean
10 On Error GoTo Err_Handler
20 frmLoadedAsSubform = True
30 Debug.Print Me.Parent.Name
Exit_Handler:
40 Exit Function
Err_Handler:
50 If Err = 2452 Then '2452 = The expression you entered has an invalid reference to the Parent property.
'@For example, you may be using the Parent property with a control on a main form or report
'rather than with a control on a subform or subreport.@@2@1@4852@1
60 frmLoadedAsSubform = False
70 Else
80 clsErrorHandler.HandleError Me.Name, "frmLoadedAsSubform"
90 End If
100 Resume Exit_Handler
End FunctionRecord source: qryOrderLineItems
Has VBA module
Events — OnCurrent: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Box229 | Rectangle | |||||
| cboProductCategories | Combo box | qrycboProductCategories | ||||
| Discount | Text box | Discount | ||||
| Label0 | Label | # | ||||
| Label1 | Label | Product | ||||
| Label122 | Label | Price | ||||
| Label124 | Label | SubTotal | ||||
| Label132 | Label | Discount | ||||
| Label133 | Label | Status | ||||
| Label135 | Label | Product Category | ||||
| Label2 | Label | Qty | ||||
| Label3 | Label | Unit Price | ||||
| OrderDetailID | Text box | OrderDetailID | ||||
| OrderDetailStatusID | Combo box | OrderDetailStatusID | qrycboOrderDetailStatus | |||
| Price | Text box | =[Quantity]*(1-[Discount])*[UnitPrice] | ||||
| ProductCategoryID | Text box | ProductCategoryID | ||||
| ProductCategoryName | Text box | ProductCategoryName | ||||
| ProductID | Combo box | ProductID | qrycboProducts | |||
| ProductName | Text box | ProductName | Double-click: ProductName_DblClick | |||
| Quantity | Text box | Quantity | ||||
| txtSubTotal | Text box | =Sum([Quantity]*(1-[Discount])*[UnitPrice]) | ||||
| UnitPrice | Text box | UnitPrice |
Private Sub cboProductCategories_AfterUpdate()
10 On Error GoTo Err_Handler
'Note that setting the Rowsource also requeries it so it will have products for all categories or for this category.
20 If Me.cboProductCategories = 0 Then
30 Me.ProductID.RowSource = "qrycboProducts_All"
40 Else
50 Me.ProductID.RowSource = "qrycboProducts"
60 End If
'If IsNull(Me.ProductID) Or Me.ProductID = 0 Then
70 Me.ProductID = Me.ProductID.Column(0, 0) 'Critical line for cascading comboboxes: it selects the first product, which then causes the value of ProductCategory textbox to be set.
80 ProductID_AfterUpdate 'Since we just set the value programmatically, we need to call this procedure which would be called if it was done interactively.
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError Me.Name, "cboProductCategories_AfterUpdate", True
110 Resume Exit_Handler
End SubPrivate Sub Form_AfterDelConfirm(Status As Integer) 10 On Error GoTo Err_Handler 20 If Status = acDeleteOK Then 30 AllocateInventory m_RowCache.ProductID 'Use the cached version, because by now the row is deleted and Me.ProductID is undefined. 40 End If Exit_Handler: 50 Exit Sub Err_Handler: 60 clsErrorHandler.HandleError Me.Name, "Form_AfterDelConfirm", True 70 Resume Exit_Handler End Sub
Private Sub Form_AfterUpdate()
10 On Error GoTo Err_Handler
20 ReallocateInventory
30 ValidateForm_RemoveHighlights Me
'Reset.
40 m_RowCache.ProductID = 0
50 m_RowCache.Quantity = 0
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True
80 Resume Exit_Handler
End SubPrivate Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer) 10 On Error GoTo Err_Handler 20 Response = acDataErrContinue 'We already asked user for confirmation in Form_Delete. Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_BeforeDelConfirm", True 50 Resume Exit_Handler End Sub
Private Sub Form_BeforeInsert(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Me.OrderDetailStatusID = enumOrderDetailStatus.odsNew 'Set initial value for new record. May be updated in Form_BeforeUpdate. Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_BeforeInsert", True 50 Resume Exit_Handler End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) 30 If Not Cancel Then SetOrderDetailStatus 'Just in case Quantity was entered before Product. Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 60 Resume Exit_Handler End Sub
Private Sub Form_Current()
10 On Error GoTo Err_Handler
20 Me.cboProductCategories = Me.ProductCategoryID 'Set the value of the unbound combobox.
30 Me.ProductID.Requery 'Requery products dropdown so it will have products for this category.
40 ValidateForm_RemoveHighlights Me
'Cache the row, in case user changes product.
50 If Not Me.NewRecord And Me.OrderDetailStatusID = enumOrderDetailStatus.odsAllocated Then
60 m_RowCache.ProductID = Me.ProductID
70 m_RowCache.Quantity = Me.Quantity
80 End If
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError Me.Name, "Form_Current", True
110 Resume Exit_Handler
End SubPrivate Sub Form_Delete(Cancel As Integer) 10 On Error GoTo Err_Handler 20 If MsgBox(GetString(enumStrings.sDeleteRecord, "order line item"), vbYesNo Or vbQuestion) = vbNo Then 30 Cancel = True 40 End If Exit_Handler: 50 Exit Sub Err_Handler: 60 clsErrorHandler.HandleError Me.Name, "Form_Delete", True 70 Resume Exit_Handler End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
10 On Error GoTo Err_Handler
'Alternatively we could have:
' * Disabled the subform until the parent form is saved, or at least started (Form_BeforeInsert).
' * Checked Me.OrderID in our Form_BeforeInsert, so an early message can be given, instead of waiting until user causes the row to (attempt to) be saved.
20 If DataErr = 3314 Then '3314 = You must enter a value in the '|' field.
30 If IsNull(Me.OrderID) Then
40 MsgBox GetString(sOrderBeforeOrderLineItems), vbExclamation
50 Response = acDataErrContinue
60 End If
70 End If
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError Me.Name, "Form_Error", True
100 Resume Exit_Handler
End SubPrivate Sub ProductCategoryName_GotFocus() 10 On Error GoTo Err_Handler 20 Me.ProductCategoryID.SetFocus Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "ProductCategoryName_GotFocus", True 50 Resume Exit_Handler End Sub
Private Sub ProductID_AfterUpdate()
10 On Error GoTo Err_Handler
Const COL_UNITPRICE As Integer = 2
20 If IsNull(Me.ProductID.Column(COL_UNITPRICE)) Then
'This can happen when changing product category on a new row without entering any other data.
30 Me.ProductID = 0 'Assigning Null is not possible with this required field. 0 is the next best value.
40 Else
50 Me.UnitPrice = Me.ProductID.Column(COL_UNITPRICE) 'Column at index 2 has the hidden UnitPrice.
60 End If
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "ProductID_AfterUpdate", True
90 Resume Exit_Handler
End SubPrivate Sub ProductID_GotFocus()
10 On Error GoTo Err_Handler
'Note that setting the Rowsource also requeries it so it will have products for all categories or for this category.
20 If Me.cboProductCategories = 0 Then
30 Me.ProductID.RowSource = "qrycboProducts_All"
40 Else
50 Me.ProductID.RowSource = "qrycboProducts"
60 End If
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError Me.Name, "ProductID_GotFocus", True
90 Resume Exit_Handler
End SubPrivate Sub ProductName_DblClick(Cancel As Integer) 10 On Error GoTo Err_Handler 20 If Not Me.NewRecord Then 30 DoCmd.OpenForm FormName:="frmProductDetail", WhereCondition:="ProductID = " & Me.ProductID, WindowMode:=acDialog 40 End If Exit_Handler: 50 Exit Sub Err_Handler: 60 clsErrorHandler.HandleError Me.Name, "ProductName_DblClick", True 70 Resume Exit_Handler End Sub
Private Sub ProductName_GotFocus() 10 On Error GoTo Err_Handler 20 Me.ProductID.SetFocus 'So user can type and the dropdown will show matching data. Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "ProductName_GotFocus", True 50 Resume Exit_Handler End Sub
Private Sub ReallocateInventory()
10 On Error GoTo Err_Handler
20 If m_RowCache.ProductID <> Me.ProductID And m_RowCache.ProductID <> 0 Then
'The product was changed, and the old quantity of it can now be reallocated.
30 AllocateInventory m_RowCache.ProductID
40 End If
'Current ProductID
50 AllocateInventory Me.ProductID
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "ReallocateInventory"
80 Resume Exit_Handler
End SubPrivate Sub SetOrderDetailStatus()
10 On Error GoTo Err_Handler
Dim intAvailable As Integer
20 If IsNull(Me.ProductID) Or IsNull(Me.Quantity) Then
'Wait until we have both Quantity and ProductID
30 Else
40 intAvailable = ProductAvailable(Me.ProductID)
50 If intAvailable >= Me.Quantity Then
'We have stock. Allocate it.
60 Me.OrderDetailStatusID = enumOrderDetailStatus.odsAllocated
70 Else
'None or not enough stock. This status is preliminary, and may be modified in Form_AfterUpdate.
80 Me.OrderDetailStatusID = enumOrderDetailStatus.odsNoStock
90 End If
100 End If
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "SetOrderDetailStatus"
130 Resume Exit_Handler
End SubRecord source: qryOrders_MostRecent
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| boxHeaderControls | Rectangle | |||||
| CompanyName | Text box | CompanyName | ||||
| FullNameFNLN | Text box | FullNameFNLN | ||||
| lblCustomer | Label | Customer | ||||
| lblEmployee | Label | Employee | ||||
| lblOrderDate | Label | Order Date | ||||
| lblOrderID | Label | # | ||||
| lblOrderTotal | Label | Order Total | ||||
| lblStatus | Label | Status | ||||
| OrderDate | Text box | OrderDate | ||||
| OrderID | Text box | OrderID | Click: OrderID_Click | |||
| OrderStatusName | Text box | OrderStatusName | ||||
| OrderTotal | Text box | OrderTotal |
Private Sub OrderID_Click() 10 On Error GoTo Err_Handler 20 OpenOrderDetailsForm Me.OrderID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "OrderID_Click", True 50 Resume Exit_Handler End Sub
Record source: qryProductCategories
Has VBA module
Events — OnCurrent: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Hyperlink destination | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|---|
| AddedBy | Text box | AddedBy | |||||
| AddedOn | Text box | AddedOn | |||||
| Auto_Header0 | Text box | =IIf(Nz([ProductCategoryID],0)>0,[ProductCategoryName],"New Product Category") | |||||
| cmdAdd | Command button | Add Category | Click: cmdAdd_Click | ||||
| cmdDelete | Command button | Delete Category | Click: cmdDelete_Click | ||||
| cmdInfo | Command button | Info | Address: https://support.microsoft.com/topic/21dc2dea-e9e7-4680-ae2c-e691dc172f67 | ||||
| EmptyCell137 | Empty cell | ||||||
| EmptyCell138 | Empty cell | ||||||
| EmptyCell139 | Empty cell | ||||||
| EmptyCell149 | Empty cell | ||||||
| EmptyCell150 | Empty cell | ||||||
| EmptyCell152 | Empty cell | ||||||
| EmptyCell153 | Empty cell | ||||||
| EmptyCell154 | Empty cell | ||||||
| EmptyCell155 | Empty cell | ||||||
| EmptyCell156 | Empty cell | ||||||
| EmptyCell157 | Empty cell | ||||||
| EmptyCell159 | Empty cell | ||||||
| EmptyCell160 | Empty cell | ||||||
| EmptyCell161 | Empty cell | ||||||
| EmptyCell165 | Empty cell | ||||||
| EmptyCell169 | Empty cell | ||||||
| EmptyCell172 | Empty cell | ||||||
| EmptyCell36 | Empty cell | ||||||
| EmptyCell41 | Empty cell | ||||||
| EmptyCell93 | Empty cell | ||||||
| imgNorthwindTradersLogo | Image | ||||||
| Label1 | Label | Category Name | |||||
| Label121 | Label | Product Category Image | |||||
| Label2 | Label | Category Code | |||||
| Label3 | Label | Category Description | |||||
| Label7 | Label | Product Category | |||||
| lblImageTip | Label | Double-click to add or remove an image | |||||
| lstCategory | List box | SELECT [ProductCategories].[ProductCategoryID], [ProductCategories].[ProductCategoryName] FROM ProductCategories ORDER BY [ProductCategoryName]; | |||||
| ModifiedOn | Text box | ModifiedOn | |||||
| ProductCategoryDesc | Text box | ProductCategoryDesc | |||||
| ProductCategoryImage | Attachment | ProductCategoryImage | |||||
| ProductCategoryName | Text box | ProductCategoryName | |||||
| txtModified | Text box | =RecordModifiedString([AddedBy],[AddedOn],[ModifiedBy],[ModifiedOn]) | |||||
| txtProductCategoryCode | Text box | ProductCategoryCode | |||||
| txtProductCategoryID | Text box | ProductCategoryID |
Private Sub cmdAdd_Click() 10 On Error GoTo Err_Handler 20 DoCmd.GoToRecord , "", acNewRec Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "cmdAdd_Click", True 50 Resume Exit_Handler End Sub
Private Sub cmdDelete_Click()
10 On Error GoTo Err_Handler
20 If Me.NewRecord Then
30 Me.Undo
40 GoTo Exit_Handler
50 End If
'Check if related records will prevent deleting this Product
60 If DCount("ProductID", "Products", "ProductCategoryID = " & Me.ProductCategoryID) > 0 Then
'================Equivalent Syntax==============================
' Two methods of generating a message box
' The first is default: Building the messagebox message
' The second uses the custom Function GetString in conjunction
' with the Enumeration enumStrings.
'Method 1
' MsgBox "Product Category '" & Me.ProductCategory Name & "' cannot be deleted because it has a related " _
' & "Product record.", vbExclamation or vbOKOnly, "Cannot Delete"
'Method 2
70 MsgBox GetString(enumStrings.sCannotDelete, "Product Category", Me.ProductCategoryName _
, "Product"), vbExclamation Or vbOKOnly, "Cannot Delete"
'===============================================================
80 GoTo Exit_Handler
90 End If
100 DoCmd.RunCommand acCmdDeleteRecord
110 Me.lstCategory.Requery
Exit_Handler:
120 Exit Sub
Err_Handler:
130 clsErrorHandler.HandleError Me.Name, "cmdDelete_Click", True
140 Resume Exit_Handler
End SubPrivate Sub Form_AfterInsert() 10 On Error GoTo Err_Handler 20 Me.lstCategory.Requery Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True 50 Resume Exit_Handler End Sub
Private Sub Form_Current()
10 On Error GoTo Err_Handler
Dim lngCategoryID As Long
20 lngCategoryID = Nz(Me.txtProductCategoryID, 0)
'If user has changed the record using the navigation controls at the bottom of the form,
'we want to ensure that a different category is not still displaying as selected in the listbox lstCategory
30 If lngCategoryID <> CLng(Nz(Me.lstCategory, lngCategoryID)) Then
40 Me.lstCategory = Null
' Me.ctlProductCategory.SetFocus
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "Form_Current", True
80 Resume Exit_Handler
End SubPrivate Sub Form_Delete(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Me.lstCategory.Requery Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_Delete", True 50 Resume Exit_Handler End Sub
Private Sub lstCategory_AfterUpdate()
10 On Error GoTo Err_Handler
20 If Nz(Me.lstCategory, 0) > 0 Then
'temporarily disable screen refresh to avoid flicker in title
30 Me.Painting = False
'=====================Equivalent Syntax=========================
40 DoCmd.SearchForRecord , "", acFirst, "ProductCategoryID = " & Me.lstCategory
' With Me.RecordsetClone
' .FindFirst "ProductCategoryID = " & Me.lstCategory
' If Not .NoMatch Then Me.Bookmark = .Bookmark
' End With
'===============================================================
50 End If
Exit_Handler:
're-enable screen refresh
60 If Me.Painting = False Then Me.Painting = True
70 Exit Sub
Err_Handler:
're-enable screen refresh
80 If Me.Painting = False Then Me.Painting = True
90 clsErrorHandler.HandleError Me.Name, "lstCategory_AfterUpdate"
100 Resume Exit_Handler
End SubPrivate Sub txtProductCategoryCode_BeforeUpdate(Cancel As Integer)
10 On Error GoTo Err_Handler
20 If Me.NewRecord Then GoTo Exit_Handler
'check if this product category has been used in a product. If so, don't allow change,
'since the Products.ProductCode is calculated based on ProductCategories.txtProductCategoryCode
30 If DCount("ProductID", "Products", "ProductCategoryID = " & Me.txtProductCategoryID) > 0 Then
40 MsgBox "You cannot change or delete this Product Code because it is in use by one or more Products" _
, vbCritical + vbOKOnly, "Protected Code"
50 Cancel = True
60 Me.txtProductCategoryCode.Undo
70 End If
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError Me.Name, "txtProductCategoryCode_BeforeUpdate", True
100 Resume Exit_Handler
End SubRecord source: qryProductOrders
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Label1 | Label | Order Date | ||||
| Label2 | Label | Quantity | ||||
| Label23 | Label | Order ID | ||||
| Label3 | Label | UnitPrice | ||||
| Label32 | Label | Order Status | ||||
| Label4 | Label | Extended Price | ||||
| Label64 | Label | Product Status | ||||
| OrderStatus | Text box | OrderStatus | ||||
| ProductStatus | Text box | ProductStatus | ||||
| txtExtendedPrice | Text box | ExtendedPrice | ||||
| txtOrderDate | Text box | OrderDate | ||||
| txtOrderID | Text box | OrderID | Click: txtOrderID_Click | |||
| txtProductID | Text box | ProductID | ||||
| txtQuantity | Text box | Quantity | ||||
| txtUnitPrice | Text box | UnitPrice |
Private Sub txtOrderID_Click() 10 On Error GoTo Err_Handler 20 OpenOrderDetailsForm (Me.OrderID) Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "txtOrderID_Click", True 50 Resume Exit_Handler End Sub
Record source: qryProductPurchaseOrder
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| CompanyName | Text box | CompanyName | ||||
| ExtendedCost | Text box | ExtendedCost | ||||
| Label0 | Label | PO ID | ||||
| Label174 | Label | PO Date | ||||
| Label179 | Label | PO Status | ||||
| Label201 | Label | Extended Cost | ||||
| Label206 | Label | Vendor | ||||
| Label86 | Label | Product ID | ||||
| Label87 | Label | Quantity | ||||
| Label88 | Label | Unit Cost | ||||
| Label89 | Label | Date Received | ||||
| PODate | Text box | SubmittedDate | ||||
| POStatus | Text box | StatusName | ||||
| ProductID | Text box | ProductID | ||||
| Quantity | Text box | Quantity | ||||
| ReceivedDate | Text box | ReceivedDate | ||||
| txtPOID | Text box | PurchaseOrderID | Click: txtPOID_Click | |||
| UnitCost | Text box | UnitCost |
Private Sub txtPOID_Click() 10 On Error GoTo Err_Handler 20 OpenPurchaseOrderDetailsForm Me.txtPOID Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "txtPOID_Click" 50 Resume Exit_Handler 60 Resume End Sub
Record source: qryStockTake
Has VBA module
Events — OnCurrent: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| ExpectedQuantity | Text box | ExpectedQuantity | ||||
| Label0 | Label | StockTakeID | ||||
| Label1 | Label | StockTake Date | ||||
| Label16 | Label | Expected Quantity | ||||
| Label2 | Label | ProductID | ||||
| Label3 | Label | Quantity On Hand | ||||
| ProductID | Text box | ProductID | ||||
| QuantityOnHand | Text box | QuantityOnHand | ||||
| StockTakeDate | Text box | StockTakeDate | ||||
| StockTakeID | Text box | StockTakeID |
Private Sub Form_AfterInsert() 10 On Error GoTo Err_Handler 20 RequeryQuantities Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_AfterInsert", True 50 Resume Exit_Handler End Sub
Private Sub Form_AfterUpdate()
10 On Error GoTo Err_Handler
20 ValidateForm_RemoveHighlights Me
'Allocate the new Inventory number
30 AllocateInventory Me.ProductID
40 RequeryQuantities
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError Me.Name, "Form_AfterUpdate", True
70 Resume Exit_Handler
End SubPrivate Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Cancel = ValidateForm(Me) Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 50 Resume Exit_Handler End Sub 'PURPOSE: ' Prevent existing records from being edited or deleted.
Private Sub Form_Current() 10 On Error GoTo Err_Handler 20 ValidateForm_RemoveHighlights Me 30 Me.AllowAdditions = True 40 Me.AllowDeletions = False 50 Me.AllowEdits = Me.NewRecord Exit_Handler: 60 Exit Sub Err_Handler: 70 clsErrorHandler.HandleError Me.Name, "Form_Current", True 80 Resume Exit_Handler End Sub
Private Sub QuantityOnHand_AfterUpdate() 10 On Error GoTo Err_Handler 20 Me.StockTakeDate = Now() 30 Me.ExpectedQuantity = ProductAvailable(Me.ProductID) 40 Me.Dirty = False 'In QuantityOnHand.BeforeUpdate, the user has confrimed the value for this one and only editable field is correct - force the record to save Exit_Handler: 50 Exit Sub Err_Handler: 60 clsErrorHandler.HandleError Me.Name, "QuantityOnHand_AfterUpdate", True 70 Resume Exit_Handler End Sub
Private Sub QuantityOnHand_BeforeUpdate(Cancel As Integer)
10 On Error GoTo Err_Handler
Dim intOnHand As Integer
Dim strMsg As String
20 intOnHand = ProductAvailable(Me.ProductID)
30 If intOnHand = Me.QuantityOnHand Then
40 Else
50 strMsg = StringFormat("You entered {0} and the expected quantity is {1}. Is {0} correct?", Me.QuantityOnHand, intOnHand)
60 If MsgBox(strMsg, vbYesNo Or vbQuestion, "Quantity On Hand Does Not Match Expected") = vbNo Then
70 Me.Undo
80 Cancel = True
90 End If
100 End If
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError Me.Name, "QuantityOnHand_BeforeUpdate", True
130 Resume Exit_Handler
End SubPrivate Sub RequeryQuantities()
10 On Error GoTo Err_Handler
20 If IsFormOpen("frmProductDetail") Then
'Example of calling a public sub on a parent form, from a subform
'Recalculates quantities on the Product Detail form (parent); sets control properties accordingly
30 Form_frmProductDetail.ControlStates
'Recalculates quantities on the Products List if it's loaded
40 RequeryProductList
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "RequeryQuantities"
80 Resume Exit_Handler
End SubRecord source: qryProductVendors
Has VBA module
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| cboVendorID | Combo box | VendorID | qrycboVendors | |||
| lblVendor | Label | Vendor | ||||
| lblVendorID | Label | Vendor ID | ||||
| ProductID | Text box | ProductID | ||||
| ProductVendorID | Text box | ProductVendorID | ||||
| txtAddedBy | Text box | AddedBy | ||||
| txtAddedOn | Text box | AddedOn | ||||
| txtModifiedBy | Text box | ModifiedBy | ||||
| txtModifiedOn | Text box | ModifiedOn | ||||
| txtVendorID | Text box | VendorID | Click: txtVendorID_Click |
Private Sub Form_BeforeUpdate(Cancel As Integer) 10 On Error GoTo Err_Handler 20 Me.txtModifiedBy = Get_EmployeeFNLN(Get_UserID()) 30 Me.txtModifiedOn = Now() Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True 60 Resume Exit_Handler End Sub
Private Sub txtVendorID_Click()
10 On Error GoTo Err_Handler
20 If Not Me.NewRecord Then
'If the Company Detail form is open let them know and ask them to close it
30 If IsFormOpen("frmCompanyDetail") Then
40 MsgBox GetString(sFormAlreadyOpen, "Company Detail"), vbOKOnly, "Already Open"
50 Exit Sub
60 End If
'Pass Company ID and CompanyTypeID in the OpenArgs Property
70 DoCmd.OpenForm "frmCompanyDetail", OpenArgs:=StringFormat("CompanyID={0}&CompanyTypeID={1}", Me.VendorID, ctVendor)
80 End If
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError Me.Name, "txtVendorID_Click", True
110 Resume Exit_Handler
End SubRecord source: qryPurchaseOrderLineItems
Has VBA module
Events — OnCurrent: [Event Procedure]
Select a non-button control to open its detailed documentation below. Buttons that open a documented form go to that form. Ctrl-click to open a link in a new tab. Use C for button code and M for its Investigation Map.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| boxHeaderControls | Rectangle | |||||
| Label0 | Label | # | ||||
| Label1 | Label | Product | ||||
| Label122 | Label | Cost | ||||
| Label124 | Label | SubTotal | ||||
| Label2 | Label | Quantity | ||||
| Label3 | Label | Unit Cost | ||||
| Price | Text box | =[Quantity]*[UnitCost] | ||||
| ProductID | Combo box | ProductID | qrycboProducts_PO | |||
| PurchaseOrderDetailID | Text box | PurchaseOrderDetailID | Click: PurchaseOrderDetailID_Click | |||
| Quantity | Text box | Quantity | ||||
| txtSubTotal | Text box | =Sum([Quantity]*[UnitCost]) | ||||
| UnitCost | Text box | UnitCost |
Private Sub Form_BeforeUpdate(Cancel As Integer)
10 On Error GoTo Err_Handler
20 Cancel = ValidateForm(Me) 'Validates required fields.
30 If Not Cancel Then
'Additional validation regarding desired inventory levels.
40 Cancel = ValidateLineItem()
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError Me.Name, "Form_BeforeUpdate", True
80 Resume Exit_Handler
End SubPrivate Sub Form_Current() 10 On Error GoTo Err_Handler 20 ValidateForm_RemoveHighlights Me Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError Me.Name, "Form_Current", True 50 Resume Exit_Handler End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer) 10 On Error GoTo Err_Handler 20 If DataErr = 3314 Then '3314 = You must enter a value in the '|' field. 30 If IsNull(Me.PurchaseOrderID) Then 40 MsgBox "You must first fill out the main Purchase Order form before entering line items. Please cancel this record by hitting Esc, and fill out the main form.", vbExclamation 50 Response = acDataErrContinue 60 End If 70 End If Exit_Handler: 80 Exit Sub Err_Handler: 90 clsErrorHandler.HandleError Me.Name, "Form_Error", True 100 Resume Exit_Handler End Sub
Private Sub ProductID_AfterUpdate() 10 On Error GoTo Err_Handler 20 Me.Quantity = ProductReorderQuantity(Me.ProductID) 30 Me.UnitCost = Me.ProductID.Column(2) 'Column at index 2 has the hidden Standard Cost. Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError Me.Name, "ProductID_AfterUpdate", True 60 Resume Exit_Handler End Sub
Private Sub PurchaseOrderDetailID_Click() 10 On Error GoTo Err_Handler 20 If Not Me.NewRecord Then 30 DoCmd.OpenForm "frmProductDetail", WhereCondition:="ProductID = " & Me.ProductID 40 End If Exit_Handler: 50 Exit Sub Err_Handler: 60 clsErrorHandler.HandleError Me.Name, "PurchaseOrderDetailID_Click", True 70 Resume Exit_Handler End Sub 'RETURNS: ' False if the line item is valid = conforms to the business rules; True otherwise.
Private Function ValidateLineItem() As Boolean
10 On Error GoTo Err_Handler
Dim rs As DAO.Recordset
Dim blnReturn As Boolean
Dim intAvailable As Integer
Dim sql As String
20 blnReturn = False
30 sql = "select * from Products where ProductID = " & Me.ProductID
40 Set rs = g_dbApp().OpenRecordset(sql, dbOpenSnapshot)
'BUSINESS RULE: Qty should be at least MinimumReorderQuantity
50 If Me.Quantity < Nz(rs!MinimumReorderQuantity, 0) Then
60 blnReturn = True
70 MsgBox GetString(sMinimumReorderQuantity, rs!MinimumReorderQuantity), vbExclamation
80 End If
'BUSINESS RULE: Qty should be sufficient to get to at least TargetLevel.
90 intAvailable = ProductToSell(Me.ProductID)
100 If intAvailable + Me.Quantity < rs!TargetLevel Then
'This is a warning, not an error, so we are not setting blnReturn = True.
110 MsgBox GetString(sLessThanTargetLevel, rs!TargetLevel, rs!TargetLevel - intAvailable - Me.Quantity), vbExclamation
120 End If
130 rs.Close
140 Set rs = Nothing
150 ValidateLineItem = blnReturn
Exit_Handler:
160 Exit Function
Err_Handler:
170 clsErrorHandler.HandleError Me.Name, "ValidateLineItem"
180 Resume Exit_Handler
End FunctionReport settings, controls, and wireframe layouts.
Record source: No record source
Events — OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Header0 | Label | Title | ||||
| imgNorthwindTradersLogo | Image |
Record source: qryrptEmployeeEmailList
Events — OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Date | Text box | =Date() | ||||
| Auto_Header0 | Label | Northwind Employee Email List | ||||
| Auto_Logo0 | Image | |||||
| Auto_Time | Text box | =Time() | ||||
| lblEmaiLAddress | Label | Email Address | ||||
| lblEmployeeID | Label | ID | ||||
| LblFirstnameLastName | Label | Full Name | ||||
| txtEmailAddress | Text box | EmailAddress | ||||
| txtEmployeeCount | Text box | =Count(*) | ||||
| txtEmployeeID | Text box | EmployeeID | ||||
| txtFullNameFNLN | Text box | FullNameFNLN | ||||
| txtPageNumber | Text box | =\"Page \" & [Page] & \" of \" & [Pages] |
Record source: qryrptEmployeePhoneList
Events — OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Auto_Date | Text box | =Date() | ||||
| Auto_Header0 | Label | Northwind Employee Phone List | ||||
| Auto_Logo0 | Image | |||||
| Auto_Time | Text box | =Time() | ||||
| EmailGrouP | Text box | EmailGrouP | ||||
| lblEmaiLAddress | Label | Primary Phone | ||||
| lblEmployeeID | Label | ID | ||||
| LblFirstnameLastName | Label | Full Name | ||||
| lblSecondaryPhone | Label | Secondary Phone | ||||
| txtEmailAddress | Text box | PrimaryPhone | ||||
| txtEmployeeCount | Text box | =Count(*) | ||||
| txtEmployeeID | Text box | EmployeeID | ||||
| txtFullNameFNLN | Text box | FullNameFNLN | ||||
| txtPageNumber | Text box | =\"Page \" & [Page] & \" of \" & [Pages] | ||||
| txtSecondaryPhone | Text box | SecondaryPhone |
Record source: qryInvoice
Filter: OrderID=52
Events — OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Address | Text box | Address | ||||
| boxHeaderControls | Rectangle | |||||
| CustomerName | Text box | CompanyName | ||||
| Image62 | Image | |||||
| Label122 | Label | Price | ||||
| Label65 | Label | Bill To | ||||
| Label69 | Label | Ship To | ||||
| Label74 | Label | # | ||||
| Label75 | Label | Product | ||||
| Label76 | Label | Quantity | ||||
| Label77 | Label | Unit Price | ||||
| Label79 | Label | Total Price | ||||
| Label85 | Label | Discount | ||||
| Label88 | Label | Tax | ||||
| Label90 | Label | SubTotal | ||||
| Label92 | Label | Shipping | ||||
| Text68 | Text box | CompanyName | ||||
| Text70 | Text box | Address | ||||
| Text71 | Text box | =[City] & \" \" & [StateAbbrev] & \", \" & [Zip] | ||||
| Text83 | Text box | =GetNorthwindAddress() | ||||
| txtCSZ | Text box | =[City] & \" \" & [StateAbbrev] & \", \" & [Zip] | ||||
| txtDiscount | Text box | Discount | ||||
| txtExtendedPrice | Text box | =(1-[Discount])*[Quantity]*[UnitPrice] | ||||
| txtInvoiceDate | Text box | =\"Invoice Date \" & Date() | ||||
| txtInvoiceNumber | Text box | =\"Invoice # \" & [OrderID] | ||||
| txtProductCode | Text box | ProductCode | ||||
| txtProductName | Text box | ProductName | ||||
| txtQuantity | Text box | Quantity | ||||
| txtSalesPerson | Text box | =\"Sales Person \" & [SalesPerson] | ||||
| txtShipping | Text box | =[ShippingFee] | ||||
| txtSubTotal | Text box | =Sum((1-[Discount])*[Quantity]*[UnitPrice]) | ||||
| txtTax | Text box | =IIf([TaxStatusID]=1,[taxrate]*Sum((1-[Discount])*[Quantity]*[UnitPrice]),0) | ||||
| txtTotal | Text box | =[txtSubTotal]+[txtTax]+[txtShipping] | ||||
| txtUnitPrice | Text box | UnitPrice |
Record source: No record source
Events — OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Image28 | Image | |||||
| Image30 | Image | |||||
| Image49 | Image | |||||
| Label12 | Label | Northwind 2.0 Developer Edition: Template Tutorial | ||||
| OLEUnbound13 | Image | |||||
| OLEUnbound18 | Image | |||||
| OLEUnbound20 | Image | |||||
| OLEUnbound23 | Image | |||||
| OLEUnbound26 | Image | |||||
| OLEUnbound32 | Image | |||||
| OLEUnbound34 | Image | |||||
| OLEUnbound40 | Image | |||||
| OLEUnbound41 | Image | |||||
| OLEUnbound43 | Image | |||||
| OLEUnbound45 | Image | |||||
| OLEUnbound47 | Image | |||||
| Text14 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=10\") | ||||
| Text16 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=20\") | ||||
| Text17 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=30\") | ||||
| Text19 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=40\") | ||||
| Text22 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=50\") | ||||
| Text24 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=60\") | ||||
| Text27 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=70\") | ||||
| Text29 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=80\") | ||||
| Text31 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=90\") | ||||
| Text33 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=100\") | ||||
| Text35 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=110\") | ||||
| Text36 | Text box | =\"To see the full-size database design image, select System Admin > Relationshi | ||||
| Text44 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=120\") | ||||
| Text46 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=130\") | ||||
| Text48 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=140\") | ||||
| Text50 | Text box | =DLookUp(\"SectionText\",\"Learn\",\"SectionNo=150\") |
Record source: qryNWP_OrderAvailability
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| AvailableToPromise | Text box | AvailableToPromise | ||||
| AvailableToPromise_Label | Label | AvailableToPromise | ||||
| Label20 | Label | Order Availability Plan | ||||
| Label23 | Label | Northwind Plus demonstration planning data — not a live production promise. | ||||
| OrderID | Text box | OrderID | ||||
| OrderID_Label | Label | OrderID | ||||
| PlannedProduction | Text box | PlannedProduction | ||||
| PlannedProduction_Label | Label | PlannedProduction | ||||
| PlanStatus | Text box | PlanStatus | ||||
| PlanStatus_Label | Label | PlanStatus | ||||
| ProductCode | Text box | ProductCode | ||||
| ProductCode_Label | Label | ProductCode | ||||
| ProductName | Text box | ProductName | ||||
| ProductName_Label | Label | ProductName | ||||
| PromiseDate | Text box | PromiseDate | ||||
| PromiseDate_Label | Label | PromiseDate | ||||
| QuantityOnHand | Text box | QuantityOnHand | ||||
| QuantityOnHand_Label | Label | QuantityOnHand | ||||
| RequiredQuantity | Text box | RequiredQuantity | ||||
| RequiredQuantity_Label | Label | RequiredQuantity | ||||
| ShortageQuantity | Text box | ShortageQuantity | ||||
| ShortageQuantity_Label | Label | ShortageQuantity | ||||
| Text21 | Text box | =Now() | ||||
| Text22 | Text box | =\"Page \" & [Page] & \" of \" & [Pages] |
Record source: qryrptProductCatalog
Events — OnOpen: [Event Procedure], OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Attachment36 | Attachment | ProductCategoryImage | ||||
| Image19 | Image | |||||
| Label1 | Label | Lowest Price: | ||||
| Label10 | Label | Items Count: | ||||
| Label12 | Label | Total Sales: | ||||
| Label13 | Label | Northwind Traders - Fall Catalog | ||||
| Label18 | Label | Fall Catalog | ||||
| Label3 | Label | Highest Price: | ||||
| Label35 | Label | srptOrderForm: | ||||
| Label5 | Label | Product Name | ||||
| Label6 | Label | Product ID | ||||
| Label7 | Label | Quantity Per Unit | ||||
| Label8 | Label | Unit Price | ||||
| Line34 | Line | |||||
| ProductCategoryDesc | Text box | ProductCategoryDesc | ||||
| ProductCategoryImage | Text box | ProductCategoryImage | ||||
| ProductCategoryName | Text box | ProductCategoryName | ||||
| ProductID | Text box | ProductID | ||||
| ProductName | Text box | ProductName | ||||
| QuantityPerUnit | Text box | QuantityPerUnit | ||||
| srptCatalog_TableOfContents | Subform/Subreport | Report.srptCatalog_TableOfContents | ||||
| srptGastronomic | Subform/Subreport | Report.srptGastronomic | ||||
| srptOrderForm | Subform/Subreport | Report.srptOrderForm | ||||
| srptQuality | Subform/Subreport | Report.srptQuality | ||||
| Text14 | Text box | =\"Page Number \" & [Page] & \"/\" & [Pages] | ||||
| Text28 | Text box | =IIf(DCount(\"*\",\"Catalog_TableOfContents\")=0,\"Preview all pages and send to | ||||
| txtItemCount | Text box | =Count([UnitPrice]) | ||||
| txtMaxPrice | Text box | =Max([UnitPrice]) | ||||
| txtMinPrice | Text box | =Min([UnitPrice]) | ||||
| txtTotalSales | Text box | =Sum([TotalSales]) | ||||
| UnitPrice | Text box | UnitPrice |
Record source: No record source
Events — OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Image3 | Image |
Record source: qryrptSalesByEmployee
Filter: EmployeeID = 3
Events — OnOpen: [Event Procedure], OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| cboFilterByEmployee | List box | SELECT 0 as EmployeeID, \" <All Employees>\" AS FullNameFNLN FROM qryrptSalesByE | Double-click: [Event Procedure] | |||
| chrtEmplyeeSalesByMonth | Chart | qryrptSalesByEmployee | ||||
| Filter by Employee_Label | Label | Double-Click to select Employee | ||||
| FullNameFNLN | Text box | FullNameFNLN | ||||
| FullNameFNLN_Label | Label | Employee | ||||
| GrandTotalSum | Text box | =Sum([OrderTotal]) | ||||
| imgLogo | Image | |||||
| Label11 | Label | Sum | ||||
| Label13 | Label | Grand Total | ||||
| Label15 | Label | Monthly Orders By Employee | ||||
| Label28 | Label | Please note: Modern Chart is only available with Access 2019 and up. | ||||
| lblCriteria | Label | Order Dates between 8/5/2022 And 11/5/2022 | ||||
| MonthYear | Text box | MonthYear | ||||
| MonthYear_Label | Label | Month | ||||
| OrderTotal | Text box | OrderTotal | ||||
| SumOfOrderTotal | Text box | =Sum([OrderTotal]) | ||||
| SumOfOrderTotal_Label | Label | Order Total | ||||
| Text16 | Text box | =Now() | ||||
| Text17 | Text box | =\"Page \" & [Page] & \" of \" & [Pages] |
Record source: qryrptSalesByProduct_ByMonth
Events — OnOpen: [Event Procedure], OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| boxLogo | Rectangle | |||||
| chrtSalesByProduct | Chart | qryrptSalesByProduct_ByMonth | ||||
| FullNameFNLN | Text box | ProductName | ||||
| FullNameFNLN_Label | Label | Product | ||||
| GrandTotalSum | Text box | =Sum([OrderTotal]) | ||||
| imgLogo | Image | |||||
| Label13 | Label | Grand Total | ||||
| Label15 | Label | Northwind Traders Monthly Orders By Product | ||||
| Label22 | Label | Please note: Modern Chart is only available with Access 2019 and up. | ||||
| lblCriteria | Label | TODO: Criteria.4583 | ||||
| MonthYear | Text box | MonthYear | ||||
| MonthYear_Label | Label | Month | ||||
| OrderTotal | Text box | OrderTotal | ||||
| SumOfOrderTotal | Text box | =Sum([OrderTotal]) | ||||
| SumOfOrderTotal_Label | Label | Orders Total | ||||
| Text16 | Text box | =Now() | ||||
| Text17 | Text box | =\"Page \" & [Page] & \" of \" & [Pages] | ||||
| Text20 | Text box | =\"Total Orders for \" & [MonthYear] |
Record source: qryrptSalesByProduct_ByQuarter
Events — OnOpen: [Event Procedure], OnClose: [Event Procedure], OnNoData: [Event Procedure]
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| boxLogo | Rectangle | |||||
| chrtSalesByProduct | Chart | qryrptSalesByProduct_ByMonth | ||||
| FullNameFNLN | Text box | ProductName | ||||
| FullNameFNLN_Label | Label | Product | ||||
| GrandTotalSum | Text box | =Sum([OrderTotal]) | ||||
| imgLogo | Image | |||||
| Label13 | Label | Grand Total | ||||
| Label15 | Label | Northwind Traders Quarterly Orders By Product | ||||
| Label23 | Label | Please note: Modern Chart is only available with Access 2019 and up. | ||||
| lblCriteria | Label | TODO: Criteria.4583 | ||||
| lblQuarter | Label | Quarter | ||||
| MonthYear | Text box | QuarterYear | ||||
| OrderTotal | Text box | OrderTotal | ||||
| SumOfOrderTotal | Text box | =Sum([OrderTotal]) | ||||
| SumOfOrderTotal_Label | Label | Orders Total | ||||
| Text16 | Text box | =Now() | ||||
| Text17 | Text box | =\"Page \" & [Page] & \" of \" & [Pages] | ||||
| Text20 | Text box | =\"Total Orders for \" & [QuarterYear] |
Record source: Catalog_TableOfContents
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Label0 | Label | Table of Contents | ||||
| txtTocPage | Text box | TocPage | ||||
| txtTocTitle | Text box | =[TocTitle] & \" \" & String(300,\".\") |
Record source: No record source
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| StringData | Text box | =GetString(44) | ||||
| Text1 | Text box | =GetString(43) |
Record source: SELECT CompanyTypes.CompanyType, Companies.CompanyID, Companies.CompanyName, Com
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Box23 | Rectangle | |||||
| HowToOrder | Text box | =GetString(47) | ||||
| Image0 | Image | |||||
| Label17 | Label | Date of Order: | ||||
| Label19 | Label | Date Required: | ||||
| Label2 | Label | ORDER FORM | ||||
| Label21 | Label | Customer ID: | ||||
| Label24 | Label | Product ID: | ||||
| Label25 | Label | Product Name: | ||||
| Label26 | Label | Unit Price: | ||||
| Label27 | Label | Quantity: | ||||
| Label28 | Label | Extended Price: | ||||
| Label47 | Label | Subtotal: | ||||
| Label48 | Label | Freight (estimated): | ||||
| Label49 | Label | Total: | ||||
| Label5 | Label | Phone: | ||||
| Label7 | Label | Bill To: | ||||
| Label8 | Label | Ship To: | ||||
| Line1 | Line | |||||
| Line10 | Line | |||||
| Line11 | Line | |||||
| Line12 | Line | |||||
| Line13 | Line | |||||
| Line14 | Line | |||||
| Line15 | Line | |||||
| Line16 | Line | |||||
| Line18 | Line | |||||
| Line20 | Line | |||||
| Line22 | Line | |||||
| Line29 | Line | |||||
| Line30 | Line | |||||
| Line31 | Line | |||||
| Line32 | Line | |||||
| Line33 | Line | |||||
| Line34 | Line | |||||
| Line35 | Line | |||||
| Line36 | Line | |||||
| Line37 | Line | |||||
| Line39 | Line | |||||
| Line40 | Line | |||||
| Line41 | Line | |||||
| Line42 | Line | |||||
| Line43 | Line | |||||
| Line44 | Line | |||||
| Line45 | Line | |||||
| Line46 | Line | |||||
| Line9 | Line | |||||
| srptShipVia | Subform/Subreport | Report.srptShipVia | ||||
| txtAddress | Text box | =[Address] & \", \" & [City] & \", \" & [StateAbbrev] & \" \" & [Zip] | ||||
| txtBusinessPhone | Text box | [BusinessPhone] |
Record source: No record source
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| StringData | Text box | =GetString(46) | ||||
| Text1 | Text box | =Getstring(45) |
Record source: qryShippers
Design-time layout of the report controls. Report sections are stacked from header to footer.
| Control | Type | Caption / attached label | Bound field/expression | Row source | Subform/subreport | Click / event code |
|---|---|---|---|---|---|---|
| Label0 | Label | Ship Via (check one): | ||||
| rectCheck | Rectangle | |||||
| txtCompanyName | Text box | CompanyName |
Macro actions, submacros, and the objects they reference.
2 actions: OpenForm: frmStartup; RunCode
No named submacros found.
| Step | Action | Details |
|---|---|---|
| 1 | OpenForm | Condition: [CurrentProject].[IsTrusted]; Form: frmStartup; View: 0; Data mode: -1; Window mode: 0 |
| 2 | RunCode | Function: Startup() |
Standard VBA modules, their procedures, and detected calls.
| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| ErrorHandlerExample | Sub | Public | () | 21 | 12 | handleerror |
| ErrorHandlerExample_EventProcedure | Sub | Public | () | 34 | 12 | handleerror |
| Class_Initialize | Sub | Private | () | 47 | 17 | — |
| HandleError | Sub | Public | () | 64 | 52 | logerrortofile |
| LogErrorToFile | Sub | Private | (ByVal strError As String, ByVal lngError As Long, ByVal lngErrorLine As Long, ByVal strModuleName As String, ByVal strProcedureName As String) | 117 | 28 | — |
Public Sub ErrorHandlerExample()
10 On Error GoTo Err_Handler
'Code goes here.
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError "YourModuleName", "YourProcedureName"
40 Resume Exit_Handler
End SubPublic Sub ErrorHandlerExample_EventProcedure()
10 On Error GoTo Err_Handler
'Code goes here.
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError "YourModuleName", "YourProcedureName", True
40 Resume Exit_Handler
End SubPrivate Sub Class_Initialize()
'NOTE: Do not add standard error handler code to this constructor. It messes with the first error.
'Create full path to error log file in same folder as current database, by concatenating the folder, a backslash, and a filename.
10 m_strLogFilePath = CurrentProject.Path & "\" & LOGFILENAME
End Sub
'Espana UG Identify the source of the error to ensure proper feedback al usario
'ARGUMENTS:
' strModuleName - Name of the VBA module where the error occurred.
' strProcedureName - Name of the VBA procedure where the error occurred.
' IsEventProcedure - (new for v2.2) True for Event Procedures and other toplevel procedures such as Startup; False for all other procedures.
' If you forget to set it, the Northwind 2.0 behavior will happen.
'NOTE:
' This main error handler should not itself have an error handler.Public Sub HandleError(ByVal strModuleName As String, ByVal strProcedureName As String, _
Optional ByVal IsEventProcedure As Boolean = False)
Dim lngError As Long
Dim lngErrorLine As Long
Dim strError As String
Dim strMsg As String
Dim strErrLine As String
Dim strErrSource As String
'Get the current error information
10 strError = Err.Description
20 lngError = Err.Number
30 lngErrorLine = Erl 'If no line number, this will be 0.
40 strErrSource = Err.Source
50 If strErrSource = m_VbProjectName Then
60 strErrSource = vbNullString
70 Else
80 strErrSource = " -> " & strErrSource
90 End If
100 If lngErrorLine > 0 Then
110 strErrLine = " (L " & lngErrorLine & ")"
120 End If
130 strErrSource = strModuleName & "." & strProcedureName & strErrLine & strErrSource
140 If lngError = 2501 Then Exit Sub '2501 = The OpenForm action was canceled. Not really an error.
'Log the error, even before we show it to the user.
150 LogErrorToFile strError, lngError, lngErrorLine, strModuleName, strProcedureName
160 If Not IsEventProcedure Then
170 Err.Raise lngError, strErrSource, strError
180 End If
'Compose the error message by concatenating substrings.
190 strMsg = "The following error has occurred: " & vbCrLf
200 strMsg = strMsg & strError & vbCrLf
210 If lngErrorLine <> 0 Then strMsg = strMsg & "On line " & lngErrorLine & vbCrLf
220 strMsg = strMsg & strModuleName & "." & strProcedureName & vbCrLf & vbCrLf
230 strMsg = strMsg & "Error number: " & lngError & vbCrLf & vbCrLf
240 strMsg = strMsg & "Call stack: " & strErrSource & vbCrLf & vbCrLf
250 strMsg = strMsg & "Please notify the Help Desk. Thank you!"
'Show the message to the user. A developer running ACCDB can hit Ctrl+Break and Step in the debugger to get to the calling procedure.
260 MsgBox strMsg, vbCritical
End SubPrivate Sub LogErrorToFile(ByVal strError As String, ByVal lngError As Long, ByVal lngErrorLine As Long, ByVal strModuleName As String, ByVal strProcedureName As String)
10 On Error GoTo Err_Handler
Dim intFile As Integer
20 intFile = FreeFile
30 Open m_strLogFilePath For Append As intFile
40 Print #intFile, "Current Time : " & Now
50 Print #intFile, "Module : " & strModuleName
60 Print #intFile, "Procedure : " & strProcedureName
70 Print #intFile, "Error String : " & strError
80 Print #intFile, "Error Number : " & lngError
90 Print #intFile, "Error Line : " & IIf(lngErrorLine = 0, "<none>", lngErrorLine)
100 Print #intFile, "User : " & Environ$("USERNAME")
110 Print #intFile, "Machine : " & Environ$("COMPUTERNAME")
120 Print #intFile, "---------------"
130 Close #intFile
Exit_Handler:
140 Exit Sub
Err_Handler:
'Do not call the error handler, or you may get recursive errors. Better to ignore it. g_ErrorHandler.HandleError "clsErrorHandler", "LogErrorToFile"
150 Debug.Print "Unable to LogErrorToFile. Error number: " & Err.Number & ", Description: " & Err.Description
160 Resume Exit_Handler
End SubAttribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Compare Database
Option Explicit
'NOTE:
' This is a "default instance" class, meaning the developer does not need to instantiate it, it is always there, and the instance always has the name of the class.
' This is somewhat similar to "static" class in other programming languages, but VBA does not have true static classes.
' To use this class in your own projects you have to use these steps: Export File out of this database, and Import File into your database.
' A simple copy/paste of the code is NOT enough.
'REFERENCE:
' https://learn.microsoft.com/openspecs/microsoft_general_purpose_programming_languages/ms-vbal/189fb41b-cc3a-4999-a6d2-ba89f72d2870
Private Const m_VbProjectName As String = "NW2-Dev" 'The name of the VBA project; often used as the Err.Source value.
Private Const LOGFILENAME As String = "Northwind-Dev.log"
Private m_strLogFilePath As String
Public Sub ErrorHandlerExample()
10 On Error GoTo Err_Handler
'Code goes here.
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError "YourModuleName", "YourProcedureName"
40 Resume Exit_Handler
End Sub
Public Sub ErrorHandlerExample_EventProcedure()
10 On Error GoTo Err_Handler
'Code goes here.
Exit_Handler:
20 Exit Sub
Err_Handler:
30 clsErrorHandler.HandleError "YourModuleName", "YourProcedureName", True
40 Resume Exit_Handler
End Sub
Private Sub Class_Initialize()
'NOTE: Do not add standard error handler code to this constructor. It messes with the first error.
'Create full path to error log file in same folder as current database, by concatenating the folder, a backslash, and a filename.
10 m_strLogFilePath = CurrentProject.Path & "\" & LOGFILENAME
End Sub
'Espana UG Identify the source of the error to ensure proper feedback al usario
'ARGUMENTS:
' strModuleName - Name of the VBA module where the error occurred.
' strProcedureName - Name of the VBA procedure where the error occurred.
' IsEventProcedure - (new for v2.2) True for Event Procedures and other toplevel procedures such as Startup; False for all other procedures.
' If you forget to set it, the Northwind 2.0 behavior will happen.
'NOTE:
' This main error handler should not itself have an error handler.
Public Sub HandleError(ByVal strModuleName As String, ByVal strProcedureName As String, _
Optional ByVal IsEventProcedure As Boolean = False)
Dim lngError As Long
Dim lngErrorLine As Long
Dim strError As String
Dim strMsg As String
Dim strErrLine As String
Dim strErrSource As String
'Get the current error information
10 strError = Err.Description
20 lngError = Err.Number
30 lngErrorLine = Erl 'If no line number, this will be 0.
40 strErrSource = Err.Source
50 If strErrSource = m_VbProjectName Then
60 strErrSource = vbNullString
70 Else
80 strErrSource = " -> " & strErrSource
90 End If
100 If lngErrorLine > 0 Then
110 strErrLine = " (L " & lngErrorLine & ")"
120 End If
130 strErrSource = strModuleName & "." & strProcedureName & strErrLine & strErrSource
140 If lngError = 2501 Then Exit Sub '2501 = The OpenForm action was canceled. Not really an error.
'Log the error, even before we show it to the user.
150 LogErrorToFile strError, lngError, lngErrorLine, strModuleName, strProcedureName
160 If Not IsEventProcedure Then
170 Err.Raise lngError, strErrSource, strError
180 End If
'Compose the error message by concatenating substrings.
190 strMsg = "The following error has occurred: " & vbCrLf
200 strMsg = strMsg & strError & vbCrLf
210 If lngErrorLine <> 0 Then strMsg = strMsg & "On line " & lngErrorLine & vbCrLf
220 strMsg = strMsg & strModuleName & "." & strProcedureName & vbCrLf & vbCrLf
230 strMsg = strMsg & "Error number: " & lngError & vbCrLf & vbCrLf
240 strMsg = strMsg & "Call stack: " & strErrSource & vbCrLf & vbCrLf
250 strMsg = strMsg & "Please notify the Help Desk. Thank you!"
'Show the message to the user. A developer running ACCDB can hit Ctrl+Break and Step in the debugger to get to the calling procedure.
260 MsgBox strMsg, vbCritical
End Sub
Private Sub LogErrorToFile(ByVal strError As String, ByVal lngError As Long, ByVal lngErrorLine As Long, ByVal strModuleName As String, ByVal strProcedureName As String)
10 On Error GoTo Err_Handler
Dim intFile As Integer
20 intFile = FreeFile
30 Open m_strLogFilePath For Append As intFile
40 Print #intFile, "Current Time : " & Now
50 Print #intFile, "Module : " & strModuleName
60 Print #intFile, "Procedure : " & strProcedureName
70 Print #intFile, "Error String : " & strError
80 Print #intFile, "Error Number : " & lngError
90 Print #intFile, "Error Line : " & IIf(lngErrorLine = 0, "<none>", lngErrorLine)
100 Print #intFile, "User : " & Environ$("USERNAME")
110 Print #intFile, "Machine : " & Environ$("COMPUTERNAME")
120 Print #intFile, "---------------"
130 Close #intFile
Exit_Handler:
140 Exit Sub
Err_Handler:
'Do not call the error handler, or you may get recursive errors. Better to ignore it. g_ErrorHandler.HandleError "clsErrorHandler", "LogErrorToFile"
150 Debug.Print "Unable to LogErrorToFile. Error number: " & Err.Number & ", Description: " & Err.Description
160 Resume Exit_Handler
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| GetRandomCustomerID | Function | Public | () | 4 | 12 | getrandompkvalue, handleerror |
| GetTaxStatusID | Function | Public | (ByVal lngCompanyID As Long) | 17 | 12 | handleerror |
Public Function GetRandomCustomerID() As Long
10 On Error GoTo Err_Handler
20 GetRandomCustomerID = GetRandomPkValue("qryCustomers", "CompanyID")
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modCompanies", "GetRandomCustomerID"
50 Resume Exit_Handler
End FunctionPublic Function GetTaxStatusID(ByVal lngCompanyID As Long) As Byte
10 On Error GoTo Err_Handler
20 GetTaxStatusID = DLookup("StandardTaxStatusID", "Companies", "CompanyID = " & lngCompanyID)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modCompanies", "GetTaxStatusID"
50 Resume Exit_Handler
End FunctionOption Compare Database
Option Explicit
Public Function GetRandomCustomerID() As Long
10 On Error GoTo Err_Handler
20 GetRandomCustomerID = GetRandomPkValue("qryCustomers", "CompanyID")
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modCompanies", "GetRandomCustomerID"
50 Resume Exit_Handler
End Function
Public Function GetTaxStatusID(ByVal lngCompanyID As Long) As Byte
10 On Error GoTo Err_Handler
20 GetTaxStatusID = DLookup("StandardTaxStatusID", "Companies", "CompanyID = " & lngCompanyID)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modCompanies", "GetTaxStatusID"
50 Resume Exit_Handler
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| GetRandomPkValue | Function | Public | (ByVal strTable As String, ByVal strPkField As String) | 8 | 28 | getrandom, handleerror |
| HasDataMacro | Function | Public | (td As DAO.TableDef) | 36 | 22 | handleerror, stringformatsql |
| HasField | Function | Public | (td As DAO.TableDef, ByVal strField As String) | 58 | 22 | — |
| HasProperty | Function | Public | (o As Object, ByVal propName As String) | 80 | 9 | — |
Public Function GetRandomPkValue(ByVal strTable As String, ByVal strPkField As String) As Long
10 On Error GoTo Err_Handler
Dim rs As DAO.Recordset
20 Set rs = CurrentDb.OpenRecordset(strTable, dbOpenSnapshot)
30 With rs
40 .MoveLast 'This assumes there is at least one record
50 .MoveFirst
60 .Move GetRandom(0, .RecordCount - 1)
70 GetRandomPkValue = .Fields(strPkField)
80 .Close
90 End With
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modDAO", "GetRandomPkValue"
120 Resume Exit_Handler
End Function
'REFERENCE:
' https://stackoverflow.com/questions/31755802/can-i-use-access-vba-to-determine-if-a-table-has-a-data-macro
'NOTE:
' While MSysObjects.LvExtra is officially undocumented, if you dump the bytes of this field for a table with table data macro,
' you will see the XML in plain text. We use that for our algorithm: if the length of the field is at least the length
' of the data macro code, we assume it has a data macro.Public Function HasDataMacro(td As DAO.TableDef) As Boolean
10 On Error GoTo Err_Handler
Dim intDmLength As Integer
Dim intLvExtraLength As Integer
20 intDmLength = Len(DLookup("DataMacro", "Welcome"))
30 intLvExtraLength = Len(Nz(DLookup("LvExtra", "MSysObjects", StringFormatSQL("Name={0}", td.Name)), ""))
40 HasDataMacro = (intLvExtraLength >= intDmLength)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modDAO", "HasDataMacro"
70 Resume Exit_Handler
End Function
'ALGORITHM:
' Attempt to set a Field object to the given field name while "On Error Resume Next" is active,
' and if no error then the field exists.
' Alternatively we could have iterated over the Fields collection. That is probably slower.Public Function HasField(td As DAO.TableDef, ByVal strField As String) As Boolean
Dim fld As DAO.Field
10 On Error Resume Next
20 Set fld = td.Fields(strField)
30 HasField = (Err.Number = 0)
40 Set fld = Nothing
End Function
'PROCEDURE:
' HasProperty
'PURPOSE:
' Test if the given object has the named property in its Properties collection.
'ALGORITHM:
' Set VBA to ignore errors. Try to use the property. If it works, it exists; if not, it does not exist.
'ARGUMENTS:
' o - Object that has a Properties collection
' propName - Name to look for
'RETURNS:
' Boolean - True if found, False otherwise.
'NOTE:
' The alternative implementation is to loop over the Properties collection. That's several times slower.Public Function HasProperty(o As Object, ByVal propName As String) As Boolean
Dim blnResult As Boolean
Dim strName As String
10 On Error Resume Next
20 strName = o.Properties(propName).Name 'All properties have a Name property.
30 blnResult = (Err.Number = 0)
40 HasProperty = blnResult
End FunctionOption Compare Database
Option Explicit
'ALGORITHM:
' Open readonly recordset on table. Move a random number of rows down, and select that PK value.
'NOTE:
' Function assumes PK is a single field and Long. This is a best practice and True for Northwind.
Public Function GetRandomPkValue(ByVal strTable As String, ByVal strPkField As String) As Long
10 On Error GoTo Err_Handler
Dim rs As DAO.Recordset
20 Set rs = CurrentDb.OpenRecordset(strTable, dbOpenSnapshot)
30 With rs
40 .MoveLast 'This assumes there is at least one record
50 .MoveFirst
60 .Move GetRandom(0, .RecordCount - 1)
70 GetRandomPkValue = .Fields(strPkField)
80 .Close
90 End With
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modDAO", "GetRandomPkValue"
120 Resume Exit_Handler
End Function
'REFERENCE:
' https://stackoverflow.com/questions/31755802/can-i-use-access-vba-to-determine-if-a-table-has-a-data-macro
'NOTE:
' While MSysObjects.LvExtra is officially undocumented, if you dump the bytes of this field for a table with table data macro,
' you will see the XML in plain text. We use that for our algorithm: if the length of the field is at least the length
' of the data macro code, we assume it has a data macro.
Public Function HasDataMacro(td As DAO.TableDef) As Boolean
10 On Error GoTo Err_Handler
Dim intDmLength As Integer
Dim intLvExtraLength As Integer
20 intDmLength = Len(DLookup("DataMacro", "Welcome"))
30 intLvExtraLength = Len(Nz(DLookup("LvExtra", "MSysObjects", StringFormatSQL("Name={0}", td.Name)), ""))
40 HasDataMacro = (intLvExtraLength >= intDmLength)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modDAO", "HasDataMacro"
70 Resume Exit_Handler
End Function
'ALGORITHM:
' Attempt to set a Field object to the given field name while "On Error Resume Next" is active,
' and if no error then the field exists.
' Alternatively we could have iterated over the Fields collection. That is probably slower.
Public Function HasField(td As DAO.TableDef, ByVal strField As String) As Boolean
Dim fld As DAO.Field
10 On Error Resume Next
20 Set fld = td.Fields(strField)
30 HasField = (Err.Number = 0)
40 Set fld = Nothing
End Function
'PROCEDURE:
' HasProperty
'PURPOSE:
' Test if the given object has the named property in its Properties collection.
'ALGORITHM:
' Set VBA to ignore errors. Try to use the property. If it works, it exists; if not, it does not exist.
'ARGUMENTS:
' o - Object that has a Properties collection
' propName - Name to look for
'RETURNS:
' Boolean - True if found, False otherwise.
'NOTE:
' The alternative implementation is to loop over the Properties collection. That's several times slower.
Public Function HasProperty(o As Object, ByVal propName As String) As Boolean
Dim blnResult As Boolean
Dim strName As String
10 On Error Resume Next
20 strName = o.Properties(propName).Name 'All properties have a Name property.
30 blnResult = (Err.Number = 0)
40 HasProperty = blnResult
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| DumpTempVars | Sub | Public | () | 4 | 17 | handleerror |
| NotImplemented | Sub | Public | (Optional ByVal strMsg As String) | 22 | 13 | handleerror |
Public Sub DumpTempVars()
10 On Error GoTo Err_Handler
Dim t As TempVar
20 Debug.Print "Dumping " & TempVars.count & " TempVars:"
30 For Each t In TempVars
40 Debug.Print t.Name, t.Value
50 Next t
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modDebug", "DumpTempVars"
80 Resume Exit_Handler
End SubPublic Sub NotImplemented(Optional ByVal strMsg As String) 10 On Error GoTo Err_Handler 20 strMsg = "This feature is not yet implemented." & vbCrLf & strMsg 30 MsgBox strMsg, vbExclamation Exit_Handler: 40 Exit Sub Err_Handler: 50 clsErrorHandler.HandleError "modDebug", "NotImplemented" 60 Resume Exit_Handler End Sub
Option Compare Database
Option Explicit
Public Sub DumpTempVars()
10 On Error GoTo Err_Handler
Dim t As TempVar
20 Debug.Print "Dumping " & TempVars.count & " TempVars:"
30 For Each t In TempVars
40 Debug.Print t.Name, t.Value
50 Next t
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modDebug", "DumpTempVars"
80 Resume Exit_Handler
End Sub
Public Sub NotImplemented(Optional ByVal strMsg As String)
10 On Error GoTo Err_Handler
20 strMsg = "This feature is not yet implemented." & vbCrLf & strMsg
30 MsgBox strMsg, vbExclamation
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError "modDebug", "NotImplemented"
60 Resume Exit_Handler
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| FileExists | Function | Public | (ByVal strFile As String, Optional ByVal blnFindFolders As Boolean) | 4 | 24 | — |
| StringToFile | Sub | Public | (ByVal strPath As String, ByVal theString As Variant) | 29 | 18 | handleerror |
Function FileExists(ByVal strFile As String, Optional ByVal blnFindFolders As Boolean) As Boolean
'Purpose: Return True if the file exists, even if it is hidden.
'Arguments: strFile: File name to look for. Current directory searched if no path included.
' blnFindFolders. If strFile is a folder, FileExists() returns False unless this argument is True.
'Note: Does not look inside subdirectories for the file.
'Author: Allen Browne. http://allenbrowne.com June, 2006. http://allenbrowne.com/func-11.html
Dim lngAttributes As Long
'Include read-only files, hidden files, system files.
10 lngAttributes = (vbReadOnly Or vbHidden Or vbSystem)
20 If blnFindFolders Then
30 lngAttributes = (lngAttributes Or vbDirectory) 'Include folders as well.
40 Else
'Strip any trailing slash, so Dir does not look inside the folder.
50 Do While Right$(strFile, 1) = "\"
60 strFile = Left$(strFile, Len(strFile) - 1)
70 Loop
80 End If
'If Dir() returns something, the file exists.
90 On Error Resume Next
100 FileExists = (Len(Dir(strFile, lngAttributes)) > 0)
End FunctionPublic Sub StringToFile(ByVal strPath As String, ByVal theString As Variant)
10 On Error GoTo Err_Handler
Dim intFile As Integer
20 intFile = FreeFile
30 Open strPath For Output As #intFile
40 Print #intFile, theString
50 Close #intFile
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modFiles", "StringToFile"
80 Resume Exit_Handler
End SubOption Compare Database
Option Explicit
Function FileExists(ByVal strFile As String, Optional ByVal blnFindFolders As Boolean) As Boolean
'Purpose: Return True if the file exists, even if it is hidden.
'Arguments: strFile: File name to look for. Current directory searched if no path included.
' blnFindFolders. If strFile is a folder, FileExists() returns False unless this argument is True.
'Note: Does not look inside subdirectories for the file.
'Author: Allen Browne. http://allenbrowne.com June, 2006. http://allenbrowne.com/func-11.html
Dim lngAttributes As Long
'Include read-only files, hidden files, system files.
10 lngAttributes = (vbReadOnly Or vbHidden Or vbSystem)
20 If blnFindFolders Then
30 lngAttributes = (lngAttributes Or vbDirectory) 'Include folders as well.
40 Else
'Strip any trailing slash, so Dir does not look inside the folder.
50 Do While Right$(strFile, 1) = "\"
60 strFile = Left$(strFile, Len(strFile) - 1)
70 Loop
80 End If
'If Dir() returns something, the file exists.
90 On Error Resume Next
100 FileExists = (Len(Dir(strFile, lngAttributes)) > 0)
End Function
Public Sub StringToFile(ByVal strPath As String, ByVal theString As Variant)
10 On Error GoTo Err_Handler
Dim intFile As Integer
20 intFile = FreeFile
30 Open strPath For Output As #intFile
40 Print #intFile, theString
50 Close #intFile
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modFiles", "StringToFile"
80 Resume Exit_Handler
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| ControlCurrentView | Function | Public | (ctl As Access.control) | 8 | 24 | handleerror |
| ControlDefaultView | Function | Public | (ctl As Access.control) | 32 | 22 | handleerror |
| IsFormOpen | Function | Public | (ByVal strFormName As String) | 54 | 12 | handleerror |
| RequeryListForms | Sub | Public | () | 67 | 21 | handleerror, isformopen |
| RequeryProductList | Sub | Public | () | 89 | 12 | handleerror, isformopen |
Public Function ControlCurrentView(ctl As Access.control) As Integer
10 On Error GoTo Err_Handler
Dim intReturn As Integer
20 If TypeOf ctl.Parent Is Page Then
30 intReturn = ctl.Parent.Parent.Parent.CurrentView
40 Else
50 intReturn = ctl.Parent.CurrentView
60 End If
70 ControlCurrentView = intReturn
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modForms", "ControlCurrentView"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Return the DefaultView property of the control's form.
'ALGORITHM:
' Take into account that if the control is on a Tab control, its parent is a Tab Page, not the form.Public Function ControlDefaultView(ctl As Access.control) As Integer
10 On Error GoTo Err_Handler
Dim intReturn As Integer
20 If TypeOf ctl.Parent Is Page Then
30 intReturn = ctl.Parent.Parent.Parent.DefaultView
40 Else
50 intReturn = ctl.Parent.DefaultView
60 End If
70 ControlDefaultView = intReturn
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modForms", "ControlDefaultView"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Returns if the given form is open or not.Public Function IsFormOpen(ByVal strFormName As String) As Boolean 10 On Error GoTo Err_Handler 20 IsFormOpen = (SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> 0) Exit_Handler: 30 Exit Function Err_Handler: 40 clsErrorHandler.HandleError "modForms", "IsFormOpen" 50 Resume Exit_Handler End Function
Public Sub RequeryListForms()
10 On Error GoTo Err_Handler
'Using the Recordset.Requery approach allows allows the form to keep its place
'Using the Requery approach takes the user to the first record in the list
20 If IsFormOpen("frmCompanyList") Then Forms!frmCompanyList.Recordset.Requery
30 If IsFormOpen("frmEmployeeList") Then Forms!frmEmployeeList.Recordset.Requery
40 If IsFormOpen("frmOrderList") Then Forms!frmOrderList.Recordset.Requery
50 If IsFormOpen("frmProductList") Then Forms!frmProductList.Recordset.Requery
60 If IsFormOpen("frmPurchaseOrderList") Then Forms!frmPurchaseOrderList.Recordset.Requery
Exit_Handler:
70 Exit Sub
Err_Handler:
80 If Err.Number = 3219 Then '3219 = Invalid operation.
90 Resume Next 'Ignore and continue with the next line.
100 End If
110 clsErrorHandler.HandleError "modForms", "RequeryListForms"
120 Resume Exit_Handler
130 Resume
End SubPublic Sub RequeryProductList()
10 On Error GoTo Err_Handler
20 If IsFormOpen("frmProductList") Then Forms!frmProductList.Requery
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modForms", "RequeryProductList"
50 Resume Exit_Handler
End SubOption Compare Database
Option Explicit
'PURPOSE:
' Return the CurrentView property of the control's form.
'ALGORITHM:
' Take into account that if the control is on a Tab control, its parent is a Tab Page, not the form.
Public Function ControlCurrentView(ctl As Access.control) As Integer
10 On Error GoTo Err_Handler
Dim intReturn As Integer
20 If TypeOf ctl.Parent Is Page Then
30 intReturn = ctl.Parent.Parent.Parent.CurrentView
40 Else
50 intReturn = ctl.Parent.CurrentView
60 End If
70 ControlCurrentView = intReturn
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modForms", "ControlCurrentView"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Return the DefaultView property of the control's form.
'ALGORITHM:
' Take into account that if the control is on a Tab control, its parent is a Tab Page, not the form.
Public Function ControlDefaultView(ctl As Access.control) As Integer
10 On Error GoTo Err_Handler
Dim intReturn As Integer
20 If TypeOf ctl.Parent Is Page Then
30 intReturn = ctl.Parent.Parent.Parent.DefaultView
40 Else
50 intReturn = ctl.Parent.DefaultView
60 End If
70 ControlDefaultView = intReturn
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modForms", "ControlDefaultView"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Returns if the given form is open or not.
Public Function IsFormOpen(ByVal strFormName As String) As Boolean
10 On Error GoTo Err_Handler
20 IsFormOpen = (SysCmd(acSysCmdGetObjectState, acForm, strFormName) <> 0)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modForms", "IsFormOpen"
50 Resume Exit_Handler
End Function
Public Sub RequeryListForms()
10 On Error GoTo Err_Handler
'Using the Recordset.Requery approach allows allows the form to keep its place
'Using the Requery approach takes the user to the first record in the list
20 If IsFormOpen("frmCompanyList") Then Forms!frmCompanyList.Recordset.Requery
30 If IsFormOpen("frmEmployeeList") Then Forms!frmEmployeeList.Recordset.Requery
40 If IsFormOpen("frmOrderList") Then Forms!frmOrderList.Recordset.Requery
50 If IsFormOpen("frmProductList") Then Forms!frmProductList.Recordset.Requery
60 If IsFormOpen("frmPurchaseOrderList") Then Forms!frmPurchaseOrderList.Recordset.Requery
Exit_Handler:
70 Exit Sub
Err_Handler:
80 If Err.Number = 3219 Then '3219 = Invalid operation.
90 Resume Next 'Ignore and continue with the next line.
100 End If
110 clsErrorHandler.HandleError "modForms", "RequeryListForms"
120 Resume Exit_Handler
130 Resume
End Sub
Public Sub RequeryProductList()
10 On Error GoTo Err_Handler
20 If IsFormOpen("frmProductList") Then Forms!frmProductList.Requery
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modForms", "RequeryProductList"
50 Resume Exit_Handler
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| AddToMRU | Sub | Public | (ByVal strTableName As String, ByVal lngPKValue As Long) | 102 | 37 | g_dbapp, get_userid, handleerror, ribbon_refreshmru, stringformatsql |
| GetNorthwindAddress | Function | Public | () | 140 | 23 | g_dbapp, handleerror, stringformat |
| GetWindowsUserName | Function | Public | () | 164 | 12 | handleerror |
| Get_EmployeeFNLN | Function | Public | (EmployeeID As Long) | 177 | 25 | handleerror |
| Get_UserID | Function | Public | () | 202 | 16 | handleerror |
| Get_UserID_ForWindowsUser | Function | Public | () | 219 | 27 | getwindowsusername, handleerror, stringformatsql |
| g_dbApp | Function | Public | () | 246 | 9 | — |
| OneTimeProcessing | Sub | Public | () | 256 | 35 | adddatamacros, getsystemsetting, handleerror, hiddenandsystemobjectsworkaround, savesystemsetting, setctrlcurrencyformat, setdatestocurrent |
| RecordModifiedString | Function | Public | () | 291 | 33 | handleerror |
| RemoveFromMRU | Sub | Public | (ByVal strTableName As String, ByVal lngPKValue As Long) | 324 | 23 | g_dbapp, handleerror, ribbon_refreshmru, stringformatsql |
| SetCtrlCurrencyFormat | Sub | Private | () | 347 | 75 | handleerror |
| ToAccessDate | Function | Public | (ByVal dt As Date) | 422 | 12 | handleerror |
| InitializeUser | Sub | Public | () | 435 | 44 | getusersetting, getwindowsusername, handleerror, stringformatsql |
| HiddenAndSystemObjectsWorkaround | Sub | Private | () | 479 | 4 | — |
Public Sub AddToMRU(ByVal strTableName As String, ByVal lngPKValue As Long)
10 On Error GoTo Err_Handler
Const MAX_MRU_COUNT As Integer = 10
Dim rs As DAO.Recordset
Dim lngMin As Long
Dim sql As String
'ddMRU_OnAction (the callback function used by the Ribbon and implemented in modRibbonCallback) currently supports 2 tables.
20 Debug.Assert strTableName = "Orders" Or strTableName = "PurchaseOrders"
30 sql = StringFormatSQL("insert into MRU(EmployeeID, TableName, PKValue, DateAdded) values ({0}, {1}, {2}, {3});", _
Get_UserID(), strTableName, lngPKValue, Now())
40 g_dbApp().Execute sql 'Do not use dbFailOnError because the record may already exist. ', dbFailOnError
'Trim back MRU list if it is getting too long. First get the value below which the records must be deleted.
50 sql = StringFormatSQL("select Min(MRU_ID) from (select top {0} MRU_ID from MRU where EmployeeID={1} order by MRU_ID)", MAX_MRU_COUNT, Get_UserID())
60 Set rs = g_dbApp().OpenRecordset(sql, dbOpenSnapshot)
70 If IsNull(rs(0)) Then
'Empty MRU list. Nothing to trim back.
80 Else
90 lngMin = rs(0)
100 sql = StringFormatSQL("delete * from MRU where MRU_ID < {0} and EmployeeID = {1};", lngMin, Get_UserID())
110 g_dbApp().Execute sql, dbFailOnError
120 End If
130 rs.Close
'Tell the ribbon element to update itself.
140 Ribbon_RefreshMRU
Exit_Handler:
150 Exit Sub
Err_Handler:
160 clsErrorHandler.HandleError "modGlobal", "AddToMRU"
170 Resume Exit_Handler
End SubPublic Function GetNorthwindAddress() As String
10 On Error GoTo Err_Handler
Static strNorthwindAddress As String 'Our address rarely changes, so OK to cache it.
Dim rs As DAO.Recordset
Dim sql As String
20 If strNorthwindAddress = "" Then
30 sql = "select * from Companies where CompanyTypeId = " & enumCompanyType.ctNorthwind
40 Set rs = g_dbApp().OpenRecordset(sql, dbOpenSnapshot)
50 strNorthwindAddress = StringFormat("{0}{1}{2} {3}, {4}", rs!CompanyName & vbCrLf, rs!Address & vbCrLf, rs!City, rs!StateAbbrev, rs!Zip)
60 rs.Close
70 Set rs = Nothing
80 End If
90 GetNorthwindAddress = strNorthwindAddress
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modGlobal", "GetNorthwindAddress"
120 Resume Exit_Handler
End FunctionPublic Function GetWindowsUserName() As String
10 On Error GoTo Err_Handler
20 GetWindowsUserName = Left(Environ("UserName"), 255)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modGlobal", "GetWindowsUserName"
50 Resume Exit_Handler
End FunctionPublic Function Get_EmployeeFNLN(EmployeeID As Long) As String
10 On Error GoTo Err_Handler
Dim varLookup As Variant
20 varLookup = DLookup("FullNameFNLN", "qryEmployees", "EmployeeID = " & EmployeeID)
30 If IsNull(varLookup) Then
'User not found in the employee table
40 Get_EmployeeFNLN = "Error Employee Not Found"
50 Else
60 Get_EmployeeFNLN = varLookup
70 End If
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modGlobal", "Get_EmployeeFNLN"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Used by queries, which cannot access global variables directly, and other code. Self-healing version.
' Alternatively we could have used a TempVar.Public Function Get_UserID() As Long 10 On Error GoTo Err_Handler 20 If m_UserID = 0 Then 30 Else 40 Get_UserID = m_UserID 50 End If Exit_Handler: 60 Exit Function Err_Handler: 70 clsErrorHandler.HandleError "modGlobal", "Get_UserID" 80 Resume Exit_Handler End Function
Public Function Get_UserID_ForWindowsUser() As Long
10 On Error GoTo Err_Handler
Dim varLookup As Variant
'What is the EmployeeID of the the Windows User
20 varLookup = DLookup("EmployeeID", "qryEmployees", StringFormatSQL("WindowsUserName = {0}", GetWindowsUserName()))
30 If IsNull(varLookup) Then
'Current windows user not found in the employee table
40 Get_UserID_ForWindowsUser = 0
50 Else
60 Get_UserID_ForWindowsUser = varLookup
70 End If
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modGlobal", "Get_UserID_ForWindowsUser"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Self-healing function to return the current database.
'NOTE:
' Previous versions of NW2 used a global variable, but it would not be set if the app is loaded with the Shift key down, or if the code is reset.Public Function g_dbApp() As DAO.Database 10 If m_dbApp Is Nothing Then 20 Set m_dbApp = CurrentDb 30 End If 40 Set g_dbApp = m_dbApp End Function
Public Sub OneTimeProcessing() 10 On Error GoTo Err_Handler 20 If Not GetSystemSetting(ssFirstTimeRun) Then 30 SysCmd acSysCmdSetStatus, "One-Time Processing. Please stand by." 40 DoCmd.Hourglass True 50 HiddenAndSystemObjectsWorkaround 60 SetDatesToCurrent 'So new instance is working with current data. 70 SetCtrlCurrencyFormat 80 AddDataMacros 90 SaveSystemSetting ssFirstTimeRun, -1 '-1 is better than True in international scenarios. 100 SysCmd acSysCmdClearStatus 110 End If Exit_Handler: 120 DoCmd.Hourglass False 130 Exit Sub Err_Handler: 140 clsErrorHandler.HandleError "modGlobal", "OneTimeProcessing" 150 Resume Exit_Handler 160 Resume End Sub 'PURPOSE: ' Returns standardized string for record create/modification ' If the Windows UserName has been recorded in the Employees table, use that name rather than
Public Function RecordModifiedString(Optional AddedBy As Variant = "", Optional AddedOn As Variant = "", _
Optional ModifiedBy As Variant = "", Optional ModifiedOn As Variant = "") As String
10 On Error GoTo Err_Handler
Dim strTemp As String
20 strTemp = ""
30 If (AddedOn & AddedBy) > "" Then
40 strTemp = "Created"
50 If AddedOn > "" Then strTemp = strTemp & " " & AddedOn
60 If AddedBy > "" Then strTemp = strTemp & " by " & AddedBy
70 End If
80 If (ModifiedBy & ModifiedOn) > "" Then
90 If strTemp > "" Then strTemp = strTemp & " ~ "
100 strTemp = strTemp & " Modified"
110 If ModifiedOn > "" Then strTemp = strTemp & " " & ModifiedOn
120 If ModifiedBy > "" Then strTemp = strTemp & " by " & ModifiedBy
130 End If
140 RecordModifiedString = strTemp
Exit_Handler:
150 Exit Function
Err_Handler:
160 clsErrorHandler.HandleError "modGlobal", "RecordModifiedString"
170 Resume Exit_Handler
End Function
'Espana Remove From MRUPublic Sub RemoveFromMRU(ByVal strTableName As String, ByVal lngPKValue As Long)
10 On Error GoTo Err_Handler
Dim sql As String
20 sql = StringFormatSQL("delete * from MRU where TableName = {0} and PKValue = {1};", strTableName, lngPKValue)
30 g_dbApp().Execute sql, dbFailOnError
'Tell the ribbon element to update itself.
40 Ribbon_RefreshMRU
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError "modGlobal", "RemoveFromMRU"
70 Resume Exit_Handler
End Sub
'PURPOSE:
' The template is created in the United States. Other regions will want to display currency values in their format.
' As of Aug-2023 Access will preserve the US format by changing the Format property to $#.##0,00;($#.##0,00).
' The code in this procedure will set them back to "Currency".Private Sub SetCtrlCurrencyFormat()
10 On Error GoTo Err_Handler
Dim i As Integer
Dim aryForms() As Variant
Dim aryControls() As Variant
Dim aryReports() As Variant
20 aryForms = Array("frmOrderDetails", "frmOrderDetails", "frmOrderDetails", "frmOrderList", "frmOrderList", "frmProductDetail", "frmProductDetail", "frmPurchaseOrderDetails", "frmPurchaseOrderDetails", "frmPurchaseOrderDetails", "frmPurchaseOrderList", "frmPurchaseOrderList", _
"sfrmCompanyDetail_CustomerOrders", "sfrmCompanyDetail_ShipperOrders", "sfrmOrderLineItems", "sfrmOrderLineItems", "sfrmOrderLineItems", "sfrmOrders_MostRecent_ByEmployee", "sfrmProductDetail_Orders", "sfrmProductDetail_Orders", "sfrmProductDetail_PurchaseOrders", "sfrmProductDetail_PurchaseOrders", _
"sfrmPurchaseOrderLineItems", "sfrmPurchaseOrderLineItems", "sfrmPurchaseOrderLineItems")
30 aryControls = Array("ShippingFee", "txtTaxAmount", "txtTotal", "OrderTotal", "txtSumOrderTotal", "txtUnitPrice", "txtStandardUnitCost", "ShippingFee", "txtTaxAmount", "txtTotal", "TotalCost", "txtSumTotalCost", _
"txtOrderTotal", "txtOrderTotal", "UnitPrice", "Price", "txtSubTotal", "OrderTotal", "txtUnitPrice", "txtExtendedPrice", "UnitCost", "ExtendedCost", _
"UnitCost", "Price", "txtSubTotal")
40 Debug.Assert UBound(aryForms) = UBound(aryControls)
50 For i = 0 To UBound(aryForms)
60 DoCmd.OpenForm aryForms(i), acDesign, WindowMode:=acHidden
70 Forms(aryForms(i)).Controls(aryControls(i)).Format = "Currency"
80 DoCmd.Close acForm, aryForms(i), acSaveYes
90 Next i
100 Erase aryForms
110 Erase aryControls
120 DoCmd.OpenForm "frmReports", , , , , acHidden 'Criteria in reports' recordsources reference the Reports form
'NOTE: aryReports(0) corresponds to aryControls(0) etc. There are several reports to be fixed. Each may have several controls with Currency.
130 aryReports = Array("rptInvoice", "rptInvoice", "rptInvoice", "rptInvoice", "rptInvoice", _
"rptProductCatalog", "rptProductCatalog", "rptProductCatalog", "rptProductCatalog", _
"rptSalesByEmployee", "rptSalesByEmployee", "rptSalesByEmployee", _
"rptSalesByProduct", "rptSalesByProduct", "rptSalesByProduct", _
"rptSalesByProductQuarterly", "rptSalesByProductQuarterly", "rptSalesByProductQuarterly")
140 aryControls = Array("txtUnitPrice", "txtExtendedPrice", "txtSubTotal", "txtShipping", "txtTotal", _
"txtTotalSales", "txtMinPrice", "txtMaxPrice", "UnitPrice", _
"OrderTotal", "SumOfOrderTotal", "GrandTotalSum", _
"OrderTotal", "SumOfOrderTotal", "GrandTotalSum", _
"OrderTotal", "SumOfOrderTotal", "GrandTotalSum")
150 Debug.Assert UBound(aryReports) = UBound(aryControls)
160 For i = 0 To UBound(aryReports)
170 DoCmd.OpenReport aryReports(i), acDesign, WindowMode:=acHidden
180 Reports(aryReports(i)).Controls(aryControls(i)).Format = "Currency"
190 DoCmd.Close acReport, aryReports(i), acSaveYes
200 Next i
210 Erase aryReports
220 Erase aryControls
'Modern chart properties.
230 On Error Resume Next 'Access 2016 and older does not support Modern Chart, so the controls would not exist.
240 aryReports = Array("rptSalesByEmployee", "rptSalesByProduct", "rptSalesByProductQuarterly")
250 aryControls = Array("chrtEmplyeeSalesByMonth", "chrtSalesByProduct", "chrtSalesByProduct")
260 For i = 0 To UBound(aryReports)
270 DoCmd.OpenReport aryReports(i), acDesign, WindowMode:=acHidden
280 Reports(aryReports(i)).Controls(aryControls(i)).PrimaryValuesAxisFormat = "Currency"
290 DoCmd.Close acReport, aryReports(i), acSaveYes
300 Next i
310 DoCmd.Close acForm, "frmReports", acSaveNo
320 Erase aryReports
330 Erase aryControls
Exit_Handler:
340 Exit Sub
Err_Handler:
350 clsErrorHandler.HandleError "modGlobal", "SetCtrlCurrencyFormat"
360 Resume Exit_Handler
370 Resume
End Sub
'PURPOSE:
' Convert the date to US date format as expected by Access. Needed when building a SQL string with literal.
' This ISO date format also has the advantage there are no issues with sorting strings, or comparing with > or <.Public Function ToAccessDate(ByVal dt As Date) As String 10 On Error GoTo Err_Handler 20 ToAccessDate = Format(dt, "yyyy-mm-dd hh:nn:ss") Exit_Handler: 30 Exit Function Err_Handler: 40 clsErrorHandler.HandleError "modGlobal", "ToAccessDate" 50 Resume Exit_Handler End Function
Public Sub InitializeUser()
10 On Error GoTo Err_Handler
Dim bolAutoLogIn As Boolean
Dim strWindowsUserName As String
Dim varEmployeeID As Variant
'Get the User's Login
20 strWindowsUserName = GetWindowsUserName()
'Is the User in the Employee table?
30 varEmployeeID = DLookup("EmployeeID", "Employees", StringFormatSQL("WindowsUserName = {0}", strWindowsUserName))
40 If IsNull(varEmployeeID) Then
'The current Windows user is not in the database. Prompt to create a new account.
50 DoCmd.OpenForm "frmCredentials", acNormal, , , , acDialog
'At this point frmCredentials is hidden, and thus "falls out of the modal loop", so we can inspect its properties before closing it.
60 m_UserID = Form_frmCredentials.UserID
70 DoCmd.Close acForm, "frmCredentials"
80 Else
90 m_UserID = varEmployeeID
'Has user checked the box on frmLogin requesting that we automatically log them in?
'If setting not found, assume False
100 bolAutoLogIn = Nz(GetUserSetting(usAutoLogin), False)
110 If bolAutoLogIn = False Then
120 DoCmd.OpenForm "frmLogin", acNormal, , , , acDialog
'At this point frmLogin is hidden, and thus "falls out of the modal loop", so we can inspect its properties before closing it.
130 m_UserID = Form_frmLogin.UserID
140 DoCmd.Close acForm, "frmLogin"
150 End If
160 End If
Exit_Handler:
170 Exit Sub
Err_Handler:
180 clsErrorHandler.HandleError "modGlobal", "InitializeUser"
190 Resume Exit_Handler
End Sub
'PURPOSE:
' Work around imperfection in Access ACCDT generation where USysRibbons table is ignored. This does not happen if hidden and system objects are showing,
' so we ship NW2 with them showing, and turn them off here, so users experience the normal list of objects, not hidden and system objects.Option Compare Database
Option Explicit
'Declaring all global variables here.
'Version history
'Version ReleaseDate Notes
'2.0 2023-04-24 Initial release.
'2.1 2023-04-27 Support for international dates and quantities.
'2.2 Aug-2023 Round of bug fixing and improvements based on community feedback.
' Consolidate one-time code in OneTimeProcessing.
' Better support for regional settings. For example dates and currencies should be displayed in your local settings.
' Improved StringFormatSQL.
' Improved error handler (clsErrorHandler.HandleError).
'2.3 Nov-2023 Fixed a few bugs reported by the community.
' Updated GetSystemSetting to support regional settings.
' Prevent data entry in OrderDetail subform until parent record is created. This works around a bug in v2.2 which MSFT hasn't fixed yet.
'2.4 Sep-2024 Fix several accessibility issues.
'2.5 Sep-2025 Change BackStyle of 2 textboxes from Transparent to Solid. Improve comments at top of clsErrorHandler. Added HiddenAndSystemObjectsWorkaround.
Public Const APP_VERSION As String = "2.5"
Public Const INTERNET_SALES_EMPLOYEEID As Long = 10
Public Const DEFAULT_LOGIN_ID As Long = 2
Public Const TWIPS_PER_INCH As Long = 1440
Public Const SINGLE_QUOTE As String = "'" 'It is common to have to wrap text in a single quote, or search for it in a string.
Public Const TWO_SINGLE_QUOTES As String = "''" 'Sometimes a single quote needs to be escaped into two single quotes. Adding this for readability.
Public g_colOrderDetailsForms As Collection 'To keep track of multiple frmOrderDetails instances (see modOrders).
Public g_colPurchaseOrderDetailsForms As Collection 'To keep track of multiple frmPurchaseOrderDetails instances (see modPurchaseOrders).
Private m_dbApp As DAO.Database
Private m_UserID As Long
'Keep this in sync with table CompanyType
'NOTE: the "ct" = "Company Type" prefix ensures there are no Reserved words in the Enum names.
Public Enum enumCompanyType
ctAll = 0
ctCustomer = 1
ctShipper = 2
ctVendor = 3
ctNorthwind = 4
End Enum
Public Enum enumOrderStatus 'Keep this in sync with table OrderStatus.
osClosed = 1 'NOTE: the "os" = "Order Status" prefix ensures there are no Reserved words in the Enum names.
osInvoiced = 2
osNew = 3
osShipped = 4
osPaid = 5
End Enum
Public Enum enumPurchaseOrderStatus 'Keep this in sync with PurchaseOrderStatus.
posApprove = 1
posClosed = 2
posNew = 3
posSubmitted = 4
posReceived = 5
End Enum
Public Enum enumOrderDetailStatus 'Keep this in sync with table OrderDetailStatus.
odsAllocated = 1
odsInvoiced = 2
odsNew = 3
odsNoStock = 4
odsOnOrder = 5
odsShipped = 6
End Enum
Public Enum enumPrivileges 'Keep this in sync with table Privileges.
pApprovePO = 1
End Enum
Public Enum enumSystemSettings 'Keep this in sync with table SystemSettings
ssTaxRate = 1
ssLastResetDate = 4
ssShowWelcome = 5
ssTaxRate_Vendors = 6
ssFirstTimeRun = 7
End Enum
Public Enum enumUserSettings 'Keep this in sync with table UserSettings
usAutoLogin = 2
End Enum
'Keep this in sync with table NorthwindFeatures
'NOTE: the "nf" = "Company Type" prefix ensures there are no Reserved words in the Enum names.
Public Enum enumNorthwindFeaturesOpenMethod
nfInPageHelp = 1
nfFollowHyperlink = 2
End Enum
'Keep this in sync with table TaxStatus
'NOTE: the "tx" = "Tax Status" prefix ensures there are no Reserved words in the Enum names.
Public Enum enumTaxStatus
txTaxExempt = 0
txTaxable = 1
End Enum
'Espana UG - Add to MRU
'PURPOSE:
' Add the given item to the MRU table and update the MRU dropdown in the Ribbon.
Public Sub AddToMRU(ByVal strTableName As String, ByVal lngPKValue As Long)
10 On Error GoTo Err_Handler
Const MAX_MRU_COUNT As Integer = 10
Dim rs As DAO.Recordset
Dim lngMin As Long
Dim sql As String
'ddMRU_OnAction (the callback function used by the Ribbon and implemented in modRibbonCallback) currently supports 2 tables.
20 Debug.Assert strTableName = "Orders" Or strTableName = "PurchaseOrders"
30 sql = StringFormatSQL("insert into MRU(EmployeeID, TableName, PKValue, DateAdded) values ({0}, {1}, {2}, {3});", _
Get_UserID(), strTableName, lngPKValue, Now())
40 g_dbApp().Execute sql 'Do not use dbFailOnError because the record may already exist. ', dbFailOnError
'Trim back MRU list if it is getting too long. First get the value below which the records must be deleted.
50 sql = StringFormatSQL("select Min(MRU_ID) from (select top {0} MRU_ID from MRU where EmployeeID={1} order by MRU_ID)", MAX_MRU_COUNT, Get_UserID())
60 Set rs = g_dbApp().OpenRecordset(sql, dbOpenSnapshot)
70 If IsNull(rs(0)) Then
'Empty MRU list. Nothing to trim back.
80 Else
90 lngMin = rs(0)
100 sql = StringFormatSQL("delete * from MRU where MRU_ID < {0} and EmployeeID = {1};", lngMin, Get_UserID())
110 g_dbApp().Execute sql, dbFailOnError
120 End If
130 rs.Close
'Tell the ribbon element to update itself.
140 Ribbon_RefreshMRU
Exit_Handler:
150 Exit Sub
Err_Handler:
160 clsErrorHandler.HandleError "modGlobal", "AddToMRU"
170 Resume Exit_Handler
End Sub
Public Function GetNorthwindAddress() As String
10 On Error GoTo Err_Handler
Static strNorthwindAddress As String 'Our address rarely changes, so OK to cache it.
Dim rs As DAO.Recordset
Dim sql As String
20 If strNorthwindAddress = "" Then
30 sql = "select * from Companies where CompanyTypeId = " & enumCompanyType.ctNorthwind
40 Set rs = g_dbApp().OpenRecordset(sql, dbOpenSnapshot)
50 strNorthwindAddress = StringFormat("{0}{1}{2} {3}, {4}", rs!CompanyName & vbCrLf, rs!Address & vbCrLf, rs!City, rs!StateAbbrev, rs!Zip)
60 rs.Close
70 Set rs = Nothing
80 End If
90 GetNorthwindAddress = strNorthwindAddress
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modGlobal", "GetNorthwindAddress"
120 Resume Exit_Handler
End Function
Public Function GetWindowsUserName() As String
10 On Error GoTo Err_Handler
20 GetWindowsUserName = Left(Environ("UserName"), 255)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modGlobal", "GetWindowsUserName"
50 Resume Exit_Handler
End Function
Public Function Get_EmployeeFNLN(EmployeeID As Long) As String
10 On Error GoTo Err_Handler
Dim varLookup As Variant
20 varLookup = DLookup("FullNameFNLN", "qryEmployees", "EmployeeID = " & EmployeeID)
30 If IsNull(varLookup) Then
'User not found in the employee table
40 Get_EmployeeFNLN = "Error Employee Not Found"
50 Else
60 Get_EmployeeFNLN = varLookup
70 End If
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modGlobal", "Get_EmployeeFNLN"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Used by queries, which cannot access global variables directly, and other code. Self-healing version.
' Alternatively we could have used a TempVar.
Public Function Get_UserID() As Long
10 On Error GoTo Err_Handler
20 If m_UserID = 0 Then
30 Else
40 Get_UserID = m_UserID
50 End If
Exit_Handler:
60 Exit Function
Err_Handler:
70 clsErrorHandler.HandleError "modGlobal", "Get_UserID"
80 Resume Exit_Handler
End Function
Public Function Get_UserID_ForWindowsUser() As Long
10 On Error GoTo Err_Handler
Dim varLookup As Variant
'What is the EmployeeID of the the Windows User
20 varLookup = DLookup("EmployeeID", "qryEmployees", StringFormatSQL("WindowsUserName = {0}", GetWindowsUserName()))
30 If IsNull(varLookup) Then
'Current windows user not found in the employee table
40 Get_UserID_ForWindowsUser = 0
50 Else
60 Get_UserID_ForWindowsUser = varLookup
70 End If
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modGlobal", "Get_UserID_ForWindowsUser"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Self-healing function to return the current database.
'NOTE:
' Previous versions of NW2 used a global variable, but it would not be set if the app is loaded with the Shift key down, or if the code is reset.
Public Function g_dbApp() As DAO.Database
10 If m_dbApp Is Nothing Then
20 Set m_dbApp = CurrentDb
30 End If
40 Set g_dbApp = m_dbApp
End Function
Public Sub OneTimeProcessing()
10 On Error GoTo Err_Handler
20 If Not GetSystemSetting(ssFirstTimeRun) Then
30 SysCmd acSysCmdSetStatus, "One-Time Processing. Please stand by."
40 DoCmd.Hourglass True
50 HiddenAndSystemObjectsWorkaround
60 SetDatesToCurrent 'So new instance is working with current data.
70 SetCtrlCurrencyFormat
80 AddDataMacros
90 SaveSystemSetting ssFirstTimeRun, -1 '-1 is better than True in international scenarios.
100 SysCmd acSysCmdClearStatus
110 End If
Exit_Handler:
120 DoCmd.Hourglass False
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError "modGlobal", "OneTimeProcessing"
150 Resume Exit_Handler
160 Resume
End Sub
'PURPOSE:
' Returns standardized string for record create/modification
' If the Windows UserName has been recorded in the Employees table, use that name rather than
Public Function RecordModifiedString(Optional AddedBy As Variant = "", Optional AddedOn As Variant = "", _
Optional ModifiedBy As Variant = "", Optional ModifiedOn As Variant = "") As String
10 On Error GoTo Err_Handler
Dim strTemp As String
20 strTemp = ""
30 If (AddedOn & AddedBy) > "" Then
40 strTemp = "Created"
50 If AddedOn > "" Then strTemp = strTemp & " " & AddedOn
60 If AddedBy > "" Then strTemp = strTemp & " by " & AddedBy
70 End If
80 If (ModifiedBy & ModifiedOn) > "" Then
90 If strTemp > "" Then strTemp = strTemp & " ~ "
100 strTemp = strTemp & " Modified"
110 If ModifiedOn > "" Then strTemp = strTemp & " " & ModifiedOn
120 If ModifiedBy > "" Then strTemp = strTemp & " by " & ModifiedBy
130 End If
140 RecordModifiedString = strTemp
Exit_Handler:
150 Exit Function
Err_Handler:
160 clsErrorHandler.HandleError "modGlobal", "RecordModifiedString"
170 Resume Exit_Handler
End Function
'Espana Remove From MRU
Public Sub RemoveFromMRU(ByVal strTableName As String, ByVal lngPKValue As Long)
10 On Error GoTo Err_Handler
Dim sql As String
20 sql = StringFormatSQL("delete * from MRU where TableName = {0} and PKValue = {1};", strTableName, lngPKValue)
30 g_dbApp().Execute sql, dbFailOnError
'Tell the ribbon element to update itself.
40 Ribbon_RefreshMRU
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError "modGlobal", "RemoveFromMRU"
70 Resume Exit_Handler
End Sub
'PURPOSE:
' The template is created in the United States. Other regions will want to display currency values in their format.
' As of Aug-2023 Access will preserve the US format by changing the Format property to $#.##0,00;($#.##0,00).
' The code in this procedure will set them back to "Currency".
Private Sub SetCtrlCurrencyFormat()
10 On Error GoTo Err_Handler
Dim i As Integer
Dim aryForms() As Variant
Dim aryControls() As Variant
Dim aryReports() As Variant
20 aryForms = Array("frmOrderDetails", "frmOrderDetails", "frmOrderDetails", "frmOrderList", "frmOrderList", "frmProductDetail", "frmProductDetail", "frmPurchaseOrderDetails", "frmPurchaseOrderDetails", "frmPurchaseOrderDetails", "frmPurchaseOrderList", "frmPurchaseOrderList", _
"sfrmCompanyDetail_CustomerOrders", "sfrmCompanyDetail_ShipperOrders", "sfrmOrderLineItems", "sfrmOrderLineItems", "sfrmOrderLineItems", "sfrmOrders_MostRecent_ByEmployee", "sfrmProductDetail_Orders", "sfrmProductDetail_Orders", "sfrmProductDetail_PurchaseOrders", "sfrmProductDetail_PurchaseOrders", _
"sfrmPurchaseOrderLineItems", "sfrmPurchaseOrderLineItems", "sfrmPurchaseOrderLineItems")
30 aryControls = Array("ShippingFee", "txtTaxAmount", "txtTotal", "OrderTotal", "txtSumOrderTotal", "txtUnitPrice", "txtStandardUnitCost", "ShippingFee", "txtTaxAmount", "txtTotal", "TotalCost", "txtSumTotalCost", _
"txtOrderTotal", "txtOrderTotal", "UnitPrice", "Price", "txtSubTotal", "OrderTotal", "txtUnitPrice", "txtExtendedPrice", "UnitCost", "ExtendedCost", _
"UnitCost", "Price", "txtSubTotal")
40 Debug.Assert UBound(aryForms) = UBound(aryControls)
50 For i = 0 To UBound(aryForms)
60 DoCmd.OpenForm aryForms(i), acDesign, WindowMode:=acHidden
70 Forms(aryForms(i)).Controls(aryControls(i)).Format = "Currency"
80 DoCmd.Close acForm, aryForms(i), acSaveYes
90 Next i
100 Erase aryForms
110 Erase aryControls
120 DoCmd.OpenForm "frmReports", , , , , acHidden 'Criteria in reports' recordsources reference the Reports form
'NOTE: aryReports(0) corresponds to aryControls(0) etc. There are several reports to be fixed. Each may have several controls with Currency.
130 aryReports = Array("rptInvoice", "rptInvoice", "rptInvoice", "rptInvoice", "rptInvoice", _
"rptProductCatalog", "rptProductCatalog", "rptProductCatalog", "rptProductCatalog", _
"rptSalesByEmployee", "rptSalesByEmployee", "rptSalesByEmployee", _
"rptSalesByProduct", "rptSalesByProduct", "rptSalesByProduct", _
"rptSalesByProductQuarterly", "rptSalesByProductQuarterly", "rptSalesByProductQuarterly")
140 aryControls = Array("txtUnitPrice", "txtExtendedPrice", "txtSubTotal", "txtShipping", "txtTotal", _
"txtTotalSales", "txtMinPrice", "txtMaxPrice", "UnitPrice", _
"OrderTotal", "SumOfOrderTotal", "GrandTotalSum", _
"OrderTotal", "SumOfOrderTotal", "GrandTotalSum", _
"OrderTotal", "SumOfOrderTotal", "GrandTotalSum")
150 Debug.Assert UBound(aryReports) = UBound(aryControls)
160 For i = 0 To UBound(aryReports)
170 DoCmd.OpenReport aryReports(i), acDesign, WindowMode:=acHidden
180 Reports(aryReports(i)).Controls(aryControls(i)).Format = "Currency"
190 DoCmd.Close acReport, aryReports(i), acSaveYes
200 Next i
210 Erase aryReports
220 Erase aryControls
'Modern chart properties.
230 On Error Resume Next 'Access 2016 and older does not support Modern Chart, so the controls would not exist.
240 aryReports = Array("rptSalesByEmployee", "rptSalesByProduct", "rptSalesByProductQuarterly")
250 aryControls = Array("chrtEmplyeeSalesByMonth", "chrtSalesByProduct", "chrtSalesByProduct")
260 For i = 0 To UBound(aryReports)
270 DoCmd.OpenReport aryReports(i), acDesign, WindowMode:=acHidden
280 Reports(aryReports(i)).Controls(aryControls(i)).PrimaryValuesAxisFormat = "Currency"
290 DoCmd.Close acReport, aryReports(i), acSaveYes
300 Next i
310 DoCmd.Close acForm, "frmReports", acSaveNo
320 Erase aryReports
330 Erase aryControls
Exit_Handler:
340 Exit Sub
Err_Handler:
350 clsErrorHandler.HandleError "modGlobal", "SetCtrlCurrencyFormat"
360 Resume Exit_Handler
370 Resume
End Sub
'PURPOSE:
' Convert the date to US date format as expected by Access. Needed when building a SQL string with literal.
' This ISO date format also has the advantage there are no issues with sorting strings, or comparing with > or <.
Public Function ToAccessDate(ByVal dt As Date) As String
10 On Error GoTo Err_Handler
20 ToAccessDate = Format(dt, "yyyy-mm-dd hh:nn:ss")
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modGlobal", "ToAccessDate"
50 Resume Exit_Handler
End Function
Public Sub InitializeUser()
10 On Error GoTo Err_Handler
Dim bolAutoLogIn As Boolean
Dim strWindowsUserName As String
Dim varEmployeeID As Variant
'Get the User's Login
20 strWindowsUserName = GetWindowsUserName()
'Is the User in the Employee table?
30 varEmployeeID = DLookup("EmployeeID", "Employees", StringFormatSQL("WindowsUserName = {0}", strWindowsUserName))
40 If IsNull(varEmployeeID) Then
'The current Windows user is not in the database. Prompt to create a new account.
50 DoCmd.OpenForm "frmCredentials", acNormal, , , , acDialog
'At this point frmCredentials is hidden, and thus "falls out of the modal loop", so we can inspect its properties before closing it.
60 m_UserID = Form_frmCredentials.UserID
70 DoCmd.Close acForm, "frmCredentials"
80 Else
90 m_UserID = varEmployeeID
'Has user checked the box on frmLogin requesting that we automatically log them in?
'If setting not found, assume False
100 bolAutoLogIn = Nz(GetUserSetting(usAutoLogin), False)
110 If bolAutoLogIn = False Then
120 DoCmd.OpenForm "frmLogin", acNormal, , , , acDialog
'At this point frmLogin is hidden, and thus "falls out of the modal loop", so we can inspect its properties before closing it.
130 m_UserID = Form_frmLogin.UserID
140 DoCmd.Close acForm, "frmLogin"
150 End If
160 End If
Exit_Handler:
170 Exit Sub
Err_Handler:
180 clsErrorHandler.HandleError "modGlobal", "InitializeUser"
190 Resume Exit_Handler
End Sub
'PURPOSE:
' Work around imperfection in Access ACCDT generation where USysRibbons table is ignored. This does not happen if hidden and system objects are showing,
' so we ship NW2 with them showing, and turn them off here, so users experience the normal list of objects, not hidden and system objects.
Private Sub HiddenAndSystemObjectsWorkaround()
10 Application.SetOption "Show Hidden Objects", False
20 Application.SetOption "Show System Objects", False
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| AllocateInventory | Sub | Public | (ByVal lngProductID As Long) | 6 | 58 | g_dbapp, handleerror, productavailable, productonorder, stringformatsql |
| OrderQuantity_ByStatus | Function | Public | (ByVal lngProductID As Long, ByVal ods As enumOrderDetailStatus) | 64 | 21 | handleerror, stringformatsql |
| ProductAllocated | Function | Public | (ByVal lngProductID As Long) | 85 | 15 | handleerror, orderquantity_bystatus |
| ProductAvailable | Function | Public | (ByVal lngProductID As Long) | 100 | 43 | handleerror, productbought, productlaststocktakedate, productlaststocktakequantity, productsold |
| ProductBought | Function | Public | (ByVal lngProductID As Long, ByVal dtAsOf As Date) | 143 | 25 | handleerror, stringformatsql |
| ProductLastStockTakeDate | Function | Public | (ByVal lngProductID As Long) | 168 | 39 | g_dbapp, handleerror, stringformatsql |
| ProductLastStockTakeQuantity | Function | Public | (ByVal lngProductID As Long) | 207 | 27 | handleerror, productlaststocktakedate, stringformatsql, toaccessdate |
| ProductNoStock | Function | Public | (ByVal lngProductID As Long) | 234 | 23 | handleerror, orderquantity_bystatus |
| ProductOnOrder | Function | Public | (ByVal lngProductID As Long) | 257 | 28 | handleerror, stringformatsql |
| ProductReorderQuantity | Function | Public | (ByVal lngProductID As Long) | 285 | 48 | handleerror, productnostock, productonorder, producttosell |
| ProductSold | Function | Public | (ByVal lngProductID As Long, ByVal dtAsOf As Date) | 333 | 22 | handleerror, stringformatsql |
| ProductToSell | Function | Public | (ByVal lngProductID As Long) | 355 | 36 | handleerror, productallocated, productbought, productlaststocktakedate, productlaststocktakequantity, productsold |
Public Sub AllocateInventory(ByVal lngProductID As Long)
10 On Error GoTo Err_Handler
Dim rsO As DAO.Recordset
Dim intQtyToAllocate As Integer
Dim intAvailable As Integer
Dim sql As String
'Get list of orderdetails waiting for this product; oldest one first. StatusID=1=Allocated, 4=NoStock, 5=OnOrder. OrderID is the tie breaker if same datetime.
20 sql = StringFormatSQL("select od.* from OrderDetails od " & _
"inner join Orders o on o.OrderID = od.OrderID " & _
"where od.ProductID = {0} and od.OrderDetailStatusID in (1, 4, 5) " & _
"order by o.OrderDate, o.OrderID", lngProductID)
30 Set rsO = g_dbApp().OpenRecordset(sql, dbOpenDynaset)
'Physical inventory at this moment in time
40 intAvailable = ProductAvailable(lngProductID)
'Physical Inventory + how much is On Order
50 intQtyToAllocate = intAvailable + ProductOnOrder(lngProductID)
60 While Not rsO.EOF 'Loop over the order line items with this product that are in status of Allocated, No Stock or On Order.
70 If rsO!Quantity <= intAvailable Then 'Only allocate if we can satisfy the entire orderdetail.
80 rsO.Edit
90 rsO!OrderDetailStatusID = enumOrderDetailStatus.odsAllocated
100 intAvailable = intAvailable - rsO!Quantity
110 intQtyToAllocate = intQtyToAllocate - rsO!Quantity
120 rsO.Update
130 ElseIf rsO!Quantity <= intQtyToAllocate Then 'Only OnOrder if we can satisfy the entire orderdetail.
140 rsO.Edit
150 rsO!OrderDetailStatusID = enumOrderDetailStatus.odsOnOrder
160 intQtyToAllocate = intQtyToAllocate - rsO!Quantity
170 rsO.Update
180 Else
'If we are here, we don't have enough
190 rsO.Edit
200 rsO!OrderDetailStatusID = enumOrderDetailStatus.odsNoStock
210 rsO.Update
220 End If
230 rsO.MoveNext
240 Wend
250 rsO.Close
260 Set rsO = Nothing
Exit_Handler:
270 Exit Sub
Err_Handler:
280 clsErrorHandler.HandleError "modInventory", "AllocateInventory"
290 Resume Exit_Handler
300 Resume
End Sub
'RETURNS:
' Integer: Quantity of this product that is in the given status.Public Function OrderQuantity_ByStatus(ByVal lngProductID As Long, ByVal ods As enumOrderDetailStatus) As Integer
10 On Error GoTo Err_Handler
Dim sql As String
20 If lngProductID = 0 Then GoTo Exit_Handler
30 sql = StringFormatSQL("ProductID = {0} and OrderDetailStatusID = {1}", lngProductID, ods)
40 OrderQuantity_ByStatus = Nz(DSum("Quantity", "OrderDetails", sql), 0)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "OrderQuantity_ByStatus"
70 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity of this product that is in Allocated status.Public Function ProductAllocated(ByVal lngProductID As Long) As Integer 10 On Error GoTo Err_Handler 20 ProductAllocated = OrderQuantity_ByStatus(lngProductID, odsAllocated) Exit_Handler: 30 Exit Function Err_Handler: 40 clsErrorHandler.HandleError "modInventory", "ProductAllocated" 50 Resume Exit_Handler End Function 'DEFINITION: ' Last Stock Take Qty + Received since last stocktake - Invoiced since last stocktake.
Public Function ProductAvailable(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim dtLastStockTake As Date
Dim intLastStockTake As Integer
Dim intAvailable As Integer
Dim intBought As Integer
Dim intSold As Integer
20 ProductAvailable = 0
30 If lngProductID = 0 Then GoTo Exit_Handler
'Last stock take
40 dtLastStockTake = ProductLastStockTakeDate(lngProductID)
50 intLastStockTake = ProductLastStockTakeQuantity(lngProductID)
'Sold
60 intSold = ProductSold(lngProductID, dtLastStockTake)
'Bought
70 intBought = ProductBought(lngProductID, dtLastStockTake)
'Allen Browne's formula - Adapted with permission from http://allenbrowne.com/AppInventory.html
80 intAvailable = intLastStockTake + intBought - intSold
90 ProductAvailable = intAvailable
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modInventory", "ProductAvailable"
120 Resume Exit_Handler
130 Resume
End Function
'DEFINITION
' Bought = When product on a PO is Received.
' ProductBought quantity: Sum of Product received since last stocktake (or since dtAsOf).
'RETURNS:
' Integer: Quantity of this product that was received after point in time.
' If you wanted all purchases you would pass g_dtNorthwindInception which is 11/01/2022Public Function ProductBought(ByVal lngProductID As Long, ByVal dtAsOf As Date) As Integer
10 On Error GoTo Err_Handler
Dim sql As String
20 If lngProductID = 0 Then GoTo Exit_Handler
30 sql = StringFormatSQL("ProductID = {0} and ReceivedDate >= {1}", lngProductID, dtAsOf)
40 ProductBought = Nz(DSum("Quantity", "PurchaseOrderDetails", sql), 0)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductBought"
70 Resume Exit_Handler
End Function
'PURPOSE:
' Returns the Date with Time of the Last StockTake for a Product.
' Northwind Expects there to be a StockTake. When a Product is added the first StockTake record is entered.
' If there is no StockTake (it has been deleted), Add a Stock Take record the same as what was created when the Product was added.
' Set StockTakeDate using the Date the Product was Added
' QuantityOnHand = 0Public Function ProductLastStockTakeDate(ByVal lngProductID As Long) As Date
10 On Error GoTo Err_Handler
Dim sql As String
Dim rsStockTake As DAO.Recordset
20 ProductLastStockTakeDate = g_dtNorthwindInception
30 If lngProductID = 0 Then GoTo Exit_Handler
40 sql = StringFormatSQL("select * from StockTake where ProductID = {0} order by StockTakeDate desc;", lngProductID)
50 Set rsStockTake = g_dbApp().OpenRecordset(sql, dbOpenDynaset)
60 If rsStockTake.RecordCount = 0 Then
'No stock take was ever done for this Product.
70 With rsStockTake
80 .AddNew
90 !StockTakeDate = Nz(DLookup("AddedOn", "Products", "ProductID = " & lngProductID), Now())
100 !ProductID = lngProductID
110 !QuantityOnHand = 0
120 .Update
130 .Move 0, .LastModified 'Move to the record just added, so we can read from it.
140 End With
150 End If
160 ProductLastStockTakeDate = rsStockTake!StockTakeDate
170 rsStockTake.Close
180 Set rsStockTake = Nothing
Exit_Handler:
190 Exit Function
Err_Handler:
200 clsErrorHandler.HandleError "modInventory", "ProductLastStockTakeDate"
210 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity in the last (most recent) StockTake for the ProductPublic Function ProductLastStockTakeQuantity(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim dtStockTakeDate As Date
20 If lngProductID = 0 Then GoTo Exit_Handler
30 dtStockTakeDate = ProductLastStockTakeDate(lngProductID)
'ERROR: This may return Null because of roundoff errors. ProductLastStockTakeQuantity = DLookup("QuantityOnHand", "StockTake", StringFormatSQL("ProductID = {0} and StockTakeDate = CDate({1})", lngProductID, dtStockTakeDate))
'NOTE: We're using ToAccessDate (which returns a string) on both sides of the expression "StockTakeDate = some_date". This is because of possible roundoff errors if we were to compare
' the date values themselves (which are floating point values). In one particular case we had this roundoff error:
'? DLookup("StockTakeDate", "StockTake", "ProductID = 3") - #11/27/2022 9:02:00 AM#
'7.27595761418343E-12
'By comparing the text values (as returned by ToAccessDate), we avoid this roundoff.
40 ProductLastStockTakeQuantity = DLookup("QuantityOnHand", "StockTake", StringFormatSQL("ProductID = {0} and ToAccessDate(StockTakeDate) = {1}", lngProductID, ToAccessDate(dtStockTakeDate)))
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductLastStockTakeQuantity"
70 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity of this product that is in No Stock status.Public Function ProductNoStock(ByVal lngProductID As Long) As Integer 10 On Error GoTo Err_Handler 20 ProductNoStock = OrderQuantity_ByStatus(lngProductID, odsNoStock) Exit_Handler: 30 Exit Function Err_Handler: 40 clsErrorHandler.HandleError "modInventory", "ProductNoStock" 50 Resume Exit_Handler End Function 'DEFINITION: ' Sum of Product Quantity for POs in the Approved status. 'NOTE: ' There can be more than one PO for the same Product, therefore we sum the quantities in qryPOProducts_ByStatus. 'RETURNS: ' Integer: Quantity of this product that is on an Approved Purchase Order ' 'We need a query in this function because we need two tables which are joined ' PurchaseOrder - contains the criteria for the POStatus of Approved ' and PurchaseOrderDetail - to support the criteria for ProductID.
Public Function ProductOnOrder(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim sqlWhere As String
20 If lngProductID = 0 Then GoTo Exit_Handler
30 sqlWhere = StringFormatSQL("StatusID={0} and ProductID={1}", enumPurchaseOrderStatus.posApprove, lngProductID)
40 ProductOnOrder = Nz(DLookup("Quantity", "qryPOProducts_ByStatus", sqlWhere), 0) 'No need for DSum: qryPOProducts_ByStatus already is a Totals query.
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductOnOrder"
70 Resume Exit_Handler
End Function
'PURPOSE:
' Calculate the minimum Reorder Quantity
'ALGORITHM:
'To determine minimum Reorder Qty we need to consider
' how much we have available intQtyAvailable
' + how much we have OnOrder intOnOrder
'then
' how much NoStock (what we need; some of which may already be On Order
' + the product Target LevelPublic Function ProductReorderQuantity(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim intReorderQty As Integer
Dim intNoStock As Integer
Dim intMinReorder As Integer
Dim intOnOrder As Integer
Dim intQtyAvailable As Integer
Dim intTargetLevel As Integer
20 intReorderQty = 0
30 If lngProductID = 0 Then GoTo Exit_Handler
40 intNoStock = ProductNoStock(lngProductID)
50 intOnOrder = ProductOnOrder(lngProductID) 'PO Status Approved.
60 intQtyAvailable = ProductToSell(lngProductID)
70 intMinReorder = Nz(DLookup("MinimumReorderQuantity", "Products", "ProductID = " & lngProductID), 1)
80 intTargetLevel = Nz(DLookup("TargetLevel", "Products", "ProductID = " & lngProductID), 0)
90 If (intQtyAvailable + intOnOrder) >= (intNoStock + intTargetLevel) Then
' we dont need to order anything, return the minimum reorder quantity for the Product.
100 intReorderQty = intMinReorder
110 Else
'we need to reorder.
120 intReorderQty = (intNoStock + intTargetLevel) - (intQtyAvailable + intOnOrder)
130 If intMinReorder > intReorderQty Then 'Return which ever is greater
'we need less than the minimum reorder quantity - return the minimum reorder quantity.
140 intReorderQty = intMinReorder
150 End If
160 End If
170 ProductReorderQuantity = intReorderQty
Exit_Handler:
180 Exit Function
Err_Handler:
190 clsErrorHandler.HandleError "modInventory", "ProductReorderQuantity"
200 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity of this product that was sold after a point in time
' If you wanted all sales you would pass g_dtNorthwindInception which is 11/01/2022Public Function ProductSold(ByVal lngProductID As Long, ByVal dtAsOf As Date) As Integer
10 On Error GoTo Err_Handler
Dim sql As String
20 If lngProductID = 0 Then GoTo Exit_Handler
' NOTE: Nz(date_field) returns 12/30/1899 (day zero) if it is null, which is less than our dtAsOf so nulls are not returned.
30 sql = StringFormatSQL("ProductID = {0} and OrderID IN (Select OrderID FROM Orders WHERE Nz(InvoiceDate) >= {1})", lngProductID, dtAsOf)
40 ProductSold = Nz(DSum("Quantity", "OrderDetails", sql), 0)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductSold"
70 Resume Exit_Handler
End Function
'DEFINITION:
' Last Stock Take Qty + Received since last stocktake - Invoiced since last stocktake - allocated to existing orders.Public Function ProductToSell(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim dtLastStockTake As Date
Dim intAllocated As Integer
Dim intAvailable As Integer
Dim intBought As Integer
Dim intSold As Integer
Dim intLastStockTake As Integer
20 If lngProductID = 0 Then GoTo Exit_Handler
'Last stock take
30 dtLastStockTake = ProductLastStockTakeDate(lngProductID)
40 intLastStockTake = ProductLastStockTakeQuantity(lngProductID)
'Sold
50 intSold = ProductSold(lngProductID, dtLastStockTake)
'Bought
60 intBought = ProductBought(lngProductID, dtLastStockTake)
'Allocated
70 intAllocated = ProductAllocated(lngProductID)
80 intAvailable = intLastStockTake + intBought - intSold - intAllocated
90 ProductToSell = intAvailable
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modInventory", "ProductToSell"
120 Resume Exit_Handler
End FunctionOption Compare Database
Option Explicit
'PURPOSE:
' Allocate Inventory to orders waiting for them.
Public Sub AllocateInventory(ByVal lngProductID As Long)
10 On Error GoTo Err_Handler
Dim rsO As DAO.Recordset
Dim intQtyToAllocate As Integer
Dim intAvailable As Integer
Dim sql As String
'Get list of orderdetails waiting for this product; oldest one first. StatusID=1=Allocated, 4=NoStock, 5=OnOrder. OrderID is the tie breaker if same datetime.
20 sql = StringFormatSQL("select od.* from OrderDetails od " & _
"inner join Orders o on o.OrderID = od.OrderID " & _
"where od.ProductID = {0} and od.OrderDetailStatusID in (1, 4, 5) " & _
"order by o.OrderDate, o.OrderID", lngProductID)
30 Set rsO = g_dbApp().OpenRecordset(sql, dbOpenDynaset)
'Physical inventory at this moment in time
40 intAvailable = ProductAvailable(lngProductID)
'Physical Inventory + how much is On Order
50 intQtyToAllocate = intAvailable + ProductOnOrder(lngProductID)
60 While Not rsO.EOF 'Loop over the order line items with this product that are in status of Allocated, No Stock or On Order.
70 If rsO!Quantity <= intAvailable Then 'Only allocate if we can satisfy the entire orderdetail.
80 rsO.Edit
90 rsO!OrderDetailStatusID = enumOrderDetailStatus.odsAllocated
100 intAvailable = intAvailable - rsO!Quantity
110 intQtyToAllocate = intQtyToAllocate - rsO!Quantity
120 rsO.Update
130 ElseIf rsO!Quantity <= intQtyToAllocate Then 'Only OnOrder if we can satisfy the entire orderdetail.
140 rsO.Edit
150 rsO!OrderDetailStatusID = enumOrderDetailStatus.odsOnOrder
160 intQtyToAllocate = intQtyToAllocate - rsO!Quantity
170 rsO.Update
180 Else
'If we are here, we don't have enough
190 rsO.Edit
200 rsO!OrderDetailStatusID = enumOrderDetailStatus.odsNoStock
210 rsO.Update
220 End If
230 rsO.MoveNext
240 Wend
250 rsO.Close
260 Set rsO = Nothing
Exit_Handler:
270 Exit Sub
Err_Handler:
280 clsErrorHandler.HandleError "modInventory", "AllocateInventory"
290 Resume Exit_Handler
300 Resume
End Sub
'RETURNS:
' Integer: Quantity of this product that is in the given status.
Public Function OrderQuantity_ByStatus(ByVal lngProductID As Long, ByVal ods As enumOrderDetailStatus) As Integer
10 On Error GoTo Err_Handler
Dim sql As String
20 If lngProductID = 0 Then GoTo Exit_Handler
30 sql = StringFormatSQL("ProductID = {0} and OrderDetailStatusID = {1}", lngProductID, ods)
40 OrderQuantity_ByStatus = Nz(DSum("Quantity", "OrderDetails", sql), 0)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "OrderQuantity_ByStatus"
70 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity of this product that is in Allocated status.
Public Function ProductAllocated(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
20 ProductAllocated = OrderQuantity_ByStatus(lngProductID, odsAllocated)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modInventory", "ProductAllocated"
50 Resume Exit_Handler
End Function
'DEFINITION:
' Last Stock Take Qty + Received since last stocktake - Invoiced since last stocktake.
Public Function ProductAvailable(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim dtLastStockTake As Date
Dim intLastStockTake As Integer
Dim intAvailable As Integer
Dim intBought As Integer
Dim intSold As Integer
20 ProductAvailable = 0
30 If lngProductID = 0 Then GoTo Exit_Handler
'Last stock take
40 dtLastStockTake = ProductLastStockTakeDate(lngProductID)
50 intLastStockTake = ProductLastStockTakeQuantity(lngProductID)
'Sold
60 intSold = ProductSold(lngProductID, dtLastStockTake)
'Bought
70 intBought = ProductBought(lngProductID, dtLastStockTake)
'Allen Browne's formula - Adapted with permission from http://allenbrowne.com/AppInventory.html
80 intAvailable = intLastStockTake + intBought - intSold
90 ProductAvailable = intAvailable
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modInventory", "ProductAvailable"
120 Resume Exit_Handler
130 Resume
End Function
'DEFINITION
' Bought = When product on a PO is Received.
' ProductBought quantity: Sum of Product received since last stocktake (or since dtAsOf).
'RETURNS:
' Integer: Quantity of this product that was received after point in time.
' If you wanted all purchases you would pass g_dtNorthwindInception which is 11/01/2022
Public Function ProductBought(ByVal lngProductID As Long, ByVal dtAsOf As Date) As Integer
10 On Error GoTo Err_Handler
Dim sql As String
20 If lngProductID = 0 Then GoTo Exit_Handler
30 sql = StringFormatSQL("ProductID = {0} and ReceivedDate >= {1}", lngProductID, dtAsOf)
40 ProductBought = Nz(DSum("Quantity", "PurchaseOrderDetails", sql), 0)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductBought"
70 Resume Exit_Handler
End Function
'PURPOSE:
' Returns the Date with Time of the Last StockTake for a Product.
' Northwind Expects there to be a StockTake. When a Product is added the first StockTake record is entered.
' If there is no StockTake (it has been deleted), Add a Stock Take record the same as what was created when the Product was added.
' Set StockTakeDate using the Date the Product was Added
' QuantityOnHand = 0
Public Function ProductLastStockTakeDate(ByVal lngProductID As Long) As Date
10 On Error GoTo Err_Handler
Dim sql As String
Dim rsStockTake As DAO.Recordset
20 ProductLastStockTakeDate = g_dtNorthwindInception
30 If lngProductID = 0 Then GoTo Exit_Handler
40 sql = StringFormatSQL("select * from StockTake where ProductID = {0} order by StockTakeDate desc;", lngProductID)
50 Set rsStockTake = g_dbApp().OpenRecordset(sql, dbOpenDynaset)
60 If rsStockTake.RecordCount = 0 Then
'No stock take was ever done for this Product.
70 With rsStockTake
80 .AddNew
90 !StockTakeDate = Nz(DLookup("AddedOn", "Products", "ProductID = " & lngProductID), Now())
100 !ProductID = lngProductID
110 !QuantityOnHand = 0
120 .Update
130 .Move 0, .LastModified 'Move to the record just added, so we can read from it.
140 End With
150 End If
160 ProductLastStockTakeDate = rsStockTake!StockTakeDate
170 rsStockTake.Close
180 Set rsStockTake = Nothing
Exit_Handler:
190 Exit Function
Err_Handler:
200 clsErrorHandler.HandleError "modInventory", "ProductLastStockTakeDate"
210 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity in the last (most recent) StockTake for the Product
Public Function ProductLastStockTakeQuantity(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim dtStockTakeDate As Date
20 If lngProductID = 0 Then GoTo Exit_Handler
30 dtStockTakeDate = ProductLastStockTakeDate(lngProductID)
'ERROR: This may return Null because of roundoff errors. ProductLastStockTakeQuantity = DLookup("QuantityOnHand", "StockTake", StringFormatSQL("ProductID = {0} and StockTakeDate = CDate({1})", lngProductID, dtStockTakeDate))
'NOTE: We're using ToAccessDate (which returns a string) on both sides of the expression "StockTakeDate = some_date". This is because of possible roundoff errors if we were to compare
' the date values themselves (which are floating point values). In one particular case we had this roundoff error:
'? DLookup("StockTakeDate", "StockTake", "ProductID = 3") - #11/27/2022 9:02:00 AM#
'7.27595761418343E-12
'By comparing the text values (as returned by ToAccessDate), we avoid this roundoff.
40 ProductLastStockTakeQuantity = DLookup("QuantityOnHand", "StockTake", StringFormatSQL("ProductID = {0} and ToAccessDate(StockTakeDate) = {1}", lngProductID, ToAccessDate(dtStockTakeDate)))
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductLastStockTakeQuantity"
70 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity of this product that is in No Stock status.
Public Function ProductNoStock(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
20 ProductNoStock = OrderQuantity_ByStatus(lngProductID, odsNoStock)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modInventory", "ProductNoStock"
50 Resume Exit_Handler
End Function
'DEFINITION:
' Sum of Product Quantity for POs in the Approved status.
'NOTE:
' There can be more than one PO for the same Product, therefore we sum the quantities in qryPOProducts_ByStatus.
'RETURNS:
' Integer: Quantity of this product that is on an Approved Purchase Order
'
'We need a query in this function because we need two tables which are joined
' PurchaseOrder - contains the criteria for the POStatus of Approved
' and PurchaseOrderDetail - to support the criteria for ProductID.
Public Function ProductOnOrder(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim sqlWhere As String
20 If lngProductID = 0 Then GoTo Exit_Handler
30 sqlWhere = StringFormatSQL("StatusID={0} and ProductID={1}", enumPurchaseOrderStatus.posApprove, lngProductID)
40 ProductOnOrder = Nz(DLookup("Quantity", "qryPOProducts_ByStatus", sqlWhere), 0) 'No need for DSum: qryPOProducts_ByStatus already is a Totals query.
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductOnOrder"
70 Resume Exit_Handler
End Function
'PURPOSE:
' Calculate the minimum Reorder Quantity
'ALGORITHM:
'To determine minimum Reorder Qty we need to consider
' how much we have available intQtyAvailable
' + how much we have OnOrder intOnOrder
'then
' how much NoStock (what we need; some of which may already be On Order
' + the product Target Level
Public Function ProductReorderQuantity(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim intReorderQty As Integer
Dim intNoStock As Integer
Dim intMinReorder As Integer
Dim intOnOrder As Integer
Dim intQtyAvailable As Integer
Dim intTargetLevel As Integer
20 intReorderQty = 0
30 If lngProductID = 0 Then GoTo Exit_Handler
40 intNoStock = ProductNoStock(lngProductID)
50 intOnOrder = ProductOnOrder(lngProductID) 'PO Status Approved.
60 intQtyAvailable = ProductToSell(lngProductID)
70 intMinReorder = Nz(DLookup("MinimumReorderQuantity", "Products", "ProductID = " & lngProductID), 1)
80 intTargetLevel = Nz(DLookup("TargetLevel", "Products", "ProductID = " & lngProductID), 0)
90 If (intQtyAvailable + intOnOrder) >= (intNoStock + intTargetLevel) Then
' we dont need to order anything, return the minimum reorder quantity for the Product.
100 intReorderQty = intMinReorder
110 Else
'we need to reorder.
120 intReorderQty = (intNoStock + intTargetLevel) - (intQtyAvailable + intOnOrder)
130 If intMinReorder > intReorderQty Then 'Return which ever is greater
'we need less than the minimum reorder quantity - return the minimum reorder quantity.
140 intReorderQty = intMinReorder
150 End If
160 End If
170 ProductReorderQuantity = intReorderQty
Exit_Handler:
180 Exit Function
Err_Handler:
190 clsErrorHandler.HandleError "modInventory", "ProductReorderQuantity"
200 Resume Exit_Handler
End Function
'RETURNS:
' Integer: Quantity of this product that was sold after a point in time
' If you wanted all sales you would pass g_dtNorthwindInception which is 11/01/2022
Public Function ProductSold(ByVal lngProductID As Long, ByVal dtAsOf As Date) As Integer
10 On Error GoTo Err_Handler
Dim sql As String
20 If lngProductID = 0 Then GoTo Exit_Handler
' NOTE: Nz(date_field) returns 12/30/1899 (day zero) if it is null, which is less than our dtAsOf so nulls are not returned.
30 sql = StringFormatSQL("ProductID = {0} and OrderID IN (Select OrderID FROM Orders WHERE Nz(InvoiceDate) >= {1})", lngProductID, dtAsOf)
40 ProductSold = Nz(DSum("Quantity", "OrderDetails", sql), 0)
Exit_Handler:
50 Exit Function
Err_Handler:
60 clsErrorHandler.HandleError "modInventory", "ProductSold"
70 Resume Exit_Handler
End Function
'DEFINITION:
' Last Stock Take Qty + Received since last stocktake - Invoiced since last stocktake - allocated to existing orders.
Public Function ProductToSell(ByVal lngProductID As Long) As Integer
10 On Error GoTo Err_Handler
Dim dtLastStockTake As Date
Dim intAllocated As Integer
Dim intAvailable As Integer
Dim intBought As Integer
Dim intSold As Integer
Dim intLastStockTake As Integer
20 If lngProductID = 0 Then GoTo Exit_Handler
'Last stock take
30 dtLastStockTake = ProductLastStockTakeDate(lngProductID)
40 intLastStockTake = ProductLastStockTakeQuantity(lngProductID)
'Sold
50 intSold = ProductSold(lngProductID, dtLastStockTake)
'Bought
60 intBought = ProductBought(lngProductID, dtLastStockTake)
'Allocated
70 intAllocated = ProductAllocated(lngProductID)
80 intAvailable = intLastStockTake + intBought - intSold - intAllocated
90 ProductToSell = intAvailable
Exit_Handler:
100 Exit Function
Err_Handler:
110 clsErrorHandler.HandleError "modInventory", "ProductToSell"
120 Resume Exit_Handler
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| GetRandom | Function | Public | (ByVal lngLowerBound As Long, ByVal lngUpperBound As Long) | 6 | 23 | handleerror |
| MaxValue | Function | Public | (ParamArray varValue() As Variant) | 29 | 23 | handleerror |
Public Function GetRandom(ByVal lngLowerBound As Long, ByVal lngUpperBound As Long) As Long
10 On Error GoTo Err_Handler
'NOTE: Int function truncates fractional part. Works for Long values as well.
20 GetRandom = Int((lngUpperBound - lngLowerBound + 1) * Rnd + lngLowerBound)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modMath", "GetRandom"
50 Resume Exit_Handler
End Function
'PROCEDURE:
' MaxValue
'PURPOSE:
' Using variants because user can pass in any data type, including dates.
' Example: myMax = MaxValue(1, 3.5, 5)
'ARGUMENTS:
' Any number of values (not an array)
'RETURNS:
' VariantPublic Function MaxValue(ParamArray varValue() As Variant) As Variant
10 On Error GoTo Err_Handler
Dim v As Variant
Dim vMax As Variant
20 If UBound(varValue) = -1 Then
30 vMax = Null 'Zero arguments passed in
40 Else
50 vMax = varValue(0)
60 For Each v In varValue
70 If v > vMax Then vMax = v
80 Next
90 End If
100 MaxValue = vMax
Exit_Handler:
110 Exit Function
Err_Handler:
120 clsErrorHandler.HandleError "modMath", "MaxValue"
130 Resume Exit_Handler
End FunctionOption Compare Database
Option Explicit
'REFERENCE:
' https://docs.microsoft.com/office/vba/language/reference/user-interface-help/rnd-function
Public Function GetRandom(ByVal lngLowerBound As Long, ByVal lngUpperBound As Long) As Long
10 On Error GoTo Err_Handler
'NOTE: Int function truncates fractional part. Works for Long values as well.
20 GetRandom = Int((lngUpperBound - lngLowerBound + 1) * Rnd + lngLowerBound)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modMath", "GetRandom"
50 Resume Exit_Handler
End Function
'PROCEDURE:
' MaxValue
'PURPOSE:
' Using variants because user can pass in any data type, including dates.
' Example: myMax = MaxValue(1, 3.5, 5)
'ARGUMENTS:
' Any number of values (not an array)
'RETURNS:
' Variant
Public Function MaxValue(ParamArray varValue() As Variant) As Variant
10 On Error GoTo Err_Handler
Dim v As Variant
Dim vMax As Variant
20 If UBound(varValue) = -1 Then
30 vMax = Null 'Zero arguments passed in
40 Else
50 vMax = varValue(0)
60 For Each v In varValue
70 If v > vMax Then vMax = v
80 Next
90 End If
100 MaxValue = vMax
Exit_Handler:
110 Exit Function
Err_Handler:
120 clsErrorHandler.HandleError "modMath", "MaxValue"
130 Resume Exit_Handler
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| RunOrderAvailabilityPlanning | Sub | Public | (ByVal OrderID As Long) | 7 | 14 | buildfulfillmentplan, clearexistingfulfillmentplan, openavailabilityreport, validateorderforplanning |
| ValidateOrderForPlanning | Function | Public | (ByVal OrderID As Long) | 22 | 15 | — |
| ClearExistingFulfillmentPlan | Sub | Private | (ByVal OrderID As Long) | 38 | 3 | — |
| BuildFulfillmentPlan | Sub | Private | (ByVal OrderID As Long) | 42 | 8 | — |
| OpenAvailabilityReport | Sub | Private | (ByVal OrderID As Long) | 51 | 3 | — |
Public Sub RunOrderAvailabilityPlanning(ByVal OrderID As Long)
On Error GoTo Err_Handler
If Not ValidateOrderForPlanning(OrderID) Then Exit Sub
ClearExistingFulfillmentPlan OrderID
BuildFulfillmentPlan OrderID
OpenAvailabilityReport OrderID
Exit Sub
Err_Handler:
MsgBox "The order availability plan could not be created: " & Err.Description, _
vbExclamation, "Northwind Traders Plus"
End SubPublic Function ValidateOrderForPlanning(ByVal OrderID As Long) As Boolean
If OrderID = 0 Then
MsgBox "Save or select an order before checking availability.", vbExclamation, _
"Northwind Traders Plus"
Exit Function
End If
If DCount("*", "OrderDetails", "OrderID=" & OrderID) = 0 Then
MsgBox "This order does not contain any order lines to plan.", vbExclamation, _
"Northwind Traders Plus"
Exit Function
End If
ValidateOrderForPlanning = True
End FunctionPrivate Sub ClearExistingFulfillmentPlan(ByVal OrderID As Long)
CurrentDb.Execute "DELETE FROM NWPFulfillmentPlan WHERE OrderID=" & OrderID, dbFailOnError
End SubPrivate Sub BuildFulfillmentPlan(ByVal OrderID As Long)
Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.QueryDefs("qryNWP_BuildFulfillmentPlan")
qdf.Parameters("pOrderID") = OrderID
qdf.Execute dbFailOnError
qdf.Close
End SubOption Compare Database
Option Explicit
' Button-driven Northwind Plus availability workflow.
' Add cmdCheckAvailability_Click to frmOrderDetails using the code in Form_and_report_steps.md.
Public Sub RunOrderAvailabilityPlanning(ByVal OrderID As Long)
On Error GoTo Err_Handler
If Not ValidateOrderForPlanning(OrderID) Then Exit Sub
ClearExistingFulfillmentPlan OrderID
BuildFulfillmentPlan OrderID
OpenAvailabilityReport OrderID
Exit Sub
Err_Handler:
MsgBox "The order availability plan could not be created: " & Err.Description, _
vbExclamation, "Northwind Traders Plus"
End Sub
Public Function ValidateOrderForPlanning(ByVal OrderID As Long) As Boolean
If OrderID = 0 Then
MsgBox "Save or select an order before checking availability.", vbExclamation, _
"Northwind Traders Plus"
Exit Function
End If
If DCount("*", "OrderDetails", "OrderID=" & OrderID) = 0 Then
MsgBox "This order does not contain any order lines to plan.", vbExclamation, _
"Northwind Traders Plus"
Exit Function
End If
ValidateOrderForPlanning = True
End Function
Private Sub ClearExistingFulfillmentPlan(ByVal OrderID As Long)
CurrentDb.Execute "DELETE FROM NWPFulfillmentPlan WHERE OrderID=" & OrderID, dbFailOnError
End Sub
Private Sub BuildFulfillmentPlan(ByVal OrderID As Long)
Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.QueryDefs("qryNWP_BuildFulfillmentPlan")
qdf.Parameters("pOrderID") = OrderID
qdf.Execute dbFailOnError
qdf.Close
End Sub
Private Sub OpenAvailabilityReport(ByVal OrderID As Long)
DoCmd.OpenReport "rptNWP_OrderAvailability", acViewPreview, , "OrderID=" & OrderID
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| InstallNorthwindPlus | Sub | Public | () | 7 | 15 | createnorthwindplusqueries, createnorthwindplustables, seedmockproductioncapacity |
| CreateNorthwindPlusTables | Sub | Private | () | 23 | 34 | tableexists |
| SeedMockProductionCapacity | Sub | Private | () | 58 | 17 | — |
| CreateNorthwindPlusQueries | Sub | Private | () | 76 | 60 | savequery |
| SaveQuery | Sub | Private | (ByVal queryName As String, ByVal sqlText As String) | 137 | 9 | — |
| TableExists | Function | Private | (ByVal tableName As String) | 147 | 10 | — |
Public Sub InstallNorthwindPlus()
On Error GoTo Err_Handler
CreateNorthwindPlusTables
SeedMockProductionCapacity
CreateNorthwindPlusQueries
MsgBox "Northwind Traders Plus planning tables, mock capacity, and queries are ready.", _
vbInformation, "Northwind Traders Plus"
Exit Sub
Err_Handler:
MsgBox "Northwind Plus setup could not finish: " & Err.Description, vbExclamation, _
"Northwind Traders Plus"
End SubPrivate Sub CreateNorthwindPlusTables()
Dim db As DAO.Database
Set db = CurrentDb
If Not TableExists("NWPProductionCapacity") Then
db.Execute _
"CREATE TABLE NWPProductionCapacity (" & _
"ProductionCapacityID COUNTER CONSTRAINT PK_NWPProductionCapacity PRIMARY KEY, " & _
"ProductID LONG NOT NULL, " & _
"ProductionDate DATETIME NOT NULL, " & _
"CapacityUnits LONG NOT NULL, " & _
"PlanningNote TEXT(255))", dbFailOnError
db.Execute "CREATE INDEX IX_NWPProductionCapacity_ProductDate " & _
"ON NWPProductionCapacity (ProductID, ProductionDate)", dbFailOnError
End If
If Not TableExists("NWPFulfillmentPlan") Then
db.Execute _
"CREATE TABLE NWPFulfillmentPlan (" & _
"FulfillmentPlanID COUNTER CONSTRAINT PK_NWPFulfillmentPlan PRIMARY KEY, " & _
"OrderID LONG NOT NULL, " & _
"ProductID LONG NOT NULL, " & _
"RequiredQuantity LONG NOT NULL, " & _
"QuantityOnHand LONG NOT NULL, " & _
"PlannedProduction LONG NOT NULL, " & _
"AvailableToPromise LONG NOT NULL, " & _
"ShortageQuantity LONG NOT NULL, " & _
"PromiseDate DATETIME, " & _
"PlanStatus TEXT(30) NOT NULL, " & _
"CreatedOn DATETIME NOT NULL)", dbFailOnError
db.Execute "CREATE INDEX IX_NWPFulfillmentPlan_Order ON NWPFulfillmentPlan (OrderID)", dbFailOnError
End If
End SubPrivate Sub SeedMockProductionCapacity()
Dim db As DAO.Database
Set db = CurrentDb
If DCount("*", "NWPProductionCapacity") > 0 Then Exit Sub
'Use real Northwind ProductIDs so the demonstration works with the supplied sample data.
db.Execute _
"INSERT INTO NWPProductionCapacity (ProductID, ProductionDate, CapacityUnits, PlanningNote) " & _
"SELECT TOP 12 ProductID, DateAdd('d', 3, Date()), 15, 'Northwind Plus demonstration capacity' " & _
"FROM Products WHERE Discontinued = False ORDER BY ProductID", dbFailOnError
db.Execute _
"INSERT INTO NWPProductionCapacity (ProductID, ProductionDate, CapacityUnits, PlanningNote) " & _
"SELECT TOP 12 ProductID, DateAdd('d', 7, Date()), 30, 'Northwind Plus follow-up capacity' " & _
"FROM Products WHERE Discontinued = False ORDER BY ProductID", dbFailOnError
End SubPrivate Sub CreateNorthwindPlusQueries()
SaveQuery "qryNWP_LatestStock", _
"SELECT StockTake.ProductID, StockTake.QuantityOnHand " & _
"FROM StockTake INNER JOIN " & _
"(SELECT ProductID, Max(StockTakeDate) AS LatestStockTakeDate " & _
" FROM StockTake GROUP BY ProductID) AS Latest " & _
"ON (StockTake.ProductID = Latest.ProductID) " & _
"AND (StockTake.StockTakeDate = Latest.LatestStockTakeDate);"
SaveQuery "qryNWP_PlannedProduction", _
"SELECT ProductID, Sum(CapacityUnits) AS PlannedProduction, " & _
"Min(ProductionDate) AS FirstProductionDate " & _
"FROM NWPProductionCapacity " & _
"WHERE ProductionDate >= Date() " & _
"GROUP BY ProductID;"
SaveQuery "qryNWP_AvailableToPromise", _
"SELECT Products.ProductID, Products.ProductCode, Products.ProductName, " & _
"Nz(LatestStock.QuantityOnHand, 0) AS QuantityOnHand, " & _
"Nz(Planned.PlannedProduction, 0) AS PlannedProduction, " & _
"Nz(LatestStock.QuantityOnHand, 0) + Nz(Planned.PlannedProduction, 0) AS AvailableToPromise, " & _
"Planned.FirstProductionDate " & _
"FROM (Products LEFT JOIN qryNWP_LatestStock AS LatestStock " & _
"ON Products.ProductID = LatestStock.ProductID) " & _
"LEFT JOIN qryNWP_PlannedProduction AS Planned " & _
"ON Products.ProductID = Planned.ProductID;"
SaveQuery "qryNWP_OrderDemand", _
"PARAMETERS [pOrderID] Long; " & _
"SELECT OrderDetails.OrderID, OrderDetails.ProductID, " & _
"Sum(OrderDetails.Quantity) AS RequiredQuantity " & _
"FROM OrderDetails " & _
"WHERE OrderDetails.OrderID = [pOrderID] " & _
"GROUP BY OrderDetails.OrderID, OrderDetails.ProductID;"
SaveQuery "qryNWP_BuildFulfillmentPlan", _
"PARAMETERS [pOrderID] Long; " & _
"INSERT INTO NWPFulfillmentPlan " & _
"(OrderID, ProductID, RequiredQuantity, QuantityOnHand, PlannedProduction, " & _
"AvailableToPromise, ShortageQuantity, PromiseDate, PlanStatus, CreatedOn) " & _
"SELECT Demand.OrderID, Demand.ProductID, Demand.RequiredQuantity, " & _
"Availability.QuantityOnHand, Availability.PlannedProduction, Availability.AvailableToPromise, " & _
"IIf(Availability.AvailableToPromise < Demand.RequiredQuantity, " & _
"Demand.RequiredQuantity - Availability.AvailableToPromise, 0) AS ShortageQuantity, " & _
"IIf(Availability.AvailableToPromise >= Demand.RequiredQuantity, Date(), " & _
"Availability.FirstProductionDate) AS PromiseDate, " & _
"IIf(Availability.AvailableToPromise >= Demand.RequiredQuantity, 'Available now', " & _
"IIf(Availability.PlannedProduction > 0, 'Planned production', 'Shortage')) AS PlanStatus, Now() " & _
"FROM qryNWP_OrderDemand AS Demand " & _
"INNER JOIN qryNWP_AvailableToPromise AS Availability " & _
"ON Demand.ProductID = Availability.ProductID;"
SaveQuery "qryNWP_OrderAvailability", _
"SELECT Plan.OrderID, Products.ProductCode, Products.ProductName, " & _
"Plan.RequiredQuantity, Plan.QuantityOnHand, Plan.PlannedProduction, " & _
"Plan.AvailableToPromise, Plan.ShortageQuantity, Plan.PromiseDate, Plan.PlanStatus " & _
"FROM NWPFulfillmentPlan AS Plan INNER JOIN Products " & _
"ON Plan.ProductID = Products.ProductID " & _
"ORDER BY Plan.OrderID, Products.ProductName;"
End SubPrivate Sub SaveQuery(ByVal queryName As String, ByVal sqlText As String)
Dim db As DAO.Database
Set db = CurrentDb
On Error Resume Next
db.QueryDefs.Delete queryName
On Error GoTo 0
db.CreateQueryDef queryName, sqlText
End SubPrivate Function TableExists(ByVal tableName As String) As Boolean
Dim td As DAO.TableDef
On Error Resume Next
Set td = CurrentDb.TableDefs(tableName)
TableExists = (Err.Number = 0)
Set td = Nothing
Err.Clear
On Error GoTo 0
End FunctionOption Compare Database
Option Explicit
' Northwind Traders Plus demonstration setup.
' Import this module into a COPY of NorthwindTraders.accdb, then run InstallNorthwindPlus.
Public Sub InstallNorthwindPlus()
On Error GoTo Err_Handler
CreateNorthwindPlusTables
SeedMockProductionCapacity
CreateNorthwindPlusQueries
MsgBox "Northwind Traders Plus planning tables, mock capacity, and queries are ready.", _
vbInformation, "Northwind Traders Plus"
Exit Sub
Err_Handler:
MsgBox "Northwind Plus setup could not finish: " & Err.Description, vbExclamation, _
"Northwind Traders Plus"
End Sub
Private Sub CreateNorthwindPlusTables()
Dim db As DAO.Database
Set db = CurrentDb
If Not TableExists("NWPProductionCapacity") Then
db.Execute _
"CREATE TABLE NWPProductionCapacity (" & _
"ProductionCapacityID COUNTER CONSTRAINT PK_NWPProductionCapacity PRIMARY KEY, " & _
"ProductID LONG NOT NULL, " & _
"ProductionDate DATETIME NOT NULL, " & _
"CapacityUnits LONG NOT NULL, " & _
"PlanningNote TEXT(255))", dbFailOnError
db.Execute "CREATE INDEX IX_NWPProductionCapacity_ProductDate " & _
"ON NWPProductionCapacity (ProductID, ProductionDate)", dbFailOnError
End If
If Not TableExists("NWPFulfillmentPlan") Then
db.Execute _
"CREATE TABLE NWPFulfillmentPlan (" & _
"FulfillmentPlanID COUNTER CONSTRAINT PK_NWPFulfillmentPlan PRIMARY KEY, " & _
"OrderID LONG NOT NULL, " & _
"ProductID LONG NOT NULL, " & _
"RequiredQuantity LONG NOT NULL, " & _
"QuantityOnHand LONG NOT NULL, " & _
"PlannedProduction LONG NOT NULL, " & _
"AvailableToPromise LONG NOT NULL, " & _
"ShortageQuantity LONG NOT NULL, " & _
"PromiseDate DATETIME, " & _
"PlanStatus TEXT(30) NOT NULL, " & _
"CreatedOn DATETIME NOT NULL)", dbFailOnError
db.Execute "CREATE INDEX IX_NWPFulfillmentPlan_Order ON NWPFulfillmentPlan (OrderID)", dbFailOnError
End If
End Sub
Private Sub SeedMockProductionCapacity()
Dim db As DAO.Database
Set db = CurrentDb
If DCount("*", "NWPProductionCapacity") > 0 Then Exit Sub
'Use real Northwind ProductIDs so the demonstration works with the supplied sample data.
db.Execute _
"INSERT INTO NWPProductionCapacity (ProductID, ProductionDate, CapacityUnits, PlanningNote) " & _
"SELECT TOP 12 ProductID, DateAdd('d', 3, Date()), 15, 'Northwind Plus demonstration capacity' " & _
"FROM Products WHERE Discontinued = False ORDER BY ProductID", dbFailOnError
db.Execute _
"INSERT INTO NWPProductionCapacity (ProductID, ProductionDate, CapacityUnits, PlanningNote) " & _
"SELECT TOP 12 ProductID, DateAdd('d', 7, Date()), 30, 'Northwind Plus follow-up capacity' " & _
"FROM Products WHERE Discontinued = False ORDER BY ProductID", dbFailOnError
End Sub
Private Sub CreateNorthwindPlusQueries()
SaveQuery "qryNWP_LatestStock", _
"SELECT StockTake.ProductID, StockTake.QuantityOnHand " & _
"FROM StockTake INNER JOIN " & _
"(SELECT ProductID, Max(StockTakeDate) AS LatestStockTakeDate " & _
" FROM StockTake GROUP BY ProductID) AS Latest " & _
"ON (StockTake.ProductID = Latest.ProductID) " & _
"AND (StockTake.StockTakeDate = Latest.LatestStockTakeDate);"
SaveQuery "qryNWP_PlannedProduction", _
"SELECT ProductID, Sum(CapacityUnits) AS PlannedProduction, " & _
"Min(ProductionDate) AS FirstProductionDate " & _
"FROM NWPProductionCapacity " & _
"WHERE ProductionDate >= Date() " & _
"GROUP BY ProductID;"
SaveQuery "qryNWP_AvailableToPromise", _
"SELECT Products.ProductID, Products.ProductCode, Products.ProductName, " & _
"Nz(LatestStock.QuantityOnHand, 0) AS QuantityOnHand, " & _
"Nz(Planned.PlannedProduction, 0) AS PlannedProduction, " & _
"Nz(LatestStock.QuantityOnHand, 0) + Nz(Planned.PlannedProduction, 0) AS AvailableToPromise, " & _
"Planned.FirstProductionDate " & _
"FROM (Products LEFT JOIN qryNWP_LatestStock AS LatestStock " & _
"ON Products.ProductID = LatestStock.ProductID) " & _
"LEFT JOIN qryNWP_PlannedProduction AS Planned " & _
"ON Products.ProductID = Planned.ProductID;"
SaveQuery "qryNWP_OrderDemand", _
"PARAMETERS [pOrderID] Long; " & _
"SELECT OrderDetails.OrderID, OrderDetails.ProductID, " & _
"Sum(OrderDetails.Quantity) AS RequiredQuantity " & _
"FROM OrderDetails " & _
"WHERE OrderDetails.OrderID = [pOrderID] " & _
"GROUP BY OrderDetails.OrderID, OrderDetails.ProductID;"
SaveQuery "qryNWP_BuildFulfillmentPlan", _
"PARAMETERS [pOrderID] Long; " & _
"INSERT INTO NWPFulfillmentPlan " & _
"(OrderID, ProductID, RequiredQuantity, QuantityOnHand, PlannedProduction, " & _
"AvailableToPromise, ShortageQuantity, PromiseDate, PlanStatus, CreatedOn) " & _
"SELECT Demand.OrderID, Demand.ProductID, Demand.RequiredQuantity, " & _
"Availability.QuantityOnHand, Availability.PlannedProduction, Availability.AvailableToPromise, " & _
"IIf(Availability.AvailableToPromise < Demand.RequiredQuantity, " & _
"Demand.RequiredQuantity - Availability.AvailableToPromise, 0) AS ShortageQuantity, " & _
"IIf(Availability.AvailableToPromise >= Demand.RequiredQuantity, Date(), " & _
"Availability.FirstProductionDate) AS PromiseDate, " & _
"IIf(Availability.AvailableToPromise >= Demand.RequiredQuantity, 'Available now', " & _
"IIf(Availability.PlannedProduction > 0, 'Planned production', 'Shortage')) AS PlanStatus, Now() " & _
"FROM qryNWP_OrderDemand AS Demand " & _
"INNER JOIN qryNWP_AvailableToPromise AS Availability " & _
"ON Demand.ProductID = Availability.ProductID;"
SaveQuery "qryNWP_OrderAvailability", _
"SELECT Plan.OrderID, Products.ProductCode, Products.ProductName, " & _
"Plan.RequiredQuantity, Plan.QuantityOnHand, Plan.PlannedProduction, " & _
"Plan.AvailableToPromise, Plan.ShortageQuantity, Plan.PromiseDate, Plan.PlanStatus " & _
"FROM NWPFulfillmentPlan AS Plan INNER JOIN Products " & _
"ON Plan.ProductID = Products.ProductID " & _
"ORDER BY Plan.OrderID, Products.ProductName;"
End Sub
Private Sub SaveQuery(ByVal queryName As String, ByVal sqlText As String)
Dim db As DAO.Database
Set db = CurrentDb
On Error Resume Next
db.QueryDefs.Delete queryName
On Error GoTo 0
db.CreateQueryDef queryName, sqlText
End Sub
Private Function TableExists(ByVal tableName As String) As Boolean
Dim td As DAO.TableDef
On Error Resume Next
Set td = CurrentDb.TableDefs(tableName)
TableExists = (Err.Number = 0)
Set td = Nothing
Err.Clear
On Error GoTo 0
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| CloseAllOrderDetailsForms | Sub | Public | () | 4 | 25 | handleerror |
| CloseOrderDetailsForm | Sub | Public | (frm As Form) | 29 | 31 | handleerror |
| CreateRandomOrders | Sub | Public | (ByVal intOrderCount As Integer) | 60 | 82 | addtomru, allocateinventory, getrandom, getrandomcustomerid, getrandomproductid, getsystemsetting, gettaxstatusid, handleerror, productavailable |
| GetRandomProductID | Function | Public | () | 143 | 15 | getrandompkvalue, handleerror |
| OpenOrderDetailsForm | Sub | Public | (Optional ByVal varOrderID As Variant) | 158 | 32 | handleerror |
| SetDatesToCurrent | Sub | Public | () | 190 | 38 | handleerror, stringformat |
| OpenOrderDetailsFormNew | Sub | Public | (Optional ByVal varOrderID As Variant) | 230 | 32 | — |
Public Sub CloseAllOrderDetailsForms()
10 On Error GoTo Err_Handler
Dim intCount As Integer
Dim i As Integer
20 If Not g_colOrderDetailsForms Is Nothing Then
30 intCount = g_colOrderDetailsForms.count
40 For i = 1 To intCount
50 g_colOrderDetailsForms.Remove 1
60 Next i
70 End If
80 Set g_colOrderDetailsForms = Nothing
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError "modOrders", "CloseAllOrderDetailsForms"
110 Resume Exit_Handler
End Sub
'PURPOSE:
' Called from frmOrderDetails.Form_Close to remove object from collection.Public Sub CloseOrderDetailsForm(frm As Form)
10 On Error GoTo Err_Handler
Dim blnRemoved As Boolean
Dim intCount As Integer
Dim i As Integer
20 If g_colOrderDetailsForms Is Nothing Then
'This may happen when the app is being shut down. Ignore it. We are on the way out anyway.
30 Else
40 intCount = g_colOrderDetailsForms.count
50 For i = 1 To intCount
60 If g_colOrderDetailsForms.Item(i).Hwnd = frm.Hwnd Then
70 g_colOrderDetailsForms.Remove i
80 blnRemoved = True
90 Exit For
100 End If
110 Next i
'Debug.Assert blnRemoved 'This will assert if form was not opened using OpenOrderDetailsForm.
120 End If
Exit_Handler:
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError "modOrders", "CloseOrderDetailsForm"
150 Resume Exit_Handler
End Sub
'PURPOSE:
' Simulate internet orders, or just for more testing.Public Sub CreateRandomOrders(ByVal intOrderCount As Integer)
10 On Error GoTo Err_Handler
Dim rsOrders As DAO.Recordset
Dim rsOrderDetails As DAO.Recordset
Dim intAvailable As Integer
Dim intOrder As Integer
Dim intDetail As Integer
Dim intDetails As Integer
Dim lngOrderID As Long
20 Set rsOrders = CurrentDb.OpenRecordset("Orders", dbOpenDynaset)
30 Set rsOrderDetails = CurrentDb.OpenRecordset("OrderDetails", dbOpenDynaset)
40 For intOrder = 1 To intOrderCount
50 With rsOrders
60 .AddNew
70 !EmployeeID = INTERNET_SALES_EMPLOYEEID
80 !CustomerID = GetRandomCustomerID()
90 !OrderDate = Now 'Now is better than Date: we want to report how long ago the last order was placed. Also for analysis purposes such as when are the busy hours.
100 !TaxRate = GetSystemSetting(ssTaxRate)
110 !TaxStatusID = GetTaxStatusID(!CustomerID)
120 !OrderStatusID = enumOrderStatus.osNew
130 !Notes = "Internet Order"
140 .Update
'Get the autonumber value just created.
150 .Move 0, .LastModified
160 lngOrderID = !OrderID
170 End With
'Create 2-5 random line items for this order.
180 intDetails = GetRandom(2, 5)
190 For intDetail = 2 To intDetails
200 With rsOrderDetails
210 .AddNew
TryAgain:
220 !OrderID = lngOrderID
230 !ProductID = GetRandomProductID()
240 !Quantity = GetRandom(5, 50)
250 intAvailable = ProductAvailable(!ProductID)
260 If intAvailable >= !Quantity Then
'We have stock. Allocate it.
270 !OrderDetailStatusID = enumOrderDetailStatus.odsAllocated
280 Else
'No or not enough stock. The purchasing department should create a new PO for this product (handled in Purchase Order module).
290 !OrderDetailStatusID = enumOrderDetailStatus.odsNoStock
300 End If
310 !UnitPrice = DLookup("UnitPrice", "Products", "ProductID = " & !ProductID)
320 .Update
330 .Move 0, .LastModified 'Move to record just added, so we can get the AutoNumber value.
'Check if the orderdetailstatus can be advanced from Nostock to OnOrder.
340 If !OrderDetailStatusID = enumOrderDetailStatus.odsNoStock Then AllocateInventory !ProductID
350 End With
360 Next intDetail
'Add the new order to the MRU list.
370 AddToMRU "Orders", lngOrderID
380 Next intOrder
390 rsOrderDetails.Close
400 rsOrders.Close
Exit_Handler:
410 Exit Sub
Err_Handler:
420 If Err.Number = 3022 Then '3022 = The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate entries and try again.
'This is normal: when choosing random numbers, occasionally the same number comes up. Just try again.
430 Resume TryAgain
440 Else
450 clsErrorHandler.HandleError "modOrders", "CreateRamdomOrders"
460 Resume Exit_Handler
470 End If
480 Resume
End SubPublic Function GetRandomProductID() As Long
10 On Error GoTo Err_Handler
20 GetRandomProductID = GetRandomPkValue("Products", "ProductID")
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modOrders", "GetRandomProductID"
50 Resume Exit_Handler
End Function
'PURPOSE:
' Support for opening multiple OrderDetails forms.Public Sub OpenOrderDetailsForm(Optional ByVal varOrderID As Variant)
10 On Error GoTo Err_Handler
Dim frm As Form
20 If g_colOrderDetailsForms Is Nothing Then Set g_colOrderDetailsForms = New Collection
'Must set TempVars before creating New form, or it is too late for Form_Open.
30 If Not IsMissing(varOrderID) Then TempVars!OpenArgs = "OrderID=" & varOrderID 'Make OpenArgs self-describing by using name=value pairs like a querystring. StringToDictionary function can be used to pick it apart.
40 Set frm = New Form_frmOrderDetails
'Does not work: OpenArgs is readonly property. frm.OpenArgs = "OrderID=" & varOrderID
50 frm.Visible = True
60 g_colOrderDetailsForms.Add frm, CStr(frm.Hwnd)
'POSSIBLE IMPROVEMENT: if using overlapped windows: Move relative to previous item in the collection using frm.Move, Otherwise the windows are stacked exactly on top of each other.
70 Set frm = Nothing
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError "modOrders", "OpenOrderDetailsForm"
100 Resume Exit_Handler
End Sub
'PURPOSE:
' Set all dates in the database relative to today, so they remain close to today's date.
' This is unlike previous version of Northwind where the dates were always in 2006.
'NOTE:
' This is a super simple algorithm. For example it does not work well if all order dates are in 2024, and one is in 2026, and then you click this button. Improve as-needed, and share your code if you can.Public Sub SetDatesToCurrent()
10 On Error GoTo Err_Handler
Dim dtMax As Date
Dim intDelta As Integer
Dim td As DAO.TableDef
Dim fld As DAO.Field
Dim db As DAO.Database
Dim sql As String
20 dtMax = Nz(DMax("OrderDate", "Orders"), Date) 'Nz in case there are no orders, and DMax returns Null.
30 intDelta = DateDiff("d", dtMax, Date)
40 If intDelta < 0 Then GoTo Exit_Handler 'Prevent error 3316: Shipped Date and Paid Date must be on or after the Order Date
50 Set db = CurrentDb
60 For Each td In db.TableDefs
70 If td.Attributes And DAO.TableDefAttributeEnum.dbSystemObject Then
'System table. Do nothing.
80 Else
90 For Each fld In td.Fields
100 If fld.Type = DAO.DataTypeEnum.dbDate Then
110 Debug.Print td.Name, fld.Name
'Example: update Orders set OrderDate = dateadd('d', 123, OrderDate)
120 sql = StringFormat("update {0} set {1} = dateadd('d', {2}, {1})", td.Name, fld.Name, intDelta)
130 db.Execute sql, dbFailOnError
140 End If
150 Next fld
160 End If
170 Next td
Exit_Handler:
180 Exit Sub
Err_Handler:
190 clsErrorHandler.HandleError "modOrders", "SetDatesToCurrent"
200 Resume Exit_Handler
210 Resume
End SubPublic Sub OpenOrderDetailsFormNew(Optional ByVal varOrderID As Variant)
10 On Error GoTo Err_Handler
Dim varOpenArgs As Variant
20 varOpenArgs = Null
30 If Not IsMissing(varOrderID) Then
40 If Not IsNull(varOrderID) Then
50 varOpenArgs = "OrderID=" & CStr(varOrderID)
'Retained for compatibility with the existing Form_Open event.
60 TempVars!OpenArgs = varOpenArgs
End If
End If
70 DoCmd.OpenForm _
FormName:="frmOrderDetails", _
View:=acNormal, _
DataMode:=acFormEdit, _
WindowMode:=acWindowNormal, _
OpenArgs:=varOpenArgs
Exit_Handler:
80 Exit Sub
Err_Handler:
90 MsgBox "Unable to open the order details form." & vbCrLf & _
"Error " & Err.Number & ": " & Err.Description, _
vbExclamation, "Open Order Details"
100 Resume Exit_Handler
End SubOption Compare Database
Option Explicit
Public Sub CloseAllOrderDetailsForms()
10 On Error GoTo Err_Handler
Dim intCount As Integer
Dim i As Integer
20 If Not g_colOrderDetailsForms Is Nothing Then
30 intCount = g_colOrderDetailsForms.count
40 For i = 1 To intCount
50 g_colOrderDetailsForms.Remove 1
60 Next i
70 End If
80 Set g_colOrderDetailsForms = Nothing
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError "modOrders", "CloseAllOrderDetailsForms"
110 Resume Exit_Handler
End Sub
'PURPOSE:
' Called from frmOrderDetails.Form_Close to remove object from collection.
Public Sub CloseOrderDetailsForm(frm As Form)
10 On Error GoTo Err_Handler
Dim blnRemoved As Boolean
Dim intCount As Integer
Dim i As Integer
20 If g_colOrderDetailsForms Is Nothing Then
'This may happen when the app is being shut down. Ignore it. We are on the way out anyway.
30 Else
40 intCount = g_colOrderDetailsForms.count
50 For i = 1 To intCount
60 If g_colOrderDetailsForms.Item(i).Hwnd = frm.Hwnd Then
70 g_colOrderDetailsForms.Remove i
80 blnRemoved = True
90 Exit For
100 End If
110 Next i
'Debug.Assert blnRemoved 'This will assert if form was not opened using OpenOrderDetailsForm.
120 End If
Exit_Handler:
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError "modOrders", "CloseOrderDetailsForm"
150 Resume Exit_Handler
End Sub
'PURPOSE:
' Simulate internet orders, or just for more testing.
Public Sub CreateRandomOrders(ByVal intOrderCount As Integer)
10 On Error GoTo Err_Handler
Dim rsOrders As DAO.Recordset
Dim rsOrderDetails As DAO.Recordset
Dim intAvailable As Integer
Dim intOrder As Integer
Dim intDetail As Integer
Dim intDetails As Integer
Dim lngOrderID As Long
20 Set rsOrders = CurrentDb.OpenRecordset("Orders", dbOpenDynaset)
30 Set rsOrderDetails = CurrentDb.OpenRecordset("OrderDetails", dbOpenDynaset)
40 For intOrder = 1 To intOrderCount
50 With rsOrders
60 .AddNew
70 !EmployeeID = INTERNET_SALES_EMPLOYEEID
80 !CustomerID = GetRandomCustomerID()
90 !OrderDate = Now 'Now is better than Date: we want to report how long ago the last order was placed. Also for analysis purposes such as when are the busy hours.
100 !TaxRate = GetSystemSetting(ssTaxRate)
110 !TaxStatusID = GetTaxStatusID(!CustomerID)
120 !OrderStatusID = enumOrderStatus.osNew
130 !Notes = "Internet Order"
140 .Update
'Get the autonumber value just created.
150 .Move 0, .LastModified
160 lngOrderID = !OrderID
170 End With
'Create 2-5 random line items for this order.
180 intDetails = GetRandom(2, 5)
190 For intDetail = 2 To intDetails
200 With rsOrderDetails
210 .AddNew
TryAgain:
220 !OrderID = lngOrderID
230 !ProductID = GetRandomProductID()
240 !Quantity = GetRandom(5, 50)
250 intAvailable = ProductAvailable(!ProductID)
260 If intAvailable >= !Quantity Then
'We have stock. Allocate it.
270 !OrderDetailStatusID = enumOrderDetailStatus.odsAllocated
280 Else
'No or not enough stock. The purchasing department should create a new PO for this product (handled in Purchase Order module).
290 !OrderDetailStatusID = enumOrderDetailStatus.odsNoStock
300 End If
310 !UnitPrice = DLookup("UnitPrice", "Products", "ProductID = " & !ProductID)
320 .Update
330 .Move 0, .LastModified 'Move to record just added, so we can get the AutoNumber value.
'Check if the orderdetailstatus can be advanced from Nostock to OnOrder.
340 If !OrderDetailStatusID = enumOrderDetailStatus.odsNoStock Then AllocateInventory !ProductID
350 End With
360 Next intDetail
'Add the new order to the MRU list.
370 AddToMRU "Orders", lngOrderID
380 Next intOrder
390 rsOrderDetails.Close
400 rsOrders.Close
Exit_Handler:
410 Exit Sub
Err_Handler:
420 If Err.Number = 3022 Then '3022 = The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate entries and try again.
'This is normal: when choosing random numbers, occasionally the same number comes up. Just try again.
430 Resume TryAgain
440 Else
450 clsErrorHandler.HandleError "modOrders", "CreateRamdomOrders"
460 Resume Exit_Handler
470 End If
480 Resume
End Sub
Public Function GetRandomProductID() As Long
10 On Error GoTo Err_Handler
20 GetRandomProductID = GetRandomPkValue("Products", "ProductID")
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modOrders", "GetRandomProductID"
50 Resume Exit_Handler
End Function
'PURPOSE:
' Support for opening multiple OrderDetails forms.
Public Sub OpenOrderDetailsForm(Optional ByVal varOrderID As Variant)
10 On Error GoTo Err_Handler
Dim frm As Form
20 If g_colOrderDetailsForms Is Nothing Then Set g_colOrderDetailsForms = New Collection
'Must set TempVars before creating New form, or it is too late for Form_Open.
30 If Not IsMissing(varOrderID) Then TempVars!OpenArgs = "OrderID=" & varOrderID 'Make OpenArgs self-describing by using name=value pairs like a querystring. StringToDictionary function can be used to pick it apart.
40 Set frm = New Form_frmOrderDetails
'Does not work: OpenArgs is readonly property. frm.OpenArgs = "OrderID=" & varOrderID
50 frm.Visible = True
60 g_colOrderDetailsForms.Add frm, CStr(frm.Hwnd)
'POSSIBLE IMPROVEMENT: if using overlapped windows: Move relative to previous item in the collection using frm.Move, Otherwise the windows are stacked exactly on top of each other.
70 Set frm = Nothing
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError "modOrders", "OpenOrderDetailsForm"
100 Resume Exit_Handler
End Sub
'PURPOSE:
' Set all dates in the database relative to today, so they remain close to today's date.
' This is unlike previous version of Northwind where the dates were always in 2006.
'NOTE:
' This is a super simple algorithm. For example it does not work well if all order dates are in 2024, and one is in 2026, and then you click this button. Improve as-needed, and share your code if you can.
Public Sub SetDatesToCurrent()
10 On Error GoTo Err_Handler
Dim dtMax As Date
Dim intDelta As Integer
Dim td As DAO.TableDef
Dim fld As DAO.Field
Dim db As DAO.Database
Dim sql As String
20 dtMax = Nz(DMax("OrderDate", "Orders"), Date) 'Nz in case there are no orders, and DMax returns Null.
30 intDelta = DateDiff("d", dtMax, Date)
40 If intDelta < 0 Then GoTo Exit_Handler 'Prevent error 3316: Shipped Date and Paid Date must be on or after the Order Date
50 Set db = CurrentDb
60 For Each td In db.TableDefs
70 If td.Attributes And DAO.TableDefAttributeEnum.dbSystemObject Then
'System table. Do nothing.
80 Else
90 For Each fld In td.Fields
100 If fld.Type = DAO.DataTypeEnum.dbDate Then
110 Debug.Print td.Name, fld.Name
'Example: update Orders set OrderDate = dateadd('d', 123, OrderDate)
120 sql = StringFormat("update {0} set {1} = dateadd('d', {2}, {1})", td.Name, fld.Name, intDelta)
130 db.Execute sql, dbFailOnError
140 End If
150 Next fld
160 End If
170 Next td
Exit_Handler:
180 Exit Sub
Err_Handler:
190 clsErrorHandler.HandleError "modOrders", "SetDatesToCurrent"
200 Resume Exit_Handler
210 Resume
End Sub
Public Sub OpenOrderDetailsFormNew(Optional ByVal varOrderID As Variant)
10 On Error GoTo Err_Handler
Dim varOpenArgs As Variant
20 varOpenArgs = Null
30 If Not IsMissing(varOrderID) Then
40 If Not IsNull(varOrderID) Then
50 varOpenArgs = "OrderID=" & CStr(varOrderID)
'Retained for compatibility with the existing Form_Open event.
60 TempVars!OpenArgs = varOpenArgs
End If
End If
70 DoCmd.OpenForm _
FormName:="frmOrderDetails", _
View:=acNormal, _
DataMode:=acFormEdit, _
WindowMode:=acWindowNormal, _
OpenArgs:=varOpenArgs
Exit_Handler:
80 Exit Sub
Err_Handler:
90 MsgBox "Unable to open the order details form." & vbCrLf & _
"Error " & Err.Number & ": " & Err.Description, _
vbExclamation, "Open Order Details"
100 Resume Exit_Handler
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| AddPurchaseOrderDetail | Function | Public | () | 6 | 42 | handleerror, stringformatsql |
| CloseAllPurchaseOrderDetailsForms | Sub | Public | () | 49 | 25 | handleerror |
| ClosePurchaseOrderDetailsForm | Sub | Public | (frm As Form) | 74 | 31 | handleerror |
| OpenPurchaseOrderDetailsForm | Sub | Public | (Optional ByVal varPurchaseOrderID As Variant) | 105 | 32 | handleerror |
| ReorderProduct | Function | Public | () | 137 | 53 | addpurchaseorderdetail, handleerror, stringformat |
Public Function AddPurchaseOrderDetail(ByVal lngPurchaseOrderID As Long, ByVal lngProductID As Long _
, ByVal intQuantity As Integer, ByVal curUnitCost As Currency) As Long
10 On Error GoTo Err_Handler
Dim strSQL As String
Dim rs As DAO.Recordset
'Create the Purchase Order Line Item for this product: begin with an 0 or 1 Line Item recordset
20 strSQL = StringFormatSQL("SELECT PurchaseOrderDetailID, PurchaseOrderID, ProductID, Quantity, UnitCost" _
& " FROM PurchaseOrderDetails" _
& " WHERE PurchaseOrderID = {0} and ProductID = {1};", lngPurchaseOrderID, lngProductID)
30 Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
40 If rs.EOF Then
'Add new line.
50 rs.AddNew
60 rs!PurchaseOrderID = lngPurchaseOrderID
70 rs!ProductID = lngProductID
80 rs!Quantity = intQuantity
90 rs!UnitCost = curUnitCost
100 Else
'Line item already exists.
'BUSINESS RULE: Blindly add to the quantity that is already there.
110 rs.Edit
120 rs!Quantity = rs!Quantity + intQuantity
130 End If
140 rs.Update
'Retrieve the new ID
150 rs.Move 0, rs.LastModified
160 AddPurchaseOrderDetail = rs!PurchaseOrderDetailID
170 rs.Close
Exit_Handler:
180 Set rs = Nothing
190 Exit Function
Err_Handler:
200 clsErrorHandler.HandleError "modPurchaseOrders", "AddPurchaseOrderDetail"
210 Resume Exit_Handler
220 Resume
End FunctionPublic Sub CloseAllPurchaseOrderDetailsForms()
10 On Error GoTo Err_Handler
Dim intCount As Integer
Dim i As Integer
20 If Not g_colPurchaseOrderDetailsForms Is Nothing Then
30 intCount = g_colPurchaseOrderDetailsForms.count
40 For i = 1 To intCount
50 g_colPurchaseOrderDetailsForms.Remove 1
60 Next i
70 End If
80 Set g_colPurchaseOrderDetailsForms = Nothing
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError "modPurchaseOrders", "CloseAllPurchaseOrderDetailsForms"
110 Resume Exit_Handler
End Sub
'PURPOSE:
' Called from frmPurchaseOrderDetails.Form_Close to remove object from collection.Public Sub ClosePurchaseOrderDetailsForm(frm As Form)
10 On Error GoTo Err_Handler
Dim blnRemoved As Boolean
Dim intCount As Integer
Dim i As Integer
20 If g_colPurchaseOrderDetailsForms Is Nothing Then
'This may happen when the app is being shut down. Ignore it. We are on the way out anyway.
30 Else
40 intCount = g_colPurchaseOrderDetailsForms.count
50 For i = 1 To intCount
60 If g_colPurchaseOrderDetailsForms.Item(i).Hwnd = frm.Hwnd Then
70 g_colPurchaseOrderDetailsForms.Remove i
80 blnRemoved = True
90 Exit For
100 End If
110 Next i
'Debug.Assert blnRemoved 'This will assert if form was not opened using OpenPurchaseOrderDetailsForm.
120 End If
Exit_Handler:
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError "modPurchaseOrders", "ClosePurchaseOrderDetailsForm"
150 Resume Exit_Handler
End Sub
'PURPOSE:
' Support for opening multiple PurchaseOrderDetails forms.Public Sub OpenPurchaseOrderDetailsForm(Optional ByVal varPurchaseOrderID As Variant)
10 On Error GoTo Err_Handler
Dim frm As Form
20 If g_colPurchaseOrderDetailsForms Is Nothing Then Set g_colPurchaseOrderDetailsForms = New Collection
'Must set TempVars before creating New form, or it is too late.
30 If Not IsMissing(varPurchaseOrderID) Then TempVars!OpenArgs = "PurchaseOrderID=" & varPurchaseOrderID 'Make OpenArgs self-describing by using name=value pairs like a querystring. StringToDictionary function can be used to pick it apart.
40 Set frm = New Form_frmPurchaseOrderDetails
'Does not work: OpenArgs is readonly property. frm.OpenArgs = "OrderID=" & varPurchaseOrderID
50 frm.Visible = True
60 g_colPurchaseOrderDetailsForms.Add frm, CStr(frm.Hwnd)
'POSSIBLE IMPROVEMENT: if using overlapped windows: Move relative to previous item in the collection using frm.Move, Otherwise the windows are stacked exactly on top of each other.
70 Set frm = Nothing
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError "modPurchaseOrders", "OpenPurchaseOrderDetailsForm"
100 Resume Exit_Handler
End Sub
'PURPOSE:
' Creates new Purchase order and adds a line item.
'RETURNS:
' New Purchase Order IDPublic Function ReorderProduct(ByVal lngProductID As Long, ByVal lngVendorID As Long, _
ByVal intQuantity As Integer, ByVal curUnitCost As Currency) As Long
10 On Error GoTo Err_Handler
Dim strSQL As String
Dim rs As DAO.Recordset
Dim lngNewID As Long
Dim lngNewLineID As Long
20 ReorderProduct = 0
'Create a new Purchase Order and retrieve the PurchaseOrderID
'Note: "WHERE PurchaseOrderID = -1" ensures an empty recordset, to which we will add a new record.
30 strSQL = "SELECT PurchaseOrderID, VendorID, StatusID" _
& " FROM PurchaseOrders" _
& " WHERE PurchaseOrderID = -1;"
40 Debug.Print strSQL
50 Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
60 With rs
70 .AddNew
80 !VendorID = lngVendorID
90 !StatusID = enumPurchaseOrderStatus.posNew
100 .Update
'retrieve the new Purchase Order ID
110 .Move 0, .LastModified 'Alternative syntax: .Bookmark = .LastModified
120 lngNewID = !PurchaseOrderID
130 .Close
140 End With
150 ReorderProduct = lngNewID
160 lngNewLineID = AddPurchaseOrderDetail(lngNewID, lngProductID, intQuantity, curUnitCost)
170 If lngNewLineID = 0 Then
180 MsgBox StringFormat("Purchase Order {0} was created, but creating a line item for ProductID={1} failed." _
, lngNewLineID, lngProductID), vbExclamation Or vbOKOnly, "Line Item Fail"
190 End If
Exit_Handler:
200 Set rs = Nothing
210 Exit Function
Err_Handler:
220 clsErrorHandler.HandleError "modPurchaseOrders", "ReorderProduct"
230 Resume Exit_Handler
240 Resume
End FunctionOption Compare Database
Option Explicit
'RETURNS:
' Long - New line item ID value, or 0 if the line item could not be added.
Public Function AddPurchaseOrderDetail(ByVal lngPurchaseOrderID As Long, ByVal lngProductID As Long _
, ByVal intQuantity As Integer, ByVal curUnitCost As Currency) As Long
10 On Error GoTo Err_Handler
Dim strSQL As String
Dim rs As DAO.Recordset
'Create the Purchase Order Line Item for this product: begin with an 0 or 1 Line Item recordset
20 strSQL = StringFormatSQL("SELECT PurchaseOrderDetailID, PurchaseOrderID, ProductID, Quantity, UnitCost" _
& " FROM PurchaseOrderDetails" _
& " WHERE PurchaseOrderID = {0} and ProductID = {1};", lngPurchaseOrderID, lngProductID)
30 Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
40 If rs.EOF Then
'Add new line.
50 rs.AddNew
60 rs!PurchaseOrderID = lngPurchaseOrderID
70 rs!ProductID = lngProductID
80 rs!Quantity = intQuantity
90 rs!UnitCost = curUnitCost
100 Else
'Line item already exists.
'BUSINESS RULE: Blindly add to the quantity that is already there.
110 rs.Edit
120 rs!Quantity = rs!Quantity + intQuantity
130 End If
140 rs.Update
'Retrieve the new ID
150 rs.Move 0, rs.LastModified
160 AddPurchaseOrderDetail = rs!PurchaseOrderDetailID
170 rs.Close
Exit_Handler:
180 Set rs = Nothing
190 Exit Function
Err_Handler:
200 clsErrorHandler.HandleError "modPurchaseOrders", "AddPurchaseOrderDetail"
210 Resume Exit_Handler
220 Resume
End Function
Public Sub CloseAllPurchaseOrderDetailsForms()
10 On Error GoTo Err_Handler
Dim intCount As Integer
Dim i As Integer
20 If Not g_colPurchaseOrderDetailsForms Is Nothing Then
30 intCount = g_colPurchaseOrderDetailsForms.count
40 For i = 1 To intCount
50 g_colPurchaseOrderDetailsForms.Remove 1
60 Next i
70 End If
80 Set g_colPurchaseOrderDetailsForms = Nothing
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError "modPurchaseOrders", "CloseAllPurchaseOrderDetailsForms"
110 Resume Exit_Handler
End Sub
'PURPOSE:
' Called from frmPurchaseOrderDetails.Form_Close to remove object from collection.
Public Sub ClosePurchaseOrderDetailsForm(frm As Form)
10 On Error GoTo Err_Handler
Dim blnRemoved As Boolean
Dim intCount As Integer
Dim i As Integer
20 If g_colPurchaseOrderDetailsForms Is Nothing Then
'This may happen when the app is being shut down. Ignore it. We are on the way out anyway.
30 Else
40 intCount = g_colPurchaseOrderDetailsForms.count
50 For i = 1 To intCount
60 If g_colPurchaseOrderDetailsForms.Item(i).Hwnd = frm.Hwnd Then
70 g_colPurchaseOrderDetailsForms.Remove i
80 blnRemoved = True
90 Exit For
100 End If
110 Next i
'Debug.Assert blnRemoved 'This will assert if form was not opened using OpenPurchaseOrderDetailsForm.
120 End If
Exit_Handler:
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError "modPurchaseOrders", "ClosePurchaseOrderDetailsForm"
150 Resume Exit_Handler
End Sub
'PURPOSE:
' Support for opening multiple PurchaseOrderDetails forms.
Public Sub OpenPurchaseOrderDetailsForm(Optional ByVal varPurchaseOrderID As Variant)
10 On Error GoTo Err_Handler
Dim frm As Form
20 If g_colPurchaseOrderDetailsForms Is Nothing Then Set g_colPurchaseOrderDetailsForms = New Collection
'Must set TempVars before creating New form, or it is too late.
30 If Not IsMissing(varPurchaseOrderID) Then TempVars!OpenArgs = "PurchaseOrderID=" & varPurchaseOrderID 'Make OpenArgs self-describing by using name=value pairs like a querystring. StringToDictionary function can be used to pick it apart.
40 Set frm = New Form_frmPurchaseOrderDetails
'Does not work: OpenArgs is readonly property. frm.OpenArgs = "OrderID=" & varPurchaseOrderID
50 frm.Visible = True
60 g_colPurchaseOrderDetailsForms.Add frm, CStr(frm.Hwnd)
'POSSIBLE IMPROVEMENT: if using overlapped windows: Move relative to previous item in the collection using frm.Move, Otherwise the windows are stacked exactly on top of each other.
70 Set frm = Nothing
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError "modPurchaseOrders", "OpenPurchaseOrderDetailsForm"
100 Resume Exit_Handler
End Sub
'PURPOSE:
' Creates new Purchase order and adds a line item.
'RETURNS:
' New Purchase Order ID
Public Function ReorderProduct(ByVal lngProductID As Long, ByVal lngVendorID As Long, _
ByVal intQuantity As Integer, ByVal curUnitCost As Currency) As Long
10 On Error GoTo Err_Handler
Dim strSQL As String
Dim rs As DAO.Recordset
Dim lngNewID As Long
Dim lngNewLineID As Long
20 ReorderProduct = 0
'Create a new Purchase Order and retrieve the PurchaseOrderID
'Note: "WHERE PurchaseOrderID = -1" ensures an empty recordset, to which we will add a new record.
30 strSQL = "SELECT PurchaseOrderID, VendorID, StatusID" _
& " FROM PurchaseOrders" _
& " WHERE PurchaseOrderID = -1;"
40 Debug.Print strSQL
50 Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
60 With rs
70 .AddNew
80 !VendorID = lngVendorID
90 !StatusID = enumPurchaseOrderStatus.posNew
100 .Update
'retrieve the new Purchase Order ID
110 .Move 0, .LastModified 'Alternative syntax: .Bookmark = .LastModified
120 lngNewID = !PurchaseOrderID
130 .Close
140 End With
150 ReorderProduct = lngNewID
160 lngNewLineID = AddPurchaseOrderDetail(lngNewID, lngProductID, intQuantity, curUnitCost)
170 If lngNewLineID = 0 Then
180 MsgBox StringFormat("Purchase Order {0} was created, but creating a line item for ProductID={1} failed." _
, lngNewLineID, lngProductID), vbExclamation Or vbOKOnly, "Line Item Fail"
190 End If
Exit_Handler:
200 Set rs = Nothing
210 Exit Function
Err_Handler:
220 clsErrorHandler.HandleError "modPurchaseOrders", "ReorderProduct"
230 Resume Exit_Handler
240 Resume
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| reportParameterStartDate | Function | Public | () | 7 | 20 | handleerror, isformopen |
| reportParameterEndDate | Function | Public | () | 28 | 20 | handleerror, isformopen |
Public Function reportParameterStartDate() As Date
10 On Error GoTo Err_Handler
Dim datStart As Date
20 If IsFormOpen("frmReports") Then
30 datStart = Forms("frmReports").txtStartDate
40 Else
50 datStart = DateAdd("m", -3, DateValue(DMax("OrderDate", "Orders"))) 'Set the date range relative to the max order date.
60 End If
70 reportParameterStartDate = datStart
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modReportParameters", "reportParameterStartDate"
100 Resume Exit_Handler
End FunctionPublic Function reportParameterEndDate() As Date
10 On Error GoTo Err_Handler
Dim datEnd As Date
20 If IsFormOpen("frmReports") Then
30 datEnd = Forms("frmReports").txtEndDate
40 Else
50 datEnd = DateValue(DMax("OrderDate", "Orders")) 'Set the date range relative to the max order date.
60 End If
70 reportParameterEndDate = datEnd
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modReportParameters", "reportParameterEndDate"
100 Resume Exit_Handler
End FunctionOption Compare Database
Option Explicit
'Functions used to supply the report queries with parameter values. These work (and return default values) even if frmReports is not open.
'Alternatively we could have used TempVars.
Public Function reportParameterStartDate() As Date
10 On Error GoTo Err_Handler
Dim datStart As Date
20 If IsFormOpen("frmReports") Then
30 datStart = Forms("frmReports").txtStartDate
40 Else
50 datStart = DateAdd("m", -3, DateValue(DMax("OrderDate", "Orders"))) 'Set the date range relative to the max order date.
60 End If
70 reportParameterStartDate = datStart
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modReportParameters", "reportParameterStartDate"
100 Resume Exit_Handler
End Function
Public Function reportParameterEndDate() As Date
10 On Error GoTo Err_Handler
Dim datEnd As Date
20 If IsFormOpen("frmReports") Then
30 datEnd = Forms("frmReports").txtEndDate
40 Else
50 datEnd = DateValue(DMax("OrderDate", "Orders")) 'Set the date range relative to the max order date.
60 End If
70 reportParameterEndDate = datEnd
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modReportParameters", "reportParameterEndDate"
100 Resume Exit_Handler
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| ActivateTab | Sub | Public | (ByVal strControlID As String) | 10 | 19 | handleerror |
| cmdAbout_OnAction | Sub | Public | (ByVal control As Object) | 29 | 12 | handleerror |
| cmdAddOrder_OnAction | Sub | Public | (ByVal control As Object) | 42 | 12 | handleerror, openorderdetailsform |
| cmdAddPurchaseOrder_OnAction | Sub | Public | (ByVal control As Object) | 55 | 12 | handleerror, openpurchaseorderdetailsform |
| cmdAdmin_OnAction | Sub | Public | (ByVal control As Object) | 68 | 12 | handleerror |
| cmdCustomers_OnAction | Sub | Public | (ByVal control As Object) | 81 | 12 | handleerror |
| cmdEmployees_OnAction | Sub | Public | (ByVal control As Object) | 94 | 12 | handleerror |
| cmdExitApplication_OnAction | Sub | Public | (ByVal control As Object) | 107 | 12 | finish, handleerror |
| cmdExportToExcel_OnAction | Sub | Public | (ByVal control As Object) | 120 | 16 | handleerror |
| cmdFeatures_OnAction | Sub | Public | (ByVal control As Object) | 137 | 12 | handleerror |
| cmdLearn_OnAction | Sub | Public | (ByVal control As Object) | 150 | 12 | handleerror |
| cmdNorthwindDocumentation_OnAction | Sub | Public | (ByVal control As Object) | 163 | 12 | handleerror |
| cmdOrders_OnAction | Sub | Public | (ByVal control As Object) | 176 | 12 | handleerror |
| cmdProducts_OnAction | Sub | Public | (ByVal control As Object) | 189 | 12 | handleerror |
| cmdPurchaseOrders_OnAction | Sub | Public | (ByVal control As Object) | 202 | 12 | handleerror |
| cmdReports_OnAction | Sub | Public | (ByVal control As Object) | 215 | 15 | handleerror |
| ddMRU_GetItemCount | Sub | Public | (ByVal control As Object, ByRef count As Variant) | 230 | 28 | handleerror |
| ddMRU_GetItemID | Sub | Public | (ByVal control As Object, ByVal Index As Long, ByRef ID As Variant) | 258 | 21 | handleerror |
| ddMRU_GetItemLabel | Sub | Public | (ByVal control As Object, ByVal Index As Long, ByRef Label As Variant) | 279 | 42 | handleerror, stringformat |
| ddMRU_GetSelectedItemIndex | Sub | Public | (ByVal control As Object, ByRef Index As Variant) | 321 | 20 | — |
| ddMRU_OnAction | Sub | Public | (ByVal control As Object, ByVal selectedId As String, ByVal selectedIndex As Integer) | 341 | 24 | handleerror, openorderdetailsform, openpurchaseorderdetailsform |
| ddMRU_OnChange | Sub | Public | (ByVal control As Object, strText As String) | 366 | 12 | handleerror |
| gReportOptions_GetVisible | Sub | Public | (ByVal control As Object, ByRef Visible As Variant) | 379 | 15 | handleerror |
| RibbonFinish | Sub | Public | () | 394 | 13 | — |
| ribbonLoaded | Sub | Public | (ByVal ribbonUI As Object) 'As Office.IRibbonUI) | 407 | 13 | activatetab |
| Ribbon_RefreshMRU | Sub | Public | () | 421 | 16 | handleerror |
| Ribbon_ShowReportsGroup | Sub | Public | () | 438 | 17 | handleerror |
Public Sub ActivateTab(ByVal strControlID As String)
10 On Error GoTo Err_Handler
20 If m_Ribbon Is Nothing Then
'User may have Shift-loaded the app and the startup code did not run.
30 Else
40 m_Ribbon.ActivateTab strControlID
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modRibbonCallback", "ActivateTab"
80 Resume Exit_Handler
End Sub
'ARGUMENTS:
' control - Required parameter for OnAction callback function. Dead Code Review may find this item, but it needs to stay this way.Public Sub cmdAbout_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmAbout", , , , , acDialog Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAbout_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdAddOrder_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 OpenOrderDetailsForm Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAddOrder_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdAddPurchaseOrder_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 OpenPurchaseOrderDetailsForm Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAddPurchaseOrder_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdAdmin_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmAdmin" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAdmin_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdCustomers_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmCompanyList" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdCustomers_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdEmployees_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmEmployeeList" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdEmployees_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdExitApplication_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 Finish Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdExitApplication_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdExportToExcel_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 RunCommand acCmdExportExcel Exit_Handler: 30 Exit Sub Err_Handler: 40 If Err.Number = 2046 Then '2046: The command or action 'ExportExcel' isn't available now. 50 MsgBox "This feature requires an exportable object (such as a form) to be selected.", vbInformation 60 Else 70 clsErrorHandler.HandleError "modRibbonCallback", "cmdExportToExcel_OnAction" 80 End If 90 Resume Exit_Handler End Sub
Public Sub cmdFeatures_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmNorthwindFeatures" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdFeatures_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdLearn_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmLearn" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdLearn_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdNorthwindDocumentation_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 Application.FollowHyperlink "https://support.microsoft.com/topic/32eb79d2-bede-4ea4-b575-0714ca8dc1e2" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdNorthwindDocumentation_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdOrders_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmOrderList" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdOrders_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdProducts_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmProductList" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdProducts_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdPurchaseOrders_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmPurchaseOrderList" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdPurchaseOrders_OnAction" 50 Resume Exit_Handler End Sub
Public Sub cmdReports_OnAction(ByVal control As Object) 10 On Error GoTo Err_Handler 20 DoCmd.OpenForm "frmReports" Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "cmdReports_OnAction" 50 Resume Exit_Handler End Sub 'PURPOSE: ' Callback function assisting with populating list of users.
Public Sub ddMRU_GetItemCount(ByVal control As Object, ByRef count As Variant)
10 On Error GoTo Err_Handler
20 If m_rsMRU Is Nothing Then
30 Set m_rsMRU = CurrentDb.OpenRecordset("qryMRU", dbOpenDynaset) 'Dynaset because we may be deleting rows that no longer apply.
40 End If
50 With m_rsMRU
60 .Requery
70 If .RecordCount > 0 Then
80 .MoveLast
90 .MoveFirst
100 End If
110 count = Nz(m_rsMRU.RecordCount, 0)
120 End With
'Debug.Print Time$, "ddMRU_GetItemCount", control.ID, count
Exit_Handler:
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_GetItemCount"
150 Resume Exit_Handler
End Sub
'PURPOSE:
' Callback function to provide the hidden ID value for this Index position.Sub ddMRU_GetItemID(ByVal control As Object, ByVal Index As Long, ByRef ID As Variant)
10 On Error GoTo Err_Handler
20 If m_rsMRU.RecordCount > 0 Then
30 m_rsMRU.MoveFirst
40 m_rsMRU.Move Index
50 ID = m_rsMRU.Fields("MRU_ID")
60 End If
'Debug.Print Time$, "ddMRU_GetItemID", control.ID, Index, ID
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_GetItemID"
90 Resume Exit_Handler
End Sub
'PURPOSE:
' Callback function to provide the label to be shown at this Index position.Public Sub ddMRU_GetItemLabel(ByVal control As Object, ByVal Index As Long, ByRef Label As Variant)
10 On Error GoTo Err_Handler
Dim varCompanyID As Variant
20 If m_rsMRU.RecordCount > 0 Then
30 m_rsMRU.MoveFirst
40 m_rsMRU.Move Index
50 Select Case m_rsMRU!tableName
Case "Orders"
60 varCompanyID = DLookup("CustomerID", "Orders", "OrderID = " & m_rsMRU!PKValue)
70 If IsNull(varCompanyID) Then
80 m_rsMRU.Delete 'MRU record points to a no longer existing order.
90 Else
100 Label = StringFormat("Order {0}, {1}", m_rsMRU!PKValue, DLookup("CompanyName", "Companies", "CompanyID = " & varCompanyID))
110 End If
120 Case "PurchaseOrders"
130 varCompanyID = DLookup("VendorID", "PurchaseOrders", "PurchaseOrderID = " & m_rsMRU!PKValue)
140 If IsNull(varCompanyID) Then
150 m_rsMRU.Delete 'MRU record points to a no longer existing purchase order.
160 Else
170 Label = StringFormat("PO {0}, {1}", m_rsMRU!PKValue, DLookup("CompanyName", "Companies", "CompanyID = " & varCompanyID))
180 End If
190 Case Else
200 Debug.Assert False 'Support for this tablename not yet implemented.
210 End Select
220 End If
'Debug.Print Time$, "ddMRU_GetItemLabel", control.ID, Index, Label
Exit_Handler:
230 Exit Sub
Err_Handler:
240 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_GetItemLabel"
250 Resume Exit_Handler
End Sub
'PURPOSE:
' Supply default value for the MRU list.Public Sub ddMRU_GetSelectedItemIndex(ByVal control As Object, ByRef Index As Variant)
10 Index = 0 'Select first item in the list.
'If the active form is an OrderDetail or PurchaseOrderDetail form, select that item in the MRU list.
'This makes it easier to select from the MRU list, because user is likely to select the non-current item, and the desired Change event happens.
20 On Error Resume Next 'Just in case there is not be an active form.
30 If Screen.ActiveForm.Name = "frmOrderDetails" Then
40 m_rsMRU.FindFirst "PKValue = " & Screen.ActiveForm.OrderID
50 Index = m_rsMRU.AbsolutePosition
60 End If
70 If Screen.ActiveForm.Name = "frmPurchaseOrderDetails" Then
80 m_rsMRU.FindFirst "PKValue = " & Screen.ActiveForm.PurchaseOrderID
90 Index = m_rsMRU.AbsolutePosition
100 End If
'Debug.Print Time$, "ddMRU_GetSelectedItemIndex", control.ID, Index
End Sub
'PURPOSE:
' Event procedure that runs when a MRU list item is selected.Public Sub ddMRU_OnAction(ByVal control As Object, ByVal selectedId As String, ByVal selectedIndex As Integer)
10 On Error GoTo Err_Handler
20 m_rsMRU.FindFirst "MRU_ID = " & selectedId
30 Debug.Assert Not m_rsMRU.NoMatch 'If this asserts, a record that was added to the dropdown is no longer there.
40 Select Case m_rsMRU!tableName
Case "Orders"
50 OpenOrderDetailsForm m_rsMRU!PKValue
60 Case "PurchaseOrders"
70 OpenPurchaseOrderDetailsForm m_rsMRU!PKValue
80 Case Else
90 Debug.Assert False 'Support for this tablename not yet implemented.
100 End Select
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_OnAction"
130 Resume Exit_Handler
End SubPublic Sub ddMRU_OnChange(ByVal control As Object, strText As String) 10 On Error GoTo Err_Handler 20 Debug.Print Time$, "ddMRU_OnChange", strText Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_OnChange" 50 Resume Exit_Handler End Sub
Sub gReportOptions_GetVisible(ByVal control As Object, ByRef Visible As Variant) 10 On Error GoTo Err_Handler 20 Visible = (Reports.count > 0) Exit_Handler: 30 Exit Sub Err_Handler: 40 clsErrorHandler.HandleError "modRibbonCallback", "gReportOptions_GetVisible" 50 Resume Exit_Handler End Sub 'NOTE: ' This is not a callback function, but still ribbon-related.
Public Sub RibbonFinish() 10 On Error Resume Next 'Just in case the recordset is not open. 20 m_rsMRU.Close 30 Set m_rsMRU = Nothing End Sub 'PROCEDURE: ' ribbonLoaded 'PURPOSE: ' Cache the ribbonUI object for later use, for example when we want to invalidate it. ' Called by the onLoad method of the customUI node of the ribbon XML. 'ARGUMENTS: ' ribbonUI - Ribbon object.
Public Sub ribbonLoaded(ByVal ribbonUI As Object) 'As Office.IRibbonUI) 10 On Error GoTo Err_Handler 20 Set m_Ribbon = ribbonUI 30 ActivateTab "tHome" Exit_Handler: 40 Exit Sub Err_Handler: '50 clsErrorHandler.HandleError "modRibbonCallback", "ribbonLoaded" 60 Resume Exit_Handler End Sub
Public Sub Ribbon_RefreshMRU()
10 On Error GoTo Err_Handler
20 If m_Ribbon Is Nothing Then
'User may have Shift-loaded the app and the startup code did not run.
30 Else
40 m_Ribbon.InvalidateControl "ddMRU"
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modRibbonCallback", "Ribbon_RefreshMRU"
80 Resume Exit_Handler
End SubPublic Sub Ribbon_ShowReportsGroup()
10 On Error GoTo Err_Handler
20 If m_Ribbon Is Nothing Then
'User may have Shift-loaded the app and the startup code did not run.
30 Else
40 m_Ribbon.InvalidateControl "gReportOptions"
'After InvalidateControl, the group control will call gReportOptions_GetVisible.
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modRibbonCallback", "Ribbon_ShowReportsGroup"
80 Resume Exit_Handler
End SubOption Compare Database
Option Explicit
'This module contains functions that are called by the Ribbon.
Private m_Ribbon As Object 'Office.IRibbonUI 'Requires reference to Microsoft Office 16.0 Object Library (mso.dll).
Private m_rsMRU As DAO.Recordset
'
Public Sub ActivateTab(ByVal strControlID As String)
10 On Error GoTo Err_Handler
20 If m_Ribbon Is Nothing Then
'User may have Shift-loaded the app and the startup code did not run.
30 Else
40 m_Ribbon.ActivateTab strControlID
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modRibbonCallback", "ActivateTab"
80 Resume Exit_Handler
End Sub
'ARGUMENTS:
' control - Required parameter for OnAction callback function. Dead Code Review may find this item, but it needs to stay this way.
Public Sub cmdAbout_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmAbout", , , , , acDialog
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAbout_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdAddOrder_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 OpenOrderDetailsForm
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAddOrder_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdAddPurchaseOrder_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 OpenPurchaseOrderDetailsForm
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAddPurchaseOrder_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdAdmin_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmAdmin"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdAdmin_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdCustomers_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmCompanyList"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdCustomers_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdEmployees_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmEmployeeList"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdEmployees_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdExitApplication_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 Finish
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdExitApplication_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdExportToExcel_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 RunCommand acCmdExportExcel
Exit_Handler:
30 Exit Sub
Err_Handler:
40 If Err.Number = 2046 Then '2046: The command or action 'ExportExcel' isn't available now.
50 MsgBox "This feature requires an exportable object (such as a form) to be selected.", vbInformation
60 Else
70 clsErrorHandler.HandleError "modRibbonCallback", "cmdExportToExcel_OnAction"
80 End If
90 Resume Exit_Handler
End Sub
Public Sub cmdFeatures_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmNorthwindFeatures"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdFeatures_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdLearn_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmLearn"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdLearn_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdNorthwindDocumentation_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 Application.FollowHyperlink "https://support.microsoft.com/topic/32eb79d2-bede-4ea4-b575-0714ca8dc1e2"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdNorthwindDocumentation_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdOrders_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmOrderList"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdOrders_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdProducts_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmProductList"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdProducts_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdPurchaseOrders_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmPurchaseOrderList"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdPurchaseOrders_OnAction"
50 Resume Exit_Handler
End Sub
Public Sub cmdReports_OnAction(ByVal control As Object)
10 On Error GoTo Err_Handler
20 DoCmd.OpenForm "frmReports"
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "cmdReports_OnAction"
50 Resume Exit_Handler
End Sub
'PURPOSE:
' Callback function assisting with populating list of users.
Public Sub ddMRU_GetItemCount(ByVal control As Object, ByRef count As Variant)
10 On Error GoTo Err_Handler
20 If m_rsMRU Is Nothing Then
30 Set m_rsMRU = CurrentDb.OpenRecordset("qryMRU", dbOpenDynaset) 'Dynaset because we may be deleting rows that no longer apply.
40 End If
50 With m_rsMRU
60 .Requery
70 If .RecordCount > 0 Then
80 .MoveLast
90 .MoveFirst
100 End If
110 count = Nz(m_rsMRU.RecordCount, 0)
120 End With
'Debug.Print Time$, "ddMRU_GetItemCount", control.ID, count
Exit_Handler:
130 Exit Sub
Err_Handler:
140 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_GetItemCount"
150 Resume Exit_Handler
End Sub
'PURPOSE:
' Callback function to provide the hidden ID value for this Index position.
Sub ddMRU_GetItemID(ByVal control As Object, ByVal Index As Long, ByRef ID As Variant)
10 On Error GoTo Err_Handler
20 If m_rsMRU.RecordCount > 0 Then
30 m_rsMRU.MoveFirst
40 m_rsMRU.Move Index
50 ID = m_rsMRU.Fields("MRU_ID")
60 End If
'Debug.Print Time$, "ddMRU_GetItemID", control.ID, Index, ID
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_GetItemID"
90 Resume Exit_Handler
End Sub
'PURPOSE:
' Callback function to provide the label to be shown at this Index position.
Public Sub ddMRU_GetItemLabel(ByVal control As Object, ByVal Index As Long, ByRef Label As Variant)
10 On Error GoTo Err_Handler
Dim varCompanyID As Variant
20 If m_rsMRU.RecordCount > 0 Then
30 m_rsMRU.MoveFirst
40 m_rsMRU.Move Index
50 Select Case m_rsMRU!tableName
Case "Orders"
60 varCompanyID = DLookup("CustomerID", "Orders", "OrderID = " & m_rsMRU!PKValue)
70 If IsNull(varCompanyID) Then
80 m_rsMRU.Delete 'MRU record points to a no longer existing order.
90 Else
100 Label = StringFormat("Order {0}, {1}", m_rsMRU!PKValue, DLookup("CompanyName", "Companies", "CompanyID = " & varCompanyID))
110 End If
120 Case "PurchaseOrders"
130 varCompanyID = DLookup("VendorID", "PurchaseOrders", "PurchaseOrderID = " & m_rsMRU!PKValue)
140 If IsNull(varCompanyID) Then
150 m_rsMRU.Delete 'MRU record points to a no longer existing purchase order.
160 Else
170 Label = StringFormat("PO {0}, {1}", m_rsMRU!PKValue, DLookup("CompanyName", "Companies", "CompanyID = " & varCompanyID))
180 End If
190 Case Else
200 Debug.Assert False 'Support for this tablename not yet implemented.
210 End Select
220 End If
'Debug.Print Time$, "ddMRU_GetItemLabel", control.ID, Index, Label
Exit_Handler:
230 Exit Sub
Err_Handler:
240 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_GetItemLabel"
250 Resume Exit_Handler
End Sub
'PURPOSE:
' Supply default value for the MRU list.
Public Sub ddMRU_GetSelectedItemIndex(ByVal control As Object, ByRef Index As Variant)
10 Index = 0 'Select first item in the list.
'If the active form is an OrderDetail or PurchaseOrderDetail form, select that item in the MRU list.
'This makes it easier to select from the MRU list, because user is likely to select the non-current item, and the desired Change event happens.
20 On Error Resume Next 'Just in case there is not be an active form.
30 If Screen.ActiveForm.Name = "frmOrderDetails" Then
40 m_rsMRU.FindFirst "PKValue = " & Screen.ActiveForm.OrderID
50 Index = m_rsMRU.AbsolutePosition
60 End If
70 If Screen.ActiveForm.Name = "frmPurchaseOrderDetails" Then
80 m_rsMRU.FindFirst "PKValue = " & Screen.ActiveForm.PurchaseOrderID
90 Index = m_rsMRU.AbsolutePosition
100 End If
'Debug.Print Time$, "ddMRU_GetSelectedItemIndex", control.ID, Index
End Sub
'PURPOSE:
' Event procedure that runs when a MRU list item is selected.
Public Sub ddMRU_OnAction(ByVal control As Object, ByVal selectedId As String, ByVal selectedIndex As Integer)
10 On Error GoTo Err_Handler
20 m_rsMRU.FindFirst "MRU_ID = " & selectedId
30 Debug.Assert Not m_rsMRU.NoMatch 'If this asserts, a record that was added to the dropdown is no longer there.
40 Select Case m_rsMRU!tableName
Case "Orders"
50 OpenOrderDetailsForm m_rsMRU!PKValue
60 Case "PurchaseOrders"
70 OpenPurchaseOrderDetailsForm m_rsMRU!PKValue
80 Case Else
90 Debug.Assert False 'Support for this tablename not yet implemented.
100 End Select
Exit_Handler:
110 Exit Sub
Err_Handler:
120 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_OnAction"
130 Resume Exit_Handler
End Sub
Public Sub ddMRU_OnChange(ByVal control As Object, strText As String)
10 On Error GoTo Err_Handler
20 Debug.Print Time$, "ddMRU_OnChange", strText
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "ddMRU_OnChange"
50 Resume Exit_Handler
End Sub
Sub gReportOptions_GetVisible(ByVal control As Object, ByRef Visible As Variant)
10 On Error GoTo Err_Handler
20 Visible = (Reports.count > 0)
Exit_Handler:
30 Exit Sub
Err_Handler:
40 clsErrorHandler.HandleError "modRibbonCallback", "gReportOptions_GetVisible"
50 Resume Exit_Handler
End Sub
'NOTE:
' This is not a callback function, but still ribbon-related.
Public Sub RibbonFinish()
10 On Error Resume Next 'Just in case the recordset is not open.
20 m_rsMRU.Close
30 Set m_rsMRU = Nothing
End Sub
'PROCEDURE:
' ribbonLoaded
'PURPOSE:
' Cache the ribbonUI object for later use, for example when we want to invalidate it.
' Called by the onLoad method of the customUI node of the ribbon XML.
'ARGUMENTS:
' ribbonUI - Ribbon object.
Public Sub ribbonLoaded(ByVal ribbonUI As Object) 'As Office.IRibbonUI)
10 On Error GoTo Err_Handler
20 Set m_Ribbon = ribbonUI
30 ActivateTab "tHome"
Exit_Handler:
40 Exit Sub
Err_Handler:
'50 clsErrorHandler.HandleError "modRibbonCallback", "ribbonLoaded"
60 Resume Exit_Handler
End Sub
Public Sub Ribbon_RefreshMRU()
10 On Error GoTo Err_Handler
20 If m_Ribbon Is Nothing Then
'User may have Shift-loaded the app and the startup code did not run.
30 Else
40 m_Ribbon.InvalidateControl "ddMRU"
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modRibbonCallback", "Ribbon_RefreshMRU"
80 Resume Exit_Handler
End Sub
Public Sub Ribbon_ShowReportsGroup()
10 On Error GoTo Err_Handler
20 If m_Ribbon Is Nothing Then
'User may have Shift-loaded the app and the startup code did not run.
30 Else
40 m_Ribbon.InvalidateControl "gReportOptions"
'After InvalidateControl, the group control will call gReportOptions_GetVisible.
50 End If
Exit_Handler:
60 Exit Sub
Err_Handler:
70 clsErrorHandler.HandleError "modRibbonCallback", "Ribbon_ShowReportsGroup"
80 Resume Exit_Handler
End Sub| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| HasPrivilege | Function | Public | (ByVal p As enumPrivileges) | 10 | 12 | get_userid, handleerror |
Public Function HasPrivilege(ByVal p As enumPrivileges) As Boolean
10 On Error GoTo Err_Handler
20 HasPrivilege = Not IsNull(DLookup("EmployeePrivilegeID", "EmployeePrivileges", "EmployeeID = " & Get_UserID() & " AND PrivilegeID = " & p))
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modSecurity", "HasPrivilege"
50 Resume Exit_Handler
End FunctionOption Compare Database
Option Explicit
'PURPOSE:
' Previously, returns true if the current user has been assigned any privilege.
' Currently, only one privilege exists: approve Purchase Orders
' If additional privileges are created, additional validation will be required
' Check specific privilege requested
'
Public Function HasPrivilege(ByVal p As enumPrivileges) As Boolean
10 On Error GoTo Err_Handler
20 HasPrivilege = Not IsNull(DLookup("EmployeePrivilegeID", "EmployeePrivileges", "EmployeeID = " & Get_UserID() & " AND PrivilegeID = " & p))
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modSecurity", "HasPrivilege"
50 Resume Exit_Handler
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| CloseAllForms | Sub | Public | () | 11 | 16 | handleerror |
| CloseAllReports | Sub | Public | () | 28 | 19 | handleerror |
| Finish | Sub | Public | () | 47 | 13 | closeallforms, closeallorderdetailsforms, closeallpurchaseorderdetailsforms, closeallreports, ribbonfinish |
| GetSystemSetting | Function | Public | (ByVal SystemSettingID As enumSystemSettings) | 61 | 28 | handleerror |
| GetUserSetting | Function | Public | (ByVal UserSettingID As enumUserSettings) | 90 | 12 | handleerror |
| SaveSystemSetting | Sub | Public | (ByVal SystemSettingID As enumSystemSettings, ByVal varValue As Variant) | 103 | 21 | g_dbapp, handleerror, stringformatsql, toaccessdate |
| SaveUserSetting | Sub | Public | (ByVal UserSettingID As enumUserSettings, ByVal varValue As Variant) | 125 | 15 | g_dbapp, handleerror, stringformatsql |
| SetAppTitle | Sub | Public | (ByVal bolIncludeUserName As Boolean) | 141 | 21 | get_employeefnln, get_userid, handleerror |
| Startup | Function | Public | () | 162 | 34 | getsystemsetting, handleerror, initializeuser, onetimeprocessing, setapptitle |
Public Sub CloseAllForms()
10 On Error GoTo Err_Handler
Dim frm As AccessObject
20 For Each frm In CurrentProject.AllForms
30 If frm.IsLoaded Then DoCmd.Close acForm, frm.Name, acSaveNo
40 Next frm
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError "modStartup", "CloseAllForms"
70 Resume Exit_Handler
End SubPublic Sub CloseAllReports()
10 On Error GoTo Err_Handler
Dim rpt As AccessObject
20 For Each rpt In CurrentProject.AllReports
30 If rpt.IsLoaded Then DoCmd.Close acReport, rpt.Name, acSaveNo
40 Next rpt
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError "modStartup", "CloseAllReports"
70 Resume Exit_Handler
End Sub
'PURPOSE:
' The opposite of Startup. We are on our way out and want to do some cleanup before we exit for real.Public Sub Finish() 10 On Error Resume Next 'We are on the way out and don't want to be bothered with error messages. 20 CloseAllOrderDetailsForms 30 CloseAllPurchaseOrderDetailsForms 40 CloseAllReports 50 CloseAllForms 60 RibbonFinish 70 Application.Quit acQuitSaveNone End Sub
Public Function GetSystemSetting(ByVal SystemSettingID As enumSystemSettings) As Variant
10 On Error GoTo Err_Handler
Dim v As Variant
20 v = DLookup("SettingValue", "SystemSettings", "SettingID = " & SystemSettingID)
'Conversion to support regional settings.
30 Select Case SystemSettingID
Case enumSystemSettings.ssTaxRate, enumSystemSettings.ssTaxRate_Vendors
40 v = CSng(v / 1000) 'Divide by 1000 to get Single value. See comment in table SystemSettings.
50 Case enumSystemSettings.ssLastResetDate
60 v = CDate(v)
70 Case enumSystemSettings.ssFirstTimeRun, enumSystemSettings.ssShowWelcome
80 v = CBool(v)
90 Case Else
100 Debug.Assert False 'Unexpected SystemSettingsID passed in.
110 End Select
Exit_Handler:
120 GetSystemSetting = v
130 Exit Function
Err_Handler:
140 clsErrorHandler.HandleError "modStartup", "GetSystemSetting"
150 Resume Exit_Handler
160 Resume
End FunctionPublic Function GetUserSetting(ByVal UserSettingID As enumUserSettings) As Variant
10 On Error GoTo Err_Handler
20 GetUserSetting = DLookup("SettingValue", "UserSettings", "SettingID = " & UserSettingID)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modStartup", "GetUserSetting"
50 Resume Exit_Handler
End FunctionPublic Sub SaveSystemSetting(ByVal SystemSettingID As enumSystemSettings, ByVal varValue As Variant)
10 On Error GoTo Err_Handler
Dim sql As String
'Conversion to support regional settings.
20 Select Case SystemSettingID
Case enumSystemSettings.ssLastResetDate
30 varValue = ToAccessDate(varValue)
40 End Select
50 sql = StringFormatSQL("Update SystemSettings set SettingValue = {0} where SettingID = {1};", varValue, SystemSettingID)
60 g_dbApp().Execute sql, dbFailOnError
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError "modStartup", "SaveSystemSetting"
90 Resume Exit_Handler
End SubPublic Sub SaveUserSetting(ByVal UserSettingID As enumUserSettings, ByVal varValue As Variant)
10 On Error GoTo Err_Handler
Dim sql As String
20 sql = StringFormatSQL("Update UserSettings set SettingValue = {0} where SettingID = {1};", varValue, UserSettingID)
30 g_dbApp().Execute sql, dbFailOnError
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError "modStartup", "SaveUserSetting"
60 Resume Exit_Handler
End SubPublic Sub SetAppTitle(ByVal bolIncludeUserName As Boolean)
10 On Error GoTo Err_Handler
20 If bolIncludeUserName = False Then
30 CurrentDb.Properties("AppTitle") = g_strAppName & Space(2) & APP_VERSION
40 Else
50 CurrentDb.Properties("AppTitle") = g_strAppName & Space(2) & APP_VERSION & Space(5) & Get_EmployeeFNLN(Get_UserID())
60 End If
70 RefreshTitleBar
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError "modStartup", "SetAppTitle"
100 Resume Exit_Handler
End Sub
'PURPOSE
' Called from AutoExec macro to start the application.Public Function Startup()
10 On Error GoTo Err_Handler
Dim varShowWelcome As Variant
20 Application.SetOption "Error Trapping", 2 'AddDataMacros calls HasField, which will fail if Error Trapping is set to "Break on all errors.". The setting is in VBA window > Tools > Options > General.
'Set the Application main window Title
30 modStartup.SetAppTitle False
40 OneTimeProcessing
'Show the Welcome form
50 varShowWelcome = GetSystemSetting(ssShowWelcome)
60 If varShowWelcome = True Then
70 DoCmd.OpenForm "frmWelcome", acNormal, , , , acDialog
80 End If
90 InitializeUser
100 SetAppTitle True
'Too soon. ribbonLoaded is a better location anyway. ActivateTab "tHome"
110 DoCmd.OpenForm "frmOrderList" 'Open the main form, rather than having the user do it.
Exit_Handler:
120 Exit Function
Err_Handler:
130 clsErrorHandler.HandleError "modStartup", "Startup", True
140 Resume Exit_Handler
150 Resume
End FunctionOption Compare Database
Option Explicit
'NOTE:
' The VBA code uses line numbers, so the error handler can report on which line the error occurred.
' If you want to remove them, search online for "Remove line numbers in VBA" and you can find the code to do so.
Public Const g_strAppName As String = "Northwind Traders Developer Edition"
Public Const g_dtNorthwindInception As Date = #11/1/2022#
Public Sub CloseAllForms()
10 On Error GoTo Err_Handler
Dim frm As AccessObject
20 For Each frm In CurrentProject.AllForms
30 If frm.IsLoaded Then DoCmd.Close acForm, frm.Name, acSaveNo
40 Next frm
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError "modStartup", "CloseAllForms"
70 Resume Exit_Handler
End Sub
Public Sub CloseAllReports()
10 On Error GoTo Err_Handler
Dim rpt As AccessObject
20 For Each rpt In CurrentProject.AllReports
30 If rpt.IsLoaded Then DoCmd.Close acReport, rpt.Name, acSaveNo
40 Next rpt
Exit_Handler:
50 Exit Sub
Err_Handler:
60 clsErrorHandler.HandleError "modStartup", "CloseAllReports"
70 Resume Exit_Handler
End Sub
'PURPOSE:
' The opposite of Startup. We are on our way out and want to do some cleanup before we exit for real.
Public Sub Finish()
10 On Error Resume Next 'We are on the way out and don't want to be bothered with error messages.
20 CloseAllOrderDetailsForms
30 CloseAllPurchaseOrderDetailsForms
40 CloseAllReports
50 CloseAllForms
60 RibbonFinish
70 Application.Quit acQuitSaveNone
End Sub
Public Function GetSystemSetting(ByVal SystemSettingID As enumSystemSettings) As Variant
10 On Error GoTo Err_Handler
Dim v As Variant
20 v = DLookup("SettingValue", "SystemSettings", "SettingID = " & SystemSettingID)
'Conversion to support regional settings.
30 Select Case SystemSettingID
Case enumSystemSettings.ssTaxRate, enumSystemSettings.ssTaxRate_Vendors
40 v = CSng(v / 1000) 'Divide by 1000 to get Single value. See comment in table SystemSettings.
50 Case enumSystemSettings.ssLastResetDate
60 v = CDate(v)
70 Case enumSystemSettings.ssFirstTimeRun, enumSystemSettings.ssShowWelcome
80 v = CBool(v)
90 Case Else
100 Debug.Assert False 'Unexpected SystemSettingsID passed in.
110 End Select
Exit_Handler:
120 GetSystemSetting = v
130 Exit Function
Err_Handler:
140 clsErrorHandler.HandleError "modStartup", "GetSystemSetting"
150 Resume Exit_Handler
160 Resume
End Function
Public Function GetUserSetting(ByVal UserSettingID As enumUserSettings) As Variant
10 On Error GoTo Err_Handler
20 GetUserSetting = DLookup("SettingValue", "UserSettings", "SettingID = " & UserSettingID)
Exit_Handler:
30 Exit Function
Err_Handler:
40 clsErrorHandler.HandleError "modStartup", "GetUserSetting"
50 Resume Exit_Handler
End Function
Public Sub SaveSystemSetting(ByVal SystemSettingID As enumSystemSettings, ByVal varValue As Variant)
10 On Error GoTo Err_Handler
Dim sql As String
'Conversion to support regional settings.
20 Select Case SystemSettingID
Case enumSystemSettings.ssLastResetDate
30 varValue = ToAccessDate(varValue)
40 End Select
50 sql = StringFormatSQL("Update SystemSettings set SettingValue = {0} where SettingID = {1};", varValue, SystemSettingID)
60 g_dbApp().Execute sql, dbFailOnError
Exit_Handler:
70 Exit Sub
Err_Handler:
80 clsErrorHandler.HandleError "modStartup", "SaveSystemSetting"
90 Resume Exit_Handler
End Sub
Public Sub SaveUserSetting(ByVal UserSettingID As enumUserSettings, ByVal varValue As Variant)
10 On Error GoTo Err_Handler
Dim sql As String
20 sql = StringFormatSQL("Update UserSettings set SettingValue = {0} where SettingID = {1};", varValue, UserSettingID)
30 g_dbApp().Execute sql, dbFailOnError
Exit_Handler:
40 Exit Sub
Err_Handler:
50 clsErrorHandler.HandleError "modStartup", "SaveUserSetting"
60 Resume Exit_Handler
End Sub
Public Sub SetAppTitle(ByVal bolIncludeUserName As Boolean)
10 On Error GoTo Err_Handler
20 If bolIncludeUserName = False Then
30 CurrentDb.Properties("AppTitle") = g_strAppName & Space(2) & APP_VERSION
40 Else
50 CurrentDb.Properties("AppTitle") = g_strAppName & Space(2) & APP_VERSION & Space(5) & Get_EmployeeFNLN(Get_UserID())
60 End If
70 RefreshTitleBar
Exit_Handler:
80 Exit Sub
Err_Handler:
90 clsErrorHandler.HandleError "modStartup", "SetAppTitle"
100 Resume Exit_Handler
End Sub
'PURPOSE
' Called from AutoExec macro to start the application.
Public Function Startup()
10 On Error GoTo Err_Handler
Dim varShowWelcome As Variant
20 Application.SetOption "Error Trapping", 2 'AddDataMacros calls HasField, which will fail if Error Trapping is set to "Break on all errors.". The setting is in VBA window > Tools > Options > General.
'Set the Application main window Title
30 modStartup.SetAppTitle False
40 OneTimeProcessing
'Show the Welcome form
50 varShowWelcome = GetSystemSetting(ssShowWelcome)
60 If varShowWelcome = True Then
70 DoCmd.OpenForm "frmWelcome", acNormal, , , , acDialog
80 End If
90 InitializeUser
100 SetAppTitle True
'Too soon. ribbonLoaded is a better location anyway. ActivateTab "tHome"
110 DoCmd.OpenForm "frmOrderList" 'Open the main form, rather than having the user do it.
Exit_Handler:
120 Exit Function
Err_Handler:
130 clsErrorHandler.HandleError "modStartup", "Startup", True
140 Resume Exit_Handler
150 Resume
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| GetString | Function | Public | (ByVal ID As enumStrings, ParamArray params() As Variant) | 61 | 30 | handleerror, stringformat |
| StringFormat | Function | Public | (ByVal s As String, ParamArray params() As Variant) | 91 | 30 | handleerror |
| StringFormatSQL | Function | Public | (ByVal s As String, ParamArray params() As Variant) | 121 | 64 | handleerror, stringformat, toaccessdate |
| StringToDictionary | Function | Public | (ByVal v As Variant) As Scripting.Dictionary 'Requires reference to Microsoft Scripting Runtime (scrrun.dll) | 185 | 37 | handleerror |
Public Function GetString(ByVal ID As enumStrings, ParamArray params() As Variant) As String
10 On Error GoTo Err_Handler
Dim s As String
20 s = Nz(DLookup("StringData", "Strings", "StringID = " & ID), "")
30 Debug.Assert s <> ""
40 s = StringFormat(s, params)
50 GetString = s
Exit_Handler:
60 Exit Function
Err_Handler:
70 clsErrorHandler.HandleError "modStrings", "GetString"
80 Resume Exit_Handler
End Function
'NOTES:
' Patterned after String.Format in .NET.
' https://docs.microsoft.com/dotnet/api/system.string.format
' Advantage of this function over traditional string concatenation is that you can focus on the string itself, what you want it to say.
' Also makes it easier to use strings from a table (see GetString function).
'EXAMPLES:
' Debug.Print StringFormat("Hello {0}. This is {1}.", "world", "ET")
' => Hello world. This is ET.
'ARGUMENTS:
' s - String with zero or more {n} placeholders for parameter values. The first one is {0}.
' params - Zero or more parameters to replace the placeholders. Can also handle a paramarray that was passed in from another function taking a paramarray (e.g. GetString).Public Function StringFormat(ByVal s As String, ParamArray params() As Variant) As String
10 On Error GoTo Err_Handler
Dim n As Integer
Dim vParams As Variant
20 If UBound(params) = -1 Then GoTo Exit_Handler 'Zero params passed in.
30 If IsArray(params) And IsArray(params(0)) Then
40 vParams = params(0)
50 Else
60 vParams = params
70 End If
80 For n = 0 To UBound(vParams)
90 s = Replace(s, "{" & n & "}", vParams(n))
100 Next n
Exit_Handler:
110 StringFormat = s
120 Exit Function
Err_Handler:
130 clsErrorHandler.HandleError "modStrings", "StringFormat"
140 Resume Exit_Handler
End Function
'PURPOSE:
' Format a string using Access SQL rules.
'NOTES:
' Better than built-in function Application.BuildCriteria which has some unexpected side-effects.Public Function StringFormatSQL(ByVal s As String, ParamArray params() As Variant) As String
10 On Error GoTo Err_Handler
Dim i As Integer
Dim vParams As Variant
20 If IsArray(params) And IsArray(params(0)) Then
30 vParams = params(0)
40 Else
50 vParams = params
60 End If
70 For i = LBound(vParams) To UBound(vParams)
80 If IsNull(vParams(i)) Then
90 vParams(i) = Nz(vParams(i), "NULL")
100 Else
'NW 2.0 code to be replaced below.
' Select Case VarType(vParams(i))
' Case vbString:
' vParams(i) = "'" & vParams(i) & "'"
' Case vbDate:
' vParams(i) = "#" & vParams(i) & "#"
' End Select
'NW 2.2 code will convert international number and date formats to those understood by Access.
'We also escape string arguments, in case an argument includes an embedded single-quote (think: ...where LastName = 'O'Brien")
110 Select Case VarType(vParams(i))
Case vbCurrency, vbSingle, vbDouble
120 vParams(i) = LTrim(Str(vParams(i))) 'Str converts regional numbers to Access standards.
130 Case vbString:
140 vParams(i) = SINGLE_QUOTE & Replace(vParams(i), SINGLE_QUOTE, TWO_SINGLE_QUOTES) & SINGLE_QUOTE
150 Case vbDate:
160 vParams(i) = "#" & ToAccessDate(vParams(i)) & "#" 'ToAccessDate ensures this works for all regional settings.
170 End Select
180 End If
190 Next i
200 StringFormatSQL = StringFormat(s, vParams)
Exit_Handler:
210 Exit Function
Err_Handler:
220 clsErrorHandler.HandleError "modStrings", "StringFormatSQL"
230 Resume Exit_Handler
240 Resume
End Function
' NOTE:
' Caller is responsible for cleaning up the dictionary object returned. Example:
' Dim dict as Scripting.Dictionary
' Set dict = StringToDictionary("a=1&b=2")
' 'Use the dictionary object
' Set dict = Nothing 'Cleanup.
' NOTE 2:
' Note the proper syntax for calling a function that returns an object is by using Set:
' Set dict = StringToDictionary(...)
' ARGUMENTS:
' s - String in querystring format (e.g. "key1=value1&key2=value2&key3=value3"
' If a key contains an embedded equals sign or ampersand, you may want to call UrlEncode/UrlDecode (code not included in this template).
' RETURNS:
' Scripting.Dictionary object with the parsed values.Public Function StringToDictionary(ByVal v As Variant) As Scripting.Dictionary 'Requires reference to Microsoft Scripting Runtime (scrrun.dll)
10 On Error GoTo Err_Handler
Const KEYVALUE_DELIMITER As String = "&"
Const VALUE_DELIMITER As String = "="
Dim dict As New Scripting.Dictionary
Dim intPos As Integer
Dim strTokens() As String
Dim varToken As Variant
20 If IsNull(v) Then
'Nothing to do.
30 Else
40 dict.CompareMode = vbTextCompare
50 strTokens = Split(v, KEYVALUE_DELIMITER)
60 For Each varToken In strTokens
70 intPos = InStr(varToken, VALUE_DELIMITER)
80 If intPos = 0 Then
'it's a token without an = sign
90 Else
100 dict.Add Left$(varToken, intPos - 1), Mid$(varToken, intPos + 1)
110 End If
120 Next varToken
130 Erase strTokens
140 End If
150 Set StringToDictionary = dict
Exit_Handler:
160 Exit Function
Err_Handler:
170 clsErrorHandler.HandleError "modStrings", "StringToDictionary"
180 Resume Exit_Handler
End FunctionOption Compare Database
Option Explicit
Public Enum enumStrings 'Corresponds to StringID values in table Strings
sHelloWorld = 1 'NOTE: the "s" = "Strings" prefix ensures there are no Reserved words in the Enum element names.
sNumberBetween = 2
sOrderMustBePaid = 4
sOrderClosed = 5
sOrderCannotDelete = 6
sDeleteRecord = 7
sRequiredFields = 8
sRequiredFields_Shipping = 9
sOrderMustBeInvoiced = 10
sReportNoData = 11
sNewEmployee = 12
sEmployeeRestraints = 13
sDeleteEmployee = 14
sInvalidPhone = 15
sDisclaimer = 16
sOrderAllocated = 17
sAlreadyOnNewRecord = 18
sNoPrivilege = 19
sPOMustBeNew = 20
sPOMustBeSubmitted = 21
sChangingVendor = 22
sPostToInventory = 23
sPOMustBeApproved = 24
sPOMustBeReceived = 25
sRequiredFields_PO_Close = 26
sPOCannotDelete = 27
sMinimumReorderQuantity = 28
sLessThanTargetLevel = 29
sNewStatusSet = 30
sOrderPaid = 32
sCannotDelete = 33
sOneLineItem = 34
sChangeCompanyType = 35
sRequiredFields_Paid = 36
sCompanyDelete_CompanyTypeChange = 37
sCompanyDelete_RelatedRecords = 38
sOptionNotAvailable_NewRecord = 39
sNoRecentOrders = 40
sAbout = 41
sFormAlreadyOpen = 42
sCatalog_GastronomicHeader = 43
sCatalog_Gastronomic = 44
sCatalog_QualityHeader = 45
sCatalog_Quality = 46
sDoYouWantToSaveYourChanges = 48
sOrderMustBeShippedBeforePaid = 49
sNewOrderInvoice = 50
sOrderBeforeOrderLineItems = 51
End Enum
'PURPOSE:
' Get a string from the Strings table. Supports {0} replacable parameters (see StringFormat).
Public Function GetString(ByVal ID As enumStrings, ParamArray params() As Variant) As String
10 On Error GoTo Err_Handler
Dim s As String
20 s = Nz(DLookup("StringData", "Strings", "StringID = " & ID), "")
30 Debug.Assert s <> ""
40 s = StringFormat(s, params)
50 GetString = s
Exit_Handler:
60 Exit Function
Err_Handler:
70 clsErrorHandler.HandleError "modStrings", "GetString"
80 Resume Exit_Handler
End Function
'NOTES:
' Patterned after String.Format in .NET.
' https://docs.microsoft.com/dotnet/api/system.string.format
' Advantage of this function over traditional string concatenation is that you can focus on the string itself, what you want it to say.
' Also makes it easier to use strings from a table (see GetString function).
'EXAMPLES:
' Debug.Print StringFormat("Hello {0}. This is {1}.", "world", "ET")
' => Hello world. This is ET.
'ARGUMENTS:
' s - String with zero or more {n} placeholders for parameter values. The first one is {0}.
' params - Zero or more parameters to replace the placeholders. Can also handle a paramarray that was passed in from another function taking a paramarray (e.g. GetString).
Public Function StringFormat(ByVal s As String, ParamArray params() As Variant) As String
10 On Error GoTo Err_Handler
Dim n As Integer
Dim vParams As Variant
20 If UBound(params) = -1 Then GoTo Exit_Handler 'Zero params passed in.
30 If IsArray(params) And IsArray(params(0)) Then
40 vParams = params(0)
50 Else
60 vParams = params
70 End If
80 For n = 0 To UBound(vParams)
90 s = Replace(s, "{" & n & "}", vParams(n))
100 Next n
Exit_Handler:
110 StringFormat = s
120 Exit Function
Err_Handler:
130 clsErrorHandler.HandleError "modStrings", "StringFormat"
140 Resume Exit_Handler
End Function
'PURPOSE:
' Format a string using Access SQL rules.
'NOTES:
' Better than built-in function Application.BuildCriteria which has some unexpected side-effects.
Public Function StringFormatSQL(ByVal s As String, ParamArray params() As Variant) As String
10 On Error GoTo Err_Handler
Dim i As Integer
Dim vParams As Variant
20 If IsArray(params) And IsArray(params(0)) Then
30 vParams = params(0)
40 Else
50 vParams = params
60 End If
70 For i = LBound(vParams) To UBound(vParams)
80 If IsNull(vParams(i)) Then
90 vParams(i) = Nz(vParams(i), "NULL")
100 Else
'NW 2.0 code to be replaced below.
' Select Case VarType(vParams(i))
' Case vbString:
' vParams(i) = "'" & vParams(i) & "'"
' Case vbDate:
' vParams(i) = "#" & vParams(i) & "#"
' End Select
'NW 2.2 code will convert international number and date formats to those understood by Access.
'We also escape string arguments, in case an argument includes an embedded single-quote (think: ...where LastName = 'O'Brien")
110 Select Case VarType(vParams(i))
Case vbCurrency, vbSingle, vbDouble
120 vParams(i) = LTrim(Str(vParams(i))) 'Str converts regional numbers to Access standards.
130 Case vbString:
140 vParams(i) = SINGLE_QUOTE & Replace(vParams(i), SINGLE_QUOTE, TWO_SINGLE_QUOTES) & SINGLE_QUOTE
150 Case vbDate:
160 vParams(i) = "#" & ToAccessDate(vParams(i)) & "#" 'ToAccessDate ensures this works for all regional settings.
170 End Select
180 End If
190 Next i
200 StringFormatSQL = StringFormat(s, vParams)
Exit_Handler:
210 Exit Function
Err_Handler:
220 clsErrorHandler.HandleError "modStrings", "StringFormatSQL"
230 Resume Exit_Handler
240 Resume
End Function
' NOTE:
' Caller is responsible for cleaning up the dictionary object returned. Example:
' Dim dict as Scripting.Dictionary
' Set dict = StringToDictionary("a=1&b=2")
' 'Use the dictionary object
' Set dict = Nothing 'Cleanup.
' NOTE 2:
' Note the proper syntax for calling a function that returns an object is by using Set:
' Set dict = StringToDictionary(...)
' ARGUMENTS:
' s - String in querystring format (e.g. "key1=value1&key2=value2&key3=value3"
' If a key contains an embedded equals sign or ampersand, you may want to call UrlEncode/UrlDecode (code not included in this template).
' RETURNS:
' Scripting.Dictionary object with the parsed values.
Public Function StringToDictionary(ByVal v As Variant) As Scripting.Dictionary 'Requires reference to Microsoft Scripting Runtime (scrrun.dll)
10 On Error GoTo Err_Handler
Const KEYVALUE_DELIMITER As String = "&"
Const VALUE_DELIMITER As String = "="
Dim dict As New Scripting.Dictionary
Dim intPos As Integer
Dim strTokens() As String
Dim varToken As Variant
20 If IsNull(v) Then
'Nothing to do.
30 Else
40 dict.CompareMode = vbTextCompare
50 strTokens = Split(v, KEYVALUE_DELIMITER)
60 For Each varToken In strTokens
70 intPos = InStr(varToken, VALUE_DELIMITER)
80 If intPos = 0 Then
'it's a token without an = sign
90 Else
100 dict.Add Left$(varToken, intPos - 1), Mid$(varToken, intPos + 1)
110 End If
120 Next varToken
130 Erase strTokens
140 End If
150 Set StringToDictionary = dict
Exit_Handler:
160 Exit Function
Err_Handler:
170 clsErrorHandler.HandleError "modStrings", "StringToDictionary"
180 Resume Exit_Handler
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| AddDataMacros | Sub | Public | () | 8 | 42 | g_dbapp, handleerror, hasdatamacro, hasfield, stringtofile |
| GetAuditFieldsUserName | Function | Public | () | 50 | 20 | get_userid, getwindowsusername, handleerror |
Public Sub AddDataMacros()
10 On Error GoTo Err_Handler
Dim td As DAO.TableDef
Dim strFileName As String
20 For Each td In g_dbApp().TableDefs
30 If td.Attributes And dbSystemObject Then
'Skip system objects like MSys* and USys*
40 Else
50 If HasField(td, "AddedBy") And HasField(td, "AddedOn") And HasField(td, "ModifiedBy") And HasField(td, "ModifiedOn") Then
60 If HasDataMacro(td) Then
'Already has data macro; nothing to do.
70 Else
'Save macro to temp file so we can LoadFromText.
80 If strFileName = "" Then
'File not yet created. Do it now.
90 strFileName = Environ("TEMP") & "\datamacro.xml"
100 StringToFile strFileName, DLookup("DataMacro", "Welcome")
110 End If
120 Application.LoadFromText acTableDataMacro, td.Name, strFileName
130 End If
140 End If
150 End If
160 Next td
Exit_Handler:
170 Exit Sub
Err_Handler:
180 clsErrorHandler.HandleError "modTableDataMacros", "AddDataMacros"
190 Resume Exit_Handler
End Sub
'NOTE:
' If you split the database into a Front End and Back End
' this module needs to be where the tables are (the Back End)
' because these function(s) are called by data macros in the tables.
'PURPOSE:
' Provide name to be used when saving to the Audit Trail fields AddedBy and ModifiedBy which are present in most tables.
' This function is called from the BeforeChange data macro for most tables.Public Function GetAuditFieldsUserName() As String
10 On Error GoTo Err_Handler
Dim strUserName As String
20 If Get_UserID() = 0 Then
'User is not logged in.
30 strUserName = GetWindowsUserName()
40 Else
50 strUserName = DLookup("FullNameFNLN", "qryEmployees", "EmployeeID = " & Get_UserID())
60 End If
70 GetAuditFieldsUserName = strUserName
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modTableDataMacros", "GetAuditFieldsUserName"
100 Resume Exit_Handler
End FunctionOption Compare Database
Option Explicit
'PURPOSE:
' Adds data macros if they don't exist.
' The reason we even have to do this adding of data macros is because Access templates cannot have data macros
' that reference custom VBA functions such as our GetAuditFieldsUserName.
Public Sub AddDataMacros()
10 On Error GoTo Err_Handler
Dim td As DAO.TableDef
Dim strFileName As String
20 For Each td In g_dbApp().TableDefs
30 If td.Attributes And dbSystemObject Then
'Skip system objects like MSys* and USys*
40 Else
50 If HasField(td, "AddedBy") And HasField(td, "AddedOn") And HasField(td, "ModifiedBy") And HasField(td, "ModifiedOn") Then
60 If HasDataMacro(td) Then
'Already has data macro; nothing to do.
70 Else
'Save macro to temp file so we can LoadFromText.
80 If strFileName = "" Then
'File not yet created. Do it now.
90 strFileName = Environ("TEMP") & "\datamacro.xml"
100 StringToFile strFileName, DLookup("DataMacro", "Welcome")
110 End If
120 Application.LoadFromText acTableDataMacro, td.Name, strFileName
130 End If
140 End If
150 End If
160 Next td
Exit_Handler:
170 Exit Sub
Err_Handler:
180 clsErrorHandler.HandleError "modTableDataMacros", "AddDataMacros"
190 Resume Exit_Handler
End Sub
'NOTE:
' If you split the database into a Front End and Back End
' this module needs to be where the tables are (the Back End)
' because these function(s) are called by data macros in the tables.
'PURPOSE:
' Provide name to be used when saving to the Audit Trail fields AddedBy and ModifiedBy which are present in most tables.
' This function is called from the BeforeChange data macro for most tables.
Public Function GetAuditFieldsUserName() As String
10 On Error GoTo Err_Handler
Dim strUserName As String
20 If Get_UserID() = 0 Then
'User is not logged in.
30 strUserName = GetWindowsUserName()
40 Else
50 strUserName = DLookup("FullNameFNLN", "qryEmployees", "EmployeeID = " & Get_UserID())
60 End If
70 GetAuditFieldsUserName = strUserName
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modTableDataMacros", "GetAuditFieldsUserName"
100 Resume Exit_Handler
End Function| Procedure | Kind | Scope | Parameters | Starts | Lines | Calls |
|---|---|---|---|---|---|---|
| HighlightControl | Sub | Public | (ByRef ctl As Access.control) | 7 | 41 | controlcurrentview, controldefaultview, handleerror, hasproperty |
| HighlightInvalidControls | Sub | Private | (ByRef frm As Access.Form) | 48 | 25 | handleerror, highlightcontrol, isboundtorequiredfield |
| IsBoundToRequiredField | Function | Private | (ByRef ctl As Access.control) | 73 | 11 | — |
| IsValidForm | Function | Private | (ByRef frm As Access.Form) | 84 | 33 | handleerror, isboundtorequiredfield |
| ValidateForm | Function | Public | (ByRef frm As Access.Form) | 117 | 24 | getstring, handleerror, highlightinvalidcontrols, isvalidform |
| ValidateForm_RemoveHighlights | Sub | Public | (ByRef frm As Access.Form) | 141 | 31 | controlcurrentview, controldefaultview |
Public Sub HighlightControl(ByRef ctl As Access.control)
10 On Error GoTo Err_Handler
Dim fc As FormatCondition
Dim intCurrentView As Integer
Dim intDefaultView As Integer
20 intCurrentView = ControlCurrentView(ctl)
30 intDefaultView = ControlDefaultView(ctl)
'If current=form and default=continuousforms, or current=datasheet
40 If (intCurrentView = 1 And intDefaultView = 1) Or intCurrentView = 2 Then
'Datasheet does not have BackColor. The way to color a column is through Conditional Formatting.
50 If ctl.FormatConditions.count >= 4 Then 'Just in case we have a runaway process.
60 ctl.FormatConditions(3).Delete
70 End If
80 Set fc = ctl.FormatConditions.Add(AcFormatConditionType.acExpression, , "True") 'In a more elaborate implementation you can limit highlighting to the current row, by making the expression something like "OrderDetailID=123". This requires finding the PK in the underlying recordsource.
90 fc.BackColor = HIGHLIGHT_COLOR
100 Else
'Transparent controls cannot have a BackColor, so first set their BackStyle to be "Normal".
'NOTE: We are not setting this property back to what it was.
110 If HasProperty(ctl, "BackStyle") Then
120 ctl.BackStyle = 1 '1=Normal, 0=Transparent
130 ctl.BackColor = HIGHLIGHT_COLOR 'If a control has a BackStyle, it also has a BackColor. No need for another HasProperty test.
140 End If
150 End If
Exit_Handler:
160 Exit Sub
Err_Handler:
170 clsErrorHandler.HandleError "modValidation", "HighlightControl"
180 Resume Exit_Handler
End Sub
'PURPOSE:
' Highlight required fields that do not have a value.
'ALGORITHM:
' Loop over the controls on the form. Test if all required fields have a value.
' If not, highlight it.Private Sub HighlightInvalidControls(ByRef frm As Access.Form)
10 On Error GoTo Err_Handler
Dim ctl As Access.control
20 For Each ctl In frm.Controls
30 If IsBoundToRequiredField(ctl) Then
40 If IsNull(ctl.Value) Then
'Control bound to required field does not have a value. Highlight it.
50 HighlightControl ctl
60 End If
70 End If
80 Next ctl
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError "modValidation", "HighlightInvalidControls"
110 Resume Exit_Handler
End Sub
'ALGORITHM:
' Access the control's Parent which is its form. Get the RecordsetClone for the form.
' Access the field we are bound to, and check its Required property.Private Function IsBoundToRequiredField(ByRef ctl As Access.control) As Boolean 10 On Error Resume Next 'Not all controls have a ControlsSource property. 20 IsBoundToRequiredField = ctl.Parent.RecordsetClone.Fields(ctl.ControlSource).Required End Function 'PURPOSE: ' Validate the form with respect to required fields. 'ALGORITHM: ' Loop over the form's controls. Test if all required fields have a value. 'RETURNS: ' True if the form is valid (all required fields have been entered); False otherwise.
Private Function IsValidForm(ByRef frm As Access.Form) As Boolean
10 On Error GoTo Err_Handler
Dim blnIsValid As Boolean
Dim ctl As Access.control
20 blnIsValid = True 'Optimistic
30 For Each ctl In frm.Controls
40 If IsBoundToRequiredField(ctl) Then
50 If IsNull(ctl.Value) Then
'This required field is not filled out.
60 blnIsValid = False
70 Exit For
80 End If
90 End If
100 Next ctl
110 IsValidForm = blnIsValid
Exit_Handler:
120 Exit Function
Err_Handler:
130 clsErrorHandler.HandleError "modValidation", "IsValidForm"
140 Resume Exit_Handler
End Function
'PURPOSE:
' Validate the form with respect to required fields.
' Typically you call this from Form_BeforeUpdate which is just before the data is (attempted to be) saved.
'RETURNS:
' The "Cancel" value used in BeforeUpdate events (True if invalid).Public Function ValidateForm(ByRef frm As Access.Form) As Boolean
10 On Error GoTo Err_Handler
Dim blnCancel As Boolean
20 blnCancel = Not IsValidForm(frm)
30 If blnCancel Then
40 HighlightInvalidControls frm
50 MsgBox GetString(sRequiredFields), vbExclamation
60 End If
70 ValidateForm = blnCancel
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modValidation", "ValidateForm"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Turn off the highlight color by setting the background to the default white color.
' Typically you call this procedure from Form_AfterUpdate, which fires after a record has been saved
' so obviously all required fields have been satisfied.Public Sub ValidateForm_RemoveHighlights(ByRef frm As Access.Form)
Dim ctl As Access.control
Dim fc As FormatCondition
Dim intCurrentView As Integer
Dim intDefaultView As Integer
10 Set ctl = frm.Controls(0) 'Any control will do; we will be inspecting parent controls.
20 intCurrentView = ControlCurrentView(ctl)
30 intDefaultView = ControlDefaultView(ctl)
'If current=form and default=continuousforms, or current=datasheet
40 If (intCurrentView = 1 And intDefaultView = 1) Or intCurrentView = 2 Then
' If frm.CurrentView = 2 Then '2=datasheet
50 On Error Resume Next 'Not all controls have FormatConditions
60 For Each ctl In frm.Controls
70 For Each fc In ctl.FormatConditions
80 If fc.Expression1 = "True" And fc.BackColor = HIGHLIGHT_COLOR Then
90 fc.Delete
100 Exit For
110 End If
120 Next fc
130 Next ctl
140 Else
150 On Error Resume Next 'Not all controls have a BackColor property
160 For Each ctl In frm.Controls
170 If ctl.BackColor = HIGHLIGHT_COLOR Then ctl.BackColor = BACKGROUND_COLOR
180 Next ctl
190 End If
End SubOption Compare Database
Option Explicit
Private Const BACKGROUND_COLOR As Long = vbWhite 'The "Background 1" color is vbWhite
Private Const HIGHLIGHT_COLOR As Long = vbYellow 'Adjust to your taste
Public Sub HighlightControl(ByRef ctl As Access.control)
10 On Error GoTo Err_Handler
Dim fc As FormatCondition
Dim intCurrentView As Integer
Dim intDefaultView As Integer
20 intCurrentView = ControlCurrentView(ctl)
30 intDefaultView = ControlDefaultView(ctl)
'If current=form and default=continuousforms, or current=datasheet
40 If (intCurrentView = 1 And intDefaultView = 1) Or intCurrentView = 2 Then
'Datasheet does not have BackColor. The way to color a column is through Conditional Formatting.
50 If ctl.FormatConditions.count >= 4 Then 'Just in case we have a runaway process.
60 ctl.FormatConditions(3).Delete
70 End If
80 Set fc = ctl.FormatConditions.Add(AcFormatConditionType.acExpression, , "True") 'In a more elaborate implementation you can limit highlighting to the current row, by making the expression something like "OrderDetailID=123". This requires finding the PK in the underlying recordsource.
90 fc.BackColor = HIGHLIGHT_COLOR
100 Else
'Transparent controls cannot have a BackColor, so first set their BackStyle to be "Normal".
'NOTE: We are not setting this property back to what it was.
110 If HasProperty(ctl, "BackStyle") Then
120 ctl.BackStyle = 1 '1=Normal, 0=Transparent
130 ctl.BackColor = HIGHLIGHT_COLOR 'If a control has a BackStyle, it also has a BackColor. No need for another HasProperty test.
140 End If
150 End If
Exit_Handler:
160 Exit Sub
Err_Handler:
170 clsErrorHandler.HandleError "modValidation", "HighlightControl"
180 Resume Exit_Handler
End Sub
'PURPOSE:
' Highlight required fields that do not have a value.
'ALGORITHM:
' Loop over the controls on the form. Test if all required fields have a value.
' If not, highlight it.
Private Sub HighlightInvalidControls(ByRef frm As Access.Form)
10 On Error GoTo Err_Handler
Dim ctl As Access.control
20 For Each ctl In frm.Controls
30 If IsBoundToRequiredField(ctl) Then
40 If IsNull(ctl.Value) Then
'Control bound to required field does not have a value. Highlight it.
50 HighlightControl ctl
60 End If
70 End If
80 Next ctl
Exit_Handler:
90 Exit Sub
Err_Handler:
100 clsErrorHandler.HandleError "modValidation", "HighlightInvalidControls"
110 Resume Exit_Handler
End Sub
'ALGORITHM:
' Access the control's Parent which is its form. Get the RecordsetClone for the form.
' Access the field we are bound to, and check its Required property.
Private Function IsBoundToRequiredField(ByRef ctl As Access.control) As Boolean
10 On Error Resume Next 'Not all controls have a ControlsSource property.
20 IsBoundToRequiredField = ctl.Parent.RecordsetClone.Fields(ctl.ControlSource).Required
End Function
'PURPOSE:
' Validate the form with respect to required fields.
'ALGORITHM:
' Loop over the form's controls. Test if all required fields have a value.
'RETURNS:
' True if the form is valid (all required fields have been entered); False otherwise.
Private Function IsValidForm(ByRef frm As Access.Form) As Boolean
10 On Error GoTo Err_Handler
Dim blnIsValid As Boolean
Dim ctl As Access.control
20 blnIsValid = True 'Optimistic
30 For Each ctl In frm.Controls
40 If IsBoundToRequiredField(ctl) Then
50 If IsNull(ctl.Value) Then
'This required field is not filled out.
60 blnIsValid = False
70 Exit For
80 End If
90 End If
100 Next ctl
110 IsValidForm = blnIsValid
Exit_Handler:
120 Exit Function
Err_Handler:
130 clsErrorHandler.HandleError "modValidation", "IsValidForm"
140 Resume Exit_Handler
End Function
'PURPOSE:
' Validate the form with respect to required fields.
' Typically you call this from Form_BeforeUpdate which is just before the data is (attempted to be) saved.
'RETURNS:
' The "Cancel" value used in BeforeUpdate events (True if invalid).
Public Function ValidateForm(ByRef frm As Access.Form) As Boolean
10 On Error GoTo Err_Handler
Dim blnCancel As Boolean
20 blnCancel = Not IsValidForm(frm)
30 If blnCancel Then
40 HighlightInvalidControls frm
50 MsgBox GetString(sRequiredFields), vbExclamation
60 End If
70 ValidateForm = blnCancel
Exit_Handler:
80 Exit Function
Err_Handler:
90 clsErrorHandler.HandleError "modValidation", "ValidateForm"
100 Resume Exit_Handler
End Function
'PURPOSE:
' Turn off the highlight color by setting the background to the default white color.
' Typically you call this procedure from Form_AfterUpdate, which fires after a record has been saved
' so obviously all required fields have been satisfied.
Public Sub ValidateForm_RemoveHighlights(ByRef frm As Access.Form)
Dim ctl As Access.control
Dim fc As FormatCondition
Dim intCurrentView As Integer
Dim intDefaultView As Integer
10 Set ctl = frm.Controls(0) 'Any control will do; we will be inspecting parent controls.
20 intCurrentView = ControlCurrentView(ctl)
30 intDefaultView = ControlDefaultView(ctl)
'If current=form and default=continuousforms, or current=datasheet
40 If (intCurrentView = 1 And intDefaultView = 1) Or intCurrentView = 2 Then
' If frm.CurrentView = 2 Then '2=datasheet
50 On Error Resume Next 'Not all controls have FormatConditions
60 For Each ctl In frm.Controls
70 For Each fc In ctl.FormatConditions
80 If fc.Expression1 = "True" And fc.BackColor = HIGHLIGHT_COLOR Then
90 fc.Delete
100 Exit For
110 End If
120 Next fc
130 Next ctl
140 Else
150 On Error Resume Next 'Not all controls have a BackColor property
160 For Each ctl In frm.Controls
170 If ctl.BackColor = HIGHLIGHT_COLOR Then ctl.BackColor = BACKGROUND_COLOR
180 Next ctl
190 End If
End Sub| Name | Path | Version | Broken |
|---|---|---|---|
| Access | C:\Program Files\Microsoft Office\root\Office16\MSACC.OLB | 9.0 | No |
| DAO | C:\Program Files\Common Files\Microsoft Shared\OFFICE16\ACEDAO.DLL | 12.0 | No |
| Scripting | C:\Windows\System32\scrrun.dll | 1.0 | No |
| stdole | C:\Windows\System32\stdole2.tlb | 2.0 | No |
| VBA | C:\Program Files\Common Files\Microsoft Shared\VBA\VBA7.1\VBE7.DLL | 4.2 | No |
| VBIDE | C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB | 5.3 | No |
| VBScript_RegExp_55 | C:\Windows\System32\vbscript.dll\3 | 5.5 | No |