Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Problem bei case // Problem bei Komponenten löschen (https://www.delphipraxis.net/154244-problem-bei-case-problem-bei-komponenten-loeschen.html)

Metallicwar 2. Sep 2010 17:16

Problem bei case // Problem bei Komponenten löschen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Erstmal mein aktueller Code, der allerdings durchaus unübersichtlich ist :)
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, CheckLst, Unit4;

type
  TForm1 = class(TForm)
    CheckListBox1: TCheckListBox;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Formular: TForm;
  Frames: TFrame4;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
iChecked, iZaehler, iGecheckteFrames, iY, iRunter, iErstellteFrames: Integer;
begin
  Formular:=TForm.Create(Self);
  Formular.ClientHeight := 1500;
  Formular.ClientWidth := 670;
  iGecheckteFrames := 0;
  iY := 0;
  iRunter := 0;
  iZaehler := 0;
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[ichecked] then
      if iGecheckteFrames = 14 then
      begin
        ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
      end
      else
      begin
        if iZaehler = 10 then
        begin
          ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
          iZaehler := 0;
          iGecheckteFrames:= iGecheckteFrames + 1;
          if iGecheckteFrames = 14  then
          begin
            ShowMessage('Zwischenablage drucken + aktuelle Form leeren')
          end;
        end
        else
        begin
          if iZaehler = 0 then
          begin
            Frames := TFrame4.Create(Self);
            Frames.Name := CheckListBox1.Items[ichecked];
            Frames.ClientHeight := 200;
            Frames.Top := iY;
            Frames.Parent := Formular;
            iZaehler := iZaehler + 1;
            iGecheckteframes := iGecheckteframes + 1;
            if iGecheckteFrames = 14 then
            begin
            ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
            end;
          end
          else
          begin
            if iZaehler <= 4 then
            begin
              Frames := TFrame4.Create(Self);
              Frames.Name := CheckListBox1.Items[ichecked];
              Frames.ClientHeight := 200;
              Frames.Top := iY + Frames.ClientHeight;
              iY := Frames.Top;
              Frames.Parent := Formular;
              iZaehler := iZaehler + 1;
              iGecheckteFrames := iGecheckteFrames + 1;
              if iGecheckteFrames = 14 then
              begin
                ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
              end;
            end
            else
            begin
              if iZaehler = 5 then
              begin
                Frames := TFrame4.Create(Self);
                Frames.Name := CheckListBox1.Items[ichecked];
                Frames.ClientHeight := 200;
                Frames.Left := 350;
                Frames.Parent := Formular;
                iZaehler := iZaehler + 1;
                iGecheckteframes := iGecheckteframes + 1;
              end
              else
              begin
                Frames := TFrame4.Create(Self);
                Frames.Name := CheckListBox1.Items[ichecked];
                Frames.ClientHeight := 200;
                Frames.Left := 350;
                Frames.Top := iRunter + Frames.ClientHeight;
                iRunter:= Frames.Top;
                Frames.Parent := Formular;
                iZaehler := iZaehler + 1;
                iGecheckteFrames := iGecheckteFrames + 1;
              if iGecheckteFrames = 14 then
                begin
                  ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
                end;
              end;
            end;
          end;
        end;
      end;
Formular.Show;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CheckListBox1.Items.Add('a1');
CheckListBox1.Items.Add('a2');
CheckListBox1.Items.Add('a3');
CheckListBox1.Items.Add('a4');
CheckListBox1.Items.Add('a5');
CheckListBox1.Items.Add('a6');
CheckListBox1.Items.Add('a7');
CheckListBox1.Items.Add('a8');
CheckListBox1.Items.Add('a9');
CheckListBox1.Items.Add('a10');
CheckListBox1.Items.Add('a11');
CheckListBox1.Items.Add('a12');
CheckListBox1.Items.Add('a13');
CheckListBox1.Items.Add('a14');
end;

end.
1. Problem:
Habe erfahren, dass es durch case Blöcke übersichtlicher machbar wäre.
Hab das mal ausprobiert, bin aber der Vermutung, dass das so nicht möglich ist, da anscheinend keine <= , <, etc. möglich sind:
Delphi-Quellcode:
        iGecheckteFrames:= iGecheckteFrames + 1;
        //iZaehler:= iZaehler +
        case iZaehler of
          10:
          begin
          // --> Anweisungen
          end;
          0:
          begin
          // --> Anweisungen
          end;
          <=4:
          begin
          // --> Anweisungen
          end;
          5:
          begin
          // --> Anweisungen
          end;
          >5<=9:
          begin
          // --> Anweisungen
          end;
        end;

2. Problem:
Wenn 10 Frames auf dem Formular platziert worden sind, soll er das Formular drücken und anschließend alle Frames vom Formular löschen. Dann soll er weiter die Schleife durchlaufen, und die weiteren Frames auf dem Formular erzeugen... usw.
Hatte es vor mit Frames.Destroy bzw. DestroyComponents. Hat da jemand eine Idee?

dadurch entsteht auch mein 3. Problem:
Wenn ich mir z.B. 5 Items anchecke und auf den Button klicke. Anschließend klicke ich erneut auf den Button und erhalte logischerweise eine Exception. Siehe Anhang.

Wäre cool, wenn ihr mir bei den Problemen helfen könntet, muss das bis Freitag Mittag fertig haben :)

stahli 2. Sep 2010 17:39

AW: Problem bei case // Problem bei Komponenten löschen
 
1) Case
Man kann z.B. "1..4" oder "1, 3, 5" nutzen.

2) alle freigeben
Du kannst Deine Frames z.B. in eine TObjektList schreiben und nachher alle Frames in der Liste freigeben.

3) Componentennamen
Den Namen kannst Du einfach leer lassen, wenn Du die Frames zur Laufzeit erzeugst und diese nicht über den Namen ansprichst...

4) Freitag Mittag
das wird knapp ;-)

Metallicwar 2. Sep 2010 19:39

AW: Problem bei case // Problem bei Komponenten löschen
 
danke für die schnelle Antwort, werd mich gleich mal dran setzen :)
mach mir doch lieber Mut :D
so viel sieht des doch garnicht aus :) dankt den Tipps sollte ich das heute noch hinbekommen und morgen dann noch die Feinheiten :)

Metallicwar 2. Sep 2010 20:04

AW: Problem bei case // Problem bei Komponenten löschen
 
also das mit dem case werd ich erstmal weglassen, wenn Zeit werd ich das morgen noch ändern, kümmere mich jetzte erstmal um die Sache mit den Komponenten löschen & dem Beheben der Exception :) P.S.: Stellt euch auf Fragen ein :P

Metallicwar 2. Sep 2010 20:32

AW: Problem bei case // Problem bei Komponenten löschen
 
also das mit der TObjectList scheint für einen Anfänger doch nicht leicht zu sein ^^
http://www.delphibasics.co.uk/RTL.asp?Name=TList
Hab da mal gekuckt und auch nachgestellt, aber der meckert mir schon ganz oben rum dass "=" fehlt... etc. :)
Zum Problem mit der Exception: Vorher hatte ich ja drinne stehn Frames.Name := CheckListBox1.Items[i]
wenn ich diese line entferne, meckert er mir sofort nach Programmstart, dass es bereits ein Object mit dem Namen Frame4 gibt.
Ahhhh, das Problem mit der Exception habe behoben können Frames.Name := ''; :)
dann besteht also vorerst nur noch das Problem mit der ObjectListe.

stahli 2. Sep 2010 20:46

AW: Problem bei case // Problem bei Komponenten löschen
 
so zur Anregung:

Delphi-Quellcode:
var
  L: TComponentList;
...
    L := TComponentList.Create;
    L.OwnsObjects := False;
...
    L.Add(NewFrame);
...
    for I := L.Count - 1 downto 0 do
    begin
      AFrame := (L[I] as TFrame);
      AFrame.Free;
    end;

Metallicwar 2. Sep 2010 21:04

AW: Problem bei case // Problem bei Komponenten löschen
 
super, hat geklappt. Danke.
Hier nochmal der Code:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
iChecked, iZaehler, iGecheckteFrames, iY, iRunter, iErstellteFrames, i: Integer;
begin
  Formular:=TForm.Create(Self);
  Formular.ClientHeight := 1500;
  Formular.ClientWidth := 670;
  l:=TComponentList.Create;
  L.OwnsObjects:= False;
  iGecheckteFrames := 0;
  iY := 0;
  iRunter := 0;
  iZaehler := 0;
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[ichecked] then
    begin
      if iGecheckteFrames = 14 then
      begin
        ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
      end
      else
      begin
        if iZaehler = 10 then
        begin
          for I := l.Count -1 downto 0 do
          begin
            Frames:= (L[i] as TFrame4);
            Frames.Free;
          end;
          ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
          iZaehler := 0;
          iGecheckteFrames:= iGecheckteFrames + 1;
          if iGecheckteFrames = 14  then
          begin
            ShowMessage('Zwischenablage drucken + aktuelle Form leeren')
          end;
        end
        else
        begin
          if iZaehler = 0 then
          begin
            Frames := TFrame4.Create(Self);
            L.Add(Frames);
            Frames.ClientHeight := 200;
            Frames.Name:='';
            Frames.Top := iY;
            Frames.Parent := Formular;
            iZaehler := iZaehler + 1;
            iGecheckteframes := iGecheckteframes + 1;
            if iGecheckteFrames = 14 then
            begin
            ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
            end;
          end
          else
          begin
            if iZaehler <= 4 then
            begin
              Frames := TFrame4.Create(Self);
              L.Add(Frames);
              Frames.ClientHeight := 200;
              Frames.Name:='';
              Frames.Top := iY + Frames.ClientHeight;
              iY := Frames.Top;
              Frames.Parent := Formular;
              iZaehler := iZaehler + 1;
              iGecheckteFrames := iGecheckteFrames + 1;
              if iGecheckteFrames = 14 then
              begin
                ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
              end;
            end
            else
            begin
              if iZaehler = 5 then
              begin
                Frames := TFrame4.Create(Self);
                L.Add(Frames);
                Frames.ClientHeight := 200;
                Frames.Name:='';
                Frames.Left := 350;
                Frames.Parent := Formular;
                iZaehler := iZaehler + 1;
                iGecheckteframes := iGecheckteframes + 1;
              end
              else
              begin
                Frames := TFrame4.Create(Self);
                L.Add(Frames);
                Frames.ClientHeight := 200;
                Frames.Name:='';
                Frames.Left := 350;
                Frames.Top := iRunter + Frames.ClientHeight;
                iRunter:= Frames.Top;
                Frames.Parent := Formular;
                iZaehler := iZaehler + 1;
                iGecheckteFrames := iGecheckteFrames + 1;
              if iGecheckteFrames = 14 then
                begin
                  ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
                end;
              end;
            end;
          end;
        end;
      end;
    end;
    Formular.Show;
end;
Werde jetzte das Programm erneut durchgehn und weitere Fehler, etc. suchen :) Davon werden mit Sicherheit noch welche vorhanden sein. Falls ich nicht weiter komme, werd ich mich hier melden :)

Metallicwar 2. Sep 2010 21:38

AW: Problem bei case // Problem bei Komponenten löschen
 
2 Fragen habe ich bisher noch :D (könnte noch mehr werden):
Nehmen wir an, es sind 13 Items gecheckt, dann steppt er durch bis zaehler = 10 ist, dann druckt er die Form (muss ich noch einbaun) und löscht die Frames vom Formular. Dann steppt er weiter durch und erstellt wieder neue Frames, die aber sobald das Formular angezeigt wird nicht erscheinen (sollten ja 3 Stück zu sehen sein, ich seh aber keines.)

Anderes kleines Problemchen: Ich habe ja iGecheckteFrames = 14. Die 14 soll eben durch die Gesamtzahl der gecheckte Items ersetzt werden. Ich habe versucht mit iGecheckteFrames = CheckListBox1.Checked[ichecked] --> Inkompatible Typen.

mfg

stahli 2. Sep 2010 22:25

AW: Problem bei case // Problem bei Komponenten löschen
 
1) Ich denke, Du musst IY nach dem ersten Druck auf 0 zurücksetzen.

2) Ich würde einfach eine neue Variable definieren und die einzelnen Checkboxen durchzählen.
"CheckedCount" o.ä. gibt es m.E. leider nicht.

Metallicwar 2. Sep 2010 22:36

AW: Problem bei case // Problem bei Komponenten löschen
 
Punkt 1 sollte ich heute noch hinbekommen
Punkt 2 werd ich mich morgen auf Arbeit drum kümmern.

Hoffe mal, du bist morgen früh/ vormittag auch anwesend, für evtl. auftretende Fragen :)

Metallicwar 2. Sep 2010 22:55

AW: Problem bei case // Problem bei Komponenten löschen
 
mhhm, dann melde ich mich doch nochmal: :D :D :D
Zu Punkt 1:
Ich habe 12 Items gecheckt er steppt durch bei zaehler = 10 löschen und die Eigenschaftswerte von Frames zurücksetzen. Dann weiter in der For Schleife. So beim elften gecheckten Item funktionierts einbandfrei, so wie es sein muss. Beim 12 Item durchläuft er aber komischerweise nicht mehr die if/else Anweisung sondern springt sofort aufs Ende --> Formular.Show;
Ich verstehs nicht -.- *Augen werden schwer* :o

Satty67 2. Sep 2010 23:21

AW: Problem bei case // Problem bei Komponenten löschen
 
Eine Antwort habe ich nicht, denke für einige andere ist der Code auch schwer auf einen Blick zu durchschauen...

Sowas kann man vermeiden, wenn man sich nicht wiederholt. Wenn es für den moment nicht klar wird, einfach später mal drüber nachenken und erst auf die eigentliche Aufgabe konzentrieren.

Also Du wiederholst sehr viel Code. Wenn Du eine Änderung probieren wilslt, musst du das an vielen Stellen machen und etwas gedeht ist das ganze ja auch.

Achtung! Alles Freihand, also nicht getestet ob es exakt so auch funktioniert!

Beispiel-Abschnitt:
Delphi-Quellcode:
       else
        begin
          if iZaehler = 0 then
          begin
            Frames := TFrame4.Create(Self);
            L.Add(Frames);
            Frames.ClientHeight := 200;
            Frames.Name:='';
            Frames.Top := iY;
            Frames.Parent := Formular;
            iZaehler := iZaehler + 1;
            iGecheckteframes := iGecheckteframes + 1;
            if iGecheckteFrames = 14 then
            begin
            ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
            end;
          end
          else
          begin
            if iZaehler <= 4 then
            begin
              Frames := TFrame4.Create(Self);
              L.Add(Frames);
              Frames.ClientHeight := 200;
              Frames.Name:='';
              Frames.Top := iY + Frames.ClientHeight;
              iY := Frames.Top;
              Frames.Parent := Formular;
              iZaehler := iZaehler + 1;
              iGecheckteFrames := iGecheckteFrames + 1;
              if iGecheckteFrames = 14 then
              begin
                ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
              end;
            end
Da sieht man schon, dass zwischen den Blöchen vieles identisch ist.

Erster Schritt wäre, die Erzeugung und Wertzuordnung des Frames auszulagern:
Delphi-Quellcode:
function TForm1.CreateFrame(Parent : TForm; aName : String; aHeight, aTop : Integer): TFrame4;
begin
  Result := TFrame4.Create(Self);
  Result.ClientHeight := Height;
  Result.Name:= aName;
  Result.Top := aTop;
  Result.Parent := Parent;
end;

// Der Block ist jetzt etwas geschrumpft
  else
  begin
    if iZaehler = 0 then
    begin
      L.Add(CreateFrame(Formular, '', 200, iY);
      iZaehler := iZaehler + 1;
      iGecheckteframes := iGecheckteframes + 1;
      if iGecheckteFrames = 14 then
      begin
      ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
      end;
    end
    else
    begin
      if iZaehler <= 4 then
      begin
        L.Add(CreateFrame(Formular, '', 200, iY + Frames.ClientHeight);
        iY := iY + Frames.ClientHeight;
        iZaehler := iZaehler + 1;
        iGecheckteFrames := iGecheckteFrames + 1;
        if iGecheckteFrames = 14 then
        begin
          ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
        end;
      end
      else
Das Frame wird jetzt in CreateFrame angelegt und diese Funktion gibt das fertige Frame zurück für L.Add.

Dann kann man den Check, ob gedruck werden soll zusammenfassen. Da auf variablen der ButtonClick-Methode zugegriffen wird, innerhalb (IncAndPrintAt14):

Delphi-Quellcode:
function TForm1.CreateFrame(Parent : TForm; aName : String; aHeight, aTop : Integer): TFrame4;
begin
  Result := TFrame4.Create(Self);
  Result.ClientHeight := Height;
  Result.Name:= aName;
  Result.Top := aTop;
  Result.Parent := Parent;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
iChecked, iZaehler, iGecheckteFrames, iY, iRunter, iErstellteFrames, i: Integer;

   procedure IncAndPrintAt(printAt : Integer);
   begin
      iZaehler := iZaehler + 1;
      iGecheckteframes := iGecheckteframes + 1;
      if iGecheckteFrames = printAt then
      begin
      ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
      end;
   end;

begin
  Formular:=TForm.Create(Self);
  Formular.ClientHeight := 1500;

// Der Block ist jetzt erheblich geschrumpft
  else
  begin
    if iZaehler = 0 then
    begin
      L.Add(CreateFrame(Formular, '', 200, iY);
      IncAndPrintAt(14);
    end
    else
    begin
      if iZaehler <= 4 then
      begin
        L.Add(CreateFrame(Formular, '', 200, iY + Frames.ClientHeight);
        iY := iY + Frames.ClientHeight;
        IncAndPrintAt(14);
      end
      else
Die beiden anderen Blöcke sind nicht ganz so identisch, aber ähnlich genug um die auch einzubinden bzw. jeweils für sich so zu schrumpfen.

Metallicwar 3. Sep 2010 07:23

AW: Problem bei case // Problem bei Komponenten löschen
 
Morgen zusammen,
danke erstmal für die ausführliche Erklärung. Werde meinen Code bei Gelegenheit auch übersichtlicher coden. Vorerst werde ich mich aber mit meinen bestehenden Problemen beschäftigen und über Tipps und Hinweise freu ich mich natürlich :)
Einen schönen Tag

Metallicwar 3. Sep 2010 07:39

AW: Problem bei case // Problem bei Komponenten löschen
 
Zitat:

2) Ich würde einfach eine neue Variable definieren und die einzelnen Checkboxen durchzählen.
"CheckedCount" o.ä. gibt es m.E. leider nicht.
So hatte ich das vor:
Delphi-Quellcode:
   for ichecked := 0 to CheckListBox1.Items.Count-1 do
    iErstellteFrames := iErstellteFrames + 1;
    if CheckListBox1.Checked[ichecked] then
    begin
      if iErstellteFrames = iErstellteFrames then
Erhalte aber eine Exception:
Im Projekt.... der Klasse EListError mit der Meldung 'ListIndex überschreitet das Maximum (14)' aufgetreten.

mkinzler 3. Sep 2010 07:49

AW: Problem bei case // Problem bei Komponenten löschen
 
Füge mal ein Begin ein, so dass alles, was in der Schleife ausgeführt werden soll auch in ihr ausgeführt wird
Delphi-Quellcode:
for ichecked := Low( CheckListBox1.Items) to High( CheckListBox1.Items) do
begin
    Inc(iErstellteFrames);
Zitat:

Delphi-Quellcode:
      if iErstellteFrames = iErstellteFrames then

Sollte immer wahr sein

Metallicwar 3. Sep 2010 08:16

AW: Problem bei case // Problem bei Komponenten löschen
 
mhhhm.. an was es liegt, wieso es nicht geht weiß ich nur wie ich`s behebe. :)
Delphi-Quellcode:
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
  begin
    iErstellteFrames := iErstellteFrames + 1;
  end;
    if CheckListBox1.Checked[ichecked] then
Er geht erst alle Items durch, die gecheckt sind und erhört iErstellteFrames um 1. Dann springt er wieder in die if Abfrage und er gibt mir wieder die Exception aus.

mkinzler 3. Sep 2010 08:18

AW: Problem bei case // Problem bei Komponenten löschen
 
Das end ist auch zu früh, deshalb sagte ich ja, alles was in die Schleife gehört

Metallicwar 3. Sep 2010 08:36

AW: Problem bei case // Problem bei Komponenten löschen
 
:pale: :pale:
Ich blick nicht mehr wirklich durch in dem Code. ^^
Finde aber nicht die richtige Stelle für das end. Mal kommt die Exception, dann erstellt er mir nur das erste Frame^^.
Hoffe mal ich bekomm das heute noch alles hin. Und am Wochenende wirds dann Zeit den Code umzustellen.
Also greift mir noch ein bisschen unter die Arme^^
mfg

mkinzler 3. Sep 2010 08:39

AW: Problem bei case // Problem bei Komponenten löschen
 
Delphi-Quellcode:
for ichecked := Low( CheckListBox1.Items) to High( CheckListBox1.Items) do
begin
  Inc(iErstellteFrames);
  if CheckListBox1.Checked[ichecked] then
  begin
    if iErstellteFrames = iErstellteFrames then
    begin
       ...
    end;
  end;
end;

Metallicwar 3. Sep 2010 08:57

AW: Problem bei case // Problem bei Komponenten löschen
 
Hatte es so auch schonmal, da lief es aber leider nicht so wie ich wollte.
Delphi-Quellcode:
procedure TForm1.bitbtnDruckenClick(Sender: TObject);
var
iChecked, iZaehler, iGecheckteFrames, iY, iRunter, iErstellteFrames, i: Integer;
begin
  Formular:=TForm.Create(Self);
  Formular.ClientHeight := 1500;
  Formular.ClientWidth := 670;
  l:=TComponentList.Create;
  L.OwnsObjects:= False;
  iGecheckteFrames := 0;
  iErstellteFrames := 0;
  iY := 0;
  iRunter := 0;
  iZaehler := 0;
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
  begin
    Inc(iErstellteFrames);
    if CheckListBox1.Checked[ichecked] then
    begin
      if iGecheckteFrames = iErstellteFrames then
      begin
        ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
      end
      else
      begin
        if iZaehler = 10 then
        begin
          for I := l.Count -1 downto 0 do
          begin
            Frames:= (L[i] as TFrame4);
            Frames.Free;
          end;
          ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
          iZaehler := 0;
          iGecheckteFrames:= iGecheckteFrames + 1;
          if iGecheckteFrames = iErstellteFrames then
          begin
            ShowMessage('Zwischenablage drucken + aktuelle Form leeren')
          end;
        end
        else
        begin
          if iZaehler = 0 then
          begin
            Frames := TFrame4.Create(Self);
            L.Add(Frames);
            Frames.ClientHeight := 200;
            Frames.Name:='';
            Frames.Top := iY;
            Frames.Parent := Formular;
            iZaehler := iZaehler + 1;
            iGecheckteframes := iGecheckteframes + 1;
            if iGecheckteFrames = iErstellteFrames then
            begin
            ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
            end;
          end
          else
          begin
            if iZaehler <= 4 then
            begin
              Frames := TFrame4.Create(Self);
              L.Add(Frames);
              Frames.ClientHeight := 200;
              Frames.Name:='';
              Frames.Top := iY + Frames.ClientHeight;
              iY := Frames.Top;
              Frames.Parent := Formular;
              iZaehler := iZaehler + 1;
              iGecheckteFrames := iGecheckteFrames + 1;
              if iGecheckteFrames = iErstellteFrames then
              begin
                ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
              end;
            end
            else
            begin
              if iZaehler = 5 then
              begin
                Frames := TFrame4.Create(Self);
                L.Add(Frames);
                Frames.ClientHeight := 200;
                Frames.Name:='';
                Frames.Left := 350;
                Frames.Parent := Formular;
                iZaehler := iZaehler + 1;
                iGecheckteframes := iGecheckteframes + 1;
              end
              else
              begin
                Frames := TFrame4.Create(Self);
                L.Add(Frames);
                Frames.ClientHeight := 200;
                Frames.Name:='';
                Frames.Left := 350;
                Frames.Top := iRunter + Frames.ClientHeight;
                iRunter:= Frames.Top;
                Frames.Parent := Formular;
                iZaehler := iZaehler + 1;
                iGecheckteFrames := iGecheckteFrames + 1;
              if iGecheckteFrames = iErstellteFrames then
                begin
                  ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
                end;
              end;
            end;
          end;
        end;
      end;
    end;
    Formular.Show;
  end;
end;
Was mach ich blos falsch? :O (Der Mittag rückt näher, da muss es fertig sein :o)

stahli 3. Sep 2010 09:22

AW: Problem bei case // Problem bei Komponenten löschen
 
Hmm, sorry, das ist alles etwas zu unübersichtlich.
Hast Du mal einen Haltepunkt gesetzt und hast das Programm Schritt für Schritt laufen lassen?
Wenn Du dabei die Inhalte der Variablen einsiehst, solltest Du sehen, was passiert (und was vielleicht passieren solle).

if A = A then ...

Ist auf jeden Fall unsinnig. Diese Anweisung kann man sich immer sparen und lässt einen Schreibfehler vermuten...

Metallicwar 3. Sep 2010 09:54

AW: Problem bei case // Problem bei Komponenten löschen
 
Delphi-Quellcode:
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
  begin
    if CheckListBox1.Checked[ichecked] then
    iErstellteFrames := iErstellteFrames + 1;
  end;
    begin
      if iGecheckteFrames = iErstellteFrames then
Er steppt alle Items durch und wenn eins gecheckt ist dann soll er iErstellteFrames eins hochzählen. So ist es ja richtig.

Dann durchläuft er die if/else Abfragen. Beim ersten mal ist der zaehler ja 0 daher springt er in:
Delphi-Quellcode:
          if iZaehler = 0 then
          begin
            Frames := TFrame4.Create(Self);
            L.Add(Frames);
            Frames.ClientHeight := 200;
            Frames.Name:='';
            Frames.Top := iY;
            Frames.Parent := Formular;
            iZaehler := iZaehler + 1;
            iGecheckteframes := iGecheckteframes + 1;
            if iGecheckteFrames = iErstellteFrames then
            begin
            ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
            end;
durchläuft die Anweisungen und bei
Delphi-Quellcode:
if iGecheckteFrames = iErstellteFrames
springt er dann runter zu
Delphi-Quellcode:
    ...
end;
  Formular.Show;
end;
also ich weiß da nicht mehr weiter -.-

stahli 3. Sep 2010 10:13

AW: Problem bei case // Problem bei Komponenten löschen
 
Du musst auf die Begin-End´s achten!

Delphi-Quellcode:
if x then
  MacheWas;
MacheDasNaechste;
Delphi-Quellcode:
if x then
begin
  MacheWas;
  MacheNochWas;
end;
MacheDasNaechste;
Wenn Du die Blöcke und Anweisungen "schön" einrückst und IN RUHE untersuchst, solltest Du wohl eine falsche begin-end Anweisung finden.

In meinem Beispiel oben sieht man auf einen Blick, dass die erste if-Bedingung nur einen Befehl betrifft und die zweite einen Block.

Ich denke, Du warst da in Deinem Code nur etwas zu schlampig.

Ordner das mal und zeig es uns dann notfalls nochmal ...

Metallicwar 3. Sep 2010 11:16

AW: Problem bei case // Problem bei Komponenten löschen
 
Hallo, ich habe mich dazu entschlossen, doch alles in case Blöcke einzubaun. Habe erstmal meine bisherigen Anweisungen einfach in die case Blöcke kopiert und sortier da jetzte aus was in allen gleich ist etc...
Delphi-Quellcode:
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[ichecked] then
      case iZaehler of
      10:
      begin
        for I := l.Count -1 downto 0 do
        begin
        Frames:= (L[i] as TFrame4);
        Frames.Free;
        end;
        ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
        iZaehler := 0;
        iGecheckteFrames:= iGecheckteFrames + 1;
          if iGecheckteFrames = 13 then
           begin
            ShowMessage('Zwischenablage drucken + aktuelle Form leeren')
           end;
      end;
      0:
      begin
      // --> Anweisungen
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Top := iY;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteframes := iGecheckteframes + 1;
        if iGecheckteFrames = 13 then
        begin
        ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
        end;
      end;
      1..4:
      begin
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Top := iY + Frames.ClientHeight;
        iY := Frames.Top;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteFrames := iGecheckteFrames + 1;
        if iGecheckteFrames = 13 then
        begin
          ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
        end;
      end;
      5:
      begin
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Left := 350;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteframes := iGecheckteframes + 1;
      end;
      6..9:
      begin
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Left := 350;
        Frames.Top := iRunter + Frames.ClientHeight;
        iRunter:= Frames.Top;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteFrames := iGecheckteFrames + 1;
        if iGecheckteFrames = 13 then
        begin
          ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
        end;
      end;
      end;
      Formular.Show;
end;
Statements, die in allen cases gleich sind, soll ich über
Delphi-Quellcode:
case iZaehler of
schreiben, da aber in keinem der 4 etwas gleich ist sonder nur in sondern nur für 3 schreibe ich jetzte über den ersten case Block noch eine und schreib da meine gleichen Statements rein, dann ist das ganze schon ein bisschen aufgeräumt? Was haltet ihr davon?

mkinzler 3. Sep 2010 11:24

AW: Problem bei case // Problem bei Komponenten löschen
 
Hierfür kann man auch die IDE-Erweiterung cnPack verwenden. Diese markiert die Blöcke dann farbig

stahli 3. Sep 2010 11:33

AW: Problem bei case // Problem bei Komponenten löschen
 
Delphi-Quellcode:
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
//begin ... so lange Folgeanweisungen würde ich der Übersichtlichkeit halber in ein begin...end kapseln. Ist zwar nicht notwendig, liest sich aber besser
    if CheckListBox1.Checked[ichecked] then
// hier evtl. auch ein begin ... end nutzen, da dann eine sehr lange Anweisung folgt
      case iZaehler of
// kann man auch schön einrücken:
//      0..100: begin
//                ...
//              end;
      10:
      begin
        for I := l.Count -1 downto 0 do
        begin
        Frames:= (L[i] as TFrame4);
        Frames.Free;
        end;
        ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
        iZaehler := 0;
        iGecheckteFrames:= iGecheckteFrames + 1;
          if iGecheckteFrames = 13 then
           begin
            ShowMessage('Zwischenablage drucken + aktuelle Form leeren')
           end;
      end;
      0:
      begin
      // --> Anweisungen
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Top := iY;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteframes := iGecheckteframes + 1;
        if iGecheckteFrames = 13 then
        begin
        ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
        end;
      end;
      1..4:
      begin
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Top := iY + Frames.ClientHeight;
        iY := Frames.Top;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteFrames := iGecheckteFrames + 1;
        if iGecheckteFrames = 13 then
        begin
          ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
        end;
      end;
      5:
      begin
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Left := 350;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteframes := iGecheckteframes + 1;
      end;
      6..9:
      begin
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        Frames.Left := 350;
        Frames.Top := iRunter + Frames.ClientHeight;
        iRunter:= Frames.Top;
        Frames.Parent := Formular;
        iZaehler := iZaehler + 1;
        iGecheckteFrames := iGecheckteFrames + 1;
        if iGecheckteFrames = 13 then
        begin
          ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
        end;
      end;
      end; // 2 "end" auf gleicher Ebene? Das ist unübersichtlich... und könnte auf einen Fehler hinweisen.
      Formular.Show;
end;

Metallicwar 3. Sep 2010 11:51

AW: Problem bei case // Problem bei Komponenten löschen
 
und wieder mal ein langer Code:
Habe hier meine 2 Case Blöcke reingeschrieben. Bei 10: sind ja keine Übereinstimmunge mit den anderen. im case 0..9: hab ich eben reingeschrieben, was in anderen Blöcken gleich ist. Irgendwo ist da mal wieder ein kleiner Fehler drin, oder ich hab noch eine Line vergessen. Aber jetzte sollte es schon übersichtlicher sein (Einrückung).
Delphi-Quellcode:
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[ichecked] then
      case iZaehler of
          0..9:
          begin
          Frames := TFrame4.Create(Self);
          L.Add(Frames);
          Frames.ClientHeight := 200;
          Frames.Name:='';
          iZaehler := iZaehler + 1;
          iGecheckteframes := iGecheckteframes + 1;
          Frames.Parent := Formular;
          end;
        end;
          case iZaehler of
          10:
          begin
            for I := l.Count -1 downto 0 do
            begin
            Frames:= (L[i] as TFrame4);
            Frames.Free;
            end;
            ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
            iZaehler := 0;
              if iGecheckteFrames = 13 then
              begin
                ShowMessage('Zwischenablage drucken + aktuelle Form leeren')
              end;
          end;
          0:
          begin
            Frames.Top := iY;
            Frames.Parent := Formular;
            if iGecheckteFrames = 13 then
            begin
            ShowMessage('Zwischenablage drucken und aktuelle Form drucken');
            end;
          end;
          1..4:
          begin
            Frames.Top := iY + Frames.ClientHeight;
            iY := Frames.Top;
            Frames.Parent := Formular;
            if iGecheckteFrames = 13 then
            begin
              ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
            end;
          end;
          5:
          begin
            Frames.ClientHeight := 200;
            Frames.Name:='';
            Frames.Left := 350;
          end;
          6..9:
          begin
            Frames.Left := 350;
            Frames.Top := iRunter + Frames.ClientHeight;
            iRunter:= Frames.Top;
            if iGecheckteFrames = 13 then
            begin
              ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
            end;
          end;
        end;
    Formular.Show;
end;

stahli 3. Sep 2010 12:02

AW: Problem bei case // Problem bei Komponenten löschen
 
Deine if-Anweisung führt NUR DAS ERSTE CASE aus:

Delphi-Quellcode:
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[ichecked] then
// if bezieht sich auf die NÄCHSTE Anweisung (da Du keinen begin...end-Block benutzt)
      case iZaehler of
          0..9:
          begin
          Frames := TFrame4.Create(Self);
          L.Add(Frames);
          Frames.ClientHeight := 200;
          Frames.Name:='';
          iZaehler := iZaehler + 1;
          iGecheckteframes := iGecheckteframes + 1;
          Frames.Parent := Formular;
          end;
        end;
// ab hier wird IMMER ausgeführt
          case iZaehler of
          10:
          begin
            for I := l.Count -1 downto 0 do
            begin
Also nochmal:
Rücke alles so ein, dass alle nachfolgenden (gleichrangigen) Anweisungen GENAU untereinander stehen.
Das betrifft auch begin und end -> sollen genau untereinander stehen.
alles zwischen begin und end wird um 2 Zeichen eingerückt.

Dann hättest Du Dein o.g. Problem selbst gesehen!

Das erste case kannst Du auch ersethen durch:
if iZaehler < 10 then begin ... end
da Du ja nicht unterschiedliche Fälle behandeln willst.

Du machst Dir Deine Probleme selbst, da Du viel zu luschig arbeitest. 3 Min in eine ordentliche Quelltextstruktur inversieren kann 3 Stunden Fehlersuche sparen!

Metallicwar 3. Sep 2010 13:27

AW: Problem bei case // Problem bei Komponenten löschen
 
Delphi-Quellcode:
procedure TForm1.bitbtnDruckenClick(Sender: TObject);
var
iChecked, iZaehler, iGecheckteFrames, iY, iRunter, iErstellteFrames, i: Integer;
begin
  Formular:=TForm.Create(Self);
  Formular.ClientHeight := 1500;
  Formular.ClientWidth := 670;
  l:=TComponentList.Create;
  L.OwnsObjects:= False;
  iGecheckteFrames := 0;
  iErstellteFrames := 0;
  iY := 0;
  iRunter := 0;
  iZaehler := 0;
  for ichecked := 0 to CheckListBox1.Items.Count-1 do
    if CheckListBox1.Checked[ichecked] then
    begin
      case iZaehler of
          0..9:
          begin
          Frames := TFrame4.Create(Self);
          L.Add(Frames);
          Frames.ClientHeight := 200;
          Frames.Name:='';
          iZaehler := iZaehler + 1;
          iGecheckteframes := iGecheckteframes + 1;
          Frames.Parent := Formular;
          end;
      end;
          case iZaehler of
          10:
          begin
            for I := l.Count -1 downto 0 do
            begin
              Frames:= (L[i] as TFrame4);
              Frames.Free;
              iZaehler := 0;
            end;
            begin
            if iGecheckteFrames = 13 then
              ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
            end;
          end;
          0:
          begin
            Frames.Top := iY;
            if iGecheckteFrames = 13 then
            ShowMessage('Zwischenablage drucken + aktuelle Form leeren');
          end;        
          2..5:
          begin
            Frames.Top := iY + Frames.ClientHeight;
            iY := Frames.Top;
            Frames.Parent := Formular;
            if iGecheckteFrames = 13 then
            begin
              ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
            end;
          end;
          6:
          begin
            Frames.ClientHeight := 200;
            Frames.Name:='';
            Frames.Left := 350;
          end;
          7..9:
          begin
            Frames.Left := 350;
            Frames.Top := iRunter + Frames.ClientHeight;
            iRunter:= Frames.Top;
            if iGecheckteFrames = 13 then
            begin
              ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
            end;
          end;
        end;
    Formular.Show;
    end;
end;
So hoffe mal jetzte siehts alles bisschen übersichtlicher aus.

stahli 3. Sep 2010 13:51

AW: Problem bei case // Problem bei Komponenten löschen
 
nein, nicht wirklich:

Delphi-Quellcode:
procedure TForm1.BitBtnDruckenClick(Sender: TObject);
var
  iChecked, iZaehler, iGecheckteFrames, iY, iRunter, iErstellteFrames, i: Integer; // hier schon einrücken
begin
  Formular := TForm.Create(Self); // Leerzeichen
  Formular.ClientHeight := 1500;
  Formular.ClientWidth := 670;
  L := TComponentList.Create; // Leerzeichen + Groß/Kleinschreibung
  L.OwnsObjects := False;
  iGecheckteFrames := 0;
  iErstellteFrames := 0;
  iY := 0;
  iRunter := 0;
  iZaehler := 0;
  for iChecked := 0 to CheckListBox1.Items.Count - 1 do
  begin // Was soll in der Schleife laufen? Bis incl. Formular.Show? Dann wird das Formular Items.Count mal angezeigt.
    if CheckListBox1.Checked[iChecked] then
    begin // alles folgende wird bei Checked durchgeführt, Formular.Show aber immer
      if iZaehler < 10 then
      begin
        Frames := TFrame4.Create(Self);
        L.Add(Frames);
        Frames.ClientHeight := 200;
        Frames.Name:='';
        iZaehler := iZaehler + 1;
        iGecheckteframes := iGecheckteframes + 1;
        Frames.Parent := Formular;
      end;
    //end; dieses End würde bedeuten dass die Checked-Bedingung nur bis hierher gelten würde
      case iZaehler of
        10: begin
              for I := l.Count -1 downto 0 do
              begin
                Frames:= (L[i] as TFrame4);
                Frames.Free;
                iZaehler := 0;
              end;
              //begin <- unnötig
              if iGecheckteFrames = 13 then
                ShowMessage('Formular in Zwischenablage kopieren + Formular leeren');
              //end; < unnötig
            end;
         0: begin
              Frames.Top := iY;
              if iGecheckteFrames = 13 then
                ShowMessage('Zwischenablage drucken + aktuelle Form leeren');
            end;
      2..5: begin
              Frames.Top := iY + Frames.ClientHeight;
              iY := Frames.Top;
              Frames.Parent := Formular;
              if iGecheckteFrames = 13 then
                ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
            end;
         6: begin
              Frames.ClientHeight := 200;
              Frames.Name := '';
              Frames.Left := 350;
            end;
      7..9: begin
              Frames.Left := 350;
              Frames.Top := iRunter + Frames.ClientHeight;
              iRunter:= Frames.Top;
              if iGecheckteFrames = 13 then
                ShowMessage('Zwischenablage drucken + aktuelle Form drucken');
            end;
      end;
    end;
    Formular.Show;
  end;
end;
Soweit mal ungetestet auf die Schnelle.
Auf jeden Fall hat man jetzt die Chance, sich ungefähr zurecht zu finden.
Die Leerzeichen und Groß/Klein-Schreibung ist vielleicht etwas Krümelkackerei, man sollte sich das aber gleich so angewöhnen, da man so viel schneller mögliche Tippfehler findet.

Ich weiß aber ehrlich gesagt jetzt nicht genau, was Du genau erreichen willst bzw. wo etwas nun nicht wie erwartet klappt (Du hast da einfach schon zu viele Varianten beschrieben).

Also nun nochmal:
- ordne Deinen Quelltext
- setze einen Breakpoint und arbeite den Quelltext schrittweise ab
- stelle konkrete Fragen mit präziser Problembeschreibung (dann kommt man oft bei einer Problemformulierung schon selbst auf die Lösung - kannst Du mir glauben :wink:)

Metallicwar 3. Sep 2010 15:02

AW: Problem bei case // Problem bei Komponenten löschen
 
Viele Vielen Dank.
Funktioniert zwar noch nicht so, wie ich mir es vorstelle, aber es nimmt Formen an.
Bisher habe ich nur getestet.
Mein eigentliches Ziel ist folgendes, ich lasse mir alle Mitarbeiter (Name, Vorname, Abteilung, Bild) in die CheckListBox schreiben. Von den gecheckten Items (Mitarbeitern) lasse ich mir anschließend Mitarbeiterausweise (Frames, auf dem Bild, Labels für Kontaktdaten, vermerkt sind) ausdrucken. Ist ja eigentlich schon "fast" :D fertig Die AdsQuery hab ich schon erstellt und den benötigten SQL geschrieben. Jetzte muss ich nur noch hinbekommen, dass er für jedes neu erstellte Frame, einen Datensatz weiterspringt, momentan wird nur ein und der selbe Mitarbeiter angezeigt.

stahli 3. Sep 2010 15:08

AW: Problem bei case // Problem bei Komponenten löschen
 
Ok, alles klar :-)

Der Weg ein Formuar anzuzeigen und auszudrucken, ist eigentlich nicht ganz optimal. Grundsätzlich kann man das besser über ein Report-Tool lösen, das also quasi ein Dokument mit Texten und Bildern erzeugt.

Aber mach das ruhig erst mal so fertig. Hauptsache, Du gehst die Sache strukturiert an. Dann wird das auch ... ;-)

Metallicwar 3. Sep 2010 23:42

AW: Problem bei case // Problem bei Komponenten löschen
 
das mit den Report-Tools ist mir bewusst (z.B. Crystal Reports) aber ist denk ich mal ne gute Aufgabe für einen Newbie :)
Angenehmen Abend noch.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:02 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