I am making a till system for a project in access and I have hit a block.
Background
There are numerous forms covered in buttons. clicking a button adds data to a table (TblCurSale) including description and price of item. each form also has a "total" button which sends you to the payment screen, doing so copies the data from the TblCurSale to another table (TblCalc)
TblCalc has columns SaleID, Item(name of item), SalePrice. the report auto adds the sale price column
The total form has two sub reports on it, the TBLCurSale and TblCalc.
On the total screen there is a text filed in which users an input money and then press pay which inputs that figure into the TblCalc as a negative number and then refreshes the page so the new total comes up. at the bottom of the subreport.
Problem
I need an IF vba code so that I can put it so that when the total of the SalePrice column <= 0 I can run a few lines of code. what I have so far is below, so any help would be greatly appreciated.
Private Sub Pay_Click()
Dim SQLPay As String
Dim SQLToTable As String
Dim SQLMoney As Variant
SQLPay = "INSERT INTO TblCalc(SalePriceTotal) VALUES (-'" & TxtPayment & "')"
SQLToTable = "INSERT INTO TblTotalSale (CurrentSaleID, SalePrice, Item) SELECT CurrentSaleID, SalePrice, Item FROM TblCurrentSale"
SQLMoney = "IF (SUM(SalePriceTotal) FROM TblCalc) <= 0 SELECT '1' ELSE '0'"
DoCmd.SetWarnings False
DoCmd.RunSQL SQLPay
DoCmd.RunSQL SQLMoney
If SQLMoney = 1 Then
DoCmd.RunSQL SQLToTable
Me.TxtPayment = ""
Me.Refresh
DoCmd.OpenReport "rptCalc"
Else
Me.TxtPayment = ""
Me.Refresh
Me.Refresh
End If
DoCmd.SetWarnings True
End Sub
I think you would be better to structure it like a transaction table. So instead of inserting the payment into a separate table, add another row to the TblTotalSale with an Item description of "Payment" and the value as a negative number. You can then simply sum the SalePrice column to give you the balance outstanding. It also allows you to record multiple payments against the one sale.
wrt to the negative sale, I think you should put some validation code on your form to prevent users from entering negative item prices, (in the beforeInsert and beforeUpdate events on the form)
Related
I have a main form and a continuous subform which is connected to main form using invoice id, customer name and invoice date. When I add a new invoice, I select customer in main form and enter data in subform because I allow edits in my subform.
Now if I change customer in main form, customer should also change in subform for the data which I already added. But my subform turns to blank, when I select previous customer it shows the entered data.
I want my subform customer update to newly selected customer in main form. I used some vba code but its not working. The below code I got from a tutorial.
Private Sub Customer_Name_AfterUpdate()
With Me.[Sales_Invoice_Detail(its my subform].Form.RecordsetClone
Do Until .EOF
.Edit
!Customer_Name = Me.Customer_Name (This is the Field which i want to update in my subform)
!Invoice_Id = Me.Invoice_Id( it has one to many relationship between forms)
.Update
.MoveNext
Loop
'MsgBox "You Change Customer To " & Customer_Name & "!"
End With
Me.Refresh
End Sub
a continuous subform which is connected to main form using invoice id,
customer name and invoice date
Remove customer name and invoice date from the connection (MasterLinkFields/ChildLinkFields). These can be pulled either directly from the parent form or - using a query - from the source of the subform.
my form looks like this:
My problem is, that he "LeistungsBezeichnungsRef" isnt filtering. In my main form, I selected "13222", in addition i want to be shown at the subform just "13222" positions, not 20455, too.
This is my diagram:
The Idea is, that I got a cost centre (13222) to these cost centres it exists some Bills ( excavator, crane etc ) These Bills are cost centre specific! So i build up a table called "LV", where i can type in a position, amount, value etc and in " Leistungserfassung ", I can select a specific position and associate it with a Date/Daily report Number etc , selected in table "Räumstelle".
The field "LeistungsBezeichnungsRef" ( called like "position billing" in engl. ) Has this query:
I already wrote the Combobox-Fieldname of the mainform into the query criteria.. but its not filtering
In the AfterUpdate of the search ComboBox you must requery the subform
Private Sub SearchComboBox_AfterUpdate()
TheSubform.Requery
'Filter the combo in the subform
TheSubform.Form!TheLVCombo.RowSource = "SELECT whatever FROM LV WHERE ID = " _
& SearchComboBox.Value
End Sub
I have an access database that I will be using to track orders and to track inventory levels. When I attempt to add the parts on my order form (sbfrmOrderDetails) to my inventory table (tblInventory) my VBA code does not execute as planned.
Please note that I have stripped down the code and the tables to just the relevant information/values. The code posted below does work, just not as intended. I explain in much more detail below.
Form Structure
I created my Order form (frmOrder) as a Single Form. This form is referred to in my later code to determine the order number using the txtOrderID control. When I link my subform, the linked master field is OrderID.
Within this form is my Order Details subform (sbfrmOrderDetails) as a continuous form. Every control is bound, and it is linked to the parent form. The linked child field is OrderID.
Photo 1: This photo may better illustrate my form:
Table Structure
The relevant tables I have are structured like so:
TableName: tblOrders
TableColumns: OrderID
TableName: tblOrderDetails
TableColumns: ID|InvID|Qty|OrderID|DeliveryStatus
TableName: tblInventory
TableColumns: ID|InvID|Qty|OrderID
Intended Action
The action I am trying to take occurs in the subform and is supposed to be isolated to the current record. When the user changes the ComboBox (Combo1 bound control to tblOrderDetails.DeliveryStatus), my VBA code will execute an 'INSERT INTO' SQL string that adds the InvID and the Qty from the current record into the inventory table (tblInventory).
VBA Code for Combo1 AfterUpdate Event (On sbfrmOrderDetails)
Private Sub Combo1_AfterUpdate()
Dim db As DAO.Database
Dim strSQL As String
Set db = CurrentDb
If Me.Combo1.Value = "Delivered" Then
strSQL = "INSERT INTO [tblInventory] ([InvID],[Qty])" _
& "SELECT " & Forms![frmOrder].Form![sbfrmOrderDetails].Form![txtInvID] & " AS InvID," & Forms![frmOrder].Form![sbfrmOrderDetails].Form![txtQty] & " AS Qty " _
& "FROM tblOrderDetails WHERE ((tblOrderDetails.OrderID)=(" & Forms![frmOrder]![txtOrderID] & "));"
Debug.Print strSQL
db.Execute strSQL, dbFailOnError
Else
'Other event
End If
End Sub
Intended Results
When Combo1 (bound control) is changed from null to “Delivered” on record ID #11 only, it is supposed to add a single new record.
Photo 2: Intended Results:
Actual Results
When Combo1 (bound control) is changed from null to “Delivered” on record ID #11 only, it is adding a new record for every record populated in the subform.
Please refer to Photo 2 above to compare the Intended Results to the Actual Results.
You can see that the quantity from records 12 and 13 are transferred over under the InvID from record 11.
Please refer to Photo 1 to view the sample data and also to Photo 2 above to see the Actual Result of the code.
I suspect that since this is a continuous form that has Parent/Child linking, the form is running the VBA code once for every record (instead of one time for the current record).
Can I alter my VBA code to only run this code once on the current record as is intended? I am hoping this is the best approach to complete this task.
The output of Debug.Print strSQL would have been helpful (see How to debug dynamic SQL in VBA ), but it would be something like this:
INSERT INTO tblInventory (InvID, Qty)
SELECT 14 AS InvID, 2 AS Qty
FROM tblOrderDetails
WHERE tblOrderDetails.OrderID = 5
You are inserting two constant values, so you may as well use the INSERT ... VALUES (...) syntax, which by definition only inserts one record:
INSERT INTO tblInventory (InvID, Qty)
VALUES (14, 2)
The reason your statement inserts multiple records is because of WHERE tblOrderDetails.OrderID = 5. Multiple records (all on the subform) satisfy this clause.
You would have to specify the OrderDetails ID instead, to get only one record:
INSERT INTO tblInventory (InvID, Qty)
SELECT 14 AS InvID, 2 AS Qty
FROM tblOrderDetails
WHERE tblOrderDetails.ID = <Forms![frmOrder]![sbfrmOrderDetails].Form![txtID]>
tblOrders.OrderID --> this table has not been referenced in the statement and vba should throw an error
strSQL = "INSERT INTO [tblInventory] ([InvID],[Qty])" _
& "SELECT " & Forms![frmOrder].Form![sbfrmOrderDetails].Form![txtInvID] & " AS InvID," & Forms![frmOrder].Form![sbfrmOrderDetails].Form![txtQty] & " AS Qty " _
& "FROM tblOrderDetails WHERE ((tblOrders.OrderID)=
(" & Forms![frmOrder]![txtOrderID] & "));"
Debug.Print strSQL
Part of my access application does invoicing. I have an invoice number table that wholes one field "InvoiceNum". On my invoice report I have the following code:
Private Sub Report_Open(Cancel As Integer)
'lookup invoice number when invoice opens
intInvoiceNum = Nz(DLookup("InvoiceNum", "tblInvoiceNum"), 0)
End Sub`
Private Sub PageHeaderSection_Format(Cancel As Integer, FormatCount As Integer)
'Incrementally add one (1) to the invoice number for every page of in the report
Me.txtInvoiceNum = intInvoiceNum
intInvoiceNum = intInvoiceNum + 1
End Sub`
Private Sub Report_Close()
'Update tblInvoiceNum with the last invoice number in the report
db.Execute ("UPDATE InvoiceNum SET InvoiceNum = " & intInvoiceNum)
End_Sub`
Problem: My report open with groupby ClientID and ProjectNum. Multiple invoices print on the same report. If any invoice spills over to second page the Format Code runs again inserting an incremental invoice number to the second page. How can I prevent this from happening?
Consider using a Running Sum control with the InvoiceNum in the report's Page Header section. No VBA required.
First, add an invisible textbox for running count over all report's records with following:
Control Source: =1
Running Sum: Over All
Name: RunningCount
Visible: No
Second, add another invisible textbox for DLookUp of InvoiceNum:
Control Source: =DLookup("InvoiceNum", "tblInvoiceNum")
Running Sum: No
Name: intInvoiceNum
Visible: No
Finally, add a visible textbox for sum of prior two controls serving as the incremental Invoice Number:
Control Source: =[intInvoiceNum] + [RunningCount]
Running Sum: No
Name: IncrementalInvoiceNum
Visible: Yes
You may be wondering, why the first two invisible controls? Reason being is using Running Sum: Over All will include both the counts and invoice number for each record of the report (e.g., 1 + InvoiceNum - 1st record; 1 + 1 + InvoiceNum + InvoiceNum - 2nd record...)
I have a button at the end of each record on a continuous form and it needs to do this:
Private Sub Update_Click()
Dim SellP As Double
Dim BuyP As Double
Dim Profit As Double
SellP = DLookup(SellPrice, Flips, [Current])
BuyP = DLookup(BuyPrice, Flips, [Current])
Profit = SellP - BuyP
Flips.Profit = Profit
End Sub
Now I know this isn't the correct code but I hope it will give you an idea of what it needs to do, essentially:
Find the SalePrice, find the BuyPrice, minus the BuyPrice from the SalePrice and make the result Profit, then populate the Profit field with profit..
Thanks!
The columns of the current record of the bound table/query are directly available in the code.
You can just write e.g.
Profit = SalePrice - BuyPrice if these fields are all part of the bound data.
You might then move this code in the "AfterUpdate"-Event of both the SalePrice- and the BuyPrice-Textfields, maybe like this:
If IsNull(salePrice) Or IsNull(buyPrice) Then
Profit = 0
Else
Profit = salePrice - buyPrice
End If