Access Totals dynamically updated based on textboxes - function

All,
I run into some problems with totals using the DSUM function.
I have a Main form and a subform (details). The subform is displayed in datasheet view inside of the main form.
The subform contains a OppL_ID (PK, autonumber), Opp_ID (FK, is multiple times present), Product, Unit, Unit price.
Now I want to calculate the total revenue per Opp_ID on the main form. In the main form an Opp_ID selected, several rows with products are shown in the subform connected with that Opp_ID. If the user enters data in the datasheet view, the revenue must be calculated again directly.
I first try to get the formula working in the footer of the subform. But I cannot get the correct sum of revenue.
Now I have added in the query of the subform the Revenue: [Units]*[Unit Price]. This displays the revenue per unique line. I want the revenue per Opp_ID, so I tried the DSUM function.
What I tried:
To total the Revenue per Opp_ID I used the formula: DSUM([Units]*[Unit Price];"Qry_lines";"[Opp_ID]=" & [Opp_ID])
I also tried the control names instead: DSUM([txt_Units]*[txt_Unit Price];"Qry_lines";"[Opp_ID]=" & [Opp_ID])
I aslo tried to reference the Revenue field: DSUM([Revenue];"Qry_lines";"[Opp_ID]=" & [Opp_ID])
All of the formulas end in the result:
Example:
Opp_ID 51 consists of two lines with products A and B, Line of product A = Units 1 Unit price 20. Line of product B = Units 2 unit price 30.
Result: If I stand on A, the total revenue is 40 and on the line of product B 120.
I would expect only one figure:
1 * 20 + 2 * 30 = 80
It looks like it calculated revenue times the number of rows? What am I doing wrong?
I also tried to create a sum query and to reference this, for example:
Select Qry_lines.Opp_ID, Sum(Qry_lines.Revenue) as SumofRevenue FROM Qry_lines Group by Qry_lines.Opp_ID.
Now I get the correct figure per Opp_ID. Only I cannot reference this in my form? Perhaps with a Dlookup?
I think I am close but I cannot really nail it. Please help :)

Consider:
Use DLookup() domain aggregate function expression in textbox to reference the aggregate query.
Commit record edits to table with code in control's AfterUpdate event. One way is If Me.Dirty Then Me.Dirty = False
In same event, use Refresh or Requery or Recalc command on main form.

Related

How to find similar records in ms access database compared to a specific record in the table

I want to find the latest record of each patient and
compare the columns of that record to another record of a specific patient ID
Bring out the similarities
and group the records according to the percentage similarity value
So I want to see patients who have most similar records to that specfic patient to come on top and the rest follows.
Patient record
In short, sort by a calculated variable. Here is the query and table structure I used:
In my first definition of similarity I weighted each test equally:
CalculatedSimilarity: IIf([TestResults]![Test1]=[TestResult1],1,0)+IIf([TestResults]![Test2]=[TestResult2],1,0)+IIf([TestResults]![Test3]=[TestResult3],1,0)
in my second definition of similarity I doubled the value of the second test and ignored the 3rd:
CalculatedSimilarity2: IIf([TestResults]![Test1]=[TestResult1],1,0)+IIf([TestResults]![Test2]=[TestResult2],2,0)
to display as a percentage just divide by the weighted number of tests included.
When run against patient 5 who had "S" results on all tests the result is:
If you have many tests it would be better to construct the query with vba rather than the designer. this next step gets around a designer bug by linking the query to normally invisible text boxes.
the combobox rowsource is set to:
SELECT Patients.PatientID, Patients.FirstName, TestResults.Test1, TestResults.Test2, TestResults.test3 FROM Patients INNER JOIN TestResults ON Patients.PatientID = TestResults.PatientID;
have the combobox set the invisible textboxes
Private Sub cmbPatient_AfterUpdate()
'access designer can't see the column property. workaround by setting normally invisible text boxes
txttest1 = cmbPatient.Column(2)
txttest2 = cmbPatient.Column(3)
txttest3 = cmbPatient.Column(4)
similarity = cmbPatient.Column(5)
Me.Requery
End Sub
change the query parameters to reference the textboxes
CalculatedSimilarity: IIf([TestResults]![Test1]=[Forms]![Patients]![txttest1],1,0)+IIf([TestResults]![Test2]=[Forms]![Patients]![txttest2],1,0)+IIf([TestResults]![Test3]=[Forms]![Patients]![txttest3],1,0)

Link Subreport to matrix

I have a matrix like below. years on columns and countries on rows.
Countries 2001 2002
US 100 400
UK 200 290
IR 300 89
I have a requirement of creating a subreport which shows Invoice details. When I click 100 (US-1002) on my main report I have to show all the 100 Invoices. I tried this way:
Since I am doing count for InvoiceID in matrix, I tried using Join(Fields!InvoiceID,", ") expression on the data test box action(Go to report). On the other side I created a subreport with multivalue parameter. But this approach dint work. I found that Join will not work with data rows as it expect arrays.
Later I used Join(LookupSet(1,1,Fields!Name.Value, "DatasetName")," / "). I could join the invoice ids but the problem is , this expression joins all the invoice ID in complete dataset. I just need US-2001 cell (100) invoice ids only to take to my subreport
From your description, it sounds like the easiest thing to do would be to set up the subreport to take two parameters, Country and Year, instead of trying to pass the list of invoices.
The subreport can then report all the invoices for a particular Country and Year combination.
It would be simpler to just set up the drillthrough to accept the two fields for its parameters, as above, instead of try to work out an expression for all the invoices in a particular cell's scope.

Query with data from subform and sum

I have three tables:
Products(ID,Name,Price) /
Customer(ID, Name, Surname)
Buys(ID, ID_customer, ID_product)
I have a form with subform. Subform gets populated with query from Buys table and then connected to Customer(ID) via ID_customer. ID and ID_customer gets hidden on subform.
Then I have two more fields/controls added on subform: Name and aPrice which gets populated via ProductsQuery:
SELECT Products.Name, Products.Price
FROM Products
WHERE (((Products.ID)=[Forms]![PregledKupcev-Form]![NAKUPI-Subform]![ID]));
//ID in this case is control on subform which holds ID of a product
using:
=DLookUp("[Name]";"[ProductsQuery]")
and
=DLookUp("[Price]";"[ProductsQuery]")
So far everything works but it gives me alot of troubles later when i try to sum one control (Price in this case).
Is there any way to do this better?
Then I try to sum up things in aPrice control into PriceSum control on subform's footer:
=Sum([Forms]![PregledKupcev-Form]![NAKUPI-subform]![aPrice])
and transfer it to form with:
=[Forms]![PregledKupcev-Form]![NAKUPI-subform]![PriceSum]
but I get error..
How do I sum up values in Price control on subform?
Pictures:
Let's say that your main form has a text box named txtInvoiceNo in which you display the Invoice Number (or whatever field links your parent table to your child table).
Let's also say that your main form has a text box named txtInvoiceTotal where you want to display the sum of the [Price] values for each child record.
Set the Control Source of the txtInvoiceTotal text box to do a DSum() on the child table (which I've called InvoiceLineItems):
=DSum("[Price]","InvoiceLineItems","InvoiceNo=" & [txtInvoiceNo])
In the After Update event of the subform, add a line to .Requery the parent form's txtInvoiceTotal text box:
Private Sub Form_AfterUpdate()
Me.Parent.txtInvoiceTotal.Requery
End Sub
See if that does the trick for you.

DSum returning number of rows instead of total value

I have the following code attached to a text box in a form:
=DSum("[subform].Form![POINTS]","ATTENDANCE","[subform].Form![EMPLOYEE NO] = [EMPLOYEE NO]")
Ideally this would yield the total amount of points accrued by the employee we are currently searching for. However, what I am getting is the total sum of rows in my table.
Does anybody have any idea of how I could get the total sum of the values instead of the number of rows?
Thanks
If you want to get the total from a subform, and your subform in in sync with the main one, it will be much more efficient to procede this way:
create txtTotalPoints textbox = sum(Points) in the footer of your subform
refer to that control from your main form: txtMainResult =subform!form!txtTotalPoints
Hide txtTotalPoints (or the footer itself)
That will generally be much faster.
As far as I know, the Domain functions such as DSum, DLookup, DCount etc. are used to lookup and return values from a table. The first argument is the field, the second the table, and the third is the criteria or WHERE statement that makes sure you get the correct set of records. Your first argument refers to a form's field. I think this is incorrect. Your first item in your WHERE statement is also a form field. I this this is also incorrect. You need to try something like this instead:
=DSum("POINTS","ATTENDANCE","[EMPLOYEE NO] = " & [subform].Form![EMPLOYEE NO])

How to Reference Individual Form Elements in a MS Access Continuous Form

MS Access Scenario:
I am using a form (we'll call it the select_contract form) and a subform (we'll call it the employee_allocations_by_contract subform).
The select_contract form:
Is unbound.
Contains a combobox that allows the user to select a contract id.
The employee_allocations_by_contract subform:
Is a continuous form.
Is bound to a table (which I'll call the hours_allocation table) that contains the number of hours that each employee is allocated to each contract.
Binds only one field, the employee_id field, to the hours_allocation table. The row source for this field is a query that returns the ids of employees that have hours allocated to the contract that the user has selected in the select_contract form.
Contains twelve other, unbound fields, one for each month of the year. These fields are intended to display the number of hours allocated to the employee listed in the employee_id field for each month of the year.
The Problem: In order to display the number of hours by month that are allocated to each employee listed on the employee_allocations_by_contract subform, the queries for each month field need access to the employee_id field of the row on which they appear. I haven't been able to figure out how to reference this field. Because the employee_allocations_by_contract subform is a continuous form, a reference to the the employee_id field name appears to reference each row on the form.
I have searched several forums and have found related continuous form issues, but nothing that clearly addresses this problem. Any thoughts?
Well, you could build a sub-query for each of the month columns you need that total for.
Something like:
Select id, employee_ID, bla, bla, bla,
(select sum(hours) where month = 1 and year = 2010 and
employee_id = ehours.Employee_id from tblProjectHours)
as month1,
(select sum(hours) where month = 2 and year = 2010 and
employee_id = ehours.Employee_id from tblProjectHours)
as month2,
(select sum(hours) where month = 3 and year = 2010 and
employee_id = ehours.Employee_id from tblProjectHours)
as month3
etc. for each column needed
from ehours
Note I used month and year as columns and you likely have to use month([SomeDate]) = 2 and year([SomeDate]) = 2010, but you get the idea.
Also, while you can't address each row and stuff a value into that un-bound text box, you CAN in fact bind the text box to a function that returns the value/expression you need.
txtBoxMonth1 txtboxMonth2 etc.
=MyMonth(1,[employee_id]) =MyMonth(2,[Employee_id])
And, then in the form, you have a public function called
Public Function MyMonth(intMonth as interger, lngEMPID as long) as long
' code here to get total based on employee id and month
End Funciton
So, you can bind a function to those text boxes, and the current row emp ID can thus drive what each text box displays. Just remember that this function should have all of the data pre-processed, and you don't want to have to re-run and re-load the data for each function call as that will be FAR too slow. However, I have used this approach to much success. So, each row of the form only has one real column (empID), the rest of the columns are derived from text boxes bound to the public function as per above with the month being passed along with the emp id to return the value for that column.
So, above is two possible approaches I used with success.
An unbound control on a continuous form can only refer to the record that has the focus. There fore, if data is entered into an unbound control, you will see the same data for every record in the continuous form.
You cannot reference controls "individually" ("at the line level") in a MS Access continuous form.
Your only solution here is to bound these controls to an underlying recordset\recordsource where corresponding fields hold the values to be displayed.
For example, if you want to display a time period as the difference between a "date in" and a "date out", your recordset\recorsource could be something like:
select id_person,dateIn,dateOut,dateDiff(xx,dateOut, dateIn) as timeIn from ...
Then your time calculation control has to be bound to the 'timeIn' field of the recordset.
(*) please check the dateDiff arguments. I do not have any help available here ..