VB7
VB7
Part 1
Introduction
Welcome to the very first part in this wizzy Visual Basic Database tutorial!
I'm your crackingly cool host, Karl Moore and over the next few weeks we'll be covering everything you
ever wanted to know about databases, but were too afraid to ask.
Whether you’re wanting a Christmas bonus or just need to boost your Visual Basic knowledge – I'm here
to help.
Don't forget that I love to hear feedback! Feel free to send me a message, abusive or otherwise by clicking
on the "Post Feedback" link at the end of the page.
Now let's get that wizzo brain cap on – as we prepare to answer the following searching questions:
• Erm… so what's a database?
• Why don't those tables have any legs?
• What's Microsoft Access got to do with it?
• Why is the grass green?
• How do I build my own mini database program in VB?
• What is the meaning of life?
Well, let's get the philosophical stuff out of the way first. The meaning of life is 42 and grass is green
'cause all the other rainbow colours are absorbed and only the green reflected, a process known as
subtractive colour mixing.
Ha - and they said this tutorial wasn't going to be interesting!
What's a Database?
When I first entered the geeky database scene, I shivered at the "d" word. Eugh, who
wants to play around with databases? Certainly not me, I just wanted to program.
But you soon realise no matter what type of program you're creating, databases can be
pretty cool things.
A database is essentially just a store of information. They usually come in the form of a
simple file (just like a Microsoft Word file, say). You can shove information into this store
or retrieve it from the store, with virtually no code at all.
Top Tip: You can make friends and impress the opposite sex at geeky cocktail parties by
saying "DB" instead of database.
Hmm, doesn't sound terribly complex does it? Erm, that’s because it's not. Most database
wizards just like to overcomplicate things in a bid to scare off any programming newbies.
Now, listen up. A database may include many different tables. You can imagine a table as
one worksheet in an Excel workbook.
Each column of the worksheet may hold something different. Column A, for example,
could hold a customer name, column B may hold the customer postal code and column C
may hold the customer telephone number.
That's all a table is – a set of pre-defined "slots" or "boxes" into which you throw
information. Each of those boxes has a descriptive name, such as "TelNumber".
Because we're supercool geeks, we’re not allowed to call those boxes… err, boxes. We
need to call them "fields", because it's the done thing and boosts your street-cred.
Just like an Excel worksheet, you can add new entries to the table – by simply filling in a
new set of fields. So each time you need to add a new customer, you just fill in the
Top Tip: You cannot eat your dinner off a database table. This is considered highly
uncool in the database world. Also, it's inadvisable to graze sheep in a table field.
OK, let’s run over those wizzy terms once more:
• Database – a bunch of tables
• Tables – store numerous rows of information
• Fields – the little boxes inside a table
A database can also contain relationships and queries. You can even have a relationship
with a query, but the Church doesn't commend it. Either way, that's pretty geeky stuff – so
we'll cover it later.
Let me Loose!
Don't tell me, your boss has asked you to develop a supercool database system and handed
you a deadline of yesterday.
You don't want to hear me babble about database theory - you need to get stuck in! Well,
I can take a hint – so let's get down and dirty, and develop our first Visual Basic database-
integrated application… with absolutely no code at all!
1. Start Visual Basic – if you’re unsure about this, check out my Visual Basic tutorial here
</beginning/vbtutorial/>.
If you're likening this to an Excel spreadsheet, you can imagine that with each click you're
moving down or up one row and displaying all the customer information on that line.
Try changing one of the company names and moving forward a few records – then moving
back. You should notice that your changes have been saved!
That's what a database table is all about. They allow you to add "rows" of information to a
table, edit stuff currently sitting in the table, remove entire rows or bunches of rows from a
table… even find rows in a table!
Top Tip: Instead of using the word "row" to describe a line of information in a table, try
using the term "record" instead. Don’t ask why, just trust me… I'm a programmer.
Creating a Database
That's all fine and dandy, but how do you actually create a database?
Unfortunately, just to confuse us all, there are many different types of databases. First off,
there's an expensive whopper of a database system called SQL Server, which is used in
corporations that need to store huge wads of information. There’s also that thing they call
Oracle, which is another database format.
But one of the most exciting (and cheap!) types of database is an Access database.
Remember when we changed the DatabaseName property of our data control to
"Nwind.mdb"?
That Nwind.mdb file is actually an Access database.
The best way to create your own Access database is by using, unsurprisingly, Microsoft
Access. This tool ships with the professional editions of Office 97 and enables you to
graphically design your own tables and individual fields.
If you don’t already have Microsoft Access, add it to your Christmas list – and be a good
boy. If you do have it, brilliant!
We'll delve into the intricacies of creating your own database next week – but for now let's
explore the existing Nwind.mdb database:
1. Click on Start, Programs, Microsoft Access
2. Select "More Files…" then click OK
3. At the Open dialog box, select the Nwind.mdb file – don’t forget, by default it is
installed at C:\Program Files\Microsoft Visual Studio\VB98\Nwind.mdb
4. Click OK when the boring "Welcome to Northwind" screen appears
5. A box should appear on your screen, looking a little like this:
6. Click on the tab entitled "Tables". These are all the tables in your database – including
the Customers one we browsed earlier in this tutorial
7. Double-click on the Customers table. You should see something like this:
</php-bin/showpic.php?section=articles&shortname=dbtutorial&image=image7big>
Blow Up! </php-
bin/showpic.php?section=articles&shortname=dbtutorial&image=image7big>
4. In the Properties window for the FlexGrid control, click on the 'DataSource' property. A list of Data
controls will appear - it should just contain the 'Data1' control you added above. Select it.
5. Change the DatabaseName property of the Data control to point to that Nwind.mdb database we talked
about last week. Mine is located at "C:\Program Files\Microsoft Visual Studio\VB98\Nwind.mdb"
6. Now insert the following code behind your command button:
On Error GoTo OhDear
Data1.RecordSource = Text1.Text
Data1.Refresh
Exit Sub
OhDear:
MsgBox "Euston, we have a problem!"
7. Err, that's it!
But just before you start telling all your friends how simple SQL is... errm, don't. It can get much more
complicated... yah booh, sucks to you, SQL!
Who are you calling a criterion?
You pick up the telephone and the caller says, "Grassy ass! My name is Maurizio Moroni and I have a
question, pleasssse!"
Hmm, you think. You'd really like to get a job with some cool company - so if this dodgy sounding
Maurizio is the owner of a customer company, then you'll probably want to sweet talk him. Of course, if
he's just a sales representative or some such, you'll want to tell him to stop bothering you.
And wahay, SQL can step in here to help. Let's take a peek at another SQL statement:
Select ContactTitle from Customers
where ContactName="Maurizio Moroni"
Despite all those strange asterisk symbols and criteria boxes lying all over the place, you'll soon get the
hang of using this 'query' builder.
Top Tip: If you have a sore throat, try drinking warm honey mixed with fresh lemon juice.
Double click on the ContactName field in the 'Customers' table. Then double click the ContactTitle field.
They should both appear on your screen, as so:
You've just designed your first query. You're asking the database "Show me everything in the
'ContactName' and 'ContactTitle' fields in the Customers table" - just as we did in the last section.
Click on View, Datasheet View. Your screen should look something like this:
Now run the query by entering into Datasheet View. You should find that all the companies are now listed
in alphabetical order.
The SQL statement for this looks like:
SELECT Customers.CompanyName, Customers.ContactName
FROM Customers
ORDER BY Customers.CompanyName;
You can even reverse that order by changing 'Ascending' to 'Descending'.
Displaying Everything
To return all the fields in a table, we can double click on the asterisk in the Customer table, like so:
This tells Access you want to return every field (*) from the table. You could then perhaps add criteria to
the query, like this:
OK, so it ain't gonna win any design awards, but I'm no Christian Dior.
Now you could design and set all the properties for this project from scratch, but I
wouldn't advise it - particularly when you can download the form by simply clicking here
</articles/dbtutorial3/db3.zip>.
Boring Explanation Bit
Let me explain how I created the Customer Browser. Well, it all started when I bought a computer and
installed Windows 98. Then I purchased Visual Basic and played around a bit. Then I read a few books,
sat a few courses and watched a few videos. Then I did some other things.
And then I created the Customer Browser. How?
Then I added individual text boxes and "bound them" direct to the Data control. I did this by changing the
DataSource property to the name of the above Data control, then changing the DataField property to the
table field I wanted to 'connect' this text box with.
Next, I added six boring (really boring!) command buttons and changed their Caption properties. I'll add
code behind these later.
So far, I've created everything I need to browse the entire Customers table. But what about the orders?
First, I added another Data control to the project. The main control above will handle the customers,
whilst this one will retrieve the orders.
Next, I added the DBGrid control to my Toolbox by clicking Project, Components and selecting 'Microsoft
Data Bound Grid Control 5.0'.
Then I added an instance of the control to my form, as above - changing its DataSource property to the
name of my second Data control.
Now the design is over and it's time to code, geek-to-geek. Here's the code you'll find underneath each
command button:
Add New
datCustomers.Recordset.AddNew
'Go on, add a new customer!
'Just fill in the customer fields
'and move to another record. Then
'try using the Search button to
'find the customer again!
Delete
Due to the way Microsoft have setup the Nwind.mdb database, you can't delete customers that have orders.
If you do, you'll receive an error. You must first delete all the orders before deleting a customer. This type
of database integrity is maintained using "relationships", which we'll cover later in this tutorial.
On Error Resume Next
datCustomers.Recordset.Delete
'Delete the record
datCustomers.Recordset.Requery
'Then 'requery' the Recordset -
'which will 'refresh' it.
'It should show everything it did
'before, minus the deleted record
< Back
datCustomers.Recordset.MovePrevious
Forward >
datCustomers.Recordset.MoveNext
CompName = _
InputBox("Which company would you like to search for?")
'Get name from user, via InputBox
datCustomers.Refresh
'Refresh the customer Data control
You'll notice that for the majority of buttons, we're simply using a method of the Data control's Recordset
object, such as datCustomers.Recordset.Delete
The Recordset object in datCustomers is the bit that actually holds all the records. As its name implies, a
Recordset is simply a "set of records". So when you want to delete a record, you simply fire that method of
the Recordset.
Top Tip: You know how you can declare and work with strings in Visual Basic? Well, you can also
declare and work direct with Recordset objects in code, something we'll be covering later in this tutorial
Of course, you can always implement error handling and all that jazz into your command button code, but
I haven't bothered in other to keep things simple. And because I'm a complete sloth.
Now things may seem a little sticky when it comes down to the Search button code, but it's really pretty
straight-forward. The code is doing this:
• Grabs the company name from the user (InputBox stuff)
• Changes the RecordSource property to an SQL string, with the company name inserted in the
middle
• Refreshes the Data control to display the new bunch of records in the Recordset
There, that wasn't too bad, was it?
Orders Section
Well that's all fine and dandy, but we've still not thought about the customer orders section at the bottom
of our form. In English, we want it to display both the order date and the actual shipping date. But how do
we do that in code?
The Reposition event of the Data control fires every time the user moves to another record. And that's just
what we want - to update the Orders section every time we move to another Customer. So, our code looks
like this:
Private Sub datCustomers_Reposition()
datOrders.RecordSource = "select OrderDate, " & _
"RequiredDate from Orders where " & _
"CustomerID = '" & datCustomers.Recordset.Fields("CustomerID") & "'"
datOrders.Refresh
End Sub
This code fires every time our first Data control - datCustomers, the one that holds customer information -
is "repositioned". In the code, we're changing the RecordSource property of our second Data control to
retrieve the OrderDate and RequiredDate fields for all Orders that have a CustomerID same as the one in
the datCustomers.
The code - datCustomers.Recordset.Fields("CustomerID") - allows us to retrieve a singular field within
our Recordset. In this case, we're asking it to give us the CustomerID field.
So, in brief, every time the user moves from one record to the next, the Reposition event occurs. You
respond to this by refreshing the Orders Section and filling it with all OrderDate and RequireDate fields
that have the same CustomerID as the current Customer record.
Quickly knock together the above in your copy of Visual Basic. I’ve not set any special
properties, just added a few labels and text boxes.
I’ve named my three text boxes -
• txtCustID - the one that holds the customer ID
• txtTotalNumber - will display the total number of orders
• txtLastDate - will display the last order date
If you stick with these names, it’ll make code writing much easier later in this tutorial.
So that’s the design out of the way... now we need to think about code.
Fancy an Object?
Previously, we’ve accessed databases solely through the Data control. But this time we’re
doing it in code, using objects.
Just as you "Dim XYZ as String", we’re going to do the same with a collection of special
objects that allow us to play with our database. For example, you might write "Dim XYZ
as Recordset" - which is an object that holds a set of records - then later say
"XYZ.Delete", to delete one particular record.
I remember back in the golden olden days of my programming life, when I first saw
database access code. Argh! I mean, who’d want to write all that code when you have the
Data controls?
Brilliant! In the next section, we’ll get down to the real groovy stuff, something even more
exciting than the ‘Bumper Book of Italian Marriage Laws’... actual database code!
The Real Code!
Hold onto your frilly knickers folks, this is where we dive straight in at the deep end, with a tonne of real-
world code.
You should find the below code fairly easy to walk through, with comments every step of the way. Add
this behind your 'Find It!' command button and give it a test run!
Private Sub cmdFind_Click()
Dim db As Database
'This is the object that will hold the connection
'to our database
Dim rs As Recordset
'This is the object that will hold a set of
'records coming back from the database
Set rs = db.OpenRecordset(SQLString)
'This ties the recordset object with the database object.
'You're telling it to set the recordset object to whatever
'the "db.OpenRecordset" function returns. And that function
'will return a set of records according to the SQL statement
'you pass it.
txtTotalNumber.Text = rs.Fields("NoOfOrders")
'Simply throws the value in the 'NoOfOrders' field
'from the Recordset, direct into the txtTotalNumber
'text box
Set rs = db.OpenRecordset(SQLString)
'This is the second time we've seen this statement. Here,
'it says the Recordset object to hold the records
'from our new SQLString statement
txtLastDate.Text = rs.Fields("LastOrderDate")
'Here, we're taking the information from the 'LastOrderDate'
'field and placing it in the txtLastDate text box
rs.Close
'Close the Recordset
db.Close
'Close the Database
End Sub
Hit the End button and let's discuss this like the adults we're not.
Runtime errors occur when you’ve told Visual Basic to do something it really can’t handle. In this case,
it’s screaming: "No current record". But why?
In Visual Basic, each set of records has two special markers in it - known as the Beginning Of File (BOF)
and the End Of File (EOF).
The BOF sits just before the first record and the EOF, just after the last record. In graphical terms, it looks
a little like this:
OK, so I’m no Picasso - but you get the idea. And at least I’ve still got both my arms.
[Ed: Ears, Karl. Picasso cut off his EAR!]
If you remember, we set the Recordset object to hold the results of our SQL statement. Most of the time,
this will contain details such as the number of orders. But when the customer ID can’t be found in the
orders table - meaning the customer is either non-existent or hasn’t yet placed an order - an empty set of
records is returned to the Recordset object.
In graphical terms, that empty set of records looks like this:
Dim db As Database
'This is the object that will hold the connection
'to our database
Dim rs As Recordset
'This is the object that will hold a set of
'records coming back from the database
Set rs = db.OpenRecordset(SQLString)
'This ties the recordset object with the database object.
'You're telling it to set the recordset object to whatever
'the "db.OpenRecordset" function returns. And that function
'will return a set of records according to the SQL statement
'you pass it.
txtTotalNumber.Text = rs.Fields("NoOfOrders")
'Simply throws the value in the 'NoOfOrders' field
'from the Recordset, direct into the txtTotalNumber
'text box
Set rs = db.OpenRecordset(SQLString)
'This is the second time we've seen this statement. Here,
'it says the Recordset object to hold the records
'from our new SQLString statement
txtLastDate.Text = rs.Fields("LastOrderDate")
'Here, we're taking the information from the 'LastOrderDate'
'field and placing it in the txtLastDate text box
rs.Close
'Close the Recordset
db.Close
'Close the Database
End Sub
Top Props
When it comes down to databases, you can do virtually everything in code. Here are a few
of the top properties and methods of the Recordset object for you to play around with:
MoveNext - Moves to the next record in the Recordset MovePrevious - Moves to the
previous record MoveFirst - Moves to the first record MoveLast - Moves to the last
record Edit - Enters edit mode, for changing fields Update - Saves any edits AddNew -
Adds a new, empty record Delete - Deletes the current record RecordCount - (Number)
Returns the number of records currently accessed (move to the last record to get total
number of records) BOF - (Boolean) Hit when you step before the first record in a
Recordset EOF - (Boolean) Hit when you pass the last record in a Recordset
Indeed, using these simple properties and methods you could very simply replicate all the
functionality of the Data control.
Go on, have a go! Try to build a simple Customer browsing application, similar to the
one we created in the third tutorial.
At this point, we want to tell Access there is a relationship between the Owners table and
Pets table. Drag the OwnerID field in the Owners table over to the OwnerID field in the
Pets table and let go of the mouse button.
You should be prompted with the following:
Notice that Access has determined the relationship type as being 'One-To-Many' –
meaning there will be one occurrence of the OwnerID number in the first Owners table
and possibly numerous instances of that number in the Pets table.
And that's right – one owner can have multiple pets. Just as one company department may
have many employees. Just as each customer order may have numerous individual order
items.
So this One-To-Many relationship isn't justuseful in the vetinary world.
Check the 'Enforce Referential Integrity' button; this will ensure your data stays in tip-top
condition. In other words, your users won't be allowed to enter a value in the OwnerID
field of the Pets table that doesn't exist in the Owners table. After all, you can't really
associate a pet with an owner that doesn't exist!
All the referential integrity thing does is enforce that rule.
Click OK. Your screen should look something like this:
When you try to move off the record, you should receive the following groan:
Or in other words, "You can't add a pet without it having an owner, you crazy crazy crazy
person!"
Try changing the OwnerID to 1 and adding the pet once more.
Does it work? Bravo!!
Try adding all my pets to your list; the three iguanas – Wiggles, Green Thing and
Strangely Brown, and that 48 year old cow, Daisy.
It's worth noting that you won't be able to put anything but a number in the OwnerID
field. When we designed the table, we choose the 'Number' data type – which protects it
from strange dates, bits of horrid text or weird boolean values. Groovy!
OK… go back to the Owners table and try to add another record. You'll notice the
OwnerID number is automatically incremented...
... and you should now be allowed to add entries to the Pets table using that newly-
generated OwnerID number.
If you remember, the OwnerID is a Foreign Key. In other words, it's a number that links this particular
record to a parent record in the Owners table.
But asking your end user to input an OwnerID isn't very user friendly. And when you start creating
databases that are absolutely jam-packed full of Foreign Keys, it'll become more confusing then the Arabic
translation of Stephen Hawking's "Bumper Book of the Galaxy".
So you need to make it simple, by allowing them to select an owner from a list... but you should still insert
the OwnerID number into the field.
How do you do this? By use of a few little-known control properties...
Introduction <index.html>DAO or ADO? <index3.html>
DAO or ADO?
In previous tutorials, we've connected to databases using the bog standard Data control.
Now this seemingly innocent control accesses your Access database via a technology
known as DAO, or Data Access Objects.
Since those halcyon days of prehistoric data access, Microsoft has released another two
ways of getting at databases – Remote Data Objects (RDO) and ActiveX Data Objects
(ADO).
You will notice the builder inserted something similar to the following in the
ConnectionString property:
• Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Surgery.mdb;Persist Security
Info=False
This string tells ADO what type of database it is looking at and where it can be found.
Now, as with the DAO control, we need to tell it what information to retrieve:
• Click the ellipsis next to the RecordSource property
• Select Command Type '2 – adCmdTable'
• Select the 'Pets' table from the available list
• Click OK
Err, as this is a kinda one-way thing... I'll presume you answered with a resounding "yes!"
You should be able to scroll backwards and forwards through your Recordset using the
ADODC control. You should also be able to change the owner of a pet very easily using
This statement simply tells the Data Environment's Owners object to retrieve all fields from the Owners
table.
• Click OK
• Tap the little + next to the Owners object
You should see a list of fields your query returns – OwnerID, OwnerName and Address. But in this report,
I want to display each owner followed by every pet name and breed owned by that character. So we need
to tell our Data Environment about the Pets table:
• Right-click Owners and select 'Add Child Command'
• Rename the command you just created, 'Pets'
• As with the previous command object, enter an SQL statement of:
Select * from Pets
• Click OK
So far we've told the Data Environment about the existence of both tables, but not how they're related to
each other. So:
• Right-click Pets and select Properties
• Click the Relation tab – this is where you define the link between the parent object Owners and
the child object Pets
• In Parent Fields combo box, select OwnerID and likewise in Child Fields. Then click the 'Add'
button. This links the two lots of information together
• Click OK
Top Tip: You can change the SQL statement behind your 'command' in code with -
YourDataEnvironmentName.Commands("Owner").CommandText = _
"select * from owners"
This is the report window in which you may design your report. But before telling it what to display, you
need to tell it to link to your Surgery Data Environment:
• Click on the 'DataReport1' title to display relevant information in the Properties window
• Change the DataSource property to Vets and the DataMember to Owners
• Now right-click anywhere on the Data Report and select Retrieve Structure – clicking Yes when
prompted
Now select Window, Tile Vertically. This should enable you to see both the Data Environment and Data
Report screens at once.
First, drag the OwnerName field from the DataEnvironment direct over to the 'Group Header
(Owners_Header)' band. Do the same with the Address field.
</php-bin/showpic.php?section=articles&shortname=dbtutorial6&image=image15>
Blow Up! </php-bin/showpic.php?section=articles&shortname=dbtutorial6&image=image15>
Next, drag and drop the PetName and Breed fields over from the Data Environment into the 'Detail
(Pets_Detail)' band.
Now try formatting the report. Perhaps you'd like to bold or rename a few of the field labels, shrink the
Details section or add a title using the toolbox controls.
This is what my report looked like after a little fiddling:
</php-bin/showpic.php?section=articles&shortname=dbtutorial6&image=image16>
Blow Up! </php-bin/showpic.php?section=articles&shortname=dbtutorial6&image=image16>
Return to the main 'Groovy Pet Adder' screen and add a command button with a caption of 'View List of
Pets'. Behind that button, add the code:
• MyReport.Show
where 'MyReport' is, err, the name of your report.
Then run your program and hit the command button. Your report should look something like this:
</php-bin/showpic.php?section=articles&shortname=dbtutorial6&image=image17>
Blow Up! </php-bin/showpic.php?section=articles&shortname=dbtutorial6&image=image17>
Note the buttons in the top left-hand corner. Although you can remove these by setting a few properties,
they allow your user to easily print the report –even export it to various file formats, including a HTML
document
Cool, eh? In fact, it's cooler than Mr Cool the Cola Bear, winner of... oh darn, I've used that one.
For more information on creating a Data Report, search help for "Creating a Simple Data Report".
Visual Basic Database Tutorial - Part 7
By Karl Moore
Introduction
Good morning fellow geeks and geekesses! Karl Moore here as usual, attempting to glide you smoothly
through the rocky mountains of Visual Basic and database design. Ahh, paints a pretty picture, don't it?
[Ed: Beautiful]
If you're unfortunate enough to have missed the previous six slots (DOH!), check them out here:
• Part One </databases/dbtutorial/>
• Part Two </databases/dbtutorial2/>
• Part Three </databases/dbtutorial3/>
• Part Four </databases/dbtutorial4/>
• Part Five </databases/dbtutorial5/>
• Part Six </databases/dbtutorial6/>
This is the seventh and final part of our Visual Basic Database tutorial. Today, we'll be covering:
•
Hit that 'Test Connection' button – and cross your fingers. It should report back
that everything is A-OK
• Click OK
• You should now be in a position to christen the Data Link – I've called mine
Colossi, after the server to which it is linked
• Click the little + beside your data link
The Data View window should now look something like this:
And from here you can do virtually anything with your database – define relationships,
create new tables, knock out a couple of views, write stored procedures or do a few other
In this section, I've shown you how to use the Visual Database tools to link direct into a
major database format. But each type has its own little quirks, so I shan't delve too far into
this subject for fear of excluding virtually all of our readers – except perhaps Crazy Jo of
Mississippi and my technically au fait pet iguana, Strangely Brown.
[Ed: I remember him!]
But you now know how to access the Visual Database tools. And you'll probably need
them as you progress onwards in the wacky world of enterprise development.
So how do you jump to those upper echelons of the nerd-world? Read on...
What Next?
So what's to do from here?
If I've inspired you to take your database development skills to the next level, read on. If
not, perhaps it's time to backtrack to the advice of tutorial one - move into biology and
study subtractive colour mixing. Or become a Welsh sheep farmer. Or something
But if you'd like more, your next step is to start really playing around with database code.
Make sure you can retrieve figures from an Access database completely in code – without
referring to previous tutorials. Then get to know the Access query builder and its various
cool uses... don't forget, it's your friend!
Your next stop is to start learning more about the more powerful databases such as SQL
Server or ORACLE. As you walk down that road, you'll also bump into 'three-tier
architecture' - which is just a fancy word that means splitting an application up into a few
different bits, making it easier to maintain.
And if you're really geeky, you'll end up surrounded by inexplicable three-letter acronyms
such as MTS, IIS, ASP and MSMQ. Hold on, the latter is a four-letter acronym, but I'll let
it pass.
So where can you learn all this? I'd recommend books. I know, I know, it's difficult to find
time, blah blah, you have to finish that assignment, blah blah, the toilet needs unblocking,
zzzz...
Listen up, if you want to start earning mega-bucks in the world of Visual Basic and
databases, it's time to put the needs of your bathroom to one side. Ideally, I'd recommend
you purchase the following book:
• Professional VB Databases
<http://www1.fatbrain.com/asp/bookinfo/bookinfo.asp?theisbn=1861002025
&from=VUN347> – £35.99 GBP / $49.99 USD - by Charles William, Wrox Press
Author Charles Williams knows what he's talking about – and drags you through the ups-
and-downs of SQL Server, Structured Query Language, three-tier architectures, classes,
reports, data warehousing... and loads more.
If you really are keen on taking your skills to the next level, this is definitely the next step.
Alternatively, here are another couple of other bedtime reads from my bookshelf:
AuTd.Fields.Append AuFlds(0)
AuTd.Fields.Append AuFlds(1)
TitTd.Fields.Append TitFlds(0)
TitTd.Fields.Append TitFlds(1)
TitTd.Fields.Append TitFlds(2)
TitTd.Fields.Append TitFlds(3)
TitTd.Fields.Append TitFlds(4)
PubTd.Indexes.Append PubIdx
Else
CompactErr:
Exit Sub
End Sub
strFolder = String(MAX_PATH, 0)
lngResult = GetTempPath(MAX_PATH, strFolder)
End Function
Setting Tab Stops in a ListBox
Want to create a simple list box that shows several fields of data? The columns property of the list box
does not do this, but you can use this function to do it.
Public Const LB_SETTABSTOPS As Long = &H192
Public Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
picDestination.Visible = False
picDestination.PaintPicture picSource.Picture, _
lMidPoint * (1 - CosAmount), 0, dblWidth, _
picDestination.ScaleHeight
picDestination.Line (0, 0)-(lMidPoint * k, _
picDestination.ScaleHeight), lLeftCol, BF
picDestination.Line (picDestination.ScaleWidth - _
lMidPoint * k, 0)-(picDestination.ScaleWidth, _
picDestination.ScaleHeight), lRightcol, BF
picDestination.Picture = picDestination.Image
picDestination.Visible = True
End Sub
picDestination.Visible = False
picDestination.PaintPicture picSource.Picture, _
0, lMidPoint * (1 - CosAmount), picDestination.ScaleWidth, dblHeight
picDestination.Line (0, 0)-(picDestination.ScaleWidth, _
lMidPoint * k), lTopCol, BF
picDestination.Line (0, picDestination.ScaleHeight - _
lMidPoint * k)-(picDestination.ScaleWidth, _
picDestination.ScaleHeight), lBottomCol, BF
picDestination.Picture = picDestination.Image
picDestination.Visible = True
picDestination.Visible = False
picDestination.PaintPicture picSource.Picture, _
lHMidPoint * (1 - CosAmount), lVMidPoint * _
(1 - CosAmount), dblWidth, dblHeight
picDestination.Picture = picDestination.Image
picDestination.Visible = True
End Sub
These functions use the trigonometry function, cosine, to paint the picture on at different widths, giving
the effect of spinning. To use it, create a timer, setting the interval property to about 100, and two picture
boxes, called picspin and piccopy. Load a picture into piccopy, then add this code to the timer's timer
event:
Static curamount As Double
If IsEmpty(curamount) Then
curamount = 0.1
Else