Announcement

Collapse
No announcement yet.

datenbankstruktur nachträglich ändern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • datenbankstruktur nachträglich ändern

    obwohl mein programm eigentlich fertig ist, hat mein chef ständig noch änderungswünsche!!!!!
    oft muß dann die datenbank struktur einer paradoxtabelle geändert werden. das bringt viel arbeit mit
    sich. wenn ein feld geändert wurde muß es in jedem fenster in der datenzugriffskomponente gelöscht und
    wieder hinzu gefügt werden oder ein feld kamm hinzu und man mußte es hinzufügen.
    und man hat eben nicht immer im kopf, in welchen formularen überall die datenbank drin steckt.
    gibt es da einen trick, wie das schnell und zügig durchzuführen ist??????????????????????

    mfg

    markus
    Herzliche Grüße

    Markus Lemcke
    barrierefreies Webdesign

  • #2
    Hallo Markus,

    nein - etwas Arbeit muss für uns Entwickler schon übrig bleiben. Man könnte zwar die DFM-Datei in eine Text-Darstellung konvertieren (entfällt bei Delphi 5) und dann nach den Feldnamen suchen/ersetzen (synchron mit der PAS-Datei) - aber da ist der Implementierungsaufwand sicher höher als der Nutzen.

    Neue TField-Instanzen für neue Tabellen-Spalten müssen nur dann hinzugefügt werden, wenn sie im Formular auch verwendet werden

    Comment


    • #3
      Hallo Markus,<br>
      <br>
      bin gerade über deine (mittlerweile schon recht alte) Frage gestolpert.<br>
      Nun, es geht sehr wohl, dieses dynamisch in dein Programm einzubinden. (Wozu ist Delphi schliesslich OO?)<br>
      Das einzige, worauf du dabei achten musst, ist: die TTAble-Objekte (oder SQL-text der TQuerys) dürfen keine Felder<br>
      fest zugewiesen haben (Feldeditor) WENN sich bei den dyn. Anpassungen auch der Feld-Typ ändern könnte <br>
      (also z.B. von ftString zu ftInteger).<br>
      <br>
      Hier ein Bsp.:<br>
      <br>
      procedure TForm1.FelderAnpassen;<BR>
      var i,j:Integer;<BR>
      obj,fnam,ftyp:array[0..2] of string; // ggf. mehr Felder!<BR>
      fsize:array[0..2] of Word; // ggf. mehr Felder!<BR>
      lab,ed:String;<BR>
      dtyp:TFieldType;<BR>
      tab:TTable;<BR>
      fm:TForm;<BR>
      begin<BR>
      i:=0; j:=0;<BR>
      try<BR>
      tab:=TTAble.create(Application);<BR>
      fm:=Form1;<BR>
      with tab do begin<BR>
      Active:=False;<BR>
      DatabaseName:=AliasBox.text; // ggf. dyn. zuweisen
      TableNAme:=TabellenBox.Text; // ggf. dyn. zuweisen
      IndexFieldNames:='';
      Active:=True;
      end; // with tab
      with Table1 do begin
      Active:=False;
      DatabaseName:=AliasBox.text; // ggf. dyn. zuweisen<BR>
      TableNAme:=TabellenBox.Text; // ggf. dyn. zuweisen<BR>
      IndexFieldNames:='';<BR>
      <BR>
      for i:=0 to 2 do begin // init arrays - hier nur 3 Felder!!!<BR>
      obj[i]:='Table1F'+IntToStr(i);<BR>
      fnam[i]:='';<BR>
      ftyp[i]:='';<BR>
      fsize[i]:=0;<BR>
      end; // for<BR>
      for i:=0 to 2 do begin<BR>
      fnam[i]:=Tab.Fields[i].FieldName;<BR>
      dtyp:=Tab.FieldDefs.Items[Tab.FieldDefs.IndexOF(Tab.Fields[i].FieldName)].DataType;<BR>
      if (<BR>
      (dtyp=ftInteger) or (dtyp=ftSmallint) or (dtyp=ftWord) or (dtyp=ftAutoInc) or (dtyp=ftDate) or<BR>
      (dtyp=ftTime) or (dtyp=ftCurrency) or (dtyp=ftDateTime) or (dtyp=ftFloat) or (dtyp=ftUnknown) or<BR>
      (dtyp=ftCursor) or (dtyp=ftReference) or (dtyp=ftDataset) or (dtyp=ftSmallInt)<BR>
      ) then<BR>
      ftyp[i]:='Integer' else ftyp[i]:='';<BR>
      fsize[i]:=(Tab.FieldDefs.Items[Tab.FieldDefs.IndexOF(Tab.Fields[i].FieldName)].Size);<BR>
      end; // for<BR>
      <BR>
      // reset DataField-Names<BR>
      for j:=0 to fm.ComponentCount -1 do begin<BR>
      if ((fm.Components[j] is TStringField)) then<BR>
      TStringField(fm.Components[j]).FieldName:=inttostr(j); // temporary<BR>
      end; // for j<BR>
      <BR>
      for i:=0 to Tab.FieldDefs.Count-1 do begin<BR>
      if i>2 then break else begin // nur 3 Felder im Test und nur 3 Anzeige-Objekte<BR>
      lab:='Label'+IntToStr(i+1);<BR>
      ed:='EDBEdit'+IntToStr(i+1);<BR>
      // folgendes geht nur gut, wenn der FeldTyp sich NICHT ändert! <BR>
      (* for j:=0 to fm.ComponentCount -1 do begin<BR>
      if ((fm.Components[j] is TStringField) and (fm.Components[j].NAme=obj[i]))then begin<BR>
      TStringField(fm.Components[j]).FieldName:=fnam[i];<BR>
      if not (ftyp[i]='Integer') then TStringField(fm.Components[j]).Size:=fsize[i] else TStringField(fm.Components[j]).Size:=0;<BR>
      break;<BR>
      end; // if<BR>
      end; // for j<BR>
      // *)<BR>
      j:=0;<BR>
      for j:=0 to fm.ComponentCount -1 do begin<BR>
      if ((fm.Components[j] is TEDBEdit) and (fm.Components[j].NAme=ed))then begin<BR>
      TEDBEdit(fm.Components[j]).DataField:=fnam[i];<BR>
      // break;<BR>
      end; // if<BR>
      end; // for j<BR>
      j:=0;<BR>
      for j:=0 to fm.ComponentCount -1 do begin<BR>
      if ((fm.Components[j] is TLabel) and (fm.Components[j].NAme=lab))then begin<BR>
      TLabel(fm.Components[j]).Caption:=fnam[i]+': ';<BR>
      // break;<BR>
      end; // if<BR>
      end; // for j<BR>
      end; // if i>2<BR>
      end; // for i<BR>
      end; // with<BR>
      finally<BR>
      tab.active:=False; tab.free;<BR>
      Table1.Active:=True;<BR>
      end; // try<BR>
      end;<BR>
      <BR>
      ==> ENDE <=

      Comment


      • #4
        du meinst also, daß man die felder im feldeditor <b>nicht</b> hinzufügen darf oder???

        mfg

        marku
        Herzliche Grüße

        Markus Lemcke
        barrierefreies Webdesign

        Comment


        • #5
          Hallo,

          die o.g. Lösung wiederholt das, was Delphi bereits intern macht. Wenn keine <b>persistenten TField</b>-Instanzen im Objektinspektor/Feldeditor konfiguriert werden, baut sich Delphi zur Laufzeit diese Informationen zur internen Verwendung jedesmal neu auf. Der Sinn der persistenten TFields liegt aber genau darin, dass der Entwickler ein Veto/Warnhinweis bekommt, wenn die Struktur geändert wurde und im Programm eine Anpassung übersehen wurde

          Comment


          • #6
            Hallo Andreas, Hallo Markus,<br>
            <br>
            re Markus: man "darf" schon, aber wenn du die Felder beliebig von aussen ohne Programm-Änderungen<br>
            verändern können möchtest, bekommst du ein Problem, wenn du die Felder im Feldeditor eingetragen<br>
            hast UND sich der Feld-TYP verändert!<br>
            Wenn sich der Feld-Typ nicht ändert (z.B.bei String-Feldern sich nur die Size ändert) dann kannst du die<br>
            Felder ruhig im Feld-Editor eintragen. Die Routine wird dann aber etwas umfangreicher, da du jedesmal<br>
            den Feldnamen vergleichen musst, wenn du die Size z.B. eines TStringFields anpassen musst.(siehe Kommentar im Source)<br>
            <br>
            re. Andreas: die vorgeschlagene "Lösung" wiederholt gar nichts von dem, was Delphi intern macht.<br>
            Das Programm-Bsp. weist den (E)DBEdit-Komponenten (und den zugehörigen Labels) im Formular <br>
            den aktuellen Feldnamen zu (der sich ja auch verändern könnte). <br>
            Ändere doch mal den Feldnamen in einer Tabelle, zu der du ein EDBEdit im Formular hast, in dem <b>KEINE</b><br>
            persistenten TField-Instanzen definiert sind: Beim Öffnen des Fensters wird Delphi monieren, dass der Feldname<br>
            nicht gefunden werden konnte.<br>
            Das ist übrigens eine recht häufig gestellte Anforderung von Kunden: Anpassungswünsche an der Tabellen-Struktur<br>
            hinsichtlich "Feldbezeichner", "Feldlänge", und neue Felder.<br>
            Im Fall von <b>neuen Feldern</b> kann der o.g. Source angepasst werden und die Labels und EDBEdits werden<br>
            dann alle zur Laufzeit erstellt - je nachdem, wieviele Felder in der Tabelle gefunden werden.<br>
            <br>
            Gruß: Helmut Böcker<br&gt

            Comment

            Working...
            X