I'm very new to MS Access and I'm trying to add a record to a form, where whenever I click on the 'Add Record' button, I keep getting an error - 'Can't go to specified record' which prevents me from using the button.
The form was created using a query, which links four tables together.
I've heard that I need to make the query editable, but I'm not sure as to how I would do that.
(This is what the query's SQL looks like - auto-generated by MS Access).
SELECT tblCustomers.Forename, tblCustomers.Surname, tblCustomers.Telephone, tblCustomers.[Customer ID], Count(tblTickets.[Ticket Number]) AS [CountOfTicket Number],
tblTickets.[Ticket Type ID], Sum(tblTickets.[Ticket Cost]) AS [SumOfTicket Cost],
tblCustomerTypes.[Customer Type ID], tblCustomerTypes.[Customer Type], tblTicketTypes.[Ticket Type ID], tblTickets.[Ticket Cost], tblTickets.[Ticket Number]
FROM ((tblCustomerTypes INNER JOIN tblCustomers ON tblCustomerTypes.[Customer Type ID] = tblCustomers.[Customer Type ID])
INNER JOIN tblTickets ON tblCustomers.[Customer ID] = tblTickets.[Customer ID]) INNER JOIN tblTicketTypes ON tblTickets.[Ticket Type ID] = tblTicketTypes.[Ticket Type ID]
GROUP BY tblCustomers.Forename, tblCustomers.Surname, tblCustomers.Telephone, tblCustomers.[Customer ID], tblTickets.[Ticket Type ID],
tblCustomerTypes.[Customer Type ID], tblCustomerTypes.[Customer Type], tblTicketTypes.[Ticket Type ID], tblTickets.[Ticket Cost], tblTickets.[Ticket Number];
This is where the issue occurs, whenever I try to add new records:
The picture above is the relationships diagram between the four tables, along with collection of data below it.
The data below is for each respective table:
This is the query which combines the four tables:
For a form to allow additions (i.e., add new record), the form must be an editable record source. However, your query record source is an aggregate query where you are running aggregate functions (COUNT, SUM) by groups (see GROUP BY clause). Since aggregate queries depend on underlying data to furnish results, you cannot update that underlying data on the aggregate output itself. Consequently, forms/reports based on aggregate queries are not editable.
SELECT tblCustomers.Forename
, tblCustomers.Surname
, tblCustomers.Telephone
, tblCustomers.[Customer ID]
, tblTickets.[Ticket Type ID]
, tblCustomerTypes.[Customer Type ID]
, tblCustomerTypes.[Customer Type]
, tblTicketTypes.[Ticket Type ID]
, tblTickets.[Ticket Cost]
, tblTickets.[Ticket Number]
, COUNT(tblTickets.[Ticket Number]) AS [CountOfTicket Number]
, SUM(tblTickets.[Ticket Cost]) AS [SumOfTicket Cost]
FROM ((tblCustomerTypes
INNER JOIN tblCustomers
ON tblCustomerTypes.[Customer Type ID] = tblCustomers.[Customer Type ID])
INNER JOIN tblTickets
ON tblCustomers.[Customer ID] = tblTickets.[c])
INNER JOIN tblTicketTypes
ON tblTickets.[Ticket Type ID] = tblTicketTypes.[Ticket Type ID]
GROUP BY tblCustomers.Forename
, tblCustomers.Surname
, tblCustomers.Telephone
, tblCustomers.[Customer ID]
, tblTickets.[Ticket Type ID]
, tblCustomerTypes.[Customer Type ID]
, tblCustomerTypes.[Customer Type]
, tblTicketTypes.[Ticket Type ID]
, tblTickets.[Ticket Cost]
, tblTickets.[Ticket Number];
MS Access does allow some JOIN queries to be editable depending on setup. So simply remove the aggregate functions (COUNT, SUM) and GROUP BY to return to unit level data. To test if query is not read-only, run it in query design and see if you can edit any value in any column (except autonumbers) of outputted results. Even scroll to the bottom and check if you can add a record.
SELECT tblCustomers.Forename
, tblCustomers.Surname
, tblCustomers.Telephone
, tblCustomers.[Customer ID]
, tblTickets.[Ticket Type ID]
, tblCustomerTypes.[Customer Type ID]
, tblCustomerTypes.[Customer Type]
, tblTicketTypes.[Ticket Type ID]
, tblTickets.[Ticket Cost]
, tblTickets.[Ticket Number]
FROM ((tblCustomerTypes
INNER JOIN tblCustomers
ON tblCustomerTypes.[Customer Type ID] = tblCustomers.[Customer Type ID])
INNER JOIN tblTickets
ON tblCustomers.[Customer ID] = tblTickets.[Customer ID])
INNER JOIN tblTicketTypes
ON tblTickets.[Ticket Type ID] = tblTicketTypes.[Ticket Type ID]
However, usually in MS Access design, you want to separate form entry much like normalized tables. Using above JOIN query, you expect the user to enter all customers and their types and all their corresponding tickets and those ticket types on a single form!
Consider a different, digestable approach:
Have the user enter all information of the customer on one form.
Record source: tblCustomers
Use a combobox for [Customer Type]. In MS Acccess, comboxboxes can show human values to users but hides and stores the corresponding primary key.
Then on a different form or subform, enter all tickets.
Record source: tblTickets
If a different form, use a combo box for [Customer ID] field to select from existing customers.
If a subform of customers main form, [Customer ID] is implicitly added with new entries to tickets subform.
Use a combobox for [Ticket Type].
Then run your aggregate query to view results only and not edit data!
To allow editing of a form?
You base the form ON ONE TABLE. And in fact in MOST cases you don't use a query for that form. Given your screen shot - you only editing values and columns from the one form anyway.
If you need to include, edit, see, have data from a child related table?
Then close the form you were just working on (the one based on ONE table - NOT a query0.
You now create a new form for say the child table. Again, that form is based on ONE table (not a query). This form will display the child data information.
Once you have that form looking all nice?
Then go back to the "main" form, design mode, and then from the side nav pane, you drag + drop in the "child" form. This will then become a sub form.
So, you this will have a main form, and for details or repeating data (child tables) you simply drop in a form (that becomes a sub form).
So you might have a main form like this:
The above has no SQL no query - just a form based on the ONE table.
But lets say I want to display a child table of "tour" booking options.
Ok, we create that form separate and base it on the child table.
And I am NOT limited to a form view. You can choose a data sheet, or better yet a multiple items form (they all work the same). After I create that form, then I go back to the main form, desing mode, and now drop in the child form.
I now get this:
And say I wanted to display the people booked in the room?
Well, once again, I go off, create a form, and AGAIN based on a single table.
And now I can drop that form into the above form.
So, now we have say this:
So, I did not actually write ANY sql. Each part of the form that is to display related (child table) information is simply another 100% separate form that I created.
I then simply dropped those additional forms into that one main form based on the main top most record.
So, where you gone wrong?
You base the form on a table. And NOT a query.
And if for some strange reason you do need or use a query for a form? AGAIN it is to be based on one table.
So that top form (a sub form) displays the people booked in the room.
The rest of the form is the booking.
And then on the bottom part I drop in the table (and from) that displays the booking options.
Access will automatic pull the child records if you setup your relationships for you.
I have a retail store data with 50000 records. One of the columns in that file is Segment (Home office, Corporate and Consumer). This data i have in one table. In another table i just have two columns - Segment, Forecast Sales. What query needs to be written to get the actual segment sales and Forecast Sales in single table or how should the relationship be created in SQL.
Data can be found here : https://community.tableau.com/docs/DOC-1236
I will assume table name [Orders] as per your excel and [Segment Forecast] for the table with columns [Segment], [Forecast Sales].
select sf.Segment,sum(o.sales) [Actual Sales],sf.[Forecast Sales]
from [Orders] o
inner join [Segment Forecast] sf on o.Segment=sf.Segment
group by sf.Segment,sf.[Forecast Sales]
I have two tables, Actual Use and Budget. I need to update my [Actual Use].Goals with my monthly Budget.goals. I have an update query:
UPDATE [Actual Use]
INNER JOIN Budget ON [Actual Use].Property_ID = Budget.Property_ID
SET
[Actual Use].Goal = [Budget].Goal
WHERE
[Actual Use].Date = [Budget].Date
This query updates my Actual Use table but only for one month. 1/1/2016. Both Actual Use and Budget have a date field and all dates are entered with the first of each month so 1/1/2016, 2/1/2016 etc... Why is my update only working on one month and not every month where the Property_ID and month are the same on both tables?
Edit
The Acutal Use Table has the following fields in this order
Property_Id, Date, Use, Goal and the Budget Table has Property_ID, Date, Goal
I agree with the comment by Olivier. You need to join on both ID and Date.
Depending on what your table keys are, the above listed query could produce a One to Many or Many to Many result, in which, the program doesn't know which goal to assign. I suppose the Where clause may catch the many to many circumstance, but in my opinion, could produce some weird behavior.
Possible solution:
UPDATE [Actual Use]
INNER JOIN Budget ON [Actual Use].Property_ID = Budget.Property_ID
AND [Actual Use].Date = Budget.Date
SET
[Actual Use].Goal = [Budget].Goal
On a side note, it seems like the data is a bit repetitious? Presuming there was no 'goal' in table [Actual Use], you could still reference the data by the following:
SELECT * FROM [Actual Use] au
JOIN Budget b on au.Property_ID = b.Property_ID AND
au.Date = b.Date
I have a MS Access query which pulls [product name] and [price] along with several other fields. My problem is that I have multiple instances where [product name] is duplicated and [price] may or may not be the same between the duplicates. I'd like the query to show only one record for each of the duplicates and the minimum [price] associated with that [product name]....one big master list with no duplicates in it..... the final list should include all [product names] that didn't have duplicates and their associated price also.
I know this should be simple but for whatever reason I'm beating my brains out on it. I tried using a crosstab query already to return the minimum values for each unique [product name] but I have so many records that the crosstab query errors out on column count.
Any help would be greatly appreciated.
AC
MSAccess doesn't support Partition functions.
However, if you were able to get your data into a SQL database, you could easily do this using Window/Partition functions, which would allow you to do interesting things like select the cheapest 2 products, etc
SELECT *
FROM
(
SELECT ROW_NUMBER()
OVER (PARTITION BY [ProductName] ORDER BY [Price]) as RowNum, *
FROM Table
) X
WHERE RowNum = 1
You can now correctly get the actual row that was identified as the one with the lowest price and you can modify the ordering function to use multiple criteria, such as "Show me the latest product which had the cheapest score", etc.
I'm trying to create a table that I can use for Accounts Receivable. It's a very simple table, needing only the total cost of an order, how much has been paid into the order, and the order number itself. I'm trying to adapt an existing query used for report generation to do so.
SELECT DISTINCTROW
Round(Sum(nz([Quantity]*[UnitPrice]*(1-[Discount])*100)/100)+
[RushCharge],2) AS TotalCost,
[Sum Of Payments Query].[Total Payments],
[Order Details].RushCharge AS RushCharge,
Orders.OrderID,
Orders.Cancel,
Orders.PriceQuote
INTO test2
FROM Orders
LEFT JOIN [Sum Of Payments Query]
ON Orders.OrderID = [Sum Of Payments Query].OrderID
GROUP BY Orders.OrderID,
Orders.Cancel,
[Sum Of Payments Query].[Total Payments],
Orders.PriceQuote
The issue is the age of the DB, where the total cost of an order is always dynamically generated instead of being stored somewhere (Even though there is only one form that alters it, but still), meaning I have to resort to the same. The Round function calculates the total cost of the order, and it works elsewhere, but here, it just prompts me for values instead of pulling them from Orders.
What am I doing wrong? I know it has to be something simple.
I am guessing that [Quantity], [unit price] and [Discount] and RushCharge are fields in [order details] table, which is not included in the query.
you could create a query that returns the totalcost per order
select orderid,
Round(Sum(nz([Quantity]*[UnitPrice]*(1-[Discount])*100)/100)+
[RushCharge],2) AS TotalCost from
from [order details]
group by orderid
and include this in your query in the same way you have [sum of Payments Query]