[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Delphi - Setting selected item in DBLookupCombo at design time

Posted on 2009-07-12
15
Medium Priority
?
3,469 Views
Last Modified: 2012-05-07
I have a picklist which is a TDBLookupComboBox with its (lookup) list attached to a populated dataset.

When the combo box is first displayed, I want the app to select the first item in the list rather than waiting for user to select an item. I do not know at design time what the contents of the lookup list will be other than it will not be empty.

Is it possible to programatically select an item from the list rather than relying on user input?
0
Comment
Question by:gamutgroup
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 2
  • +2
15 Comments
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 24837390
use the AfterInsert event of the dataset to set any intial fields in the inserted record

if you want the first record, then you may need to execute a separate query to know which is first
this will also depend on sorting
unit Unit2;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, ExtCtrls, DBCtrls, DBClient, Mask;
 
type
  TForm2 = class(TForm)
    cds: TClientDataSet;
    dbcbbDescr: TDBLookupComboBox;
    DBNavigator1: TDBNavigator;
    ds: TDataSource;
    cdsSub: TClientDataSet;
    dsSub: TDataSource;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    DBText1: TDBEdit;
    DBText2: TDBEdit;
    procedure FormCreate(Sender: TObject);
    procedure cdsAfterInsert(DataSet: TDataSet);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.dfm}
 
procedure TForm2.cdsAfterInsert(DataSet: TDataSet);
begin
  cds.FieldByName('cdsDescrId').AsInteger := 1;
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  cdsSub.Active := True;
  cdsSub.AppendRecord([1, 'Test Descr 1']);
  cdsSub.AppendRecord([2, 'Test Descr 2']);
  cdsSub.AppendRecord([3, 'Test Descr 3']);
  cdsSub.AppendRecord([4, 'Test Descr 4']);
  cds.Active :=True;
end;
 
end.
 
--dfm--
object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'Form2'
  ClientHeight = 301
  ClientWidth = 467
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 120
    Top = 34
    Width = 10
    Height = 13
    Caption = 'Id'
  end
  object Label2: TLabel
    Left = 120
    Top = 57
    Width = 27
    Height = 13
    Caption = 'Name'
  end
  object Label3: TLabel
    Left = 120
    Top = 80
    Width = 27
    Height = 13
    Caption = 'Descr'
  end
  object dbcbbDescr: TDBLookupComboBox
    Left = 168
    Top = 80
    Width = 145
    Height = 21
    DataField = 'cdsDescrID'
    DataSource = ds
    KeyField = 'cdsDescrID'
    ListField = 'cdsDescr'
    ListSource = dsSub
    TabOrder = 2
  end
  object DBNavigator1: TDBNavigator
    Left = 32
    Top = 136
    Width = 240
    Height = 25
    DataSource = ds
    TabOrder = 3
  end
  object DBText1: TDBEdit
    Left = 168
    Top = 34
    Width = 81
    Height = 17
    AutoSize = False
    Color = clWhite
    DataField = 'cdsID'
    DataSource = ds
    TabOrder = 0
  end
  object DBText2: TDBEdit
    Left = 168
    Top = 57
    Width = 145
    Height = 17
    AutoSize = False
    Color = clWhite
    DataField = 'cdsName'
    DataSource = ds
    TabOrder = 1
  end
  object cds: TClientDataSet
    Active = True
    Aggregates = <>
    FieldDefs = <
      item
        Name = 'cdsID'
        DataType = ftInteger
      end
      item
        Name = 'cdsName'
        DataType = ftString
        Size = 20
      end
      item
        Name = 'cdsDescrID'
        DataType = ftInteger
      end>
    IndexDefs = <>
    Params = <>
    StoreDefs = True
    AfterInsert = cdsAfterInsert
    Left = 24
    Top = 24
    Data = {
      570000009619E0BD010000001800000003000000000003000000570005636473
      49440400010000000000076364734E616D650100490000000100055749445448
      0200020014000A6364734465736372494404000100000000000000}
  end
  object ds: TDataSource
    DataSet = cds
    Left = 72
    Top = 24
  end
  object cdsSub: TClientDataSet
    Active = True
    Aggregates = <>
    FieldDefs = <
      item
        Name = 'cdsDescrID'
        DataType = ftInteger
      end
      item
        Name = 'cdsDescr'
        DataType = ftString
        Size = 100
      end>
    IndexDefs = <>
    Params = <>
    StoreDefs = True
    Left = 24
    Top = 80
    Data = {
      4A0000009619E0BD0100000018000000020000000000030000004A000A636473
      4465736372494404000100000000000863647344657363720100490000000100
      0557494454480200020064000000}
  end
  object dsSub: TDataSource
    DataSet = cdsSub
    Left = 72
    Top = 80
  end
end

Open in new window

0
 
LVL 1

Expert Comment

by:ccupo
ID: 24837752

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, DBCtrls, StdCtrls;
 
type
  TForm1 = class(TForm)
    DBLookupComboBox1: TDBLookupComboBox;
    DataSource1: TDataSource;
    ADOConnection1: TADOConnection;
    ADOTable1: TADOTable;
    ADOTable2: TADOTable;
    DataSource2: TDataSource;
    Button1: TButton;
    ADOTable1SIFRA: TStringField;
    ADOTable1NAZIV: TStringField;
    ADOTable2SIFRA: TStringField;
    ADOTable2NAZIV: TStringField;
    ADOQuery1: TADOQuery;
    ADOTable2SJEDIS: TStringField;
    ADOTable1SJEDIS: TStringField;
    procedure Button1Click(Sender: TObject);
    procedure ADOTable1AfterEdit(DataSet: TDataSet);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var FirstValue:string;
begin
  ADOTable1.Active:=true;
  ADOTable2.Active:=true;
  ADOTable1.Edit;
end;
 
procedure TForm1.ADOTable1AfterEdit(DataSet: TDataSet);
var FirstValue:string;
begin
  ADOQuery1.Active:=false;
  ADOQuery1.SQL.Text:=
    'select  top 1 sifra from fs01 ';
  ADOQuery1.Active:=True;
 
  FirstValue:= ADOQuery1.fieldbyname('sifra').AsString;
  DBLookupComboBox1.KeyValue:=FirstValue;
end;
 
end.
 
////////////////////////////////////////////////////////////////
 
 
dfm:
 
object Form1: TForm1
  Left = 633
  Top = 104
  Width = 493
  Height = 350
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object DBLookupComboBox1: TDBLookupComboBox
    Left = 64
    Top = 120
    Width = 281
    Height = 21
    DataField = 'SJEDIS'
    DataSource = DataSource1
    KeyField = 'SIFRA'
    ListField = 'NAZIV'
    ListFieldIndex = 15
    ListSource = DataSource2
    TabOrder = 0
  end
  object Button1: TButton
    Left = 128
    Top = 232
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 1
    OnClick = Button1Click
  end
  object DataSource1: TDataSource
    DataSet = ADOTable1
    Left = 56
    Top = 16
  end
  object ADOConnection1: TADOConnection
    Connected = True
    ConnectionString = 
      'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initi' +
      'al Catalog=DB2007;Data Source=.'
    Provider = 'SQLOLEDB.1'
    Left = 104
    Top = 16
  end
  object ADOTable1: TADOTable
    Connection = ADOConnection1
    CursorType = ctStatic
    AfterEdit = ADOTable1AfterEdit
    TableName = 'FS01'
    Left = 160
    Top = 16
    object ADOTable1SIFRA: TStringField
      FieldName = 'SIFRA'
      Size = 15
    end
    object ADOTable1NAZIV: TStringField
      FieldName = 'NAZIV'
      Size = 60
    end
    object ADOTable1SJEDIS: TStringField
      FieldName = 'SJEDIS'
      Size = 60
    end
  end
  object ADOTable2: TADOTable
    Connection = ADOConnection1
    CursorType = ctStatic
    TableName = 'FS01'
    Left = 288
    Top = 32
    object ADOTable2SIFRA: TStringField
      FieldName = 'SIFRA'
      Size = 15
    end
    object ADOTable2NAZIV: TStringField
      FieldName = 'NAZIV'
      Size = 60
    end
    object ADOTable2SJEDIS: TStringField
      FieldName = 'SJEDIS'
      Size = 60
    end
  end
  object DataSource2: TDataSource
    DataSet = ADOTable2
    Left = 304
    Top = 64
  end
  object ADOQuery1: TADOQuery
    Connection = ADOConnection1
    Parameters = <>
    Left = 16
    Top = 16
  end
end 

Open in new window

0
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 24838948
>>ccupo
for inserting a record, the after edit does not get fired
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 24838961
>>ccupo
i tested it with below code :
even when editing a empty dataset , only the after insert will fire, not after edit
procedure TForm2.cdsAfterEdit(DataSet: TDataSet);
begin
  cds.FieldByName('cdsDescrId').AsInteger := 2;
  Memo1.Lines.Add('After Edit');
end;
 
procedure TForm2.cdsAfterInsert(DataSet: TDataSet);
begin
  cds.FieldByName('cdsDescrId').AsInteger := 1;
  Memo1.Lines.Add('After insert');
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  cdsSub.Active := True;
  cdsSub.AppendRecord([1, 'Test Descr 1']);
  cdsSub.AppendRecord([2, 'Test Descr 2']);
  cdsSub.AppendRecord([3, 'Test Descr 3']);
  cdsSub.AppendRecord([4, 'Test Descr 4']);
  cds.Active :=True;
end;

Open in new window

0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 24849254
[quote]
I want the app to select the first item in the list
<SNIP>
Is it possible to programatically select an item from the list rather than relying on user input?
[/quote]

To set the lookup list to the first items you have to do this:
  DBLookupCombo1.ListSource.Dataset.First;
 
0
 
LVL 22

Expert Comment

by:senad
ID: 24891742
set combos itemindex property to '0' or you can do it in code....
0
 
LVL 22

Expert Comment

by:senad
ID: 24891756
Here is an example :

procedure TForm1.Button1Click(Sender: TObject);
begin
table1.open;
dblookupcombobox1.ListSource.DataSet.First;
dblookupcombobox1.KeyValue :=
dblookupcombobox1.ListSource.DataSet.FieldValues[dblookupcombobox1.ListField];
end;
0
 

Author Comment

by:gamutgroup
ID: 24892631
DBLookupCombo doesn't have an itemindex property. The list is a dataset, not a stringlist (or list)

Solutions based on "dblookupcombobox1.ListSource.DataSet.First" look right but don't seem to work - i.e. moving the record pointer in the underlying dataset programatically doesn't seem to affect which item in the dropdown is selected
0
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 24897512
you can't change the combobox
you can only change the value of the field
the combobox will set itself

not the other way around
0
 
LVL 26

Accepted Solution

by:
EddieShipman earned 1500 total points
ID: 24898340
There is no way to do this without focusing the DBLookupCombo, calling the DropDown and sending it key events
to select the first item.

Reasoning is this:
TDBLookupComboBox is NOT a ComboBox control.
It has a TPopupDataList property, which has a SelectedItems BUT you cannot access it because it is private.
I can get the handle to the list but it also entails calling dropdown. However, once you have the handle, you cannot
send it regular List control messages. It is derived from TDBLookupListBox which will not accept list control messages.

The only way to do this is to write your own control and expose the private TPopupDataList.

Geert has the idea, though, if you set the Datasource's value to the first value in the ListSource, it will show the
first value in the list, like below...


with DBLookupComboBox1 do
begin
  ListSource.DataSet.First;
  // Locate the record you want to store the value to first before you edit!
  DataSource.DataSet.Edit;
  DataSource.DataSet.FieldByName(DataField).Value :=
      ListSource.DataSet.FieldByName(ListField).Value;
  DataSource.DataSet.Post;
end;

Open in new window

0
 
LVL 22

Expert Comment

by:senad
ID: 24899147
just set the keyvalue (property of dblookupcombo) to your default value  :-)
0
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 25002370
not that you might think, but you accepted a wrong answer ...

afterinsert
--> dataset is in edit mode and you can directly set the field as in my sample

browsing mode for existing records
--> if you call this method your field will change to the first listsource value and be posted (it won't even show the original value, well it will, but only for the time you can blink)

--> browsing mode with no records
dataset.post will create a record

Have you tested this solution ?
0
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 25002376
>>EddieShipman
these 2 lines:
-->  DataSource.DataSet.Edit;
-->  DataSource.DataSet.Post;

what if in insert mode ?
what if empty dataset ? (other key fields may be required)

>>gamutgroup
if you post the piece of your code where you use this,
i'll immediately point you to the problems

0
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 25002379
>>DBLookupCombo at design time
and for this, you'll have to create your own derived component
0
 
LVL 22

Expert Comment

by:senad
ID: 25008918
not to mention it will be all random data ....
0

Featured Post

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question