Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Über ADOX kein Zugriff auf Tabellenanzahl od. -felder (https://www.delphipraxis.net/27585-ueber-adox-kein-zugriff-auf-tabellenanzahl-od-felder.html)

Legolas 12. Aug 2004 16:38


Über ADOX kein Zugriff auf Tabellenanzahl od. -felder
 
Hallo alle zusammen,

ich werde noch verrückt. :wall: :wall:

Ich habe über ADOX eine Datenbank erstellt und darin eine Tabelle "Kunden" erstellt (Felder indiziert etc.), soweit alles wunderbar. Aber jetzt kommts:

Ich wollte mal die Tabellenanzahl in der Datenbank anzeigen lassen, im Prinzip auch kein Problem aber er zeigt mir gleich 6 Tabellen an obwohl ich nureine angelegt habe (nähmlich "Kunden" (1. Kunden, 2. MSAccessObjects 3. MSysACEs 4. MSysObjects 5. MSysQueries 6. MSysRelationships).

Dann wollte ich die Felder auslesen (Die natürlich mit Daten gefüllt sind).
In einer Editbox kann ich sie schon garnicht anzeigen, da gibts gleich ne Exeption (Variante des Typs (NULL konnte nicht im Typ (String) konvertiert werden - ok müsste klar sein) aber in einer Listbox mit "Format" zeigt er mir was an. Allerdings wird dort nur Schrott angezeigt (z.b. ",&S,".

Hier mal der vollständige Code, vielleicht kann mir jemand helfen. Ich habe echt keine Idee mehr.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComObj, ComCtrls, ADOX_TLB, ADODB_TLB, XPMan, StdCtrls, Buttons;

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    XPManifest1: TXPManifest;
    EditMDB: TEdit;
    Button1: TButton;
    TabSheet2: TTabSheet;
    GroupBox1: TGroupBox;
    MemoLog: TMemo;
    GroupBox2: TGroupBox;
    GroupBox3: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Button2: TButton;
    Button3: TButton;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    ListBox1: TListBox;
    Label7: TLabel;
    Label8: TLabel;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure TabSheet2Show(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

resourcestring
  cCONNECTSTRING='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=';

procedure TForm1.Button1Click(Sender: TObject);
var
  aCatalog : _Catalog;
  aTable  : _Table;
  AColumn : _ColumnDisp;
  aIdx    : _Index;
  sDBPath : String;
  sDS     : String;
  vColName : OLEVariant;
begin
  MemoLog.Lines.Clear;
  sDBPath:=EditMDB.Text;
  if FileExists(sDBPath) then
  begin
    DeleteFile(sDBPath);
    memoLog.Lines.Add(Format('Datenbankdatei %S gelöscht',[sDBPath]));
  end;
  aCatalog:=CoCatalog.Create;
  MemoLog.Lines.Add('Catalog erstellen...');
  sDS:=aCatalog.Create(Format('%s%s',[cCONNECTSTRING, sDBPath]));
  MemoLog.Lines.Add(sDS);
  aTable:=CoTable.Create;
  MemoLog.Lines.Add('Table erstellen...');
  aTable.ParentCatalog:=aCatalog;
  aTable.Name:='Kunden';

  //Spalte 1 = Primärschlüssel
  vColName:='KundenNummer';
  aTable.Columns.Append(vColName,adVarWChar,30);
  aColumn:=aTable.Columns.Item[vColName] as _ColumnDisp;
  aColumn.Properties['Description'].Value:='Name des Künstlers';
  MemoLog.Lines.Add('Spalte 1 hinzugefügt...');

  //Primärschlüssel hinzufügen
  aTable.Keys.Append('Kundennummer',adKeyPrimary,vColName,'','');
  MemoLog.Lines.Add('Spalte 1 als Primärschlüssel definiert...');

  //Spalte 2 = Zeichenfeld das auch Leer bleiben kann
  vColName:='eMail';
  aTable.Columns.Append(vColName,adVarWChar, 20);
  aColumn:=aTable.Columns.Item[vColName] as _ColumnDisp;
  aColumn.Properties['Description'].Value:='eMail Adresse des Kunden';
  aColumn.Properties['Jet OLEDB:Allow Zero Length'].Value:=True;
  aColumn.Properties['Default'].Value:='(unbekannt)';
  MemoLog.Lines.Add('Spalte 2 hinzugefügt...');

  //Index auf die Spalte 2 legen
  aIdx:=CoIndex.Create;
  with aIdx do
  begin
    Name:='IdxMail';
    Columns.Append(aColumn.Name, aColumn.type_,aColumn.DefinedSize);
    PrimaryKey:=False;
    Unique:=False;
  end;
  aTable.Indexes.Append(aIdx,EmptyParam);
  MemoLog.Lines.Add('Index IdxMail hinzugefügt...');

  //Spalte 3 - Zeichenfeld mit "Erforderlich = Nein"
  vColName:='Telefon';
  aTable.Columns.Append(vColName,adVarWChar, 15);
  aColumn:=aTable.Columns.Item[vColName] as _ColumnDisp;
  aColumn.Properties['Description'].Value:='Telefonnummer des Kunden';
  aColumn.Properties['Nullable'].Value:=True;
  MemoLog.Lines.Add('Spalte 3 jinzugefügt...');

  //Tabelle hinzufügen
  aCatalog.Tables.Append(aTable);
  MemoLog.Lines.Add('...Fertig');
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  aConnection : _Connection;
  aCatalog     : _Catalog;
  aTable      : _Table;
  swConnString : WideString;
  iRecCount   : Integer;
  i           : Integer;
begin
  //Schritt 1 - Das Connection Objekt
  aConnection:=CoConnection.Create;
  swConnString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Stamm.mdb; Persist Security Info=False';
  aConnection.Open(swConnString,'','',-1);

  //Schritt 2 - Das Catalog Objekt
  aCatalog:=CoCatalog.Create;
  aCatalog.Set_ActiveConnection(aConnection);
  iRecCount:=aCatalog.Tables.Get_Count;
  Label5.Caption:=IntToStr(iRecCount);
  ListBox1.Items.Clear;
  for i:=0 to iRecCount-1 do
  begin
    aTable:=aCatalog.Tables.Item[i];
    ListBox1.Items.Add(aTable.Name);
  end;
  aConnection.Close;
end;

procedure TForm1.TabSheet2Show(Sender: TObject);
var
  aCon : _Connection;
  aRS  : _Recordset;
  cCS  : WideString;
  sData : String;
begin
  cCS:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Stamm.mdb';
  aCon:=CoConnection.Create;
  aCon.Open(cCs,'','',adConnectUnspecified);
  try
    aRS:=aCon.OpenSchema(adSchemaTables,EmptyParam,EmptyParam);
    while not aRS.EOF do
    begin
      sData:=Format('%s,&S,%s',[aRS.Fields[0].Value,aRS.Fields[1].Value,aRS.Fields[2].Value]);
      ListBox1.Items.Clear;
      ListBox1.Items.Add(sData);
      //Edit1.Text:=aRS.Fields[0].Value;
      aRS.MoveNext;
    end;
  finally
    aCon.Close;
  end;
end;

end.
Ich bitte dringen um eure Hilfe.

Gollum 12. Aug 2004 17:24

Re: Über ADOX kein Zugriff auf Tabellenanzahl od. -felder
 
Hallo,

ich würde einmal folgendes ausprobieren:
Delphi-Quellcode:
var tabname:String;
...
  ListBox1.Items.Clear;
  for i:=0 to iRecCount-1 do
  begin
    tabname:=aCatalog.Tables.Item[i].Name;
    ListBox1.Items.Add(tabname);
  end;
...
Alles was mit MS beginnt, sind normalerweise Systemtabellen. Da ich in letzter Zeit sehr viel mit den VCL-ADO-Komponenten gearbeitet habe, habe ich jetzt auf die schnelle auch keine Lösung parat.

Eine gute Möglichkeit herauszubekommen wo die Unterschiede sind bzw. welche Eigenschaften unterstützt werden bietet sich die Eigenschaft Properties an.

Folgend ein Beispiel, dass Dir alle Properties eines Table-Objects zurückgibt:
Delphi-Quellcode:
uses
  Variants; // <-- für D7
...
var i:Integer;
    s:String;
...
// 1. Tabelle des Catalogobjects
  s:='';
  for i:=0 to aCatalog.Tables.Item[0].Properties.Count-1 do
  begin
    s:=s+aCatalog.Tables.Item[0].Properties[i].Name+' - '+
       VarToStr(aCatalog.Tables.Item[0].Properties[i].Value)+#13#10;
  end; // for i
  ShowMessage(s);
...
Ich hoffe, ich konnte trotzdem ein wenig helfen.

Legolas 12. Aug 2004 18:05

Re: Über ADOX kein Zugriff auf Tabellenanzahl od. -felder
 
Hallo Gollum,

schön das du dich mit meinem Problems mal wieder beschäftigst.

Ich habe meinen Quellcode entsprechend deinem ersten Quellcode abgeändert und das Testprogramm laufenlassen, aber leider zeigt er mir ausser der Tavelle "Kunden" die selben 5 zusätzlichen Tabellen. Also alles wie vorher. Mit deinem zweiten Quellcode komme ich irgendwie vom Verständniss her nicht ganz zurecht (auf deutsch: Ich weiß leider nicht was mir das Ergebnis bringt :gruebel: ).

Ich bin mittlerweile echt am verzweifeln, zumal es im Internet nicht mal ein vernünftiges Tutoriel über dieses Thema gibt. Ich scheine im Moment der einzige zu sein der sich mit dem Kram beschäftigt (warum mußte ich mir das auch in den Kopf setzen :-D ).

Naja, vielleicht gebe ich es einfach auf. Zumindest schaue ich mich nochmal (nun zum 1100ten Mal ?????) im Internet um. Bielleicht habe ich was übersehen.

Ich danke dir auf jedenfall für deine guten Hilfeversuche (das meißte von deinen Ideen hat mich ja schon ein kleines Stück weitergebracht).

shmia 12. Aug 2004 18:12

Re: Über ADOX kein Zugriff auf Tabellenanzahl od. -felder
 
Zitat:

Zitat von Legolas
Ich bin mittlerweile echt am verzweifeln, zumal es im Internet nicht mal ein vernünftiges Tutoriel über dieses Thema gibt. Ich scheine im Moment der einzige zu sein der sich mit dem Kram beschäftigt (warum mußte ich mir das auch in den Kopf setzen :-D ).

Naja, vielleicht gebe ich es einfach auf. Zumindest schaue ich mich nochmal (nun zum 1100ten Mal ?????) im Internet um. Bielleicht habe ich was übersehen.

Nicht weinen :zwinker:
http://www.activevb.de/tutorials/tut...s/adokurs.html
http://www.activevb.de/tutorials/tut_adox/adox.html
Ist zwar für VB-Legasteniker geschrieben, kann aber leicht auf Delphi umgesetzt werden.

PS: Ich hab noch einen:
http://www.activevb.de/tutorials/tut_ado_db/adodb.html

Legolas 12. Aug 2004 18:17

Re: Über ADOX kein Zugriff auf Tabellenanzahl od. -felder
 
Hi shmia,

ich glaub's ja net,es gibt doch Tutorials zu diesem Thema????

Aber in Visual Basic???

Naja besser als nix. Mittlerweile klammere ich mich an jeden Strohhalm. Mal sehen was sich aus den Infos machen läßt.

Ich danke dir für die Links.

Gollum 13. Aug 2004 07:58

Re: Über ADOX kein Zugriff auf Tabellenanzahl od. -felder
 
Hallo Legolas,

ich habe zumindest eine Lösung für Dein Problem bzgl. der (Access-)Systemtabellen gefunden. Anstatt die Tabellenname über das Catalog-Object einzulesen, ist es besser, diese über OpenSchema einzulesen:
Delphi-Quellcode:
// füllt eine ListView mit 2 Spalten
procedure UpDateLV;
var aSchema:_RecordSet;
    aCon  :_Connection;
begin
  ListView1.Clear;
  aCon:=CoConnection.Create;
  aCon.Open(....);

  aSchema:=CoRecordSet.Create;
  aSchema:=aCon.OpenSchema(adSchemaTables, EmptyParam, EmptyParam);
  while not aSchema.EOF do
  begin
    with ListView1.Items.Add do
    begin
      Caption:=VarToStr(aSchema.Fields.Item['TABLE_NAME'].Value);
      SubItems.Add(VarToStr(aSchema.Fields.Item['TABLE_TYPE'].Value));
    end; // with
    aSchema.MoveNext;
  end; // while
end; // UpDateLV
Laut obigen Beispiel gibt es die Tabllentypen "VIEW", "TABLE", "ACCESS TABLE" und "SYSTEM TABLE".

Nun ist es ein leichtes, nur die Tabellen anzuzeigen, die auch wirklich benötigt werden:
Delphi-Quellcode:
// analog zu oberem Beispiel
...
  while not aSchema.EOF do
  begin
    if (aSchema.Fields.Item['TABLE_NAME'].Value)='TABLE') then
    begin
      with ListView1.Items.Add do
      begin
        Caption:=VarToStr(aSchema.Fields.Item['TABLE_NAME'].Value);
        SubItems.Add(VarToStr(aSchema.Fields.Item['TABLE_TYPE'].Value));
      end; // with
    end; // if
    aSchema.MoveNext;
  end; // while


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz