Witam,
chciał bym zapętlić program, ale żeby wykonał się tyle razy ile zostanie wciśnięty przycisk Button. Ma to wyglądać tak, że wyświetla się formularz z paroma Editami i po kliknięciu przycisku param sczytuje zmienne(typu int), wpisuje je do tablicy, następnie mamy możliwość zmiany zmiennych na inne i po kolejnym kliknięciu w przycisk program znowu sczyta zmienne i dopisze(doda) je do już istniejących w tablicy. Program ma się wykonać 10 i wszystko mam, cały program tylko nie wiem jak go zapętlić.
Proszę o pomoc.
Zadeklaruj sobie dodatkową zmienną liczbową z indeksem iteracji i inkrementuj ją w pętli po każdym pobraniu danych od użytkownika (czyli po otwarciu okna dialogowego, wpisaniu danych i zaakceptowaniu).
No tak, tak zrobiłem i program po kliknięciu przycisku wykonuje się 10 razy z rzędu z tymi samymi zmiennymi
int i:=0;
for m:= 1 to 10 do
begin
[...]
i++;
end;
A okno z tymi polami edycyjnymi ma być cały czas widoczne?
https://4programmers.net/Forum/1546077 - @damianmajor987 czemu duplikujesz wątki i pytasz o coś, co było omówione w Twoim poprzednim wpisie?
@cerrato no tak tylko tu chodzi mi o to czy idzie to zrobić jednym przyciskiem, a nie pięcioma czy dziesięcioma. Bo jak nie to zostaje przy tamtym sposobie.
@furious programming tak, żeby dało się zmieniać wartości w editach
wydawało mi się, że w tamtym poście napisałem też, jak można to rozwiązać jednym przyciskiem. Zresztą temat był w toku, a Ty zamiast napisać coś dalej w odpowiedzi na to, co ja napisałem, po paru dniach założyłeś nowy wątek....
@cerrato o to kod i ss działania programu który po prostu mnoży wartości razy 10, a powinien dodawać 10 różnych wartości (zdefiniowane przez użytkownika)
unit unit6;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit10: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Label1: TLabel;
Label10: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
var
Tablica : array[0..9] of integer;
var a, b, c, d, e, f, g, h, i, j :integer;
implementation
{$R *.lfm}
procedure TForm1.Button1Click(Sender: TObject);
var n,o,s,r,p,w,u,x,y,z:real;
var m : integer;
begin
a:=0;b:=0;c:=0;d:=0;e:=0;f:=0;g:=0;h:=0;i:=0;j:=0;
Tablica[0] := a;
Tablica[1] := b;
Tablica[2] := c;
Tablica[3] := d;
Tablica[4] := e;
Tablica[5] := f;
Tablica[6] := g;
Tablica[7] := h;
Tablica[8] := i;
Tablica[9] := j;
n:=StrToFloat(Edit1.text);
o:=StrToFloat(Edit2.text);
s:=StrToFloat(Edit3.text);
r:=StrToFloat(Edit4.text);
p:=StrToFloat(Edit5.text);
w:=StrToFloat(Edit6.text);
u:=StrToFloat(Edit7.text);
x:=StrToFloat(Edit8.text);
y:=StrToFloat(Edit9.text);
z:=StrToFloat(Edit10.text);
for m:= 1 to 10 do
begin
if n = 1 then a:=a+25;
if n = 2 then a:=a+18;
if n = 3 then a:=a+15;
if n = 4 then a:=a+12;
if n = 5 then a:=a+10;
if n = 6 then a:=a+8;
if n = 7 then a:=a+6;
if n = 8 then a:=a+4;
if n = 9 then a:=a+2;
if n = 10 then a:=a+1;
if o = 1 then b:=b+25;
if o = 2 then b:=b+18;
if o = 3 then b:=b+15;
if o = 4 then b:=b+12;
if o = 5 then b:=b+10;
if o = 6 then b:=b+8;
if o = 7 then b:=b+6;
if o = 8 then b:=b+4;
if o = 9 then b:=b+2;
if o = 10 then b:=b+1;
if s = 1 then c:=c+25;
if s = 2 then c:=c+18;
if s = 3 then c:=c+15;
if s = 4 then c:=c+12;
if s = 5 then c:=c+10;
if s = 6 then c:=c+8;
if s = 7 then c:=c+6;
if s = 8 then c:=c+4;
if s = 9 then c:=c+2;
if s = 10 then c:=c+1;
if r = 1 then d:=d+25;
if r = 2 then d:=d+18;
if r = 3 then d:=d+15;
if r = 4 then d:=d+12;
if r = 5 then d:=d+10;
if r = 6 then d:=d+8;
if r = 7 then d:=d+6;
if r = 8 then d:=d+4;
if r = 9 then d:=d+2;
if r = 10 then d:=d+1;
if p = 1 then e:=e+25;
if p = 2 then e:=e+18;
if p = 3 then e:=e+15;
if p = 4 then e:=e+12;
if p = 5 then e:=e+10;
if p = 6 then e:=e+8;
if p = 7 then e:=e+6;
if p = 8 then e:=e+4;
if p = 9 then e:=e+2;
if p = 10 then e:=e+1;
if w = 1 then f:=f+25;
if w = 2 then f:=f+18;
if w = 3 then f:=f+15;
if w = 4 then f:=f+12;
if w = 5 then f:=f+10;
if w = 6 then f:=f+8;
if w = 7 then f:=f+6;
if w = 8 then f:=f+4;
if w = 9 then f:=f+2;
if w = 10 then f:=f+1;
if u = 1 then g:=g+25;
if u = 2 then g:=g+18;
if u = 3 then g:=g+15;
if u = 4 then g:=g+12;
if u = 5 then g:=g+10;
if u = 6 then g:=g+8;
if u = 7 then g:=g+6;
if u = 8 then g:=g+4;
if u = 9 then g:=g+2;
if u = 10 then g:=g+1;
if x = 1 then h:=h+25;
if x = 2 then h:=h+18;
if x = 3 then h:=h+15;
if x = 4 then h:=h+12;
if x = 5 then h:=h+10;
if x = 6 then h:=h+8;
if x = 7 then h:=h+6;
if x = 8 then h:=h+4;
if x = 9 then h:=h+2;
if x = 10 then h:=h+1;
if y = 1 then i:=i+25;
if y = 2 then i:=i+18;
if y = 3 then i:=i+15;
if y = 4 then i:=i+12;
if y = 5 then i:=i+10;
if y = 6 then i:=i+8;
if y = 7 then i:=i+6;
if y = 8 then i:=i+4;
if y = 9 then i:=i+2;
if y = 10 then i:=i+1;
if z = 1 then j:=j+25;
if z = 2 then j:=j+18;
if z = 3 then j:=j+15;
if z = 4 then j:=j+12;
if z = 5 then j:=j+10;
if z = 6 then j:=j+8;
if z = 7 then j:=j+6;
if z = 8 then j:=j+4;
if z = 9 then j:=j+2;
if z = 10 then j:=j+1;
end;
ShowMessage('Ferrari '+inttostr(a)+#13#10+'Renault '+inttostr(b)+#13#10+'McLaren '+inttostr(c)+#13#10+'RedBull '+inttostr(d)+#13#10+'Alfa Romeo '+inttostr(e)+#13#10+'Honda '+inttostr(f)+#13#10+'Mercedes '+inttostr(g)+#13#10+'Williams Martini '+inttostr(h)+#13#10+'Haas '+inttostr(i)+#13#10+'Sahara Force India '+inttostr(j)+#13#10);
end;
end.
P.S. wiem, że kod zostawia wiele do życzenia, ale na razie nie umiem inaczej, więc proszę o wyrozumiałość
Muszę przyznać, że masz rację - ten kod dość mocno odbiega od tzw. "dobrych standardów".
Pytanie - czy chcesz się pobawić (z nasza pomocą oczywiście) w napisanie tego tak, żeby było porządnie, czytelnie i 10x krócej, czy masz to gdzieś, nie chcesz poprawiać, a jedynie zrobić tak, żeby działało?
Zastanów się ze spokojem, ja idę spać, do tematu wrócimy jutro (chyba, że w międzyczasie ktoś inny przejmie pałeczkę ;))
I jak możesz to spakuj cały projekt do jakiegoś archiwum ZIP i prześlij jako załącznik do posta. W ten sposób będę mógł to odpalić u siebie bez konieczności tworzenia formatki z komponentami, a do tego na 100% "numerki" Edit'ów i Labeli będą u mnie i u Ciebie takie same ;)
Tak bardzo z wielką chęcią napiszę go 10x krócej po prostu wszelkie moje próby skrócenia kodu kończyły się masą błędów dlatego zrobiłem to bardzo łopatologicznie.
P.S. projekt dołączam w załączniku
unit unit6;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit10: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Label1: TLabel;
Label10: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
var
Tablica : array[0..9] of integer;
licznik: Integer;
sledit: TStringList;
procedure TForm1.Button1Click(Sender: TObject);
var
i, wartosc: Integer;
tekst: String;
begin
if licznik<11 then //jeżeli jest mniej niż 11 przebiegów
begin
for i:=0 to sledit.Count-1 do //dla każdego edita - oczywiście zadziała bez błędu jeżeli ilość editów będzie zgodna z rozmiarem tablicy
begin
if TryStrToInt(TEdit(sledit.Objects[i]).Text, wartosc) then //jeżeli zawartość edita jest liczbą
Tablica[i]:=Tablica[i]+wartosc; //zwiększ odpowienią wartość w tablicy
end;
if licznik=10 then //jeżeli ostatni przebieg
begin
tekst:='';
for i:=0 to sledit.Count-1 do
tekst:=tekst+sledit[i]+': '+IntToStr(Tablica[i])+#13#10;
ShowMessage(tekst); //to wyświetl sumę
end;
Button1.Caption:='Przebieg '+IntToStr(licznik);
Inc(licznik); //zwiększ licznik
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
sledit:=TStringList.Create; //lista editów z odpowiadającym im tekstem
sledit.AddObject('Ferrari', Edit1);
sledit.AddObject('Renault', Edit2);
sledit.AddObject('McLaren', Edit3);
sledit.AddObject('RedBull', Edit4);
sledit.AddObject('Alfa Romeo', Edit5);
sledit.AddObject('Honda', Edit6);
sledit.AddObject('Mercedes', Edit7);
sledit.AddObject('Williams Martini', Edit8);
sledit.AddObject('Haas', Edit9);
sledit.AddObject('Sahara Force India', Edit10);
for i:=0 to High(Tablica) do
Tablica[i]:=0;
licznik:=1;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
sledit.Free;
end;
end.
To ja też zaproponuję kod z dynamicznym tworzeniem komponentów. Opisów niestety brak. Pod Lazarusem trzeba będzie pozmieniać nazwy unitów.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure Calculate(Sender: TObject);
procedure UpdateCaption;
public
{ Public declarations }
end;
var
Form1: TForm1;
CarArr : array[1..10] of Integer;
count : Integer;
const
TCars : array[1..10] of string = ('Ferrari',
'Renault',
'McLaren',
'RedBull',
'Alfa Romeo',
'Honda',
'Mercedes',
'Williams Martini',
'Haas',
'Sahara Force India');
ButtonName = 'Button1';
EditName = 'Edit';
LabelName = 'Label';
implementation
{$R *.dfm}
procedure TForm1.Calculate(Sender: TObject);
var
i : Integer;
value : Integer;
edt : TEdit;
mess : string;
begin
for I := 0 to ComponentCount do
begin
edt := TEdit(FindComponent(EditName + i.ToString));
if Assigned(edt) then
if TryStrToInt(edt.Text, value) then
begin
case value of
1..5 : CarArr[i] := CarArr[i] + 25 - value * 3;
6..9 : CarArr[i] := CarArr[i] + 8 - (value - 6) * 2;
10 : CarArr[i] := CarArr[i] + 1;
end;
mess := mess + TCars[i] + ' ' + CarArr[i].ToString + #13;
end;
end;
Dec(count);
UpdateCaption;
if count = 0 then
(FindComponent(ButtonName) as TButton).Enabled := False;
ShowMessage(mess);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
edt : TEdit;
btn : TButton;
lbl : TLabel;
begin
Randomize;
count := 10;
UpdateCaption;
for i := 1 to 10 do
begin
edt := TEdit.Create(form1);
with edt do
begin
Name := EditName + i.ToString;
Parent := Form1;
Top := 20 + i * 30;
Left := 150;
Height := 30;
Width := 100;
Text := (random(10) + 1).ToString;
end;
lbl := TLabel.Create(form1);
with lbl do
begin
Name := LabelName + i.ToString;
Parent := Form1;
Top := 25 + i * 30;
Left := 20;
Height := 30;
Width := 100;
Caption := TCars[i];
end;
end;
btn := TButton.Create(Form1);
btn.Name := ButtonName;
btn.Parent := Form1;
btn.Top := 350;
btn.Left := 150;
btn.Height := 30;
btn.Width := 80;
btn.Caption := 'Wprowadź';
btn.OnClick := Calculate;
Form1.Height := 500;
Form1.Width := 600;
end;
procedure TForm1.UpdateCaption;
begin
Form1.Caption := count.ToString;
end;
end.
@damianmajor987: możesz skrócić ten kod znaaaacznie, ale musisz się nauczyć korzystać z macierzy i pętli, bo bez tego się nie obejdzie. No i zanim zabierzesz się za cokolwiek, napierw powinieneś znaleźć najlepsze i przy okacji najkrótsze rozwiązanie, zamiast korzystać z pierwszego, które na myśl przyjdzie.
Po pierwsze, zamień pary TLabel
+ TEdit
na kontrolki typu TLabeledEdit
– będziesz miał o połowę mniej komponentów na formularzu. Nazwij je jak chcesz, bo to akurat nie jest istotne.
Po drugie, wywal wszystkie zmienne globalne, bo takich rzeczy się nie robi. A już na pewno nie tworzy się dziesięciu zmiennych, skoro można zadeklarować sobie jedną macierz z dziesięcioma liczbami. Wywal też zmienną Tablica
, bo w ogóle z niej nie korzystasz po inicjalizacji zerami (co jest bez sensu, bo zmienne globalne – również tablice – są inicjalizowane automatycznie).
Jeśli potrzebujesz do tablicy wpisać liczby podane w polach edycyjnych, to zadeklaruj sobie taką tablicę (np. jako pole klasy). Napisz sobie metodę, która w pętli pobierze wartości z pól edycyjnych, przekonwertuje je i wpisze do tablicy. Możesz skorzystać z metody FindComponent
do odszukania editów, a możesz też zadeklarować sobie tablicę przechowującą referencje, którą wystarczy uzupełnić np. kontruktorze klasy okna.
Zamiast potężnej drabiny if
ów, zapisz wszystkie stałe wartości w stałej tablicy i w pętli odczytuj z niej wartości, które potrzebujesz dodać do wartości z tablicy liczb pobranych z pól edycyjnych. W Twoim oryginalnym kodzie, te wartości dodajesz do zmiennych od n
do z
– w razie gdybyś nie wiedział o co mi chodzi. W każdej grupie warunków dodajesz te same liczby, więc możesz skrócić ten kod dramatycznie.
@Paweł Dmitruk, @Clarc Bardzo dziękuję wam za rozwiązanie mojego problemu tylko nie wiem czemu, ale podczas próby uruchomienia robi się dosyć dziwna sytuacja. Otwiera mi zupełnie inny plik i pokazuje błąd widoczny na załączonym zrzucie. Mój program jest pod nazwą unit 6, a otwiera mi Program.lpr
Przecież treść błędu jasno informuje o tym, że nazwa programu jest nieprawidłowa – masz ją podkreśloną czerwonym wężykiem. Wszystko dlatego, że program
to zarezerwowane słowo, które nie może być użyte jako identyfikator.
@furious programming Po zmianie nazwy program dalej pokazuje błąd, teraz dlatego bo nie może znaleźć Tforrm1, chociaż jak można zaopserwować we wszystkich 3 kodach moim dostępnych wyżej Tform występuje i nie mam pojęcia o co chodzi
Dołączam zrzut ekranu.
Klasa formularza ma inną nazwę niż TForm1
. Weź zapisz ten projekt na dysku, nadaj plikom i klasom konkretne nazwy i dopiero wtedy wszystko skompiluj.