Convert linked DBF's to Access with recordnumbers - ms-access

I have an old dbase-database (made with a program programmed with clipper 5.2) which consists of multiple tables (files). The tables are linked with some sort of recordnumber, but in the source table, no recordnumber-field is found. I want to convert this database to Access and re-establish the links. I've read something about a dbf recordpointer (?) but i don't know how to extract it from the DBF.

Well, if recno() or some such is being used, then it suggests that the table starts at one.
Remember, you can’t update a PK autonumber in Access, BUT YOU CAN RUN append queries against such tables!!!
So link to a dBase table. When you view this table in Access does it show that incrementing column?
It should and does for me.
The above detail has not been made clear by you.
So let’s assume you see this column that increments and is NOT marked as a PK?
That is just fine (and is expected). As LONG as you see the incrementing number in that linked table then you are just fine.
This process of importing then becomes rather fast and easy.
On the create ribbon tab, just choose query design.
Drop in that linked table.
From ribbon choose make table. Enter your new local table name.
Drag the * from the table into the into the query grid (first column of grid).
You have this:
Now run the above query query (hit the run button in ribbon).
Exit (toss that query out – no need to save).
The result will be a new local table, with that number column.
Now, empty data from that local table.
(Ctrl-g to debug window)
Currentdb.execute "delete * from NewLocalTable"
Now do a compact + repair (this re-sets any autonumber columns in empty tables – might not be required – but just do it anyway). And it reclaims the empty space for that table we just emptied out.
Ok, now open that new local table in design mode. Select that first number id column, and delete it. (click on that row - likely first row - hit del key).
Now, click on first row to select the column that is first. Hit insert key to push it all down, and enter the name of the numbering column you JUST deleted. Tab key, autonumber, and then from ribbon whack the PK button (primary key button).
Close table designer. Save the design changes.
We now have an empty table with a PK autonumber column as the SAME name as what we had before.
Now, create new query, droop in linked table.
From ribbon choose append query, and enter name of new local empty table.
Drag the * into the query grid.
Run it.
We now have a local table, with PK autonumber, and the columns will match up to the linked table.
For a 10 second test?
Ctrl-g (jump to debug window).
Type in:
? dcount("*","linkeddBaseTabble name")
? dcount("*","NewlocalTable name")
The record counts should be the same.
At this point you have a local table with same columns + the PK ID autonumber column.
You can repeat the above over and over. It goes fast. 20-30 tables will not take long.
The result is now local tables, and each table will have an autonumber PK column with the same column name.
I would think the column as a linked table is “ID”, but it might be RECNO. (So use that for the local PK column names).
So you:
Link to dbase table.
Query builder – make table.
Ctrl-g to empty local table:
Currentdb.execute "delete * from local table name"
Open local table in desing - delete number column, add it back as PK autonumber.
Query builder, drop in linked table. From ribbon select append query, enter name of local table.
Drag “*” to query grid – run it.
You now have a local table, with PK autonumber same as linked table.
Move on to next table to import (add an autonumber to each table you import with above few steps.

You could just import the tables in Access...and work your way using them as blueprint.
Just ensure that the "table relations" are correct... i know that there isn't one but take the "logical" path...if you a table with a fieldName "FaxBookID" and you have a table "FaxBook" ...you know they are related

Related

MS Access - Table where all deleted items go to

I need a table where all deleted items from my main table go. I found the easiest way to do this is to copy my main table, paste the table and change the name. In my main table I went to the design tab, Create Data Macros, after delete. In the set field I put the name of the field, and for the value I put [Old].[ID] etc. My problem is this works great until I try to add in my "comments field" to the list. My comments field data type is "Long Text".
Somethings I have tried: deleting all calculated fields and adding them back in as short text (worked for some fields), Deleted all default values, deleted all validation rules.
Expected result would be for my deleted record from my main table to show up into the deleted records table. I receive no error message when deleting a record. It simply doesn't add to the to the deleted table. Thanks for looking.
Why copy tables? Create a yes/no field On your table called "Deleted." Then you can run a query for or against that field depending on if you want to see the deleted data or not. Add the field to existing queries that shouldn't show these, and set its criteria to false.

Access Records/Rows disappearing from lookup table

Access 2013
I have a simple lookup table that twice in the last month a record (different record on each occasion) has disappeared.
Since the auto id of the table is used as the foreign key I am forced to drop the table and recreate it.
I don't provide any delete functionality at all to users in the Access DB and especially not to the lookup table.
I have done a global search for all references to the table in my VBA code and found it was used several times but only in select statements.
At the moment I suspect a user is fiddling with something they don't fully understand and they are inadvertently deleting the record.
What else can I do determine the cause of this problem?
Can I make the lookup table read only?
Look at the relationships window. Look at the linked tables in question and see if there is a 'Cascade Deletes' checked. If so, deleting one record will delete related records.
It turned out to be a second lookup table that had a temporary relationship defined in the query that was not required. i.e: no columns were based upon this unnecessary table. This unnecessary lookup table was simply being used as a row source for a combobox on the form.
I discovered this after I noticed the form data type was set to Dynaset (Inconsistent Updates). Why? When I tested the form with normal Dynaset the form refused to perform any updates!
When I removed the unnecessary lookup table from the query I was able to set the data type back to Dynaset with updates continuing to work and deletions no longer cascading through to my first and required lookup table.
In addition the unnecessary lookup table was actually a query that was referencing a table in another database.

Sequential Number in Access Form Based on Field Selection

Hoping someone can assist here, I'm fairly new to SQL but yet the most experienced person in the office so this job has fallen to me.
I'm trying to build a form that will insert customer orders into production scheduling. The form allows users to select a machine from the machine list table, however what I need it to do after that is find the last job number for that specific machine and show the next sequential number in a text box; and that's where I'm stuck. The goal is that when the production user is adding an order to the database, by selecting their machine the next available job number is automatically populated. The information entered will be saved to a master scheduling table.
I've got a query built that pulls the entire list of machine and job combinations, as my goal was to build a macro that could search from that list, but so far I haven't gained any traction. Any help/advice would be appreciated!
Welcome to SO.
My suggestion would be to create a table to hold the sequence numbers. For the sake of this example, let's call it ProdSeq, which means Production Sequences. As part of this table definition, I would use Data Macros (Access 2010 and up) in order to assign the sequences as records are added. I would use a Unique index in order to ensure no duplicates are created.
Table: ProdSeq (Field Definitions)
MachineID (Number - Long) - References Machine ID in Machines Table
ProdSeq (Number - Long) - Incremented for each machine
OrderID (Number - Long) - References Order ID in Orders Table
Indexes
Under the Design ribbon tab when designing the ProdSeq table, click the Indexes button.
Create an Index called UniqueKey
Row 1: Index Name = UniqueKey, Field Name = MachineID
Row 2: Index Name = Leave Blank, Field Name = ProdSequence
Click on Row 1, Column 1 and set the following Index Properties:
Primary = Yes
Unique = Yes
Ignore Nulls = No
Data Macros
Under the Design ribbon tab when designing the ProdSeq table, click the Create Data Macros button, and then the Before Change button. Enter the following data macro: (Pastebin link)
Create the Before Change data macro and set it as follows:
If [IsInsert] Then
SetLocalVar
Name LatestProdSequence
Expression = 0
Look Up A Record In ProdSeq
Where Condition =[ProdSeqLookup].[MachineID]=[ProdSeq].[MachineID] And
[ProdSeqLookup].[LatestSeq] = True
Alias ProdSeqLookup
SetLocalVar
Name LatestProdSequence
Expression =[ProdSeqLookup].[ProdSequence]
SetField
Name ProdSeq.ProdSequence
Value = [LatestProdSequence]+1
SetField
Name ProdSeq.LatestSeq
Value = True
End If
Pay special attention to the fact that only one SetLocalVar is within the LookUpRecord clause. Use the collapse / expand (-/+) button on LookUpRecord to make sure.
Create the After Insert data macro and set it as follows: (Pastebin Link)
For Each Record In ProdSeq
Where Condition = [ProdSeqFlagFix].[MachineID]=[ProdSeq].[MachineID] And
[ProdSeqFlagFix].[LatestSeq]=True And
[ProdSeqFlagFix].[ProdSequence]<>[ProdSeq].[ProdSequence]
EditRecord
SetField
Name ProdSeqFlagFix.LatestSeq
Value = False
End EditRecord
Test it Out
You can create this in a blank database in order to see what I am talking about. You should be able to adapt it to your specific situation.
Form
On your form, when the user selects a machine and order, you can use VBA in order to check for an existing record in ProdSeq, and fetch the ID. If no record exists, then you can create one, and then return the ProdSeq ID to the form.
Note: Depending on your design, you may also need to create a Data Macro on the Schedules table. Suppose someone creates a schedule with a specific machine and order and reserves a production slot. Now assume they change the Order ID .. we have a production slot reserved in error. So if this applies, you'll also need an AfterUpdate data macro on the Scheduling table that checks to see if [old].OrderID <> [Schedule].OrderID - and if they do differ, to remove the Production slot from the schedule table and the Prod Sequence table.
As I understand, you need to add suggested value for job number when you add new record to the table. If so, you can use, for instance DMax function. Here is example of VBA code for this, it can be called when you add new record:
Me.MyTextBox = DMax("JobField", "JobsTable") + 1
I supposed that JobField, which contains job numbers has Number data type.
Also you can use this function inside any query as a calculated field.

MS Access - Add new record using form and add info to subform

Not exactly sure how to title this one..
I have 2 tables (websites & website_info).
The websites table has a column called websites_website_info_id, which has a relationship linked to the website_info_id row in the website_info table.
I created a form from the websites table, and I want to be able to choose a row from the website_info table (in a subform). For example, the website_info table has a list of hosting providers used, I need to link these hosting providers with the websites. Only problem is, I cant find a way to choose a singe row from the website_info table and insert the id number into the websites_website_info_id column of the websites table.
I can create a lookup to find the ID, but i have to copy and paste it, which is not ideal because there will be others using this app. If it was just me, then i would be ok with that, but I need it to be as easy to use as possible for anyone to use without having to give too much instruction.
So, is there a way to find a value in a subform and add a value from the subform to a column in the main form.
Normally I would just use a lookup on the column in the table itself, but the database is a myslq database hosting on an external server so using lookups isn't an option.
Yes.
This will - in the main form - return the current ID of the subform:
Dim SubId As Long
SubId = Me!NameOfYourSubformControl.Form!ID.Value

How to restart counting from 1 after erasing table in MS Access?

I have table in MS Access that has an AutoNumber type in field ID
After inserting some rows, the ID has become 200
Then, I have deleted the records in the table. However, when I tried to insert a new row, I see that the ID starts with 201
How can I force the ID to restart with 1, without having to drop the table and make new a new one?
In Access 2010 or newer, go to Database Tools and click Compact and Repair Database, and it will automatically reset the ID.
You can use:
CurrentDb.Execute "ALTER TABLE yourTable ALTER COLUMN myID COUNTER(1,1)"
I hope you have no relationships that use this table, I hope it is empty, and I hope you understand that all you can (mostly) rely on an autonumber to be is unique. You can get gaps, jumps, very large or even negative numbers, depending on the circumstances. If your autonumber means something, you have a major problem waiting to happen.
In addition to all the concerns expressed about why you give a rat's ass what the ID value is (all are correct that you shouldn't), let me add this to the mix:
If you've deleted all the records from the table, compacting the database will reset the seed value back to its original value.
For a table where there are still records, and you've inserted a value into the Autonumber field that is lower than the highest value, you have to use #Remou's method to reset the seed value. This also applies if you want to reset to the Max+1 in a table where records have been deleted, e.g., 300 records, last ID of 300, delete 201-300, compact won't reset the counter (you have to use #Remou's method -- this was not the case in earlier versions of Jet, and, indeed, in early versions of Jet 4, the first Jet version that allowed manipulating the seed value programatically).
I am going to Necro this topic.
Starting around ms-access-2016, you can execute Data Definition Queries (DDQ) through Macro's
Data Definition Query
ALTER TABLE <Table> ALTER COLUMN <ID_Field> COUNTER(1,1);
Save the DDQ, with your values
Create a Macro with the appropriate logic either before this or after.
To execute this DDQ:
Add an Open Query action
Define the name of the DDQ in the Query Name field; View and Data Mode settings are not relevant and can leave the default values
WARNINGS!!!!
This will reset the AutoNumber Counter to 1
Any Referential Integrity will be summarily destroyed
Advice
Use this for Staging tables
these are tables that are never intended to persist the data they temporarily contain.
The data contained is only there until additional cleaning actions have been performed and stored in the appropriate table(s).
Once cleaning operations have been performed and the data is no longer needed, these tables are summarily purged of any data contained.
Import Tables
These are very similar to Staging Tables but tend to only have two columns: ID and RowValue
Since these are typically used to import RAW data from a general file format (TXT, RTF, CSV, XML, etc.), the data contained does not persist past the processing lifecycle
I think the only ways to do this is outlined in this article.
The article explains several methods. Here is one example:
To do this in Microsoft Office Access 2007, follow these steps:
Delete the AutoNumber field from the main table.
Make note of the AutoNumber field name.
Click the Create tab, and then click Query Design in the Other group.
In the Show Table dialog box, select the main table. Click Add, and then click Close.
Double-click the required fields in the table view of the main table to select the fields.
Select the required Sort order.
On the Design tab, click Make Table in the Query Type group. Type the new table name in the Table Name box, and then click OK.
On the Design tab, click Run in the Results group.
The following message appears:
You are about to paste # row(s) into a new table.
Click Yes to insert the rows.
Close the query.
Right-click the new table, and then click Design View.
In the Design view for the table, add an AutoNumber field that has the same field name that you deleted in step 1. Add this AutoNumber
field to the new table, and then save the table.
Close the Design view window.
Rename the main table name. Rename the new table name to the main table name.
I always use below approach. I've created one table in database as Table1 with only one column i.e. Row_Id Number (Long Integer) and its value is 0
INSERT INTO <TABLE_NAME_TO_RESET>
SELECT Row_Id AS <COLUMN_NAME_TO_RESET>
FROM Table1;
This will insert one row with 0 value in AutoNumber column, later delete that row.