MS Access sum of related records - sql

I have a purchase form that has a continuous subform which shows line items for that purchase. Each line item needs to include a text box that shows the sum for a number of related records in a table for that line item.
(Each line item is allocated for a specific purpose(s). For instance, a line item says that 100 widgets are ordered; the allocation table says that 20 widgets are for this purpose and 40 are for this purpose. The text box needs to say that 60 / 100 are allocated.)
I have written this in VBA for the OnCurrent event of the form, but this only occurs when the first "copy" of the continuous form receives focus. Then all the other "copies" of the form show the same values in the text box.
I then realized that I could perhaps do this as part of the query for the form. Whenever I add ... Sum(Quantity) AS TotalAllocations to the SQL query, I get the following error:
"You tried to execute a query that
does not include the specified
expression 'VendorPartNumber' as part
of an aggregate function."
(VendorPartNumber is a field for the records that show up on the continuous form.)
Can someone explain how to do this successfully in a query designer / SQL view or with VBA?
Complete aside:
Ideally, it would be nice to have this as a continuous subform on a continuous subform. However, Access does not allow continous subforms on continuous subforms.

If you're going to SUM in SQL, you need to include a GROUP BY clause for the non-aggregated columns, such as:
SELECT VendorPartNumber, Sum(Quantity) as TotalAllocations
FROM YourTable
GROUP BY VendorPartNumber

Related

Select Query Doesn't Show All Results

I have a combobox on a subform (ProgramSubform) in Access that's supposed to list report years for a project from a table (Program). Most projects have more than one report year, but the combobox always brings only 2014.
For example, the dropdown for project 5278 should be:
2012
2013
2014
Instead, it's only
2014
This is the select query that I'm using. It was working properly before, but I don't know when it stopped working; no changes were made to the tables or subform.
SELECT Program.ReportYear
FROM Program
WHERE (((Program.ProjNo)='ProgramSubform.ProjNo'));
Any idea why it might have stopped working, or how to fix it?
This WHERE clause asks Access to limit the rows returned by the query to those whose ProjNo values match the text string 'ProgramSubform.ProjNo'
WHERE (((Program.ProjNo)='ProgramSubform.ProjNo'))
But ProgramSubform.ProjNo is actually a data control on a subform. So don't include quotes around its name.
You can use a reference to the control via the parent form in the Forms collection:
WHERE Program.ProjNo= Forms![Parent Form]!ProgramSubform!ProjNo
If you're building the SELECT statement with VBA code in the form, you can include the control's value instead of its name:
"WHERE Program.ProjNo=" & Me!ProgramSubform!ProjNo.Value
"WHERE Program.ProjNo='" & Me!ProgramSubform!ProjNo.Value & "'"
Use the first version for a numeric field or the second for text.
Notes:
I assumed ProgramSubform is the name of the subform control. It could also be the name of the form contained in that subform control. But those names can be different. So make sure you used the subform control name.
This query is used as the Row Source for a combo box on the subform. You want to update the values displayed in the combo whenever ProjNo.Value changes. You can accomplish that by calling the combo's Requery method from the After Update event of ProjNo.
Pay attention to the brackets, you have three before Program.ProjNo on WHERE clause, but you only need two brackets (in this case) you should use:
SELECT Program.ReportYear
FROM Program
WHERE ((Program.ProjNo='ProgramSubform.ProjNo'));
anyway you will prefer:
SELECT Program.ReportYear
FROM Program
WHERE Program.ProjNo='ProgramSubform.ProjNo';

How to get min/max values on form that returns multiple records

I've got a form that returns multiple records from a table. Each of these records has a field indicating what the measurement was and the measurement's value. My form's record source pulls the appropriate ID's set of measurements and values, and then I want to write each of these measurements to different text boxes on the form.
The problem is that I'm also keeping track of the date this data was updated, and want to include only the data pulled based on the "date updated" selected at the top of the form.
When I go to pull the measurement value into a text box (with something like max(iif(Measurement="Acidity", [Value],[Null])) I get #Error all down my form. This had been working earlier today, and as I've been developing the form something changed and now it no longer works (everything but the date returned is saying #Error). I've set it to Requery when the form loads and whenever the date selected is changed.
EDIT:
This form is actually a subform of another main form. The main form has a control called MemberID which a user can use to select the Member they want information about. This is based on a query that pulls from a table the information related to that MemberID (one row per MemberID). When the form loads, the query behind the main form needs to be requeried to get the data for the selected MemberID.
Then there is this subform causing the problems. On this subform is a "Data Updated" drop down box, which lists the possible dates that the data was updated. When one chooses a particular "Data updated" in the drop down box, this chooses the latest data for all the data measures up to that date selected. This means the form's record source pulls about 10 records in my case.
Then, on this subform I try to layout these 10 records' values in different text boxes. So, in my acidity case above, I would say iif(Measurement="Acidity", [Value], Null). Because there are 10 rows returned, I will end up with 9 Nulls and 1 value, and to get that value I use the max function, so the text box's control source reads: max(iif(Measurement="Acidity",[Value],Null)).
The strange thing is this code was working this morning, until later this afternoon when I was filling in the remaining text boxes with similar code, and then it stopped working. I had also renamed the boxes from Text71 to more relevant names, but none of these are referenced in the code.

How can I bind a multi-row update or insert statement to a form?

I have a table Prices:
ID -- primary key, autonumber long integer
PriceDate -- Date
Price - Currency
Quantity - Number, DECIMAL subtype
UnitPrice - Number, DECIMAL subtype (an update statement is run to keep this in synch with price and quantity, but it's just a convenience for indexing... probably it'll be replaced with an expression in my queries)
ItemNote - Text
NewStores_ID - long integer key, lookup to another table of stores
NewItems_ID - long integer key, lookup to another table of items
To enter prices for a given store on a given day, I would like to be able to select the store and date ONCE on a form, then enter the items individually in a datasheet. For reasons unexplained, this proves difficult.
I can create a subform binding everything but the store and price to a temp table TempPrices with the same structure as the original. Then I run the SQL statement
INSERT INTO Prices
(PriceDate,Price,Quantity,UnitPrice,Brand,ItemNote,NewStores_ID,NewItems_ID)
SELECT
PriceDate,Price,Quantity,Price/Quantity AS
UnitPrice,Brand,ItemNote,NewStores_ID,NewItems_ID)
FROM Temp_Prices;
This will feed all the new rows into the main table. But, when I want to set the store and date only once, I run into problems. I've tried using named parameters for date an store in the insert statement... which can cause a pop-up prompt, but I cannot bind it to a form control. I've tried binding an update statement for those fields in the temp table to a form... but it doesn't even show an option to bind a multi-row update.
How can I get this to work with a minimum of clumsy hackery? It seems like there ought to be a simple solution, and if I were using something like PHP or JDBC I'd just run an extra query.
Edit: changed storage type for Quantity and UnitPrice to Number, Decimal subtype in place of double float. Just so people won't cry about using a float in any proximity to currency. It doesn't pose a problem in my use, but there are enough people who have a knee-jerk reaction to that.
Edit 2: Form/Subform
I'm trying to structure this as a master form with a either fields for entering store name and date, or a subform for the same, then a subform mapping to the temporary table for entering pricing data. There is an action button to run the insert/update queries to dump the temp table into my main prices table and clear out the temp table. However, the problem is that I can't figure out how to get the date/store fields in the master (or subform) to bind to an insert/update value applied to all the new rows at once.
Edit 3: SQL Statements (for clarity)
INSERT INTO
PRICES(NewStores_ID,PriceDate,NewItems_ID,Brand,Price,Quantity,
UnitPrice,ItemNote)
SELECT
#MyStore_ID,#MyPriceDate,NewItems_ID,Brand,Price,Quantity,
Price/Quantity,ItemNote
FROM TempPrices;
UPDATE TempPrices SET PriceDate=#MyPriceDate,NewStores_ID=#MyStoreID;
For these queries, I cannot bind parameters for #MyStore_ID or #MyPriceDate to fields in any form. The queries don't show up as options when trying to link them to a form. I can run them and get popup boxes to input parameters, but that's not what I want.
This is the target I'm aiming at:
"I would like to be able to select the store and date ONCE on a form, then enter the items individually in a datasheet."
However, if you have a reason why you need to do it with a temp table and DML statements, then this suggestion will not be useful.
I created a Prices table with only 4 fields, then a query on that table which I used as the Record Source for a form, "fsubPrices":
SELECT p.ID, p.NewStores_ID, p.PriceDate, p.Price
FROM Prices AS p
ORDER BY p.NewStores_ID, p.PriceDate;
The form has text boxes (txtNewStores_ID, txtPriceDate, and txtPrice) bound to the similarly-named query fields. I set Enabled=Yes for txtPrice, and Enabled=No for the other two.
Then I created an unbound form "frmPrices", and in the form header added a combo box "cboStores" and a text box "txtPriceDate". The combo has Bound Column = 1 with this query for its Row Source:
SELECT l.Store_ID, l.Store_name FROM tblkupStores AS l ORDER BY l.Store_name;
Then I added fsubPrices as a subform control to the detail section of frmPrices. The tricky part is setting the Link Master/Child Fields. There is a "wizardy dialog thing", but it will only allow you to select from the available fields, and I needed to link controls on the main form with fields on the subform. To do that, I had to type what I wanted directly into the subform control's property sheet:
Link Child Fields......NewStores_ID;PriceDate
Link Master Fields.....cboStores;txtPriceDate
The result is ... choose a store and date combination in the main form ... any matching records are displayed in the subform. You can navigate to the "new record" in the subform to add records for that store/date combination. But the txtNewStores_ID and txtPriceDate controls don't show the updated values until the new record is saved.
I hope this is close to what you want. It's actually fairly quick and easy to create; not so easy to describe.
You can't really do that. You are always going to have one row being worked with at a time.
What you can do is simulate it by changing the form's Default View from "Single Form" to "Continuous Form" or perhaps "Data sheet" and making is a child(sub) form of a master form.
Then you can put the store and date on the Master form, and linking to the child form using the NewStores_ID and PriceDate fields.

GridControl doesn't display the data it contains

I am using DevExpress GridControl to display information from my database through a stored procedure (ie. SELECT * FROM aTable). Unfortunately when I run the program it doesn't display any of the information, columns, etc. It displays an empty table.
I know that there is information contained by the GridView though as I have print statements that return the row count. Specifically:
Console.WriteLine(GridView2.RowCount) ' returns the number of rows that should be displayed
Console.WriteLine(myTable.Rows.Count) ' returns the number of rows that should be displayed
What should I do so that the actual data within the table (DataTable) and the DataView is displayed to the user. I know the row count is correct as when I add/remove a record the row count correlates by incrementing/decrementing.
In addition I have this same problem in C# and in Visual Basic
Ok I have the solution and it is rather easy. Go into the design view and from there go into the designer for the GridView. In there go to Columns, under Main, and add each column that you want displayed from your select statement. For each put the name that the select statement had for each column under 'FieldName' and under 'Caption' you can rename the columns to what you prefer.

ms-access listbox weirdness (memory issue?)

i have a huge sql query that is attached to the rowsource of a listbox.
the SQL statement seen here:
ms-access: select from another query
actually returns the correct information if that information is under 2 records.
however if it returns more than 2 records it still populates the listbox but it populates it with null values. when i right click on one of the values and press COPY, it gives me this message:
"there isnt enough memory to retrieve data for the list box"
But does the query work if it is run separately? And is the number of columns in the query the same number of columns as you've specified in the listbox Column Count property?
In your reply you state that you have to combine it? Why? Basic trouble shooting is to see if you can run the query separate from the lixtbox.