Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VBA: Missä vika VB-kodissa?

Sivun loppuun

Liisapu [13.11.2004 18:54:49]

#

Minulla on tietokannassa Lukuvuosi, Luokka, Oppilas, Poissaoloseuranta ja Paiva taulut. Päälomakkeella on lstluokka, lstoppilas ja oppilasId listat. Päälomakkeella on listassa kaikki luokat, kun klikkaa luokkaa tulevat kyseisen luokan oppilaiden nimet lstOppilas- listaan ja jokaisen oppilaan oppilastunnus lstOppId-listaan. Nyt en saa tallennettua OppilasId:tä Poissaoloseutanta taulukkoon. Ohjelma antaa virheen rivillä: rsPoissa.Fields(1) = lstOppID.Text ja syyksi: tyypit eivät ole yhteensopivia. Muut tiedot tallentuvat Poissaoloseuranta taulukkoon. Tuntien tallennus koodi alla. Missähän vika?

 Private Sub cmdTunnit_Click()
   ' määritellään muuttuja
   Dim i As Integer
   ' mennään poissaolotietojen viimeiseen tietueeseen
   rsPoissa.MoveLast
   ' käydään läpi kaikki txtPoissa kentät, joissa on merkitty poissaolotunnit
   For i = 0 To txtLuku - 1
      ' jos poissaolotunnit eivät ole tyhjiä, niin lisätään ne poissaoloseuranta
      ' tietokantaan
          If txtTunnit(i) <> "" Then
          ' avataan uusi poissaolo lomake
          rsPoissa.AddNew
          rsPoissa.Fields(1) = lstOppID.Text
          rsPoissa.Fields(2) = DTPicker1.DayOfWeek
          rsPoissa.Fields(3) = DTPicker1.Value
          rsPoissa.Fields(4) = txtTunnit(i)
          rsPoissa.Update
          End If
   Next
   MsgBox "Poissaolotunnit lisätty!"
End Sub

Gaxx [14.11.2004 09:49:00]

#

Menee vähän arvailuks kun en tiedä mitä tyyppiä mikin on, mutta kokeileppa muuttaa kyseinen virherivi muotoon:

rsPoissa.Fields(1) = Val(lstOppID.Text)

Edit: tekstiä ei voi tallentaa lukumuuttujaan vaan se pitää ensin konvertoida luvuksi Val()-funktiolla.

Liisapu [14.11.2004 10:26:09]

#

Muutoksen jälkeen virheilmoitus: Tietuetta ei voi lisätä tai muuttaa, koska tähän tietuseen liittyvän on oltava taulukossa öoppilasö. Taulukossa oppilas ovat kentät: OppilasId, Nimi ja luokkaId ja vastaavasti Poissaoloseuranta taulukossa ovat kentät: SeurantaId, OppilasID, PoissaPaiva, PoissaPVM, PoissaTunnit ja PoissaoloSyy. (Luokka taulukossa: LuokkaId, LuokanNimi,LukuvuosiId ja Lukuvuositaulukossa:LukuvuosiId ja Lukuvuosi)

glottis [14.11.2004 10:32:19]

#

rsPoissa.Fields(1) = lstOppID.Text

Onko tuo rsPoissa.Fields todellakin indeksoitu ykköseksi vai onko se numero 0? On myös vaikea käsittää, että miksi ID-numero olisi Text-arvolla.. hmm

Liisapu [14.11.2004 12:36:10]

#

Kyseessä on Poissaoloseuranta taulukon toinen kenttä, ensimmäinen on rsPoissa.fields(0). ID-numero on tietenkin numero, mutten osannut sitä laittaa...

tuomas [14.11.2004 12:50:58]

#

Mikä kontrolli on tuo rsPoissa?

Liisapu [14.11.2004 13:10:13]

#

moduulissa määritelty: Global rsPoissa As ADODB.Recordset

glottis [14.11.2004 16:38:34]

#

Liisapu kirjoitti:

moduulissa määritelty: Global rsPoissa As ADODB.Recordset

Global? Neverheard... tuskin auttaa mutta korvaa se Public -muuttujalla.

Ja eikös ID-numeron (jossa on varmaan myös perusavain määriteltynä? Siis, jos käytät accessia tietokannan rakentamiseen) ole syytä olla se eka kenttä eli rsPoissa.fields(0).

Mitä muuten yleensä käytät tietokantayhteyden muodostamiseen? ADOa? DAOa? Entä mitä "tietokantaengineä"?

Liisapu [14.11.2004 23:23:19]

#

Yhteys ADOlla, koodi alla. Taulukossa Oppilas on OppilasId perusavain ja Poissaolotaulussa on perusavaimena SeurantaId ja viiteavaimena OppilasId.

 Public Function avaaYhteys()

    'Yhteyden alustaminen
    kohde = "Poissaolo.mdb"

    Set cn = New ADODB.Connection
    'Jos kantaan ei saada yhteyttä, niin ilmoitetaan siitä käyttäjälle
    'provider ominaisuus viittaa OLEDB:n tietokantatyyppiin
    cn.Provider = "Microsoft.Jet.OLEDB.4.0"

    'yhteyden asentaminen
    cn.ConnectionString = App.Path + "\" + kohde

    'avataan yhteys
    cn.Open


End Function

glottis [15.11.2004 08:18:29]

#

Liisapu kirjoitti:

Yhteys ADOlla, koodi alla. Taulukossa Oppilas on OppilasId perusavain ja Poissaolotaulussa on perusavaimena SeurantaId ja viiteavaimena OppilasId.

 Public Function avaaYhteys()

    'Yhteyden alustaminen
    kohde = "Poissaolo.mdb"

    Set cn = New ADODB.Connection
    'Jos kantaan ei saada yhteyttä, niin ilmoitetaan siitä käyttäjälle
    'provider ominaisuus viittaa OLEDB:n tietokantatyyppiin
    cn.Provider = "Microsoft.Jet.OLEDB.4.0"

    'yhteyden asentaminen
    cn.ConnectionString = App.Path + "\" + kohde

    'avataan yhteys
    cn.Open


End Function

Miten olisi

Set cn = New ADODB.Connection
'Asettaa cn -metodin uudeksi ADO-tietokantayhteydeksi
    cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & App.Path & "\TIETOKANNAN NIMI.mdb"
    cn.Open   'Avataan tietokantayhteys
    Set JOKU = New ADODB.Recordset    'Asetetaam Tietokanta -metodi uudeksi ADO-recordsetiksi (
    JOKU.Open "TIETOKANTATAULUN NIMI TÄHÄN", myYhteys, adOpenKeyset, adLockPessimistic, adCmdTable

Ehkä? Sitten siihen vielä... e h k ä

Antti [15.11.2004 09:35:51]

#

Liisapu kirjoitti:

Muutoksen jälkeen virheilmoitus: Tietuetta ei voi lisätä tai muuttaa, koska tähän tietuseen liittyvän on oltava taulukossa öoppilasö.

Sinulla on relaatio poissaolo-taulun ja oppilas-taulun välillä ja kyseessä on relaatiovirhe. Lisätessäsi poissaolo tauluun rivin ei vastaavaa oppilasta löydy oppilas-taulusta.

Ongelma syntyy tarkalleen ottaen lisättäessä tekstiä numeeriseen kenttään. Kenttään lisättävä arvo pitää tyypittää tarkalleen sarakkeen tyypiksi: CInt(Tekstiarvo); ja vastaavan tulee löytyä oppilastaulusta.

Syytä olisi varmaan myös ennen lisäämistä tarkistaa arvon olemassaolo ja tyyppi.

Edit: Typoja

Liisapu [16.11.2004 11:18:39]

#

Tarkistin kannan ja Poissaoloseuranta taulukossa OppilasId on pitkä kokonaisluku. OppilasId on Oppilas taulukossa perusavain ja laskuri tyyppinen. Millä konvertoidaan testi pitkäksi kokonaisluvuksi? (CInt antaa tyyppivirheen)

glottis [16.11.2004 11:34:13]

#

öööh... pitääkö teksti siis konvertoina numeroksi? Tarkennas nyt hieman. Ja pitääkö tuo konvertointi tapahtua tietokannassa (Access?) vai ohjelmakoodissa (Visual Basic)?!

setä [16.11.2004 12:05:53]

#

Clng(lstOppID.Text)

BadSource [18.11.2004 08:46:49]

#

Ongelma ilmeisesti ratkennut, kun kerran mitään ei kuulu, mutta kiinnitin vain huomiota noihin lstOppilas- ja lstOppId-listoihin.

Jos listat luodaan "käsin", niin nuo kannattaisi yhdistää käyttämällä ListBox:n ItemData-toimintoa. Kun oppilaiden nimet lisätään listaan, niin nimen ItemDataan tallennetaan samalla kyseisen oppilaan oppilasID.

List1.AddItem [Oppilaan nimi]
List1.ItemData(.List1.NewIndex) = [OppilasID]

ItemDataan viitataan samalla tavalla mitä itse Listaankin, eli

MsgBox List1.List(i) & ":n ItemData on " & List1.ItemData(i)

Huomioitavaa on, että ItemDataan voi laittaa ainoastaan numeerisia arvoja, eli juuri jotain ID arvoja.

Edit: tyop, toyp, typo...


Sivun alkuun

Vastaus

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

Tietoa sivustosta