Alle Objekte einer Klasse durchlaufen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
sierdolg
Beiträge: 66
Registriert: Mi 24. Okt 2012, 15:50

Alle Objekte einer Klasse durchlaufen

Beitrag von sierdolg »

Hallo beisammen,

nach langem Suchen und Versuchen im Zusammenhang mit einer kleinen Anwendung, die eine Sqlite-Datenbank verwendet (und über eine ZConnection einbindet), habe ich einen (sicher nicht den optimalen) Weg gefunden, wie auch letzte Änderungen in einem beliebigen Data Access Control beim Schließen der Anwendung sicher in der Datenbank landen (eigentlich sollten sie das mit AutoCommit:=True meinem Verständnis nach ja theoretisch immer, tun sie aber praktisch nur manchmal ... ich komme von MS Access und kenne daher wohl die BDE-Eigenheiten ebenso wie das OOP noch nicht gut genug): In OnFormCloseQuery alle Datasets, falls in einem dsEdit-State, posten lassen.

Nun zur eigentlichen Frage: kann man an Stelle von

Code: Alles auswählen

    if dm1.queryA.State in [dsEdit, dsInsert] Then dm1.queryA.Post
    if dm1.queryB.State in [dsEdit, dsInsert] Then dm1.queryA.Post
    ///(...)
    if dm1.queryZ.State in [dsEdit, dsInsert] Then dm1.queryZ.Post
    // "dm1" ist dabei das DataModule, in welchem alle TZQueries definiert sind.
 
auch eleganter einfach sämtliche Objekte der Klasse TZQueries in dm1 durchlaufen?

Die Vorstufe einer Entsprechung zu for each element in gruppe: element.machwas wäre wohl etwas wie

Code: Alles auswählen

  for aDataset in [dm1.queryA, dm1.queryB, ..., dm1.queryZ] do
   begin
       if aDataset.state in [dsEdit, dsInsert] Then aDataset.Post
   end;
doch selbst das funktioniert nicht.

Da sich die grundsätzliche Frage ("Alle Objekte einer Klasse durchlaufen") auch auf andere Dinge bezieht, die nichts mit Datenbanken zu tun haben müssen, stelle ich sie mal zu den allgemeinen Einsteigerfragen.

Hat jemand einen Link, ein Beispiel oder das richtige Stichwort, nach dem man hier suchen muß - oder ist das generell gar nicht möglich?

baumina
Beiträge: 152
Registriert: Mo 3. Feb 2014, 14:07
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Alle Objekte einer Klasse durchlaufen

Beitrag von baumina »

Ich hab das so bei mir gelöst:

Code: Alles auswählen

 
procedure TfmDesigner.CheckEdits;
var
  i           : Integer;
  MerkControl : TWinControl;
  gefragt     : Boolean;
  ModRes      : TModalResult;
 
begin
  If (Visible and Assigned(ActiveControl)) then
  begin
    if (ActiveControl.InheritsFrom(TDBEdit) or
        ActiveControl.InheritsFrom(TDBCheckBox) or
        ActiveControl.InheritsFrom(TDBComboBox) or
        ActiveControl.InheritsFrom(TDBListBox) or
        ActiveControl.InheritsFrom(TDBRadioGroup) or
        ActiveControl.InheritsFrom(TDBMemo)) then
    begin
      // WorkAround : Dataset.modified ist ggf. false, solange das geänderte Feld nicht
      //              verlassen wurde, deswegen Feld verlassen und neu fokussieren
      MerkControl := ActiveControl;
      ActiveControl := Nil;
      if (not Assigned(ActiveControl) and
          Assigned(MerkControl) and
          MerkControl.CanFocus) then
      begin
        MerkControl.SetFocus;
        if MerkControl.InheritsFrom(TCustomEdit) then
        begin
          TCustomEdit(MerkControl).SelectAll;
        end;
      end;
    end;
  end;
 
  gefragt := False;
  for i := 0 to ComponentCount-1 do
  begin
    if Components[i].InheritsFrom(TDataSource) and
       Assigned(TDataSource(Components[i]).DataSet) then
    begin
      if TDataSource(Components[i]).DataSet.active then
      begin
        if (TDataSource(Components[i]).DataSet.State in [dsEdit,dsInsert]) then
        begin
          if TDataSource(Components[i]).DataSet.Modified then
          begin
            if not gefragt then
            begin
              ModRes := MessageDlg('Sollen die Änderungen gespeichert werden?', mtWarning,[mbYes,mbNo],0);
              gefragt := True;
            end;
            case ModRes of
              mrYes : TDataSource(Components[i]).DataSet.Post;
              else    TDataSource(Components[i]).DataSet.Cancel;
            end;
          end else TDataSource(Components[i]).DataSet.Cancel;
        end;
      end;
    end;
  end;
end;
 
.

Antworten