I need to develop a front end to a MSSQL database just to modify a few tables. I decided to use Access 2003 simply because of time restraints.
I used Linked Tables over ODBC to get them into Access, I'm designing the forms but I'm having problems creating an interface to allow users to create and delete new association between entities.
My Database structure is:
product
# productcode
- name
product_part
* productcode
* partnumber
- position
part
# partnumber
- comment
There is a many-to-many relationship between product and part (a product can have many parts and a part can belong to many products) except I can't find any easy way to allow a user to just associate a new part to product, only view the existing ones.
I've defined the relationships in Access except the options for cardinality and referential integrity are greyed out, I'm assuming this is because they're linked tables? Not sure if this would affect anything.
I created a form for product with an embedded subform which lists all the associated parts and their position (position is an attribute of the relationship since it's contextual but I can spin this out into it's own table if it'll make things easier).
Basically I need to make an user interface mechanism which will associate a selected part from a list to the shown product or any other way to create new and delete existing associations flexibly. I would have thought Access would have something in some wizard somewhere to do this, but if it does I can't find it.
Any help would be appreciated.
Judging on what noted so far, then this should be a simple matter to have the main form based on your topmost table (product). The continues sub form should then be based on ONLY the product part table.
If you think about this, the third table is really only a lookup table there for your convenience to allow you to not have to type in manually type in the part number.
So, base the child sub form as a continuous form, and make that column for part number a combo box that looks up the part numbers from the third table (part). So this combo boss can search and display by description, but will in fact automatically store the part number in that colum for you.
So while there's no need for any types of wizards, you certainly do not have to write any type of code whatsoever. Just ensure that the master child link settings for the sub form are set up correctly, and access will thus insert and maintain The product code columns used to link back to the main product table. You can most certainly use the combo box wizard to create the combo box in the continuous sub form that you're going to use to Select what part and set the part number column from the parts table.
The result will be a form that allows you to add new part assemblies or edit existing. While access will maintain the product code column for you, if you delete a main record, you'll need to have setup referential integrity and cascade deletes on the back end database part. So as you correctly note, all the integrity features will be set up in the database back end, not in the access front end part.
I've discovered what I wanted to do isn't easily possible using Linked Tables, I was able to do what I wanted to do easily if I used native access tables (since it let me properly define the relationships) but I couldn't do that with linked tables.
Related
(Beginner of SQL so I do apologize for any novice mistake that I made)
So essentially, I'm currently making an access form that allows the user to update their stock inside the warehouse. I'm using the ODBC link database in which I can store various data inside the server (the configuration for the database will be seen down below)
However, when I created a combo box that linked to a column(IDDH), it automatically pops up an error stating that it is violating the PK constraint whenever I switch to another column.At this point I don't know what I did wrong since I already connected two tables with a relationship of one-to-many inside the SQL along with connecting it on Microsoft Access(Just in case). And connect Foreign Key in the dbo.DonHang table (ProductID)
Here is my configuration
SQL:
Relationship in Access
The error in the access form whenever I switched to a different column in the combo box
If you want to require more information. Please do not hesitate to ask.
You base one form directly on the main table. Not a sql join.
You then create a sub form with the "many" entries for the one record. And again that form is NOT based on some sql join, but ONLY the linked child table.
You don't try and use sql joins to solve this kind of data editing in Access (using sql server does not change this). So you need a main form (based ONLY directly on the ONE linked table of master (parent) records. You then have a sub form and again it is based directly on the child linked table (again not some sql query).
So, for editing main records and child records? you use a form + sub form in Access to achieve this goal. And this setup will also work well with sql server linked tables.
But all in all? You don't try and edit sql joined data. you build up the main form, and drop in a sub form to a classic and common editing of master/child data in Access.
If you really want to edit both as one row? Well, you can often edit but you not be allowed in general to add rows. But if the sql VIEW you create allows editing of rows (you can test/try this in SSMS), then if you save that query in SSMS as a view? Then simply link the view to Access and you can edit the one row, but there are limitations in terms of adding new rows etc. it really depends on your goal.
but, at the end of the day, editing of master + child records is NOT achieved by a sql join query, but that of editing each table separate, or a form + sub form in access.
To keep this as short as possible I'm going to use and example.
So let's say I have a simple database that has the following tables:
company - ( "idcompany", "name", "createdOn" )
user - ( "iduser", "idcompany", "name", "dob", "createdOn" )
event - ( "idevent", "idcompany", "name", "description", "date", "createdOn" )
Many users can be linked to a single company as well as multiple events and many events can be linked to a single company. All companies, users and events have columns as show above in common. However, what if I wanted to give my customers the ability to add custom fields to both their users and their events for any unique extra information they wish to store. These extra fields would be on a company wide basis, not on a per record basis ( so a company adding a custom field to their users would add it to all of their users not just one specific user ). The custom fields also need to be sesrchable and have the ability to be reported on, ideally automatically with some sort of report wizard. Considering the database is expected to have lots of traffic as well as lots of custom fields, what is the best solution for this?
My current research and findings in possible solutions:
To have generic placeholder columns such as "custom1", "custom2" etc.
** This is not viable as there will eventually be too many custom columns and there will be too many NULL values stored in the database
To have 3x tables per current table. eg: user, user-custom-field, user-custom-field-value. The user table being the same. The user-custom-field table containing the information about the new field such as name, data type etc. And the user-custom-field-value table containing the value for the custom field
** This one is more of a contender if it were not for its complexity and table size implications. I think it will be impossible to avoid a user-custom-field table if I want to automatically report on these fields as I will have to store the information on how to report on these fields here. However, In order to pull almost any data you would have to do a million joins on the user-custom-field-value table as well as the fact that your now storing column data as rows which in a database expected to have a lot of traffic as well as a lot of custom fields would soon cause a problem.
Create a new user and event table for each new company that is added to the system removing the company id from within those tables and instead using it in the table name ( eg user56, 56 being the company id ). Then allowing the user to trigger DB commands that add the new custom columns to the tables giving them the power to decide if it has a default value or auto increments etc.
** Everytime I have seen this solution it has always instantly been shut down by people saying it would be unmanageable as you would eventually get thousands of tables. However nobody really explains what they mean by unmanageable. Firstly as far as my understanding goes, more tables is actually more efficient and produces faster search times as the tables are much smaller. Secondly, yes I understand that making any common table changes would be difficult but all you would have to do is run a script that changes all your tables for each company. Finally I actually see benefits using this method as it would seperate company data making it impossible for one to accidentally access another's data via a potential bug, plus it would potentially give the ability to back up and restore company data individually. If someone could elaborate on why this is perceived as a bad idea It would be appreciated.
Convert fully or partially to a NoSQL database.
** Honestly I have no experience with schemaless databases and don't really know how dynamic user defined fields on a per record basis would work ( although I know it's possible ). If someone could explain the implications of the switch or differences in queries and potential benefits that would be appreciated.
Create a JSON column in each table that requires extra fields. Then add the extra fields into that JSON object.
** The issue I have with this solution is that it is nearly impossible to filter data via the custom columns. You would not be able to report on these columns and until you have received and processed them you don't really know what is in them.
Finally if anyone has a solution not mentioned above or any thoughts or disagreements on any of my notes please tell me as this is all I have been able to find or figure out for myself.
A typical solution is to have a JSON (or XML) column that contains the user-defined fields. This would be an additional column in each table.
This is the most flexible. It allows:
New fields to be created at any time.
No modification to the existing table to do so.
Supports any reasonable type of field, including types not readily available in SQL (i.e. array).
On the downside,
There is no validation of the fields.
Some databases support JSON but do not support indexes on them.
JSON is not "known" to the database for things like foreign key constraints and table definitions.
I have a sub form tied to a table. This table has a foreign key, which holds the key to different tables, depending on the value. Based on the value, the information in the record is tied to a certain object level in the schema. It may be tied to the main record based on the main entry form. It may be tied to another subform record, etc.
So let's say the main form is for projects. For each project they could be placed into many buildings. Within each building they may have multiple staff. This somewhat inter-dependent sub form is for project documents. They may relate to the current project. They can also relate to one of the buildings for the current project, but only for that current project. Or the document could relate to one of the buildings, but for all projects. I already have a combo that gets it's row source based on the relationship type/doc type combo that is chosen first. That let's the user choose the actual building, staff or whatever the doc is related to.
I need to create a filter for the sub form that will give all records related to that main record and/or it's sub records, and still be able to add new records. I've been looking at a case statement, but concerned that will only apply the first true case. I was thinking of a union, but guessing I won't be able to add records. It won't be updateable.
Any suggestions appreciated!
Thanks. I ended up creating 2 sub forms. One for viewing all records that are somehow tied to the main record. This has a record source set to a union view, with a where clause for the main record ID. The second form is for adding/editing new records and the record source is tied to the documents table, with a filter to the record being edited, or the data entry set to yes, for adding new records. This is all set based on a toggle button, new main record activity, etc.
I know this question has been asked numerous times, but the situations people had were slightly different each time, or lacked enough detail, or the explanation for the problem lacked specific detail that I could understand the solution.
So here is my thing. I've got a combobox called "StatesComboBox" in a form that takes in customer data. This form is bound to a table called "States" in an ms access database file. So whatever states are in that table are reflected in the StatesComboBox.
In my access database file, I've got a table that stores the customer data called "CustomerData". One of the fields in it is called "customerstate", which stores the "StatesComboBox" selection made by the user.
I have connected the "States" table to the "CustomerData" table with a relationship. It connects the States table to the "customerstate" field. This is a one-to-many relationship, and I have checked off on the enforce referential integrity, cascade add and cascade delete options.
Now, when I enter data in the form and hit my register button, I get the message stated above - "You cannot add or change a record because a related record is required in table 'States'". But when I go back to access, delete the relationship between "States" and "CustomerData", the data gets stored just fine.
But I need to enforce limitations on the states selected... What am I doing wrong? What can I do to address this? Thank you.
Currently I'm performing a migration from a microsoft access database to an SQL Express 2010 database.
Basically, I have an Access application that searches a customer database. The access app is developed in 2 parts. An access front end on each client called application.mdb and a data backend on a windows 2008 server called data.mdb. The application.mdb has 3 linked tables to data.mdb. which holds customers and contracts and items. The customer table relates to the contracts table (one to many) and the contracts table relates to the items table (one to many)
I imported the tables from the data.mdb into the sql tables by the same name and created the same relationships and configured them to cascade. I then created an obdc connection on the clients and updated the 3 linked tables in application.mdb to point to the tables on the sql server.
I start the application and everything seemed to work great, I can see all the data perfectly and the performance increase was well worth the effort.
Then I found a problem, when I add a new customer to the database it autonumbers the customer table and the contracts table but not the items table.... Thus if I attempt to alters any of the items in the items table for new customers I can not. I get the following error "cannot add record(s); primary key for table "items" not in recordset" which makes sense because SQL had not autonumbered the items table.
I can't understand why....
Any help would be greatly appreciated.
Well, just manually adding record direct in the items view should tell you if the autonumber is working. You MUST get the autonumber working when you edit + use in direct table view.
As always these kinds of issues comes down to the details. One thing that's different when using a SQL based backend compared for access applications is the generation of auto numbers (primary key) does not occur on server based systems until record is actually saved. When working with the jet based back end, the auto number is available the instant the record is dirtied.
So I would check if you have some type of code or event running in the application that is attempting to use as primary key value before the record been actually saved.
Usually access does a pretty good job. For example when you build a form in access, and then have a sub form in access to edit child records (and a child table), then as a rule when the focus switches from a main form to a sub form, access will force a save of the main record. This thus means the primary key (auto number column) is now available for correct functioning of the relationship. Access can and will use this PK value and insert this value into the foreign key value column in this child table for you.
However access will only do above for you WHEN you correctly set up the link master and link child settings in the sub form control. As a general rule when building forms in regular access, Access can detect the settings required and insert the correct values into the link master and link child settings for you. However, the detection of the FK column will not occur with linked tables.
So when you use SQL server, you have to edit and set these values manually in the sub form control. So I would check your link master and link child settings in the sub form you're using to edit this data, and ensure that the correct values are set. If this is VBA code, then ensure the record is actually saved before attempt to use and grab a PK value.
I should point out that even in non SQL server based applications, it is the setting up of the link master + child settings in the sub form that allows access to setup and maintain this foreign key value for you. So access is always had the ability to insert these values for you, and it'll do so with you about having to write any code at all. So during the editing process to insert and maintain these values Access does all of the work for you (so it's not the data engine that inserts these FK values for you, but the user interface or in some cases code you write)
So access will not setup and insert these correct values unless you set up the link master + child settings in that sub form control.
I would simply check if your link master and child master settings are correct in any sub form control you are using here.
This sounds like a stupid answer but check the Items table to be sure that auto-numbering is turned on.
One of the things I would suggest whenever you migrate a Jet/ACE database to SQL Server is to thoroughly review the database design, e.g.: the implementation of keys and constraints, choice of data types, choice of indexes, etc. Jet/ACE is a very different thing to most SQL DBMSs so you shouldn't assume that a database design that worked well for Jet/ACE is automatically suitable for a SQL DBMS. Upsizing wizards won't always identify every possible issue.
In SQL Server the nearest equivalent of an "auto-number" is the IDENTITY property. Check to be sure which columns are IDENTITY in your tables and create an IDENTITY column if you need one.