Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Pascal: Delphi: array luominen ja haku?

doze [07.02.2005 02:37:33]

#

Heps, pikkuinen aloittelijan kysymys..

Yritän tehdä sellasta juttua, että käyttäjä voi valita formilla olevista DateTimePicker komponenteista alotus ja lopetus päivän. Sitten klikata alla olevista valintaruuduista viikon päivät jotka halutaan sisällyttää laskuun. Kun klikataan nappia, ohjelma menee alotuspäivästä lopetuspäivään ja laskee montako valittua viikonpäivää aikavälillä on.

Ajattelin että se pitäisi tehdä ilmeisesti jotenkin näin: Ensin luodaan taulukko missä on valittujen viikonpäivien nimet, sitten käydään while -lauseella päivät läpi ja aina while lauseen sisällä tarkastetaan DayOfWeek-funktiolla, että onko ko. päivä 'valitut päivät' -taulukossa, jos on kasvatetaan päivien laskuri muuttujan arvoa. While lauseen jälkeen näytetään laskettu lukumäärä..

En tiedä käykö tähän array vai set vai mikä. Mutta tälläistä olisi tarkoitus tehdä, kaikki muu onnistuu itseltä paitsi taulukon luominen ja tarkastaminen onko päivä taulukossa..

En tiedä oikeen mitää taulujen maailmasta, mutta siis jotain tähän tyyliin:

procedure TForm1.Button1Click(Sender: TObject);
const
  Days : array[1..7] of string;
var
  alku_pvm: Date;
  pvm_maara: Integer;
begin
  if checkbox_maanantai.checked then
      asetetaan 'monday' taulukkoon
  if checkbox_tiistai.checked then
      asetetaan 'tuesday' taulukkoon

...jne.. valitut päivämäärät taulukkoon

  alku_pvm := DateTimePicker1.Date;
  pvm_maara := 0;
  while alku_pvm <= DateTimePicker2.Date do
    begin
      if DayOfWeek(alku_pvm) in Days then
        inc(pvm_maara);
      inc(alku_pvm)
    end;
  ShowMessage(IntToStr(pvm_maara));
end;

Eli onnistuuko tälläinen taulukoilla? apua kaivataan päivän laittamisessa taulukkoon ja tarkistamisessa onko jokin string taulukossa. Tai sitten jokin muu konsti jos ei taulukoilla luonnaa..

Kiitos vastauksista etukäteen! :)

doze [07.02.2005 04:14:15]

#

No niin, tämä ratkesikin sitten jo.. DayOfTheWeek funktio palauttaa viikonpäivän integer arvon 1-7 (DayOfWeek sama mutta aloittaa viikon sunnuntailla), joten tein niin että laitoin checkboxien nimiksi Checkbox_paiva1, Checkbox_paiva2, jne (maanantaista sunnuntaihin) ja sitten FindComponentilla katsoin onko ko checkbox ruksattu vai ei while lauseessa.. eli näin:

procedure TForm1.Button1Click(Sender: TObject);
var
  alku_pvm: Date;
  pvm_maara: Integer;
begin
  alku_pvm := DateTimePicker1.Date;
  pvm_maara := 0;
  while alku_pvm <= DateTimePicker2.Date do
    begin
      if TCheckBox(self.FindComponent('Checkbox_paiva'+IntToStr(DayOfTheWeek(alku_pvm)))).Checked then
        Inc(pvm_maara);
      alku_pvm := alku_pvm + 1;
    end;
  ShowMessage(IntToStr(pvm_maara));
end;

Metabolix [07.02.2005 08:04:25]

#

Hyvä ratkaisu, eipä olisi tullut mieleenkään :)

Minä tekisin tuon niin, että määrittelisin globaalin muuttujan PaivienMaara: Integer; ja nostaisin / laskisin sen arvoa aina, kun jokin CheckBox menee päälle tai pois (jokaiselle CheckBoxille yhteinen OnClick-proseduuri). Kun kalenterin valinta muuttuu, voisi mustata (Enabled := False) ne boksit, joita ei saa käyttää. Käytettävä tapa riippuu tietenkin siitä, mitä tarkalleen halutaan saada aikaan, ja tämä keino laskisi jokaisen viikonpäivän vain kerran...

Kuitenkin FindComponentia nopeampaa olisi laittaa CheckBoxin OnClickissa pienen globaalin taulukon alkio Trueksi / Falseksi ja tarkistaa tuossa loopissa vain, onko se True. Mutta Pascal-ohjelmoijahan ei nopeudesta välitä (Olen vain käyttänyt liikaa C:tä :)

Tiedätkin varmaan, mutta mainitsen varmuuden vuoksi: globaali muuttuja on sellainen, joka näkyy kaikkiin proseduureihin, ja sen voi määritellä samaan var-lauseeseen, jossa Form1:n määrittely on.

zacura [07.02.2005 11:38:41]

#

Metabolix kirjoitti:

Kuitenkin FindComponentia nopeampaa olisi laittaa CheckBoxin OnClickissa pienen globaalin taulukon alkio Trueksi / Falseksi ja tarkistaa tuossa loopissa vain, onko se True.

Toinen tapa on taulukoida CheckBoxit tähän tyyliin:

...

var
  Form1: TForm1;
  box_array: array[1..3] of ^TCheckBox;  //Pointteritaulukko

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  box_array[1] := @CheckBox1;   //Asetetaan kolme CheckBoxia taulukkoon
  box_array[2] := @CheckBox2;
  box_array[3] := @CheckBox3;
end;

...

//Näin yksinkertaista on käyttäminen
procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 1 to 3 do
    box_array[i].Checked := True;
end;

Metabolix [07.02.2005 19:29:54]

#

Ei itse asiassa tarvitse olla edes erityisesti pointtereita, koska luokat ovat niitä jo automaattisesti.

doze [08.02.2005 01:43:16]

#

Jep, ei tuu hirveemmin nopeutta/prosessori rasitusta ajateltua näin kun tässä aloittelee.. delphillä kun tekee, niin tulee liikaa käytettyä muutenkin kaikkia "mennään siitä mistä aita on matalin" juttuja. Esim noi valmiit db-komponentit, mitkä "oikeat" ohjelmoijat on manannut jo moneen kertaan alimpaan helvettiin.. tosin aikeissa on, että jos tekemäni ohjelma menee yleiseen käyttöön ja osoittautuu tarpeelliseksi, niin db komponentit poistetaan ja laitetaan tavalliset gridit ja editit tilalle, ja kiinnitetään muutenkin huomiota paremmin muuttujien luomiseen ja vapauttamiseen ja yleensäkin komponenttien luomiseen ja vapauttamiseen jne..

Mutta näin nykypäivän kohta valmistuvana ohjelmoinnin opiskelijana hieman kummastelen sitä, kun aina ensimmäisenä toitotetaan mitenkä kannattaisi mikäkin tehdä, että on mahdollisimman kevyt ja vähän muistia kuluttava ja nopea ja niin edelleen.. eihän näillä nykykoneilla mikään missään tunnu ja niiden "oikeiden" tapojen ohjelmoiminen vie paljon kauemmin kuin käyttämällä valmiita esim funktioita/methodeja vaikka olisivatkin hitaampia ;)

Mutta siis tottakai, jos kunnolla tekee niin kannattaisi ottaa kaikki nopeus ja muistinkulutus asiat aina huomioon jne. Kai sen sitten oppii kantapään kautta joskus, kun aloittaa pienellä ohjelmalla ja sitten kun se on paisunut massiiviseksi järjestelmäksi, niin alkaa ne pienetkin nopeusrasitteet tulemaan esiin moninkertaistuneena.

Kiitos vastauksista!

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta