Link to home
Start Free TrialLog in
Avatar of senad
senadFlag for Slovenia

asked on

get the names of the tables of an Access database

How can I get the names of the tables of an Access database
and have them display in TListView (or memo).Then on onchange event of the ListView
open the corresponding (selected) table in the grid (next to listview) and at the same time
have a label display the name of the table which was opened???
My database lies in my app.exe folder.
Just for the record, the database is allready opened (on main form create).
(ADOConnection1).This form in which  I am trying to do above is not the mainform.
I hope I do not have to disconnect...
Avatar of Mike Littlewood
Mike Littlewood
Flag of United Kingdom of Great Britain and Northern Ireland image

If you are using an ADO connection to connect to your database, pass a stringlist to the function below to grab all the table names
ADOConnection.GetTableNames(MyTables, False)  // wont get system tables if you set to false

Adding them to a listview

var
  lsti:TListItem
  iLoop: Integer;
begin
  // loop through the stringlist
  for iloop:= 0 to MyTables.Count - 1 do
  begin
    //add a new listitem to the listview
    lsti:= ListView.Items.Add
    // set the caption to the table name
    lsti.caption := MyTables[iLoop];
  end;
SOLUTION
Avatar of Mike Littlewood
Mike Littlewood
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Also a good idea to put the code

if ListView.Selected = nil then exit;

before everything, just to make sure something is selected
<I hope I do not have to disconnect>

No, just keep closing the ADOQuery, change the SQL, and reopen the query to change the data in the grid
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of senad

ASKER

Actually,I was looking for this :

procedure TForm11.FormCreate(Sender: TObject);
var
  tables: TStringList;
  i: integer;
  FN:     string;
  ConnStr: string;

begin
  FN := ExtractFilePath(Application.ExeName) + 'Mydatabase.MDB';
  ConnStr := 'Data Source=' + FN + ';Provider=Microsoft.Jet.OLEDB.4.0';
  ADOConnection1.Close;
  ADOConnection1.ConnectionString := ConnStr;
  ADOConnection1.Open;
  tables := TStringList.Create;
  try
  AdoConnection1.GetTableNames(Tables);
      for i:=0 to tables.Count-1 do
      ListView1.Items.Add.Caption := tables[i];
  finally
    tables.free;
  end;
end;



procedure TForm11.ListView1Change(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
{$IFNDEF D5H}
  if (AnsiCompareText(Item.Caption, 'Log') <> 0) then
    begin
{$ENDIF}
      Label1.Caption := Item.Caption;
      ADOTable1.Close;
      ADOTable1.TableName := Item.Caption;
      ADOTable1.Open;
{$IFNDEF D5H}
    end;
{$ENDIF}
end;


But if I may, I have a few questions regarding opening of the tables this way.
Clicking in listview opens the table in the grid,that is ok.
But how do I apply some functionality ?
I have a time field in one of the tables and when it opens it shows
30.12.1899 17:44:42
(It should show only time)
Since in ADOTable1 I can not have any fields I can not set the right format.
Or the field width,name etc...
Is there a way to correct this??
procedure TForm1.ADOQueryAfterScroll(DataSet: TDataSet);
var
  HH:            Integer;
  MM:            Integer;
  SS:            Integer;
begin
  HH := HourOf(ADOQuery.FieldByName('CURR_MOMENT').AsDateTime);
  MM := MinuteOf(ADOQuery.FieldByName('CURR_MOMENT').AsDateTime);
  SS := SecondOf(ADOQuery.FieldByName('CURR_MOMENT').AsDateTime);
  Edit_CurrentMoment.Text := IntToStr(HH) + ':' + IntToStr(MM) + ':' + IntToStr(SS);
end;
uses
  ...., DateUtils;
You change the viewing of the database grid at runtime to alter names and columns

DBGrid1.Columns[x].Width := 200;
DBGrid1.Columns[x].Title := 'Column 1';
Sorry that should read DBGrid1.Columns[x].Title.Caption := 'Column 1';

I thought you said you already had your connection to the database open, which is why I didnt write the rest of the code to connect along with the code to get the table names.
Avatar of senad

ASKER

eso , if I write that then when I open the table that has no such field I get the error...
and what is " Edit_CurrentMoment.Text "??? :-)
Edit_CurrentMoment: TEdit;

I made a simple example about your question and do visualization of the Time-Filed into a TEdit component to avoid:  30.12.1899 17:44:42

the above method     ADOQueryAfterScroll()
sets the correct visualization into Edit_CurrentMoment as:
17:44:42

What could be the reason that in your table  sometimes to have that Field, but sometimes to have not it ?
I don't understan this problem ....
Oh, I understand .... I am testing only a table, but you have more tables with different set of fields ....
Avatar of senad

ASKER

Yes,that is the problem...
Avatar of pcsentinel
pcsentinel

I haven't tested this but the simplest way would be to run through all the fields on the table and then set the format e.g.

var
      li: integer;
begin
      for li:=0 to pred(adotable1.fields.count) do
  begin
        if adotable1.Fields[li].DataType=ftDateTime then
          TDateTimeField(adotable1.Fields[li]).DisplayFormat:='hh:mm:ss';
  end;
end;

But there is a hard problem - not every field of type ftDateTime contains Time, some of them could contain Date and Time ....
Ok then just compare the value to >1 i.e.

var
     li: integer;
begin
     for li:=0 to pred(adotable1.fields.count) do
  begin
       if adotable1.Fields[li].DataType=ftDateTime then
       begin
         if adotable1.Fields[li].AsDateTime>1 then
           TDateTimeField(adotable1.Fields[li]).DisplayFormat:='dd/mm/yyyy hh:mm:ss'
          else
           TDateTimeField(adotable1.Fields[li]).DisplayFormat:='hh:mm:ss';
       end;  
  end;
end;

any time only value should have a value of less than 1 where a datetime should be greater than 1

Hope this helps
It is not so easy as you explain: it is possible to be a field about real Dates before 1900 and does not represent only a Time, for example - Bulgaria is liberated at 03.03.1878, but in your example it will be represent as Time ....
So there is not information that correctly distinguish fields what they really contain Date & Time, Date only or Time only ....
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial