Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VBA: Access, VBA

Sivun loppuun

Bittinikkari [21.01.2007 12:58:17]

#

Olen ohjelmoinnin osalta aloitteleva, jonkin verran tutustunut opinnoissani SQL:ään, Javaan sekä C-kieleen. VBA on vieras.

Nyt olen rakentamassa tietokantaa, jolla pidän yllä tietoja taloyhtiöistä ja niiden toimintaan liittyvistä asioista ja minulla olisi muutama ongelma, johon tarvitaan nähtävästi VBA:ta.

1. Isannointipalkkiot-taulukko, johon tallennetaan taloyhtiöiden isännöintipalkkiohistoria.

    Kentät: TalonNro, PalkkioAlkaen, VerollinenKkPalkkio

    Esim.
             0010     1.3.2005      100,00
             0010     1.5.2006      102,00
             0015     1.3.2005      200,00
             0015     1.5.2006      204,00
             0023     1.8.2006      150,00  (tullut uusi taloyhtiö 1.8.06 alkaen isännöintiin)

Miten saan haettua palkkiot niin, että jos haluan tietää palkkioiden suuruuden esim. ajalta 1.1. - 31.1.2007, niin se osaa hakea 1.5.06 olevat palkkiot taloyhtiölle nro 10 ja 15 sekä 1.8.06 olevan palkkion taloyhtiölle nro 23? Kokeilin parametrikyselyä Between[Alkupvm]And[Loppupvm], mutta sehän ei toimi tässä, jos ei käy katsomassa alkupäivämäärää aina oikeaksi, todelliseksi PalkkioAlkaen-päivämääräksi. Niin ja minulla on vielä sopimustaulu, jossa on SopimusPaattyyPvm eli on huomioitava, onko taloyhtiöllä isännöintisopimus voimassa hakuajankohtana eli 1.1. - 31.1.2007 vai onko talo siirtynyt muualle isännöintiin. Jos sopimus päättyisi 1.2.2007, niin palkkion olisi vielä tultava näkyviin.

2. Tietokannan jokaisessa taulukossa on myös kenttä PaivitettyPvm. Sen olisi tarkoitus toimia niin, että jos jotain taulukon tietueen kenttää (sen tietoa) käydään muuttamassa, PaivitettyPvm-kentän päiväykseksi päivittyisi automaattisesti muutospäivä.

3. Olen aloittanut tietokannan teon Access 2000:lla, kokeilin tietokannan avausta Access 2003:lla, mutta ohjelma ilmoittaa joidenkin taulukoiden kohdalla niitä avattaessa: Luku on liian suuri. Mistähän tämä johtuu?

Kuinka suuri Accesilla tehtävä tietokanta voi olla kooltaan, entä käyttäjien määrä, niin että tietokanta toimii vielä hyvin?

Olen kahlaillut isoja manuaaleja ja nettiä läpi, mutta en ole onnistunut/osannut ratkaista ongelmia. Olisin todella iloinen, jos saisin selkeää ja mahdollisimman yksinkertaista ratkaisua ongelmiini.

Harrikma [23.01.2007 11:51:08]

#

1. Helpoin ratkaisu on tehdä kaksi kyselyä, jos kerran käytät Accessia. Tee ensin kysely, joka hakee jokaisen talon viimeisimmän (max) palkkion päiväysten mukaan:

 SELECT Isannointipalkkiot.TalonNro, Max(Isannointipalkkiot.PalkkioAlkaen) AS MaxOfPalkkioAlkaen
FROM Isannointipalkkiot
GROUP BY Isannointipalkkiot.TalonNro

Tee seuraavan kysely, joka käyttää tuota ylläolevaa kyselyä apuna ja antaa loput tiedot näkyville. Et tarvitse päivämäärä rajoja, vaan tuloksena saat aina viimeisimmän päivämäärän / talo ja tiedon milloin palkkio on muuttunut.

 SELECT Isannointipalkkiot.TalonNro, Isannointipalkkiot.PalkkioAlkaen, Isannointipalkkiot.VerollinenKkPalkkio
FROM Isannointipalkkiot INNER JOIN Query1 ON (Isannointipalkkiot.PalkkioAlkaen = Query1.MaxOfPalkkioAlkaen) AND (Isannointipalkkiot.TalonNro = Query1.TalonNro)

Ensimmäinen kysely on Query1 niminen ja tämä toinen kysely on liitetty ensimmäiseen talonnro ja palkkioalkaen kenttien avulla.

Sopimusten voimassaolo ja niiden päättyminen voidaan toteuttaa periaatteessa ihan samalla periaatteella. Eli liität sopimus talun tähän jälkimmäiseen kyselyyn ja siinä voi käyttää sitten ehtona tuota päivämäärä rajaa.

2. Tuo on helpointa tehdä Accessin päälle jollain lomakkeella, jolta hoidetaan päivitys kysely ja samalla kertaa viedään muutospäivä myöskin tietokantaan.

3. Tuossa varmaan Google auttaa. En ole törmännyt ko. ongelmaan.

Vanhasta näppituntumasta voisi sanoa, että Access taipuu suuriinkin sovelluksiin. Esimerkiksi olin aikanaan kehittämässä sovellusta, jota käytti 20 henkilöä samanaikaisesti ja tietokantarivejä siinä oli yli 200 000 ja tauluja noin 40. (silloin toteutus oli vielä access 97:lla)

Bittinikkari [25.01.2007 01:20:00]

#

MAHTAVAN SUURET KIITOKSET.

1. Sain palkkiohaun toimimaan mainiosti. Todella selkeä ja yksinkertainen ratkaisu. Juuri sellainen, mitä kaipasinkin. Tein ratkaisun pohjalta sekä voimassaolevat isännöintipalkkiot, että tiettyyn ajankohtaan ajoittuvan palkkiohaun, esim. vaikkapa tilanteeseen 31.3.2005.

2. Tämä kohta jäi vielä askarruttamaan. Tarkoitus on, että lomakkeen avulla päivitetään taulukon tietoja. Esim. jos jonkun henkilön sukunimi muuttuisi ja teen muutoksen 25.1.2007 hänen tietoihinsa Henkilotiedot-taulun Sukunimi-kenttään (henkilötiedot perustettu 23.6.2006), niin PaivitettyPvm muuttuisi vanhasta päivämäärätiedosta eli 23.6.2006 automaattisesti päivämääräksi 25.1.2007, niin ettei käyttäjän itse tarvitse sitä muuttaa. Jos muutoksia ei tapahdu, päivämäärä ei myöskään muutu.

Vielä kerran paljon kiitoksia tiedoista.

neau33 [26.01.2007 12:49:32]

#

Moikka Bittinikkari!

Tässä olis kevyt & toimiva ratkaisu...

Formin Declarations osaan:

Option Compare Database
Public muuttuja As Variant

Tapahtumiin:

Private Sub Sukunimi_Exit(Cancel As Integer)
 If muuttuja <> Sukunimi.Value Then Päivitetty.Value = Now()
End Sub

Private Sub Sukunimi_GotFocus()
 muuttuja = Sukunimi.Value
End Sub

Bittinikkari [28.01.2007 02:10:21]

#

KIITOKSIA PALJON KOODISTA.

Olen ohjelmoinnin osalta aloitteleva, joten tarvitsisin vielä apuja edelliseen.

Sain koodin toimimaan, mutta tyhjät eli Is Null kentät aiheuttavat ongelmaa. Jos esim. lisään PuhKoti-kenttään puhelinnumeron, jossa ei ole ollut tietoa, ei päivitä uutta päivää PaivitettyPvm-kenttään. Myös jos tyhjennän vaikkapa Etunimi-kentän arvon, ei päivitystä tapahdu PaivitettyPvm-kenttään.

Muita pohdintojani:

Käynkö Henkilötiedot-lomakkeen kentät läpi niin, että lisään vain formin tapahtumiin Exit- ja GotFocus-tapahtumia allekkain jokaiselle kentälle (HloNumero, Etunimi, Sukunimi...)? HloNumero-kenttä on tosin laskuri, sitähän ei pääse muuttamaan, joten sen voi varmaankin jättää pois?

Voisikohan Exit- ja GotFocus-tapahtumat olla toisin päin, jos katsoo esim. yllä olevaa koodia Sukunimi-kentästä? Luetaanko kentän arvo ensin muuttujaan ja sen jälkeen verrataan muuttujan arvoa kentän arvoon, kun Sukunimi-kentästä poistutaan?

Voisiko muuttuja olla määrittelyosassa moduulikohtainen eli Private?


-Aloitteleva Bittinikkari-

neau33 [28.01.2007 13:46:00]

#

Moikka Bittinikkari!

Tässä olis kevyt lisäys...

Option Compare Database
Public muuttuja As Variant, muutettu As Boolean

Private Sub Sukunimi_BeforeUpdate(Cancel As Integer)
 muutettu = True
End Sub

Private Sub Sukunimi_Exit(Cancel As Integer)
 If muuttuja <> Sukunimi.Value Or muutettu Then Päivitetty.Value = Now()
End Sub

Private Sub Sukunimi_GotFocus()
 muuttuja = Sukunimi.Value: muutettu = False
End Sub

1. Lisäile koodit vain niiden kontrollien tapahtumiin joiden arvojen muutosten haluat vaikuttavan
Päivitetty-kenttään.

2. Kontrollin Exit tapahtumaa ei pääse syntymään ilman, että kontrolli on ensin saanut focuksen...

3. Voit esitellä muuttujat määrittelyosassa vaikka Dim -avainsanalla, joka käsittääkseni tekee
muuttujista tässä tapauksessa lomakekohtaisia. Privaatiksi määrittäminen ei muuta koodin
toimivuutta. Voit jakaa muuttujia toisten lomakkeiden käyttöön ainoastaan esittelemällä ne
julkisiksi globaalissa moduulissa.

neau33 [28.01.2007 19:30:50]

#

Heippa Bittinikkari!

Tässä olis vielä tapahtumakevennys...

Option Compare Database
Dim muuttuja As Variant

Private Sub Sukunimi_Exit(Cancel As Integer)
  If muuttuja <> Sukunimi.Value Or _
  IsNull(muuttuja) <> IsNull(Sukunimi.Value) _
  Then Päivitetty.Value = Now()
End Sub

Private Sub Sukunimi_GotFocus()
 muuttuja = Sukunimi.Value
End Sub

Bittinikkari [29.01.2007 01:06:23]

#

Moikka Nea!

Suuret, suuret kiitokset sinulle. Kokeilin viimeistä koodausta ja toimii hyvin.

Olisitko vielä niin ystävällinen, että selventäisit koodin rautalangasta. Ymmärrän kyllä koodin idean ja pääpiirteet, mutta... (esim. GotFocus, luetaan muuttujaan Sukunimi-kentän uusi arvo, eikö se pitäisi lukea ensin ja sitten vasta vertailla, vai miten tämä oikein menee?

-aloitteleva Bittinikkari-

neau33 [29.01.2007 16:48:00]

#

Hei taas Bittinikkari!

Kontrollin (Tässä lomakkeen, taulun Sukunimi-sarakkeen kenttiin sidottu, tekstiruutu) GotFocus tapahtuma laukaistaan (fires) kun, kontrolli aktivoidaan (kursori siirtyy tekstiruutuun), tällöin poimitaan kentän senhetkinen arvo muuttujaan. Kontrollin Exit-tapahtumassa eli kontrollista poistuttaessa sitten verrataan onko kyseistä arvoa muutettu sitten GotFocus-tapahtuman.
Jos arvo on Null ei tätä arvoa voida suoraan käyttää vertailuun syystä, että Null-arvo voi olla vain TOSI tai EPÄTOSI (True or False).
Eli vertailu: muuttuja <> TOSI jne. ei onnistu. Tällöin on tutkittava IsNull() funktion avulla sekä muttujan Null-arvon totuusarvo että tekstiruudun Null-arvon totuusrvo, jolloin vertailu onnistuu: Jos totuusarvo <> totuusarvo...

Bittinikkari [29.01.2007 22:58:48]

#

Moikka vielä Nea!

Oikein paljon kiitoksia neuvoista sekä hyvästä ja selventävästä vastauksesta.

Yksi asia kuitenkin vieläkin hämmentää ja haluaisin saada tämän itselleni selväksi; voiko koodi olla myös näin päin vai onko sillä mitään merkitystä? Ensin luetaan kursorin siirtyessä tekstiruutuun tekstiruudun sen hetkinen arvo muuttujaan ja sitten tekstiruudusta poistuttaessa verrataan onko kyseistä arvoa muutettu, koodi olisi näin samassa järjestyksessä kuin itse tapahtumat.

Option Compare Database
Dim muuttuja As Variant

Private Sub Sukunimi_GotFocus()
  muuttuja = Sukunimi.Value
End Sub

Private Sub Sukunimi_Exit(Cancel As Integer)
  If muuttuja <> Sukunimi.Value Or _
  IsNull(muuttuja) <> IsNull(Sukunimi.Value) _
  Then Päivitetty.Value = Now()
End Sub

Terveisin, Bittinikkari

Blaze [29.01.2007 23:23:04]

#

Bittinikkari kirjoitti:

voiko koodi olla myös näin päin vai onko sillä mitään merkitystä

Toki voi, aliohjelmat (siis ne Private Sub -- End Sub -riveillä erotetut osaset) on itsenäisiä kokonaisuuksia, joitten järjestyksellä koodissa ei oo väliä.

Bittinikkari [30.01.2007 00:07:33]

#

Kiitos vaan kaikille, tästä pääsen jo hyvin eteenpäin.

Mukavaa viikkoa, Bittinikkari


Sivun alkuun

Vastaus

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

Tietoa sivustosta