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 am trying to import a CSV file exported from Ebay into MS Access.
Ebay cram into one file what should be in two files. So if someone purchases two products, Ebay puts the customer details in one row and the products bought in the following lines.
Customer cruze130613 bought two products, so has information spread over three lines!
What I would like to do is fill the empty User ID column blanks.
So:
Set [User ID] equal same 'User ID' as where [Sales record number] = [Sales record number]
I think the select clause for [Sales record number] should use DISTINCT as is duplicated on >1 rows.
Any help with the SQL code will be appreciated.
Perhaps something along the lines of the following:
update YourTable t1
set t1.[user id] = dlookup
(
"[user id]",
"YourTable",
"[user id] is not null and [sales record number]=" & t1.[sales record number]
)
where t1.[user id] is null
Change both references of YourTable to the name of your table.
Here, the domain aggregate function DLookup is used to acquire the value of the User ID field for a record meeting the supplied criteria (in this case where User ID is not null, and where the sales record number is equal to that of the record being updated).
There are other ways to achieve the same result, but DLookup is used here to retain the 'updateability' of the query in MS Access.
Thank you Lee for your suggestion.
As far as I can see Ebay only export these pseudo CSV files.
I had another look today and managed to find a solution. I wonder which would be more efficient yours or mine?
UPDATE tEbImportRaw AS eir1
INNER JOIN tEbImportRaw AS eir2
ON eir1.[Sales Record Number] = eir2.[Sales Record Number]
SET eir1.[User ID] = eir2.[User ID];
I'm working on merging individual Access databases into a single SQL database, but there are collisions that need to be sorted out first.
For example, the table in each database that holds course/class information (it's school-related) uses the [Course ID] as a key value, but the other columns in that table don't necessarily match across all of the individual Access databases. So, a [Course ID] of "0106" might exist in multiple databases, and I need to make sure that the other 19 columns associated with that [Course ID] are identical in the other access databases.
I've already compiled the data from all of the access databases into an Access database as an aggregate with all of the duplicated/colliding data.
I've already developed a query to find all of the duplicate [Course ID] values, but I need another query to find any other inconsistent data between records.
How can I structure a SQL query to find records with duplicate [Course ID] values, but only the ones where one of the other columns has an inconsistency?
I have two tables that I'm working with; CHI(fields Expr1000,School) and CRS (fields Expr1000,Course ID, Course title).
The query I'm using atm is:
SELECT CRS.[Course ID], CRS.[Course title], CHI.Name
FROM CHI RIGHT JOIN CRS ON CHI.Expr1000 = CRS.Expr1000
WHERE (
((CRS.[Course ID]) In
(SELECT [Course ID] FROM [CRS] As Tmp GROUP BY [Course ID] HAVING Count(*)>1 ))
AND ((CRS.Expr1000)=[CHI].[School]))
ORDER BY CRS.[Course ID];
This generates a list of all records with duplicate [Course ID]s, though I'd prefer a list that will exclude occurrences where all the records with a given [Course ID] have matching [Course title].
E.g., If all records with Course ID=106 also have matching [Course Title], then they should be excluded.
I'm not sure if I should try to consolidate everything into a single query or create multiple queries to whittle the data down, and I'm not sure how to structure the queries for the data I desire.
You could do something like this:
SELECT *
FROM table1
LEFT JOIN table2 ON table1.key = table2.key
and (
table1.property1 <> table2.property1
or table1.SomeOtherProperty <> table2.SomeOtherProperty
-- etc
)
this would return records from the tables that have a matching key, but at least one other column in the table is not matching - note using column stubs here, plug in your own column names.
I have a strange problem that I believe is related to the way my lookups are structured.
TABLE Category
ID
CategoryName
TABLE Product
ID
ProductName
Category - Number (SELECT [Category].[ID], [Category].[Category Type] FROM Category ORDER BY [Category Type];)
TABLE SalePrices
Several fields related to sale date, price, &c.
ProductName - Text (SELECT [Product].[ID], [Product].[Product Name] FROM Product ORDER BY [Product Name];
For some reason I get a blank result set when I run the following query:
SELECT SalePrices.[Product Name], Product.[Product Name]
FROM SalePrices INNER JOIN Product ON SalePrices.[Product Name] = Product.[Product Name];
I have a query that displays the MIN of SalePrices.UnitPrice which I want to display with the ProductName and CategoryName, but I'm not getting results for that so I wanted to simplify things first.
When I join Product and Category I have to match Product.[Category Type] = Category.ID;, but when I try to do SalePrices.[Product Name] = Product.[ID]; I get a TYPE MISMATCH error. I'm not sure where I went wrong.
The eventual goal is to combine the SalesPrices <-> ProductName join with this one:
SELECT Product.[Product Name], Category.[Category Type]
FROM Product INNER JOIN Category ON Product.[Category Type] = Category.ID;
As suggested in the comments by #Scotch and #HansUp, defining "Lookup" fields in an Access table is generally regarded as a Bad Idea for all but the most trivial of cases. They hide what is really going in the database and they can lead to all kinds of confusion (as you have discovered) when you actually try to use them. (Ref: here, via comment by #HansUp.)
Your best course of action would be to replace the Lookup fields in your tables with regular numeric fields containing the ID (key) values in the related tables. Then, if necessary, you can create and save Select Queries to explicitly do the lookups and display the results as they previously appeared in the [Product] and [SalePrices] Datasheet Views.
I have an Update query that says it's updating 1029 rows, when there are only 994 rows in the database that it's updating.
The query references an external Excel file and updates the "Master Calendar" with "Posted Date" when the batch numbers are equivalent:
UPDATE [Mapped Link] RIGHT JOIN Master_Calendar ON [Mapped Link].Reference = Master_Calendar.[Batch Number] SET Master_Calendar.[Actual Posted Date] = [Mapped Link]. [Entry Date];
Whenever rows get added to the external 'Mapped Link' document, the rows increase on the update query. There are about 2000 rows in 'Mapped Link', so it's not adding the rows from Master Calendar to Mapped Link together.
The data doesn't seem to be updating incorrectly -- all the data is correct. But how can it be updating more rows than it exists? Is it just counting wrong? Thoughts?
Thanks, guys.
You have either duplicates in either Master_Calendar.[Actual Posted Date] or [Mapped Link].[Entry Date]
To check for duplicate dates, you can run a query. For example:
SELECT [Actual Posted Date], Count(ID) AS CountOfID
FROM Master_Calendar
GROUP BY [Actual Posted Date]
HAVING Count(ID)>1
You will need to change ID to the name of the index on your table.