| View previous topic :: View next topic |
| Author |
Message |
kearnguy General User

Joined: 29 Apr 2008 Posts: 6
|
Posted: Tue Apr 29, 2008 4:21 pm Post subject: Populating combo box based on selection in another combo box |
|
|
I have two combo boxes on a form.
The first is ClassCategory. The second is ClassName.
I want ClassName to only show data corresponding to the selection in ClassCategory.
Example:
- ClassCategory has available: Art, Science, and Math
- User selects "Science"
- ClassName shows: Biology and Chemistry
- User goes back to ClassCategory and selects "Art"
- ClassName now shows: Painting, Sculpture, and Crafts
How do I do this? I now it probably is based on a query, but I don't know where to begin.
Thanks |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Tue Apr 29, 2008 5:27 pm Post subject: |
|
|
I.m not sure how easy it is to do with combobox's but an example on how to use listbox's this way using macros can be found here:
http://www.oooforum.org/forum/viewtopic.phtml?t=57424
The macros if importance in the posting are:
onStatusChange_STKOUT_Category( oEv as object ) and
sub limitItems( aDataForm as variant, aCategory as string )
Cheers
Voo |
|
| Back to top |
|
 |
kearnguy General User

Joined: 29 Apr 2008 Posts: 6
|
Posted: Wed Apr 30, 2008 8:41 am Post subject: |
|
|
Thanks Voobase. I will play with this, but I am a total noob to database programming. I can read the code and understand the majority of what it is doing, but I have no clue where this code goes.
Is there a sample database that I can download and reverse engineer it to learn how to accomplish what I want?
PS You are right, I could do this with list boxes instead of combo boxes. |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Wed Apr 30, 2008 9:26 pm Post subject: |
|
|
Hi again,
Yes Base can have a bit of a learning curve attached to it. It wasn't too long ago I was at total noob status too. I will try to list the important things you need to learn to be able to comfortably design your own databases in Base:
1/ When creating your tables it is best to have an auto incrementing primary key on every one of your tables. Create your tables in design view (not Wizard) and put in your various fields and field types. The best way to get the auto incrementing primary key is to then press save and it will prompt you for a primary key. Select yes and once it is created you must then click on the primark key ID field and select "auto increment" down the bottom. Most people will be after a one to many relationship between there tables so don't forget to create an extra field in your second table of type "integer" that you label something like "Foreign_Key" (not auto incrementing)
2/ Using the form wizard is a really good way to get a basic database going that will have a 1 to many type relationship between two tables. Just follow it through and when it gets to subform you can ask the wizard to link the "ID" field in your master form to the "foreign key" of your subform. It is good to display these fields in your form while designing, so that you can see what is going on.
3/ Once created, to change things in your form you need to launch the form in design mode. To do this right click on the form and select edit. When you want to toggle between design and normal modes there is a button on your "Form Design" toolbar for this.
4/ There is also a button on the "Form design" toolbar for launching the "Form Navigator" This is increadably handy as it shows you the structure of your form in a tree like view. You can also select directly the individual controls and forms to examine their properties (right click). This gets you past the noob hurdle of not being able to see the properties of things because the form wizard automatically groups a control with its title. The other way around this is to right click on your fields and controls and select "ungroup".
5/ When you have found the properties of your forms and controls you will notice there are three tabs up the top. The "general" tab includes what the name of the control is (you will need to know this when using macros). The "data" tab shows you what data field the control is working with and the "events" tab is for choosing what action will trigger a macro.
6/ Make sure on your "Form Control" toolbar you have the "Wizards" button pressed in. This will launch a wizard when ever you drop something like a "listbox" or "tablecontrol" on your form. Make sure you have selected a field in either your mainform or subform when drawing a new control on your form so it ends up in the correct form. This can be checked with the "Form Navigator"
7/ With the fields in your form it is good to right click on them and choose "anchor to page". This will stop them from moving around on you too much.
8/You are now ready to think about macros. To edit your macros go to Tools>Macros>Organise Macros>OpenOffice.org basic or just press ALT F11. You can store your macros in "standard" or create your own folder by choosing Organizer>new. Click on the "module 1" macro file and choose edit. Put a new macro in... like
| Code: | Sub Simple_Macro
msgbox "Hi Earthling"
End Sub |
Now if you go back to your form you can experiment by choosing different events from your controls or forms, pointing the event to this macro and seeing in which circumstances they trigger the macro.
9/ An invaluable tool for helping with your writing of macros is XRay.
http://ooomacros.org/dev.php#101416
This tool allows you to call Xray from within a macro and it will show you all the properties and methods of a particular form or control. To use you would include a line in your code such as:
| Code: | | Xray oEv.source.model |
I recently explained to someone what my interpretation of all the oEv and oEvent stuff was here...
http://www.oooforum.org/forum/viewtopic.phtml?t=71057
10/ If you have downloaded an example database you will most likely need to import the macro file as well. To do this, go to macro's (ALT F11) then Organized>Libraries>Import and choose the script file. Sometimes there are dialogs too so that file may also need to be selected. Another important thing to do is register the database in Open Office. This is done by Tools>Options>OpenOffice.org Base>Databases and select "New"
Now you are ready for some examples. I am not sure of an easy one with a listbox that narrows the list of another listbox, however I have recently done some examples for some other people that include that feature. Have a look at this links...
http://user.services.openoffice.org/en/forum/viewtopic.php?f=13&t=5234
Let me know how you go. After you have done some re-work of your database and if you are having troubles getting the listbox narrowing macros working, post it somewhere (say.. mediafire.com) and let me know. I could have a quick go at getting it to work for you.
Cheers
Voo |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Wed Apr 30, 2008 11:48 pm Post subject: |
|
|
continued...
I Should also include a little more about ListBox's and Combobox's here...
Listbox's and combobox's are best used getting their "List Source" from separate tables. A combobox differs from a listbox in that, rather than having to select something from a list, it allows you to type in your own entry if required. A limitation of a combobox is that it only has one field that it can use to display and "put somewhere else". A listbox however also has something called a "bound field". This is an extra field and is usually selected as the primary key from the table that supplies the list source (when you create the listbox). In the data properties it just shows a "1" no matter what you have selected.
By having a bound field, the listbox can display one thing whilst storing the related primary key somewhere else. This feature is what enables us to create a situation where one listbox can narrow the field of another. If you look at the data properties of a listbox you will see a SQL statement that is responsible for deciding what is in the list. Usually something like: | Code: | | SELECT "Field_Name", "ID" FROM "Table_Name" |
"ID" is the "bound field" if you primary key was selected when the listbox was created. When we want to narrow the list we are really just adding to the SQL statement a "Where". for example.... | Code: | | SELECT "Field_Name", "ID" FROM "Table_Name WHERE "ID" = something |
Don't forget to have the "wizards" button pressed in when adding a listbox as this will prompt you through selecting the fields you need.
Now to populate the data tables so this type of arrangement will work, it is best if you create a separate mainform, subform writer document just for the purpose of populating the tables with entries that you want displayed in the lists. If you create a form how I explained in the above post where a one to many relationship exists, then you will be storing the data in the correct way. This is because the table that the subform relates to will also hold the primary key from the mainform where the entry is related to.
Voo |
|
| Back to top |
|
 |
kearnguy General User

Joined: 29 Apr 2008 Posts: 6
|
Posted: Sat May 03, 2008 7:22 am Post subject: |
|
|
| Awesome info... I am just now sitting down to read through it all. I appreciate the time you took to type it all out. Hopefully I will be able to get my solution from what I'll learn. Thanks again. |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Sun May 04, 2008 2:52 am Post subject: |
|
|
No worries,
Give a yell if you get lost doing the listbox's.
Cheers
Voo |
|
| Back to top |
|
 |
kearnguy General User

Joined: 29 Apr 2008 Posts: 6
|
Posted: Tue May 06, 2008 9:33 am Post subject: |
|
|
I guess I just don't get the basics somewhere. Forget auto-filtering of listbox data, I can't even get a listbox populated!
Here is my setup:
Sessions (Table)
- SessionID
- SessionName
ClassCategories (Table)
- CategoryID
- CategoryName
Classes (Table)
- ClassID
- SessionName
- CategoryName
- ClassName
Now I build a form called "AddNewClass" to populate the Classes table. I want a listbox to with SessionName as its source and a listbox with CategoryName as its source. All I could get was the integers from each of those tables to show up...
What am I doing wrong? |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Wed May 07, 2008 7:29 am Post subject: |
|
|
Hi again,
No, I think you are on the right track. A list box will display one thing and put another field from the listbox table's row somewhere else. Having the integers (Primary Key) show up in the table the listbox is attached to is a good thing. This way it is copying the Primary Key that identifies the particular row of data that holds your category name (or class name) and copying it into the other table where it is then known as a Foreign Key. You must make sure however that it ends up in an integer field that is called something along the lines of Category_FK or Class_FK. The advantage of doing it this way is that you are guaranteed that the Primary Key will always be unique where a class name may not always be.
The only downside of doing it this way is that you will need a macro to copy the actual Category or Class name across to the table the listbox is sitting in (your classes table), unless you use a query to get that name for you. Doing it this way should be OK for you because you will need a macro to make one listbox limit the items in the other. You can just incorporate copying the name across into those macros by adding a couple of extra lines of code.
....OK What I have done is quickly put together an example. I had already done something similar so quickly adapted it. Its a bit rough but I might be able to tidy it up a bit on the weekend. I have put it on mediafire.com. You will need to unzip the file then..
http://www.mediafire.com/?zndlcyafyzg
(EDIT: I have updated this example, it's simpler and works better. See next page of this thread)
Make sure you register the db in Open office (see point 10 from before) and import the script file which are the Macros.
The example has one extra table to what you have, the sesXREF table. Macro's are fired from the "on status changed" event of both listbox's and there is a Macro attached to the MainForm's "BeforeRecordChange" event.
There is also another form for populating the listbox tables with the correct categories and classes.
I'll explain more later, but have a play with it and see how you go.
Cheers
Voo
Last edited by Voobase on Fri May 16, 2008 12:36 am; edited 1 time in total |
|
| Back to top |
|
 |
kearnguy General User

Joined: 29 Apr 2008 Posts: 6
|
Posted: Sat May 10, 2008 7:36 am Post subject: |
|
|
Amazing stuff! I really appreciate your help. I am stumbling around this sample and getting some stuff to do what I want, and confused by other stuff...but I am learning. The macro is way beyond me in terms of knowing the Base framework (I'm a web dev - html, css, actionScript, JS, etc.), but I am starting to see how things work together.
I will probably have more questions as I keep playing, but feel free to chime in whenever you can if you want to clarify, explain, or clean up code.
Again, thank you thank you thank you for your willingness to help a noob who bit off more than he could chew. I'll keep you posted... |
|
| Back to top |
|
 |
JDHeinzmann General User

Joined: 04 Mar 2008 Posts: 44 Location: Manchester, NH
|
Posted: Sat May 10, 2008 8:47 pm Post subject: |
|
|
Regarding the Bound field in a listbox, | Voobase wrote: | | In the data properties it just shows a "1" no matter what you have selected. |
Actually, Voo, if you delete the 1 in Bound field, the bound field will be the first field returned by the SELECT statement. If the SELECT statement returns more than 2 fields, Bound field = 2 binds the 3rd field returned, etc. Thanks to a pointer from a newbie in another thread, details on this are clearly explained in OOo help by searching for "Bound Field". _________________ JD
MySQL 5.0.45-community-nt, OOo 2.3.1, MySQL ODBC 5.1.5, Windows 6.0 SP1. |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Sun May 11, 2008 4:13 am Post subject: |
|
|
Yeah thanks JD,
I was being a bit slack by not fully explaining that bit. What I should have said was that... it just displays a 1 no matter which field you have selected as your extra field.
I am wondering though, in what situation you would need to return more than this one extra field when using a listbox as it can only have a single bound field. All I can think of is, if you wanted to change the bound field "on the fly" by using a macro to change that property rather than having to change the Select statement and reload the list. Spose that is a good enough reason.
Cheers
Voo |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Sun May 11, 2008 5:12 am Post subject: |
|
|
Hi Kearnguy,
No worries. Happy to help.
I couldn't tidy that example this weekend as I spent most of Saturday chasing a bug which was stopping my main form from opening in the project I am working on. It even effected my backups and a reload of Open Office didn't help. Really had me going. What it ended up being was the Open Office "Quick starter" (I'm fairly sure). Its turned off now!
Good that you are learning. If you play with the macros by 'commenting' out bits to see what they do, by what they don't do, is always a good way of reverse engineering things. There is a lot in the macro that is just hacks to get it to behave the way I want it to.
An example of this is, after the second listbox has had its items limited, I have to load a non limited "select" statement back into the listbox, ready for when you change to another row in the subform. If I didn't do this then as you changed rows the listbox would show a blank value and also blank out any "bound values" that had already been put in the subform by that second listbox.
The "BeforeRecordAction" macro looks complicated but is just performing a "refresh" of the listbox. The "var_refresh" global variable is there so the macro only does a "refresh" when it is needed to, i.e after the SQL statement has been sent to the listbox. The refresh is needed to actually put the new list in the listbox list, but takes a fraction of a second, so I only have it occur just after listbox values have changed something and you then wish to change rows of the subform, not for when just browsing through the subform records which also calls the "BeforeRecordAction" event. The rest of this macro is there due to needing to use this particular event without an error occuring. There is a document that explains why, which is called "Forms and Dialogs" by C. Benitez, if you see P18.
http://www.geocities.com/rbenitez22/
Also in the macro is shown two different methods to copy the text from the listbox selection to another field in the subform's grid. The second way uses a "prepared statement" which would copy the value directly into the table the subform is based on using SQL. The first way is simpler and copy's the text into a control (text box or grid field) in the subform and then has the form do the updating of the table later when it does an "UpdateRow".
Anyway, if you have any questions on the listbox example happy to help here. I guess more general or other questions you might want to start a new thread.
I'll also try to tidy the example up a bit more when I get a chance with some clearer comments etc.
Cheers
Voo
Last edited by Voobase on Sun May 11, 2008 5:21 am; edited 1 time in total |
|
| Back to top |
|
 |
JDHeinzmann General User

Joined: 04 Mar 2008 Posts: 44 Location: Manchester, NH
|
Posted: Sun May 11, 2008 5:13 am Post subject: |
|
|
Hi, Voo,
| Voobase wrote: | | I am wondering though, in what situation you would need to return more than this one extra field when using a listbox as it can only have a single bound field. All I can think of is, if you wanted to change the bound field "on the fly" by using a macro to change that property rather than having to change the Select statement and reload the list. Spose that is a good enough reason. |
Actually, I think this functionality is there for when you specify a table directly (instead of writing your own SELECT statement). In that case, the result set for for the listbox includes all the columns of the table, so Bound field gives you a mechanism for specifying which field you want bound to the mainform's result set. But your idea of changing the bound field on the fly could be very cool.
The problem I see with using a table directly though is that the field used to populate the listbox's list is always the first field of the listbox's result set, so the table would need to be organized in such a fashion as to include that column first. In my case, I always construct my tables with the primary key (like WineryID) first and the column I wish to populate the list with (like Winery) later (like 2nd, 3rd or 4th) and thus I cannot use a table directly.
Ever since I have come to understand these wonderful properties of the listbox, I have had fun (yes, Base is starting to become fun for me) using the listbox in all kinds of crazy ways, all without needing Macro programming. For example, I created a main form with only a Table Contol on it to list all the wine bottles in one big list. Then, I used listboxes in the Table Control's columns to retrieve the data from all the associated tables (wine, grape, merchant, appellation and vineyard), even if there was only one Appellation, for example, associated with that bottle. No subforms required. In many cases, since I didn't need to change the data displayed, I would disable the listbox making the dropdown arrow disappear and giving the Table Control's list a pretty normal appearance. The only thing I don't like about this is that the alignment property for the listbox appears to be ignored (alway left justified) and the user is not able to sort the Table Control on one of these columns. Pretty powerful stuff though. _________________ JD
MySQL 5.0.45-community-nt, OOo 2.3.1, MySQL ODBC 5.1.5, Windows 6.0 SP1. |
|
| Back to top |
|
 |
Voobase OOo Advocate


Joined: 21 Nov 2007 Posts: 400 Location: Australia
|
Posted: Sun May 11, 2008 6:21 am Post subject: |
|
|
Thanks JD,
| Quote: | | Actually, I think this functionality is there for when you specify a table directly (instead of writing your own SELECT statement). In that case, the result set for for the listbox includes all the columns of the table, so Bound field gives you a mechanism for specifying which field you want bound to the mainform's result set. But your idea of changing the bound field on the fly could be very cool. |
I think you are totally correct. Thanks for explaining that. I forget that people may wish to use a table to directly supply a listbox's list. What you point out about the first field in the table having to be the displayed field would be a real impediment. I remember it not being too easy moving fields around in your table once it is created. I always let the "form design" GUI drop the Primary Key on for me when I hit save and it always goes to position 1.
| Quote: | | Ever since I have come to understand these wonderful properties of the listbox, I have had fun (yes, Base is starting to become fun for me) |
Yes likewise, Base is fun. I'm always up for a challenge and getting to know Base has never let me down there. As more and more things make sense and you find better ways to do things its good as that feeling of achievement grows.
| Quote: | | Then, I used listboxes in the Table Control's columns to retrieve the data from all the associated tables |
Sounds like an interesting way to do things. I havn't played with listbox's in table grids much yet. You were saying that it dosen't need to use many macros but do you have to limit the contents of the listbox's or are the list sizes fairly managable. There has got to be numerous vineyards and wine's. Do you limit these due to which Appellation is selected (I guess Appellation means region, from what wikipedia told me!)
Cheers
Voo |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|