Add Conditional Column To Database

Hi Everyone.

First time poster, new to Visual Basic Express 2005, experienced with VBA.

I have 2 tables in an access database as shown below. I have created a vb express project with a link to the access database and a form with a datagridview showing table B.

What I would like to do is add a column to Table 2 either in design time or runtime. I want the new columns values to be the result of looking up the Limit column of table B and matching it to the Limits column of table A and adding the Current column to the interval column.

Hope that makes sense. Thanks in Advance.

Sam

Table A

LimitsCurrent
AC Hours1000
Engine 1 Hours1000
NG 1 Cycles1356
NF 1 Cycles1568
Engine 2 Hours1000
NG 2 Cycles1234
NF 2 Cycles1789
Hook Cycles189
Hoist Cycles213
Landings2300

Table B

Limit IDComp IDAircraftDateCountEventLimitIntervalPrior Count
11ZK-HQQ
0On ConditionAC Hours200000
22ZK-HQQ
0RetireEngine Hours20000
33ZK-HQQ
0RetireNg Cycles20000
43ZK-HQQ
0RetireLandings120000
55ZK-HQQ
0RetireAC Hours200000
65ZK-HQQ
0RetireLandings120000
77ZK-HQQ
0RetireAC Hours200000
88ZK-HQQ
0RetireAC Hours20000
99ZK-HQQ
0OverhaulAC Hours2000

[13601 byte] By [Reafidy] at [2008-1-10]
# 1

Nice tables !

If you're using the data designer I never found a way to change a table design after it was put in place but that was many years ago so I think design time is out which is one of many reasons why I won't use the data designer.

I have some other bad news for you. ADO does not have a way to add a column such that it is persistable in a database.

It's possible but I am not sure that the ADOX objects may use that but please be weary as they are COM Objects.

I believe you may be able to do this using sql statements. I have created entirely new tables with SQL.

What I said above relates to persisting these dataobjects. If there is no need to persist then, you can append all you want but it's my impression that this is not what you want to do.

This can be done thusly:

Dim a as new datacolumn

A.Datatype = system.type.Gettype("System.Integer") ' Case sensitve!!!!

A.ColumnName = "Bob"

Table.columns.add(a)

But I do not think there's anyway to persist this change without using ADOX or SQL.

ReneeC at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 2

Hi,

Thank you for the reply. Smile

Okay Ive carefully read your post a couple of times and Im thinking perhaps I didnt explain properly. I didnt use a data designer, I made the tables in MS access. I can change them to whatever I need. ie I can add a blank column if I need to.

The trouble for me is that I need a "formula" for this new column.

For example I managed to come up with a simple addition "formula" sorry I guess I should say "expression" (im new to non excel programs!) that add's to columns:

Code Snippet

Me.DB2DataSet.Tables("Limits").Columns("NewColumn").Expression = "[Prior Count] + [Interval]"

But this is not what I need. What I need is a expression that for each cell in this new column looks up the text in the "limit" column of "table B" and matches it to the "Limits" column of "Table A" and returns the corresponding value in the "current" column of "table A" which is then added to the value in the "interval" column of "table B". Arrrh what a mouthful I hope im making sense.

The results of the column I am trying to achieve would look like this:

21000

21000

21356

122300

etc..

Thank you very much for your help.

Sam

Reafidy at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 3

I was looking at your tables and i am guessing that you are trying to keep track of the hours on particular parts and perform maintenance or replace at certain intervals.

I don't know your system but it seems as though you could make it easier to keep track of individual parts and their hours if you were to break it up into several tables.

You have the same aircraft listed 9 times with different events, limits and intervals. After a while this is going to get real confusing to keep track of individual items.

Your master table could be the aircraft table for each individual aircraft

Then you would have a part or assembly table that would be a child of the aircraft table

this would give you the ability to keep track of specific parts for each aircraft

Then you have an hours table for each individual part or assembly

this will let you log individual hours for each trip or to make it easier you could just leave it with one record and update the hours as a total after each trip instead of dealing with a bunch of individual ones.

When you have them set up with a foreign key relationship then you can set it up to automatically filter the parts and hours based on which aircraft you select.

When you select aircraft with id - ZK-HQQ in the master table then it will show all the parts for that particular aircraft in the child part table and it will the show the hours for that particular part in the hours table.

Then you can run a report that will be based on a certain total hours for each part or assembly

Then you can check the total hours for each part or assembly and compare to the events and determine what needs to be done to the part or assembly.

I hope this makes sense

js06 at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 4
"

You have the same aircraft listed 9 times with different events, limits and intervals. After a while this is going to get real confusing to keep track of individual items."

The term for this is "normalization". This design is not normalized and the result will be exactly what JS06 described. Such databases are diffciult to support and to write code for. The are likely to be erroneous over time because one loses track of the locations of unnormalized data.

ReneeC at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 5
js06 wrote:

I was looking at your tables and i am guessing that you are trying to keep track of the hours on particular parts and perform maintenance or replace at certain intervals.

Yes Exactly!

I think I do actually have my tables setup similar to what you are saying. I just posted bad examples. I will post some actual examples from my tables below.

  • I have a main table (no example shown) with a list of all the aircraft and its details ie manufacturer, type, model...
  • I then have another table (Table A) which lists all the Limits that apply to the aircraft ie AC Hours, Engine Hours, Cycles, Landings...etc
  • I then have another table (Table B) which lists all the components on the aircraft. This table contains all the component details it does not contain details of the limits because one component may have more than 1 limit assigned to it ie AC Hours and Landings.
  • I have another table (Table C) which contains the limit details for each component.

All tables contain the aircraft rego ZK-HQQ. Tables B and C are linked by the "Comp ID".

The problem is I am trying to get the correct values in the "current", "remaining" and "due at" columns of table C. They need to look up the master limit table A to see where the aircraft is at in the "current column". The "remaining" and "due at" columns need to be calculated from this lookup column "current"

I have shown a few examples of the results i am looking for in the "current" "due at" and "remaining" columns.

Thanks you both for your ongoing help and patience. Smile

AC Master Limits (table A)
Limit Type Aircraft AC Serial No Description Current Total Calc Factor Date Last Updated TTCW DateCW
AC Hours ZK-HQQ 4381 Hourly Limit 100 100 Counts 23/02/01 50 20/06/07
Cycles ZK-HQQ 4381 Cycle Limit 120 120 Counts 27/02/01 89
20/06/07
Engine 1 Hours ZK-HQQ 4381 Hourly Limit 100 100 Counts 27/02/01 46
30/05/06
Months ZK-HQQ 4381 Monthly 0 0 Months 23/02/01

Days ZK-HQQ 4381 Days 100 100 Days 13/09/01

AC Hours ZK-HZZ 4234 Hourly Limit
1000 1000 Counts 27/09/07

Component Details(Table B)
Aircraft Tracking No TT Installed Sort Order Assembly Name Sub Assembly Name Component Part Number Serial No ATA Comp ID Date Installed
ZK-HQQ 104 1500 1


Seat Belt AS350-355678 3131 32-10 1 2/04/05
ZK-HQQ 105 1230 2

Tail Rotor Blade AS350-239984 2134 42-10 2 3/08/06
ZK-HQQ 106 1230 3 Aircraft
Rotor Drive
Main Drive Shaft AS350-242332 3213 31-43 3 3/08/06
ZK-HQQ 107 1430 4 Aicraft Fuel A/F Fuel Filter AS350-234232 432 43-34 4 2/09/06
ZK-HZZ 108 3450 5 Cockpit Guages Altimeter AS355-323211 1422 5 3/04/05

AC Limit Details(Table C)
ACLD ID Aircraft Limit Type Life Limit Event Current Prior Count Transacted At Remaining Due At Transacted Date Comp ID
1001 ZK-HQQ AC Hours 2025 Retire 100 0 50 1975 2125 1/01/01 1
1002 ZK-HQQ Cycles 3000 Retire 120 0 60 2940 3060 1/01/01 1
1003 ZK-HQQ Engine Hours 1 2025 Retire 0 1146.00

1/01/01 1
1004 ZK-HQQ AC Hours 4550 Retire 926 1146

1/01/01 2
1005 ZK-HQQ Cycles 6000 Retire 2999 2998.00

27/02/01 2
1006 Zk-HZZ Engine Hours 1 4550 Retire 926 1146.00

27/02/01 2

Reafidy at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 6

Ok, well i see basically what you are trying to do now.

You will have to bare with me because i have a little case of brain lock today. I have a lot on my mind because i am starting a new project and trying to think through setting up the database for it.

First let me say that i think i understand what you want as far as the calculations, however i think you could setup the whole database to work more efficiently for you. Let it do more of the work.

It still seems like the tables are setup a little more complex than they need to be.

I was thinking that it might help keep track of everything better if you were to break it up into more tables

Example:

Aircraft - master table (craft details and limits)

Assembly - child of aircraft

Sub Assembly - child of assembly

Component - child of sub assembly

And i see that you also want to keep track of the total hours and cycles of the craft itself

which i think you could do in the aircraft master table by using the limit types as your columns instead of a type for each row. And engine 1 would be a component of the aircraft wouldn't it?

What i am baseing all this on is the idea of keeping track of the time on all individual parts to either maintain or replace.

And i know this probably isn't exactly how it should be setup but i think this will give you more of an idea about normalizing it.

If you were to set it up similar to the above then if you had the tables on a single form then when you select a particular aircraft then it would automatically filter the assemblies for that aircraft and filter the sub assemblies for that assembly and also the components for that sub assembly.

If you were to select a different assembly then it would filter the sub assembly for that particular assembly and then filter the components for that sub assembly.

And if you were to select a different sub assembly then it would filter the components for that sub assembly.

It would all work in a chain.

Let me know what you think about all this and if it makes sense to you

It's late and i am tired so if it doesn't all make sense then let me know and i can get back to you

js06 at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 7

js06,

Thanks for your reply.

I currently have 2 datagridviews on my userform one which shows the component list table B. and when the users clicks on one of the components in that datagridview the second datagridview only show the limit details that apply to that component. I really like this for our particular situation it is very clear to the user. This is because one component might have a limit imposed by the manufacturer of 1000 AC hours and another limit of 3 Months and may be even another limit of 5000 Landing cycles just for that one component!

I dont have a need to filter by assembly or sub assembly yet. But I like your clever thinking and will definately think it over in fact I probably will use that idea. It would be good to like you say select an aircraft then have the 1st datagridview filtered to show only assemblies for that aircraft then filter again to show sub assemblies.

However I can still not see how that will help with my underlying problem. And that is getting the correct data for the calculations for the limits of each component. I only want to update the hours of the aircraft in the limit table I dont want to have to update the limits for each component individually.

Can you see away to do the calculations.

Thanks again for your help, its great, this is a big project for me and I am well aware of the complex nature and are more than prepared to put the work in. But I do appreciate all the help I can get!!

Reafidy at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 8

Once you get going on this i think it will get increasingly more difficult to have it automatically figure the time for each item if you don't set up the database correctly.

Either way what you are going to need is a set of loops that work together to look up the data in the limit table and match it to the current row of the compnent table.

Give me a little bit and i will give you some code to get you started on it. It won't be exactly what you need but it will give you a way to change it to make it work for you.

js06 at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 9

Ok i have some code for you.

This is based on the your first post where it shows tableA and tableB

How it works is to get the forst record from tableB and find the limit name and the interval

then it loops through the entire tableA untill it finds the match and then gets the current value

it adds the interval to the current value and then displays the total in the new column next to the record in tableB

It loops through every record in tableB repeating the same process

Basically

Get first record values in tableB

loop through tableA to find match then get value

add value and display

get next record and repeat again

etc...

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim totcol As New DataGridViewTextBoxColumn

totcol.HeaderText = "Total"

totcol.ValueType = System.Type.GetType(DbType.Int32)

Me.TableBDataGridView.Columns.Add(totcol)

Dim limitB As String = Nothing

Dim intervalB As Integer = 0

Dim limitA As String = Nothing

Dim currentA As Integer = 0

Dim total As Integer = 0

Dim tableBrow As Integer = 0

For Each rowB As DataRow In Me.DB2DataSet.TableB.Rows()

If Not TypeOf rowB("Limit") Is DBNull Then

limitB = rowB("Limit")

intervalB = rowB("Interval")

'MsgBox(r("Limit"))

End If

For Each rowA As DataRow In Me.DB2DataSet.TableA.Rows

If Not TypeOf rowA("Limits") Is DBNull Then

If rowA("Limits") = limitB Then

If Not TypeOf rowA("Current") Is DBNull Then

currentA = rowA("Current")

Exit For

End If

End If

End If

Next rowA

total = intervalB + currentA

Me.TableBDataGridView.Rows(tableBrow).Cells(9).Value = total

tableBrow = tableBrow + 1

Next rowB

End Sub

in this line Me.TableBDataGridView.Rows(tableBrow).Cells(9).Value = total

the cells(9) is the column index of the added total column

so if you have 5 columns and you add the new one - the index will be 5 because they start at 0

Now the problem you are going to have to face is if your database isn't setup properly it will never work correctly.

As you progress with this you will have to match up the aircraft, the assembly, sub assembly and then the component and then get the values.

I'm afraid though that as you move further into this project it will become very complex this is why you should set up your database correctly from the beginning. Once you get to a certain point you will realize that you may have to start over and redo the whole thing. But sometimes that may be unavoidable when working on a project like this. The whole idea is to keep everything in table groups to access the data easily and not have to find it in different places in the same table.

Let me know if you have any questions.

Good luck with it.

If you need me to i can send you the project i have setup with this code so you can see it work.
js06 at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 10

Ok excellent. So the solution is a lot of loops. I thought it would have been some kind of formula (thats my excel knowledge and inbuilt loathing of VBA loops getting in the way).

I understand all that code and can get it to work for my tables. I fully take onboard what you are saying about having the correct design. But I need to experiment a bit and find out the limitations before I can get a good design. I agree there will be times when I have to redo things due to bad design but I was expecting that.

One more question on the same issue. At the moment the code adjusts the values in the datagridview on the click of a button. What I would like is to calcuate and repopulate the values in the actual limits table when the program loads instead of in the datagridview. Then I can show the datagridview without having to loop each time its shown if Im switching between userforms. Is this possible?

Your ideas and suggestions have been very helpful!! - Thank You.
Reafidy at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 11

I'm not quite sure about populating the data in the table directly at the program load. I don't know how to do it with the loops. And i don't know how to modify the existing rows in the table directly.

If you are wanting to load the data and show it quickly when ready, another alternative might be to load the form and populate the datagridview at the program start and simply keep the form hidden untill you are ready for it. Instead of closing the form you can just hide it and then show it as needed.

Also, once you get the tables setup correctly, if you were to have the tables all on one form then you would not have to switch between forms. Or you can link the tables to work together on seperate forms and then you can just switch between the forms without closing them.

I would suggest starting a new thread for this question about populating the values directly in the table itself. This is just beyond my knowledge at the moment.

js06 at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...
# 12

Okay No Problem. Youve been very helpful. I will carry on with the project and if I need too I will start a new thread.

Thank you everyone who has helped me.

Reafidy at 2007-10-3 > top of Msdn Tech,Visual Studio Express Editions,Visual Basic 2005 Express Edition...