Zapętlenie polecenia z licznikiem.

0

Piszę program który ma obliczac pewne wartosci, wrzucac wyniki do roznych memo, a nastepny z dwóch memo, wysylac wyniki do jednego pliku tekstowego i rysować wykres. Wszystko juz prawie udało mi się zrobić, tylko, że gdy kaze mu wysyłać dane z tego memo to wysyła je tylko raz. Wrzucam kod i proszę o pomoc.

unit Wentylatory;

interface

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

type
  TForm1 = class(TForm)
    OknoCisnienieStatyczne: TEdit;
    OknoCS: TLabel;
    OknoCisnienieDynamiczne: TEdit;
    OknoCD: TLabel;
    KlawiszOblicz: TButton;
    MemoHp: TMemo;
    LabelWysokoscpompowania: TLabel;
    LabelCisnienieDynamiczne: TLabel;
    Memodh: TMemo;
    memov: TMemo;
    LabelPredkoscchwilowa: TLabel;
    MemoRe: TMemo;
    LabelRe: TLabel;
    Memocsrednie: TMemo;
    Labelc: TLabel;
    MemoQ: TMemo;
    LabelQ: TLabel;
    Wyniki: TGroupBox;
    OknoSrednica: TEdit;
    Label1: TLabel;
    KlawiszRysujWykres: TButton;
    procedure OknoCisnienieStatyczneChange(Sender: TObject);
    procedure OknoCisnienieDynamiczneChange(Sender: TObject);
    procedure KlawiszObliczClick(Sender: TObject);
    procedure OknoSrednicaChange(Sender: TObject);
    procedure OknoCisnienieStatyczneKeyPress(Sender: TObject;
      var Key: Char);
    procedure OknoCisnienieDynamiczneKeyPress(Sender: TObject;
      var Key: Char);
    procedure OknoSrednicaKeyPress(Sender: TObject; var Key: Char);
    procedure KlawiszRysujWykresClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  const
  pi=3.141592;
  T=293; // [K] temperatura
  u=0.000001; // [m2/s] lepkosc kinematyczna
  qp=1.25; // [kg/m3] gestosc powietrza
  qs=790; // [kg/m3] gestosc spirytusu
  qw=1000; // [kg/m3] gestosc wody
  g=9.81; // [m/s2] siła grawitacji

var
  Form1: TForm1;
  Hp:real; // wysokosc pompowania [mmH2O]
  dh:real; // cisnienie dynamiczne [mmH2O]
  v:real; // predkosc chwilowa [m/s]
  Re:real; // liczba reynoldsa
  c:real; // predkosc srednia [m/s]
  Q:real; // natezenie przeplywu [m3/s]
  dhs:real; // wysokosc pompowania [mmSpirytusu]
  Pd:real; // cisnienie dynamiczne [Pa]
  A:real; //pole przekroju rury[m2]
  d:real; //srednica rury [m]


implementation

{$R *.dfm}

procedure TForm1.OknoCisnienieStatyczneChange(Sender: TObject);
begin
try
dhs:=strtofloat(OknoCisnienieStatyczne.Text) ;
except
OknoCisnienieStatyczne.Text:='';
dhs:=0;
end;
end;

procedure TForm1.OknoCisnienieDynamiczneChange(Sender: TObject);
begin
try
Pd:=strtofloat(OknoCisnienieDynamiczne.Text);
except
OknoCisnienieDynamiczne.Text:='';
Pd:=0;
end;
end;

procedure TForm1.KlawiszObliczClick(Sender: TObject);
begin
A:=(d*d*pi)/4;

dh:=Pd/g;
memodh.Lines.Add(floattostrF(dh,ffFixed,100,4));   // policzenie dh

Hp:=(dhs*qs)/qw;
memoHp.Lines.Add(floattostrF(Hp,ffFixed,100,4),);  // policzenie Hp

v:=sqrt((2*(dh/1000)*qs*g)/qp);
memov.Lines.add(floattostrF(v,ffFixed,100,4));     // policzenie v

Re:=ln((v*D)/u);
memoRe.Lines.Add(floattostrF(Re,ffFixed,100,4));  // policzenie Re

c:=0.9*v;
memocsrednie.Lines.add(floattostrF(c,ffFixed,100,4));   //policzenie c

Q:=A*c;
memoQ.Lines.add(floattostrF(Q,ffFixed,100,4));     //policzenie natezenia przepywu

end;

procedure TForm1.OknoSrednicaChange(Sender: TObject);
begin
try
d:=strtofloat(OknoSrednica.Text);
except
OknoSrednica.Text:='';
d:=0;
end;
end;

procedure TForm1.OknoCisnienieStatyczneKeyPress(Sender: TObject;
  var Key: Char);
Const Dozwolone: Set Of Char = ['-', 'e', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', #8];
begin
 if Not (Key In Dozwolone) Then
  Key := #0;
end;


procedure TForm1.OknoCisnienieDynamiczneKeyPress(Sender: TObject;
  var Key: Char);
Const Dozwolone: Set Of Char = ['-', 'e', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', #8];
begin
 if Not (Key In Dozwolone) Then
  Key := #0;
end;

procedure TForm1.OknoSrednicaKeyPress(Sender: TObject; var Key: Char);
Const Dozwolone: Set Of Char = ['-', 'e', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', #8];
begin
 if Not (Key In Dozwolone) Then
  Key := #0;
end;

procedure TForm1.KlawiszRysujWykresClick(Sender: TObject);
var
TF_Hp : TextFile;
TF_Q  : TextFile;
TF_Suma : TextFile;
a : Real;
b : Real;
begin
try
memoHp.Lines.SaveToFile('Hp.txt');
memoQ.Lines.SaveToFile('Q.txt');

assignfile(TF_Hp,'Hp.txt');
assignfile(TF_Q,'Q.txt');
assignfile(TF_Suma,'Wykres.txt');

Reset(TF_Hp);
Reset(TF_Q);
Rewrite(TF_SUma);

ReadLn(TF_Hp,a);
ReadLn(TF_Q,b);
WriteLn(TF_Suma,a,b);

finally
CloseFIle(TF_Hp);
CloseFIle(TF_Q);
CloseFIle(TF_Suma);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
DecimalSeparator := '.';
end;

end.

do tego momentu wszystko jest dobrze, nie wiem jak zrobic dalej, proszę o pomoc

wiem, że powinienem zrobić licznik, którym by był klawisz oblicz, żeby dane były zapisywane tyle razy ile był kliknięty klawisz oblicz, lecz nie wiem jak to zrobić.

1

Nie wiem o co chodzi w tym zadaniu (znaczy nie rozumiem pytania) ale ujmujący jest sposób obsługi wyjątków w kodzie powyżej (chodzi o zdarzenia OnChange) polegający na tym że obsługujemy jeden wyjątek po to tylko aby go wygenerować ponownie... poza tym wszystkie trzy zdarzenia OnKeyPress robią to samo to po co 3 jak wystarczy jedno no i kompletny brak formatowania kodu że aż się nie chce go analizować.

0

dzięki wielki za komplementy dotyczące mojej wiedzy z programowania, niestety mam do czynienia z delphi tylko na zajęciach które mam od niedawna, kilka prostych rzeczy potrafię zrobić, a ten program próbuję napisać sam. Jakbyś chciał jednak pomóc to chodzi mi o zapętlenie procedury 'rysuj wykres' a konkretnie po kliknieciu 'rysuj wykres' ma zapisywać mi dane z dwóch memo do jednego pliku tekstowego i rysować z tego wykres, niestety w tych memo jest kilka wartosci a zapisuje do pliku tylko ta jedna. A tych danych jest tyle, ile razy kliknę 'oblicz' i właśnie tego nie mogę zrobić aby zapisywał wszystkie dane.

0

Cały tekst danego Memo znajduje się we własności Text. I bez sensu imo jest, że skoro posługujesz się komponentami VCL, to później męczysz się z zapisem do pliku typu tekstowego. Lepiej do tego celu użyć niewizualnego komponentu typu TStringList. Jego opis masz w helpie do IDE. Ewentualnie w google. Natomiast jeżeli chcesz zapisywać konkratne wiersze Memo, to odwołujesz się do nich poprzez Lines[I]. Gdzie I to wartośc indeksowana od zera. Może to być rownie dobrze zmienna - iterator pętli for.

0

Ok, rozumiem. Tylko, że problem w tym, że mam kilka memo, a w nich dane. Nie potrafię w inny sposób wysłać danych z dwóch memo do jednego pliku tekstowego i to jeszcze w taki sposób aby były w dwóch kolumnach, ponieważ chcę aby z tego pliku gnuplot rysował wykres. A jeżeli za [I] wstawię, np. 8 to zapisze mi osiem wierszy czy ósmy? Nawet gdbyby zapisywał osiem to problem w tym, że niby będzie działać ale jeżeli ktoś będzie chciał mieć tam więcej danych to zapisze i tak tylko te osiem. Dane pojawiają się po kliknieciu oblicz, i chciałem zrobić tak aby do pliku tekstowego wysyłał tyle danych ile razy się kliknie oblicz. Wiem, że tak można tylko nie wiem jak to zrobić...

0

Nie wiem czy dobrze zrozumiałem co chcesz zrobić, ale może to ci pomoże:

procedure ZapiszDane(NadpiszPlik: Boolean = False);
const
    NAZWA_PLIKU = 'Wykres.txt';
var
    StringList: TStringList;
    i: Integer;
begin
    StringList := TStringList.Create;
    
    if not NadpiszPlik then 
    if FileExists(NAZWA_PLIKU) then
        StringList.LoadFromFile(NAZWA_PLIKU);

    for i := 0 to form1.memoHp.Lines.Count - 1 do
        StringList.Add(form1.memoHp.Lines[i] + ' ' + form1.memoQ.Lines[i]);

    StringList.SaveToFile(NAZWA_PLIKU);
    FreeAndNil(StringList);
end;
0

@maaziii - przecież nic nie stoi na przeszkodzie aby w locie pobierać poszczególne linie z komponentów i zapisywać je do pliku; Jeśli ilość linii w obu komponentach TMemo jest zawsze taka sama to jedyne co potrzeba to tylko je połączyć i wpisać do pliku docelowego, który jak widać zawsze tworzysz na nowo (nie dopisujesz nowych danych na koniec);

Nie musisz korzystać z klasy TStringList i zapisywać jej zawartości metodą SaveToFile - tak jak masz w swoim pierwszym przykładzie - tworzysz plik, otwierasz go do zapisu, wpisujesz po kolei wszystkie połączone linie i zamykasz plik na koniec; Nie potrzeba przepisywać wszystkiego do osobnej listy i dopiero ją zapisywać do pliku; Przykład poniżej (bez obsługi błędów IO):

function SaveDataToFile(const AFileName: AnsiString): Boolean;
var
  fOutput: TextFile;
  I: Integer;
begin
  {$I-}
  AssignFile(fOutput, AFileName);
  try
    ReWrite(fOutput);
    Result := IOResult = 0;

    if Result then
      for I := 0 to memoHp.Lines.Count - 1 do
        WriteLn(fOutput, memoHp.Lines[I], #9, memoQ.Lines[I]);
  finally
    CloseFile(fOutput);
  end;
  {$I+}
end;
0

Oczywiście, że nie musi używać TstringList. Jednak skoro już i tak pisze pod VCL, to po co się męczyć z typami zapożyczonymi jeszcze z dawnych czasach, gdzie rządził Turbo Pascal. Jedyny sens bawienia się tymi typami, to według mnie pisanie pod WinAPI i konieczność rozbicia pliku na wiersze, przy wczytaniu. Wtedy najwygodniej. I oczywiście, że połączenie tekstu z kilku Memo to żaden problem. W razie czego zawsze jest FindComponent albo można zrobić też tablice tych Memo i do niej sie odnośić. Jeżeli TMemo jest sporo.

A co do pytania, co jeżeli podstawisz na przykład [8]. To najlepiej było zajrzeć do Helpa. Pogooglować. Dawno już byś znał odpowiedź. Oczywiście (po raz trzeci wiszą te oczy ;)), że Lines[IndeksOdZera] to konkretnia linijka w TMemo. Natomiast ich ilość jest zapisana we własności Count. I jest ona tylko do odczytu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1