How to display all data from 2 related tables in a dbgrid with sql - delphi

I'm new to delphi and have created an SQL query which displays the results of a search entered by the user through an edit box (showing data from 2 related tables) in a dbGrid.
The dbgrid displays no data until a search has been made and then the results of that search are displayed, however i was wondering whether it was possible to show all the related data in the dbgrid as if it were a table and the search then simply selects from it?
thanks

You could display all the data in the table. Then write an onExit event handler for your edit box which would look something like this (assuming that the string which you are entering in the edit box is supposed to match the value in the 'name' field of the query)
query.locate ('name', edit1.text, [loPartialValue]);
This will cause the dbgrid's cursor to jump to the first line which matches the string in the edit box.
Instead of using the OnExit event, you could also use the OnChange event of the edit box, but this would mean a search after every key stroke.
Your question was a bit vague so it's difficult to give a specific answer.

Related

How can I auto-fill Edit fields by using different options of a drop-down list?

am using a VCL form in Delphi, where I have put about 10 edit boxes.
These Edit boxes contain values that are related to specific models of solar panels.
These values are needed in order to calculate the output power of a solar panel.
So far, I am able to type these values in every run with the command:
c0:= StrToFloat(Edit1.Text);
for c0 to c10. But, instead of asking the user to manually type these 10 values in each run, is there any way to let the user select one option (i.e. a model of a solar panel) of a drop down list and these values being filled automatically for them?
Does the combobox do such a thing and if yes, how exactly? I am sorry, I am a very new Delphi user. Any help much appreciated.
Set the combo box Style to csDropDownList.
Populate the combo box Items with appropriate values for the user to select.
Add an OnSelect event handler. This will fire whenever the user selects a new item in the combo box.
Implement the OnSelect event handler by populating the edit controls with appropriate values, based on the value of ItemIndex.
You will need to think a little about the UI. If the user changes the combo box selection, then the edit control values change. But can the user then modify the edit controls? Now the values in the edit controls no longer match the combo box. Is that what you want? I guess that the UI needs a little more polish.

Delphi grid with a different data type in each row, displayed dynamically

I am trying to create a Delphi grid to allow display and edit in a db grid of data that might have a different data type on each row. I would like to display a specific control for each data type, e.g. when the data type is DateTime, I want to display my custom edit control that allows typing a date in or popping up a calendar.
The data looks something like this:
Name DataType DateValue StringValue BooleanValue
---------------------------------------------------------
A Date 1/1/2007
B String asdf
C Boolean True
...and in the db, this table has a column for each possible type of value. So, there is a BooleanValue column, DateValue, etc.
What I would like to do is display a single 'Value' column in the grid that displays the appropriate edit control depending on what the 'DataType' is for that row. So, the grid should look like :
Name DataType Value
---------------------------
A Date 1/1/2007
B String asdf
C Boolean True
It seems I will need to display a different edit control (to allow the user to edit the Value column) for each row dynamically based on the value of the DataType column. I know there are more advanced grids out there that handle this sort of problem, but the powers that be will not allow anything but what is available out-of-the-box with Delphi.
Any ideas on how to make something like this work?
Personally, I would not go for editing directly inside the TDBGrid in this case, since your Table is not DB normalized (I don't use it in any case actually). I would have used a Calculated field to display the desired value in the grid, And dynamically created the TDBxxxEdits on the form for each field type (How about your own TDBTreeEdit for example, a TDBRichEdit, or a DB Image pickup editor, etc...?).
In case you do want to use your own controls on the TDBGrid, and replace the default TInplaceEdit editor, you can refer the following article: Adding components to a DBGrid, and a related article: Displaying and editing MEMO fiels in Delphi's TDBGrid
Displaying all of the data in the same column is quite easy. You can simply add a calculated string field, and change the value according to what you are storing in that row.
The editing is quite a bit more complicated. If you want to have an in-place editor, you are in for a world of hurt... I've done it, it's a pain, and takes a lot of time. If you want to display a dialog to edit the value, that's much easier. You can add a column objects to the grid and you can setup the column you have attached to the calc field to display a button. When the button is clicked you simply display the editing dialog needed for that row, and commit the edits when the dialog is closed.
There are other ways to get this done, but I would say the above would be the shortest way. Other ways may include custom draw events to display your data in one column, intercept clicks to create your own editor, etc, etc, etc...
after add calculated fields .
Sample:
procedure OnCalculate(DataSet:TDataSet);
begin
case IndexText(DataSet['ValueType'],['Date','String','Boolean']) of
0:DataSet['DateValue']:=StrToDateTime(DataSet['Value']); // also converting
1:DataSet['StringValue']:=DataSet['Value'];
2:DataSet['BooleanValue']:= MatchText(DataSet['Value'],['1','True','T','Y','Yes']);
{etc datatypes}
end;
end;

Delphi 2007 Unable to modify the data in beforescroll event using source code, Error: Dataset not in Edit or Insert Mode

A bit of History:
I have a DBlistbox containing textt descriptions and I store just the codes of this in a mysql table which is displayed in a dbgrid. User can select multiple options and I like to process these and store as comma separated values in one of the columns (this column is invisible in the dbgrid).
Right now I can populate the listbox when the user scroll through the dbgrid using event Afterscroll and Formcreate. But when I try to process the list and update the myquery behind the dbrgid I get an error saying 'Dataset not in Edit or Insert mode' - I do this in beforescroll
Please help!!
I have tried to set the dataset to edit mode before changing then as soon the data is posted dbgrid seems to have funny characters
If I got you right, the DBListBox is not connected to the dataset lonked in the grid? This would explain why the grid's dataset is not set to edit mode when you change the data in the DBListBox.
Anyway, whenever you change data that has to go into the mysql table, you should switch this dataset into edit mode. Then you can place your coding of the comma separated values into the OnBeforePost event.
When the dataset scrolls without any change in the data of the listbox, there is no need to store any data. This is achieved with the above approach as without edit mode no BeforePost event will fire in this case.

How to fill a combobox when a row in a dbgrid is selected?

In Delphi 2007 I have a DBGrid. I need to fill a ComboBox when a row in the DBGrid is selected. The data in the the ComboBox depends on the selected row, and can be different for each selected row.
The DBGrid contains products orders. When an order is selected, I need a ComboBox to be filled with batch numbers of the product in the order. This batch number is saved in the order record, when the order is executed.
I could not find a onSelect or onChange event, which I could use to do this.
So how can I do this?
You should use TDataSet.AfterScroll event
If the data comes from a DataSet in a DataModule, as it looks from comments to #Roman response, you can rely on TDataSource events.
If your datasource is also located in the datamodule, you can place a new DataSource in the form itself (IMO is where it belongs).
Then, use the TDataSource.OnDataChange event, from help:
Write an OnDataChange event handler to take specific actions when a field in the current record has been edited and the application moves to another field, or when the current record in the associated dataset changes. OnDataChange is especially useful in applications that must synchronize data display in controls that are not data-aware. This event is typically used to make sure the control reflects the current field values in the dataset, because it is triggered by all changes.
The Field parameter is nil when the linked dataset is moving to a new record or refreshing a record buffer. The Field is not nil when the changes belong to a particular field (a user or the program itself changing it's value).
I suggest the double click event (OnDblClick) to catch when the user clicks with his mouse and OnKeyPress for the Enter key (Key=#13)

Benefit of using DBComboBox over CombBox?

So I'm messing around with a new project in Delphi 2009 and the default components that can be dropped onto a form for accessing data consist of a SQLConnection, DataSource and SQLQuery. If I add a simple select to the query component, say:
select name from customers
and then drop a DBComboBox on the form and link it up with the DataSource I get a single record in the combo box. After using Google for half and hour to figure out what I was doing wrong it looks like you have to manually add some code to your project which loops through the dataset and adds all the records to the drop down box. Something like:
while not SQLQuery.eof do
begin
DBComboBox.items.add(SQLQuery.fieldbyname('name').asstring);
SQLQuery.next;
end;
And that actually sort of works, but then you get a list in the drop down which you can't actually select anything from. Regardless of the result though I'm wondering why would you even use a DBComboBox if you have to manually add the result of your query to it? Seems to me that if it doesn't automatically populate the db combo box with the result of the query then we might as well be using a non-data-aware component like tcombobox.
I guess what I'm asking is why does it work this way? Isn't the purpose of data aware drag-and-drop controls to minimize the amount of actual written code and speed development? Is there a method that I'm missing that is supposed to make this easier?
A TDBComboBox doesn't get its list of values from the database; it gets its current value from the database. Link it to a field in your dataset, and when you change the active record, the combo box's current value will change. Change the combo box's current value, and the corresponding field's value will change.
If you want to get the list of values from the database as well, then use a TDBLookupComboBox.
This is all covered in the help:
Using TDBListBox and TDBComboBox
Displaying and Editing Data in Lookup List and Combo Boxes
Defining a Lookup List Column
I think you want the TDBLookupComboBox because that allows you to lookup from a list of items where the list comes from a dataset.
In the TDBComboBox, the list is just a TStrings manually filled with data.
--jeroen
DbCombox is a dbaware version of the standard combobox component.

Resources