Henkilökohtaisen tiedonhallinnan perusteet -kurssin FAQ

Erkka-ohjelma

Minkä kardinaalisuuden valitsen suhteiden välille, 1-to-1, 1-to-M vai M-to-M?

1-to-1-suhdetta ei kannata tehdä juuri koskaan. Tällöin kahden taulun välille tulee pakollinen suhde. Tällöin yhteen tietueeseen liittyy aina yksi toisen taulun tietue. Käytännössä järkevämpää on sijoittaa ominaisuudet jompaankumpaan tauluista ja poistaa toinen taulu kokonaan. Osan ominaisuuksista voidaan laittaa pakollisuusarvoksi NULL, jolloin niitä ei ole välttämätön antaa.

Henkilöstä 1-to-M urheilusuoritukseen, M-to-M lajiin

1-to-M-suhdetta kannattaa käyttää silloin kun yksi voi liittyä useaan toisen taulun tietueeseen, mutta ei toisinpäin. Eli esimerkiksi tietty henkilö voi liittyä useaan urheilusuoritukseen, mutta tietyn urheilusuorituksen voi tehdä vain yksi henkilö (paitsi jos halutaan mahdollistaa myös joukkueen yhteinen suoritus). Tällöin M on tultava urheilusuorituksen viereen.

M-to-M-suhdetta tarvitaan taas sellaisessa tilanteessa, jossa myös liittyminen voi tapahtua toisinkin päin. Esim. tietty henkilö voi harrastaa useaa lajia ja tiettyä lajia voi harrastaa usea henkilö. M-to-M-suhteesta muodostuu aina uusi taulu, jossa on molempien taulujen perusavaimet. Tällä taululla voidaan tehdä kytkennät molempiin suuntiin.

M-to-1-suhde sykkeestä

Jos halutaan luoda valinnainen suhde (0...*-suhde), niin tällöin on käytettävä M-to-1-suhdetta tai M-to-M-suhdetta. Esimerkiksi lisätietotyyppinen kohteessa kuten syke-tiedot, voidaan liittää M-to-1-suhteella urheilusuoritukseen. M on tultava syke-kohteen viereen. Tällöin syke-tauluun tulee viiteavain, jonka kohteena on urheilusuoritustaulun perusavain. Jokaiseen urheilusuoritukseen ei kuitenkaan tarvitse tällöin antaa syke-tietoja, jos niitä ei ole. Tällöin vain syke-taulussa ei ole tietoa, joka viittaisi urheilusuoritukseen.

M-to-M-suhteet sykkeestä

M-to-1-suhteen sijaan on kuitenkin käytettävä M-to-M-suhdetta, jos halutaan kirjata syke-tietoja ilman pakollista kytkentää urheilusuoritukseen. Tällainen tilanne voisi tulla, jos syke-kohde liittyisi lisäksi esimerkiksi kuntotesti-kohteeseen (oletetaan, että kuntotesti olisi olennaisesti erilainen kohde ominaisuuksiltaan kuin urheilusuoritus). Jos nyt sykkeen ja urheilusuorituksen välillä on M-to-M-suhde, niin kirjatun syke-tiedon ei tarvitse välttämättä liittyä urheilusuoritukseen, kytkentä jätetään vain kirjaamatta suhteen muodostamaan tauluun. Tällöin syke-tieto voi rauhassa liittyä pelkästään esim. kuntotesti-kohteeseen. M-to-1-suhteen tapauksessa viiteavain urheilusuoritukseen olisi pakko antaa.

Nämä valinnat koskevat vain Erkka-ohjelmalla tuotettuja ER-kaavioita. Laajemmilla ER-kaaviomalleilla voidaan muodostaa tarkemmin erilaisia riippuvuussuhteita, mm. määrittää onko suhde välttämätön.

SQL-lauseiden suorittamisessa tulee Syntax error, mitä teen? Miksi muunnoksessa SQL-lauseisiin tulee teksti error?

Joskus Erkasta jää SQL-lauseisiin muunnoksessa sana error mikä sotkee SQL-lauseiden suorituksen. Tämä ongelma johtuu jostain bugista Erkka-ohjelmassa, se ei aina rekisteröi oikealla tavalla pakollisuustiedon (compulsion) muutosta. Mene takaisin ER-kaavioon, klikkaa ongelmallista ominaisuutta, valitse uudestaan sopiva pakollisuustyyppi (esim. NOT NULL) ja napauta kaaviossa johonkin tyhjään kohtaan. Nyt muutos rekisteröityy muistiin. Valitse SQL-paneeli ja napauta ER to SQL valikosta.

Toinen vaihtoehto on käydä itse muuttamassa SQL-lauseista error-sana sopivaksi määritykseksi, korvaa se esimerkiksi sanoilla NOT NULL.

Kolmas vaihtoehto on, että jossain suhteen tai kohteen nimessä on jokin SQL-kielessä käytetty varattu sana. Esimerkiksi sana On aiheuttaa tyypillisesti Syntax error -virheen (käytetään esim. UNION- ja FOREIGN KEY-osissa).

Miksi M-M-suhteeseen liitettyä ominaisuutta ei tule SQL:ään?

Jos suhteesta ominaisuuteen menevään viivaan on määrätty kardinaalisuus, niin Erkka ei ymmärrä että kyseessä on ominaisuus. Poista tarpeeton kardinaalisuusmerkintä.

Mitä uutta on Erkka 1.2:ssä verrattuna versioon 1.0?

Erkan uusimman version saa osoitteesta:

http://appro.mit.jyu.fi/tools/erkka/

Erkan File | New -valinta ei toimi?

Jos saat komentoriville virheilmoituksen Provider org.apache.xerces.parsers.XML11Configuration not found niin kyse on bugista, joka on korjattu versioon 1.22. Hae uusin Erkka. Ongelman voi kiertää myös valitsemalla New-valinnan sijaan File | Open ja sen jälkeen tiedoston konfitiedosto.erkka.

Erkka herjaa String index out of range eikä SQL-lauseita tule, missä vika?

Vika on korjattu Erkan versioon 1.22. Älä luo SQL-lauseita tyhjästä kaaviosta :)

En saa luotua tietokantaa Erkan luomilla SQL-lauseilla. Mitä teen?

Kokeile ladata Erkan uusin versio ja luoda SQL-lauseet sillä. Nyt tietokannan luonnin pitäisi onnistua.

Erkan vanhemmat versiot eivät pysty täydellisesti huomioimaan seuraavia erikoistapauksia:

Voit muuttaa itse SQL-lauseita SQL- tai Query-näkymässä ja ajaa korjatut versiot sen jälkeen. Lauseiden järjestystä voi vaihtaa leikepöydän avulla, muista tällöin ottaa koko lause komennon alusta lopussa olevaan puolipisteeseen. Toisen vaihtoehto on korjata nämä Drawing-näkymässä ja päivittää SQL-lauseet uudelleen valinnalla Edit | Refresh SQL (F5).

Kardinaalisuuden muutos ei näy ER-kaaviossa. Miksei?

Erkan versiossa 1.0 muutokset tulevat näkyviin jos napautat jotain toista objektia. Sama ongelma näyttää vaivaavan Erkka 1.1:stä jos käytössä on Java 1.4. Uusimmalla Javalla muutokset näkyvät heti.

Erkka kadotti ER-kaaviostani viivat! Mitä teen?

Erkassa on jokin outo bugi, jonka takia joissain tapauksissa tallentaessasi kaavion ja uudelleen avatessasi sen viivat ja jotain ominaisuuksia katoaa kaavioasta. Tämä on bugi Erkka-ohjelmassa. Ongelma johtuu compulsion-kohtaan valitusta DEFAULT-valinnasta. Vältä siis tätä valintaa kunnes korjattu versio (>1.1) tulee jakoon.

Miksi relaatiokaaviostani puuttuu yhdysviivoja?

Ongelmaa ei esiinny uusimmassa Erkan versiossa.

Suhteet, joiden kardinaalisuudet ovat M-M-M eli suhde liittyy kolmeen (tai useampaan) kohteeseen, eivät toimi relaationäkymässä. Voit tallentaa relaatiokuvan PNG:nä (File | Export) ja lisätä tarvittavat viivat kuvankäsittelyohjelmalla.

Miksi Erkka 1.0-ohjelman pikakuvake ei enää toimi?

Erkka-ohjelman nykyinen pikakuvake on suoraan valinnan Start | All Programs alla nimellä Erkka. Kuvakkeena on tähtikuvio.

Mikroluokissa on oikean Java-version paikka muuttunut uusien asennusten myötä. Itselläni pikakuvake oli päivittynyt automaattisesti oikeanlaiseski, mutta se ei välttämättä toimi kaikilla. Kannattaa siis tarkistaa, että Erkka-ohjelman käynnistävän pikakuvakkeen Target-kentässä on seuraavat tekstit:

"C:\Program Files\jbuilder7\jdk1.3.1\bin\java.exe" -jar Erkka.jar

Tarkemmin pikakuvakkeen määrittämisestä oli kurssi toisten demojen alussa.

Uusimmassa Erkan versiossa ongelma pitäisi olla korjattuna.

Miksi Erkka-ohjelma ei tee SQL-lauseita ja relaatiokuvaa?

Päivitä ohjelmasi uusimpaan Erkkaan:teen. Syitä ongelmaan on muutamia. Tarkista seuraavat kohdat huolella:

Miksi Erkka piirtää relaatiokuvaan omituisia numeroita joidenkin attribuuttien perään?

Uusimmassa Erkan versiossa ongelmaa ei pitäisi olla.

Erkka bugaa. Erkka menee hieman sekaisin jos jossain ominaisuudessa on tietotyyppinä NUMERIC. Tämä aiheuttaa ylimääräisiä numeroita relaatiokuvaan.

Asialle ei ole tehtävissä muuta kuin väliaikaisesti muuttaa ER-kaaviosta kaikkien NUMERIC-tyyppisten kenttien määritykset muotoon jossa ei käytetä pilkkua esim. 7,2 muutettaisiin muotoon 7. Muutoksen jälkeen antaa Erkan tehdä uuden relaatiokuvan, ottaa sen talteen ja käy korjaamassa tietotyypin määritykset oikeiksi.

Miksi Erkasta ODBC Query Tooliin kopioidut SQL-lauseet antavat virheitä?

Syitä asiaan voi olla muutamia. Tarkista seuraavat seuraavat kohdat huolella.

Uudessa Erkassa on oma työkalu SQL-kyselyjen tekemiseksi. Käytä sitä ensisijaisesti.

Erkalla luodut taulut eivät näy OpenOffice Basessa. Mitä teen?

Erkka 1.22 toimii väärin .odb-tiedostojen suhteen. Ongelma on korjattu Erkka 1.23:ssa. Huomaa kuitenkin, että Erkka avaa ODB-tiedostosta tietokannan väliaikaishakemistoon ja päivittää tiedoston vasta kun tietokantayhteys katkaistaan (Disconnect) tai ohjelma sammutetaan.

Apuja vanhoihin versioihin

Varsinainen tietokanta on pakettu zip-muotoon odb-tiedoston sisään eikä ole olemassa tietokanta-ajuria, joka osaisi käsitellä suoraan kyseisen muotoista pakattua tietokantaa. Kun odb-tiedosto valitaan Erkka 1.22:ssa niin hsqldb-ajuri luo uuden tietokannan, johon sql:t ajetaan. Tähän tietokantaan pääsee käsiksi seuraavin konstein:

  1. Sulje luomasi tyhjä tietokanta ja valitse File | New | Database.
  2. Valitse Connect to an existing database ja tyypiksi JDBC.
  3. Kirjoita kohtaan Datasource URL hsqldb:hakemistopolku_tietokantaan ja kohtaan JDBC driver class org.hsqldb.jdbcDriver. hakemistopolku_tietokantaan voi olla esimerkiksi C:\Mytemp\omatietokanta.odb .
  4. Tallenna uudella nimellä. Nyt taulujen pitäisi olla paikallaan.

Edelleen kyselyjä ei voi tehdä Erkasta tähän uuteen odb-tiedostoon muutoin kuin OpenOfficen kautta.

Miksi Openofficessa tehdyt taulut eivät näy SQL:n avulla Erkassa?

Openoffice.org 2.0 nimeää taulut siten, että se laittaa tekstin ympärille lainausmerkit. Esimerkiksi henkilo-tauluun pitää viitata tekstillä "henkilo"

SELECT * from "henkilo"

Haen kyselyllä aikaa TIME-tyyppisestä kentästä, mutta miksi saan myös päivämäärän?

Tämä johtuu siitä, että vaikka aika onkin TIME-tyyppiä, niin sisäisesti Access käsittää DATE- ja TIME-tietotyypit samoina. Access-ohjelma on muotoilla pelkän ajan siten, että se jättää "nollapäivämäärän" pois, mutta kun tietoa kysellään jostain muualta, esim. Erkka-ohjelmasta, niin tuo päivämääräkin tulee mukana.

Ajallinen kesto pitäisi oikeastaan merkitä INTERVAL-tietotyypillä, mutta Erkka ja Access eivät ymmärrä sitä.

Tietokannat

Aikojen yhteenlasku ei toimi jos niistä kertyy yhteensä yli 24 tuntia?

Aikojen yhteenlasku toimii Accessissa hyvin, kunnes vuorokausi ylittyy. Aikaa syötettäessa syötetään pelkkä kellonaika.

Tässä on se ongelma, että accessissa ei oikeasti ole INTERVAL-tietotyyppiä, joka olisi tarkoitettu ajanjaksojen tallentamiseen vaan accessin TIME-tyyppi tarkoittaa oikeasti aina päiväystä eikä päivämääriä oikeasti voida laskea yhteen.

Tämän kurssin puitteissa ei tarvitse välittää tästä yhteenlaskuongelmasta.

Lasken Accessilla yhteen TIME-tyyppisiä kenttiä ja saan tuloksena desimaaliluvun. Mikä on vikana?

Access antaa vastauksena tiedon siitä, paljonko yhteenlaskettu aika on vuorokausina ja jos tulos on alle vuorokauden niin se tulee desimaalilukuna. Tulos pitää siis muotoilla uudelleen jotta siitä saa selkeän. Esim. näin:

SELECT Format( SUM(aika), "hh:nn:ss")

Mikä on COUNTER-tietotyyppi ja mihin sitä kannattaa käyttää?

Accessissa automaattisesti numeroitavat kentät voidaan määrätä tietokannan luontikyselyissä COUNTER-tietotyypillä INTEGER-tietotyypin sijaan. Uutta tietoa lisättäessä Accessissa COUNTER-tietotyypillä määrättyyn kenttään tulee automaattisesti sellainen numero, jota ei ole käytössä. Tietotyyppiä on kannattaa käyttää ID-avainkenttien kanssa. Esimerkiksi:

CREATE TABLE Tavara (
TavaraID COUNTER NOT NULL,
TavaranNimi VARCHAR(100) NOT NULL,
Omistaja_OmistajaID INTEGER NOT NULL,

CONSTRAINT Tavara_PK
	PRIMARY KEY (TavaraID),
CONSTRAINT Tavara_OmistajaID
	FOREIGN KEY (Omistaja_OmistajaID)
	REFERENCES Omistaja (OmistajaID)
		ON DELETE NO ACTION
		ON UPDATE CASCADE
)
;

ID-kenttään viittaavissa kentissä ei saa käyttää COUNTER-tietotyyppiä, koska haluamme määrätä mihin numeroon viitataan.

Mikä on COUNTER-tietotyypin vastine OpenOfficen Basessa?

COUNTER-tyyppiä vastaavan toiminnan saa aikaan Basessa korvaamalla COUNTER-sanan seuraavalla:

INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1)

Mikä on tehokkain tapa syöttää tietoa tietokantaan?

Varmin tapa lisätä dataa on tehdä INSERT INTO taulu (kentta1, kentta2, ...) VALUES (arvo1, arvo2, ...); -lauseita ja kopioida niitä ja muuttaa arvot sopiviksi. Tällöin SQL:n voi kopioida talteen ja jos jostain syystä syötetyt tiedot häviävät niin ne voi ajaa uudelleen tietokantaan. INSERT-lauseet voi suorittaa esim. Erkka-ohjelmasta.

Toinen vaihtoehto on tehdä tietokanta valmiiksi, luoda sinne tiedonsyöttölomakkeet (Forms) ja käyttää näitä tiedon syöttöön. Lomakkeista on Henkilökohtaisen tiedonhallinnan perusteet -kurssin demoissa 7.

Miten syötän Erkasta tietoa INSERT INTO-lauseilla?

Tietojen lisääminen Erkassa onnistuu kun luo ensin tietokannan Erkasta saaduilla SQL-lauseilla, sitten valitsee Query-välilehden ja sieltä File | Open database... ja valitse tuo .mdb-tiedoston. Sitten tyhjää kaikki SQL-lauseet ja alkaa kirjoittamaan insert-lauseita. INSERT INTO osan ensimmäiselle riville pitää tulla taulun nimi ja sitten lueteltuna kentät joihin tietoa syötetään, yleensä siis kaikki kentät. Kenttien nimet saa selville ER-kaavio, luontilauseita tai Accessissa olevia tauluja katsomalla. VALUES-sanan jälkeen suluissa tulee arvot mitä annetaan. Ne tulevat samassa järjestyksessä kuin kenttien järjestys on edellä annettu. Merkkijono-arvot täytyy kapseloida ' -merkkien sisälle, numeeriset arvo voivat olla paljaana. M-to-M-suhteista muodostuisiin tauluihin täytyy laittaa yleensä kaksi ID-numeroa, jotka löytyvät niihin viittaavista tauluista. Jos jossain muussakin paikassa on viittauskenttiä, niin ensin on lisättävä tauluun ne tietueet, joihin toisista tietuista on tarkoitus viitata.

Kts. myös luennon asia aiheesta.

Miten OpenOfficella saa tehtyä lomakkeita ja raportteja?

Avaa OpenOffice ja valitse File | AutoPilot | Form lomakkeita varten tai File | AutoPilot | Report raporttien tekemiseksi. Kummastakin aukeaa luontivelho, jonka avulla pääset alkuun. OpenOfficea varten kurssilla ei ole vielä ohjeistusta, mutta internetistä löytyy paljon aiheeseen liittyvää (englanninkielistä) materiaalia.

En saa luotua lomakkeita tai raportteja! Saan vain virheilmoituksen "You do not have exclusive access to the database at this time. If you proceed to make changes, you may not be able to save them."

Sulje tietokantayhteys Erkka-ohjelmasta valinnalla File | Disconnect. Access ei pysty joissain tapauksissa käsittelemään kuin yhden tietokantayhteyden (se mikä on parhaillaan auki Access-ohjelmassa).

Mitä ovat indeksit (CREATE INDEX)?

Indeksit ovat tietokannan ylläpitämiä hakemistoja taulujen sarakkeille. Hakemisto nopeuttaa tiedon hakemista ja lajittelua kyseisen sarakkeen suhteen. Indeksi kannattaa määrittää niille kentille, joita käytetään usein haku- tai lajitteluehdoissa.

Kuinka teen dynaamisen SQL-kyselyn Access 97:llä?

  1. Kirjoita jokin tarvitsemasi SQL-haku aivan normaalisti ja talleta se sopivalla nimellä. Esim.
    SELECT *
    FROM foo
    WHERE bar = 'testi1'
    
    
  2. Tekemäsi kysely on staattinen ja haluat sen kuitenkin muuttuvan käyttäjän toiveiden mukaan. Muuta kyselysi seuraavanlaiseksi:
    SELECT *
    FROM foo
    WHERE bar = [Kirjoita jotain]
    
    
  3. Kokeile nyt kyselyäsi. Access kysyy tarvittavan hakuehdon -> hakusi on nyt dynaaminen!
  4. Luo seuraavaksi itsellesi jokin raportti, joka pohjautuu suoraan aiemmin tekemääsi kyselyyn. Raportin avatessasi Access kysyy jälleen haussa tarvittavan ehdon, jonka jälkeen saat tuloksen suoraan siistinä raporttina eteesi. Dynaaminen haku kannattaa kuitenkin yleensä perustaa jonkin lomakkeen sisältämien kenttien arvoihin jolloin voidaan hyödyntää listabokseja, listoja yms.
  5. Luo uusi tyhjä lomake. Lisää lomakkeelle nappula, jolla avaat aiemmin luomasi raportin. Lisää lomakkeelle comboboxi, jonka liität suoraan aiemmin tekemässäsi haussa käyttämääsi tauluun.
  6. Anna comboboxillesi jokin helposti muistettava nimi esim. haku (hiiren oikea nappi, properties, all, name).
  7. Talleta lomakkeesi nimellä testi
  8. Siirry muuttamaan aiemmin luomaasi SQL-hakua. Muuta haku seuraavan näköiseksi:
    SELECT *
    FROM foo
    WHERE bar = [Forms]![testi]![haku]
    
    
  9. WHERE ehdossa lukee siis ensin hakasulkeiden sisässä sana Forms ([Forms]), sitten ! ja hakasulkeiden sisässä luomasi lomakkeen nimi testi ([testi]) ja jälleen ! ja viimeisenä hakasulkeiden sisässä lomakkeella olevan objektin nimi, jonka arvo halutaan syöttää tähän hakuun eli tässä tapauksessa haku ([haku]). Kirjoita kaikki nämä tiukasti yhteen ilman välilyöntejä.
  10. Talleta SQL-hakusi. Avaa äsken luomasi lomake. Valitse jokin arvo comboboxiin ja kokeile raportin aukaisevaa nappulaa. Jos kaikki meni oikein niin sinulta ei enää kysytä mitään arvoja SQL-hakuun vaan Access automaattisesti syöttää hakuun comboboxissa valittuna olevan arvon.
  11. Jos haluat hakea SQL-lauseeseen jonkin alilomakkeessa (Subform) sijaitsevan kentän arvon niin siihen pitää viitata seuraavasti:
    Forms!Lomakkeennimi!Alilomakkeennimi!Kentännimi
    Lomakkeennimi on siis varsinaisen lomakkeen nimi. Alilomakkeen nimi on se nimi, joka alilomakeobjektilla on varsinaisen lomakkeen sisällä. Ei siis välttämättä sama nimi, jolla alilomake löytyy lomakelistauksesta.
  12. Dynaamisesta SQL:stä löytyy esimerkki myös demo 5:en tehtävistä osoitteesta http://www.jyu.fi/tt-appro/2000/tietokannat/demot/demo5/index.shtml#dyn

Kuinka haetaan comboboxin tiedot jostakin taulusta?

Tämä ohje on niille, joiden Accessissa eivät velhot (Wizard) toimi tai jostakin syystä eivät halua niitä käyttää.

  1. Siirry muokkaamaan comboboxin ominaisuuksia (properties)
  2. Valitse välilehti data
    • Control Source -kohtaan voit valita sen kentän johon haluat comboboxilla syöttää tietoa
    • Row Source -kohtaan voit valita sen taulun tai kyselyn josta haluat haettavan comboboxin sisällön
    • Bound Column kohtaan pitää merkitä kuinka monennesta kentästä Row Source -kohdassa määritellystä taulusta halutaan ottaa arvo, joka sitten sijoitetaan Control Source -kohdassa määriteltyyn kenttään
    • Column Count -kohtaan voit määritellä montako kenttää Row Source -kohdassa määritellystä taulusta halutaan näyttää comboboxissa
    • Column Widths -kohtaan voit määritellä kuinka leveästi kukin kenttä halutaan näyttää comboboxissa. Leveydet ilmoitetaan puolipisteellä (;) erotettuina. Määritä pituudeksi 0 jos et halua kentän näkyvän.

Miten saadaan comboboxin sisältö päivitettyä?

Olet tehnyt lomakkeille combo boxeja ja nyt jos valikossa ei ole käyttäjän haluamaa valintaa, niin olet tehnut comboboxin viereen napin, joka aukaisee uuden lomakkeen jolla käyttäjä voi lisätä uuden esim. henkilön. Mutta nyt kun käyttäjä on lisännyt uuden henkilön, niin tämä lisäys ei päivity combo boxiin. Miten ratkaista tämä ongelma, jotta tämä käyttäjän uusi lisäys päivittyy myös comboon?

  1. Ota esiin comboboxin ominaisuudet (properties) ja edelleen Event-välilehti.
  2. Valitse kohta On Got Focus ja klikkaa sen oikeaan reunaan ilmaantuvaa nappulaa, jossa on kolme pistettä (...).
  3. Valitse Code Builder
  4. Nyt pääset/joudut kirjoittamaan Visual Basic -ohjelmakoodia. Ruutuun pitäisi aueta jotain tämän tyylistä (riippuen comboboxisi nimestä):
    Private Sub Combo0_GotFocus()
    
    
    End Sub
    
    
  5. Kirjoita valmiiden rivien väliin DoCmd.DoMenuItem acFormBar, acRecordsMenu, 5, , acMenuVer70. Tämä rivi aktivoi Records|Refresh-valinnan, joka päivittää comboboxin sisällön.
    Private Sub Combo0_GotFocus()
    
    DoCmd.DoMenuItem acFormBar, acRecordsMenu, 5, , acMenuVer70
     
    End Sub
    
    
  6. Toinen vaihtoehto on käskeä juuri haluttua comboboxia hakemaan uudelleen sisältönsä requery-funktion avulla:
    Private Sub Combo0_GotFocus()
    
    Combo0.requery
     
    End Sub
    
    
  7. Ennen requery-sanaa oleva Combo0-teksti on päivitettävän comboboxin nimi, joka näkyy myös ylempänä olevalta Private Sub Combo0_GotFocus() riviltä.
  8. Sulje koodi-ikkuna.
  9. Kokeile päivittyvätkö comboboxin tiedot nyt

Miten käsitellään Date-tyyppisiä kenttiä Access 97:ssa SQL:llä

Accessin SQL-tulkki käsittelee päivämäärät hieman eri tavalla kuin yleisesti on tapana. Yleensä päivämäärät esitetään heittomerkkien (') sisällä.

SELECT *
FROM Taulu
WHERE pvm < '1.1.2000'

Jos halutaan luoda SQL-haku, jossa WHERE-lauseen ehdossa esiintyy päivämäärä-tyyppinen (DATE) kenttä niin se on Accessissa kirjoitettava seuraavaan muotoon:

SELECT *
FROM Taulu
WHERE pvm > #1-1-2000#

Elikkäs päivämääränä käsiteltävä teksti on laitettava #-merkkien sisään. Kuukaudet, päivät ja vuosi on erotettava toisistaan, joko --merkillä tai /-merkillä. Käyttöjärjestelmän maa-asetuksista riippuen myös . saattaa kelvata erotinmerkiksi.

Miten SQL-operaattoria LIKE käytetään Accessissa?

LIKE-operaattorin yhteydessä Access eroaa standardista:

Access Standardi SQL
Mikä tahansa yksittäinen merkki ? (kysymysmerkki) _ (alaviiva)
Nolla tai useampi mikä tahansa merkki * (asteriski) % (prosentti)

Mitä CREATE TABLE -lauseen määritteitä Access ei tue?

Access ei osaa kaikkia viite-eheysmäärittelyjä. Seuraava EI TOIMI Accessissa:

CREATE TABLE Taulu (
Avain INTEGER NOT NULL,
Kentta VARCHAR(50) NOT NULL,
Viite INTEGER NOT NULL,
CONSTRAINT Taulu_PrimaryKey
        PRIMARY KEY (Avain),
CONSTRAINT Taulu_FK_Taulu2
        FOREIGN KEY (Viite)
        REFERENCES Taulu2 (Avainkentta)
                ON DELETE NO ACTION
                ON UPDATE CASCADE
)

Access ei siedä viimeisiä ON DELETE NO ACTION ja ON UPDATE CASCADE -määreitä joten ne on tiputettava pois ja tehtävä tämä Accessisa vain näin:

CREATE TABLE Taulu (
Avain INTEGER NOT NULL,
Kentta VARCHAR(50) NOT NULL,
Viite INTEGER NOT NULL,
CONSTRAINT Taulu_PrimaryKey
        PRIMARY KEY (Avain),
CONSTRAINT Taulu_FK_Taulu2
        FOREIGN KEY (Viite)
        REFERENCES Taulu2 (Avainkentta)
)

Tarkemmat viite-eheysmäärittelyt on käytävä hiirellä klikuttelemassa Accessin Relationship-ikkunaan (kts. demo1)

Myöskään DEFAULT-määrittelyt tai CHECK-lauseet eivät toimi Accessissa.

Miten Accessin käyttämät tietotyypit eroavat standardoiduista tyypeistä?

Accessin ja ANSI SQL:n (standardi) tietotyypit eroavat hieman toisistaan. Seuraava listaus on lainattu suoraan Access 97:n avustuksesta

ANSI SQL Access Synonyymeja
BIT, BIT VARYING BINARY VARBINARY
Not supported BIT BOOLEAN, LOGICAL, LOGICAL1, YESNO
Not supported BYTE INTEGER1
Not supported COUNTER AUTOINCREMENT
Not supported CURRENCY MONEY
DATE, TIME, TIMESTAMP DATETIME DATE, TIME, TIMESTAMP
Not supported GUID
DECIMAL Not supported
REAL SINGLE FLOAT4, IEEESINGLE, REAL
DOUBLE PRECISION, FLOAT DOUBLE FLOAT, FLOAT8, IEEEDOUBLE, NUMBER, NUMERIC
SMALLINT SHORT INTEGER2, SMALLINT
INTEGER LONG INT, INTEGER, INTEGER4
INTERVAL Not supported
Not supported LONGBINARY GENERAL, OLEOBJECT
Not supported LONGTEXT LONGCHAR, MEMO, NOTE
CHARACTER,CHARACTER VARYING TEXT ALPHANUMERIC, CHAR, STRING, VARCHAR

Miten toimivat EXCEPT- ja INTERSECT-operaatiot Accessissa?

EXCEPT (erotus) ei toimi Accessissa ollenkaan.

INTERSECT (leikkaus) ei toimi Accessissa ollenkaan.

Nämä puutteet on kierrettävä käyttämällä alikyselyjä.

Miten saa Accessin Relationships-ikkunan sisällön liitettyä dokumentaatioon?

Kuva täytyy kopioida leikepöydän avulla johonkin kuvankäsittelyohjelmaan ja muokata siellä sopivaan muotoon.

  1. Käynnistä jokin kuvankäsittelyohjelma
  2. Ota näkyville Accessin Relationships-ikkuna
  3. Paina Print Screen -näppäintä niin koko näkyvissä ole ruutu kopioituu leikepöydälle. ALT + PrintScreen kopioi pelkän aktiivisen ikkunan.
  4. Siirry kuvankäsittelyohjelmaan
  5. Liitä leikepöydältä kuva käsiteltäväksi (Edit|Paste)
  6. Rajaa kuvasta haluamasi osa eli pelkkä Relationships-ikkunan sisältö
  7. Pienennä kuvan värimäärä mahdollisimman vähäiseksi niin säästät muistia. Yleensä 16 väriä riittää.
  8. Kopioi rajaamasi alue leikepöydälle (Edit|Copy) ja liitä se edelleen tekstinkäsittelyohjelmassa haluaamasi kohtaan (Edit|Paste).
  9. Jos olet liittämässä kuvaa HTML-dokumenttiin niin talleta se PNG-, tai GIF-muodossa.

Miksi SQL-kyselyni lopputuloksessa on kummallista toistoa?

Kysely on mitä todennäköisimmin kohdistunut useaan tauluun ilman, että niiden välille on määritelty mitään yhdistäviä kenttiä (liitoksia). Jos haku kohdistuu N:ään tauluun niin niiden välille pitää määritellä vähintään N-1 kappaletta liitoksia. Suomeksi, jos haet tietoa kahdesta taulusta sinun pitää määritellä WHERE-lauseessa ainakin yhdellä ehdolla miten taulut liittyvät toisiinsa. Jos haet kolmesta taulusta niin tarvitset ehtoja vähintään kaksi jne.

mallitietokanta

Haetaan oppilaiden sukunimet ja kyseisten oppilaiden kaikkien tenttien arvosanat. Kysely kohdistuu kahteen tauluun eli tarvitaan yksi liitosehto. Vertaa ehdossa käytettyjä kenttiä kuvaan ja viite-eheysmäärittelyihin.

SELECT Oppilaat.sukunimi, Tentit.arvosana
FROM Oppilaat, Tentit
WHERE Oppilaat.hetu = Tentit.hetu

Haetaan oppilaiden sukunimet, kurssien nimet ja tenttiarvosanat. Kysely kohdistuu kolmeen tauluun eli tarvitaan kaksi liitosehtoa. Vertaa ehdossa käytettyjä kenttiä kuvaan ja viite-eheysmäärittelyihin.

SELECT O.sukunimi, K.kurssinnimi, T.arvosana
FROM Oppilaat AS O, Tentit AS T ,Kurssit AS K
WHERE O.hetu = T.hetu
AND K.KurssiID = T.KurssiID

Mitä ovat alilomakkeet ja mihin niitä käytetään?

Postituslistalle tuli seuraavanlainen kysymys:

On jäänyt ehkä hämärän peittoon, mihin alilomakkeita tarvitaan, että saataisiin tietoa lomakkeille muista relaatioista, vai? Joka tapauksessa on niin, että omalla koneellani ei saa alilomakkeita tehtyä, onko ne pakollisia? Ohjelmani kaipailee nimittäin uudelleen asennusta ja siinä kehitystyökalujen valintaa. Asennus-CD:tä ei ole käytettävissä, joten umpikujassa ollaan. Mikä neuvoksi?

Ei alilomakkeita pakko ole käyttää. Ne vain monesti helpottavat tietojen syöttämistä. Kuvitellaan vaikkapa tilanne, jossa meillä on kaksi taulua: Oppilaat ja Tentit. Tentit-taulussa eri oppilaiden tenttisuorituksia. Nyt jos haluamme syöttää tai muuttaa jonkun tietyn oppilaan tietoja niin se tapahtuu helpoimmin alilomakkeen avulla. Teemme lomakkeen oppilaat-taulun pohjalta ja tälle lomakkeelle sijoitamme alilomakkeeksi tentit-taulun pohjalta luodun lomakkeen. Näiden lomakkeiden välille määritellään oppilaan sotu-kenttä yhdistäväksi tekijäksi. Nyt kun valitsemme "ylilomakkeelta" eli oppilas-tasolta jonkun tietyn oppilaan niin tämä automaattisesti rajaa alilomakkeella näkyvät suoritukset vain tähän kyseiseen oppilaaseen liittyviksi. Jos nyt lisättäisiin jokin tenttisuoritus niin siitä tulisi automaattisesti tämän "ylemmällä" lomakkeella valitun oppilaan suoritus.

Accessissa voi myös aukaista toisen lomakkeen niin, että se näyttää vain tiettyjä tietoja. Tehtäessä lomakkeelle nappulaa, jolla avattaisiin toinen lomake näkyviin, niin valitaan lomakewizardin alkuvaiheessa vaihtoehto: "Open the form and find specific data to display". Tämän jälkeen päästäänkin kertomaan millä tavalla lomakkeet liittyvät toisiinsa eli mikä on niitä yhdistävä kenttä/kentät jonka perusteella halutaan rajoittaa näytettäviä tietueita. Idea on siis täysin sama idea kuin alilomakkeen kohdalla. Nyt kun "päälomakkeelta" eli tässä tapauksessa vaikkapa oppilaat-lomakkeelta etsittäisiin tietyn oppilaan tiedot näkyviin ja aukaistaan sen jälkeen edellämainitulla tavalla tehtyä nappulaa käyttäen tentit-lomake niin saamme näkyviin vain tämän kyseisen oppilaan tenttisuoritukset ja voimme lisätä uusia suorituksia vain hänelle.

Kuinka saan erotettua päivät/tunnit/minuutit DATE-tyyppisestä kentästä?

Accessissa voi DATE-tyyppisestä kentästä erotella haluttuja osia DatePart-funktiolla. Tarkka ohjeistus löytyy Accessin omasta avustuksesta. Seuraavassa esimerkissä haetaan taulusta tuloaika(Tulo, lähtöaika(Lahto) ja halutaan näkyviin näiden välisenä aikana kuluneiden päivien, tuntien ja minuuttien määrät.

SELECT Tulo, Lahto,
    DatePart("d", (lahto - tulo)) AS Päivät,
        DatePart("h", (lahto - tulo)) AS Tunnit,
        DatePart("n", (lahto - tulo)) AS Minuutit
FROM Taulu

DATE-tyyppisten kenttien käsittelyä

Kuinka voin yhdistellä merkkijonoja?

Accessissa voi merkkijonoja ja periaatteessa mitä tahansa kenttiä yhdistellä samaan tapaan kuin Visual Basicissa. Käytettävä operaattori on &. Esimerkki kertonee enemmän kuin tuhat sanaa.

SELECT  etunimi, muut_nimet, sukunimi,
    etunimi & " " & muut_nimet & " " & sukunimi AS Nimitiedot
FROM Taulu

Kenttien yhdistely yhdeksi kentäksi

Kuinka saan laskettua henkilön iän SOTUn perusteella?

Tämä on hieman hankala temppu. SOTU:n sisältämästä kentästä täytyy poimia erikseen vuosi, kuukausi ja päivä jolloin henkilö on syntynyt. Nämä pitää muuttaa DATE-tyyppiseksi informaatioksi, jonka jälkeen tuloksena saatu päivämäärä voidaan vähentää nykyhetkestä. Lopullinen tulos on päivämäärä lukien viime vuosisadan alusta, joten otamme siitä talteen pelkän vuoden ja vähennämme 1900. Lopputuloksena kyseisen henkilön ikä. Toteuttaminen vaatii Accessin merkkijono- ja konversiofunktioiden käyttöä. Käytettyjen funktioiden toiminta selviää helpoimmin tutkimalla Accessin omaa avustusta.

SELECT Sotu,
  Left(Sotu, 2) AS Päivä,
  Mid(Sotu, 3, 2) AS Kuukausi,
  Mid(Sotu, 5, 2) AS Vuosi,
  CDate(Left(Sotu,2) & "." & Mid(Sotu,3,2) & "." & Mid(Sotu, 5, 2)) AS Päiväys,
  DatePart( "yyyy",
    CDate( Now() - CDate(   Left(Sotu,2) &
                "-" &
                Mid(Sotu,3,2) &
                "-" &
                Mid(Sotu, 5, 2)
                )
        )
    ) - 1900
    AS Ikä
FROM Taulu

Iän laskeminen sotun perusteella

Onko Accessilla mahdollista luoda normaalisti toissijaisia avaimia CREATE INDEX -komennolla?

Toissijaisten avainten (secondary index) luominen onnistuu aivan normaalisti.

CREATE INDEX Taulu_sukunimi ON Taulu (Sukunimi)

Saako lomakkeille yhteenvetofunktioita (SUM, COUNT, AVG jne.)?

Lomakkeille pystyy hyvin helposti lisäämään yhteenvetofunktioita.

  1. Lisää lomakkeelle uusi Text Box objekti.
  2. Ota esiin textboxin ominaisuudet (properties) ja sieltä Data-välilehti.
  3. Kirjoita Control Source -kohtaan haluamasi yhteenvetofunktio:

    =Funktio([kenttä])

    Esimerkkejä:

    =COUNT([VaihtoehtoID])
    
    =SUM([Hinta])
    
    =AVG([Tenttipisteet])
    
    

Miksi Access ei anna määritellä viite-eheyksiä?

Viite-eheyksiä määriteltäessä pitää varmistaa muutama seikka:

  1. Kenttien täytyy olla samaa tietotyyppiä. Tekstityyppisten kenttien pitää periaatteessa olla myös samanmittaisia.
  2. äiti-taulussa olevan kentän täytyy olla indeksoitu. Kentän pitää siis olla joko perusavain tai siihen pitää olla määritelty toissijainen indeksi (secondary index).
  3. Viite-eheys täytyy määritellä oikeaan suuntaan. Ei siis ole yhdentekevää kummasta taulusta viittaus tehdään.

viite-eheys Tape- ja Supplier-taulujen välillä

Ylläolevassa kuvassa Tape-taulu on lapsi-taulu, josta on luotu viite-eheys äiti-tauluun eli Supplier-tauluun. Tämä tarkoittaa, että Tape-taulun SupplierID-kenttään voidaan syöttää vain sellaisia arvoja joita löytyy Supplier-taulun SupplierID-kentästä. Viittaus tehdään siis Tape-taulusta Supplier-tauluun eikä missään nimessä toistepäin. Kummankin taulun SupplierID-kentät ovat samaa tietotyyppiä. Tässä tapauksessa Integer. Kenttien ei tarvitse olla samannimisiä. Supplier-taulun SupplierID-kenttä on perusavain, joten siihen voidaan viitata.

Viittaaminen yhdistettyyn avaimeen onnistuu vain viittaamalla samaan aikaan kaikkiin avaimen muodostaviin kenttiin. Jos on välttämätöntä viitata yhteen yhdistetyn avaimen sisältämistä kentistä täytyy tälle kentälle määritellä toissijainen indeksi.

Miksi tekemäni nappula ei toimi vaan Access valittaa tyyliin: Ambiguous name detected: nappulannimi_Click

Nappuloita luotaessa ja niitä poistellessa voi tulla vastaan seuraavantyyppinen virheilmoitus:

virheilmoitus: Ambiguous name detected: Ensimmäinen_Click

Virheilmoitus johtuu siitä, että ensimmäiseksi on luotu nappula, jolle on annettu nimeksi Ensimmäinen. Accessin nappulavelho on tehnyt tähän nappulaan halutut valmiit toiminnot esimerkiksi siirtymisen ensimmäisen tietueen kohdalle. Jostakin syystä tämä nappula ei ole kelvannutkaan vaan se on poistettu ja luotu uusi nappula samalle nimelle. Access ei ole ensimmäistä nappulaa tuhottaessa osannut poistaa siihen liittyvää Visual Basic -koodia, joka määrittelee nappulan toiminnallisuuden. Nyt uuden samannimisen nappulan luominen on aiheuttanut, että Access on muodostanut uuden Visual Basic -aliohjelman samalle nimelle kuin ensimmäisen nappulan yhteydessä. Nappulaa käytettäessä Access ei kuitenkaan ymmärrä kumpaa koodia pitäisi käyttää; ensimmäiseksi vai jälkimmäiseksi luotua. Ongelma korjautuu helpoiten poistamalla ylimääräinen Visual Basic -koodi seuraavasti:

  1. Valitse ongelmia aiheuttava nappula ja ota näkyville sen ominaisuudet (properties). Ominaisuudet-ikkunassa siirry edelleen Event-välilehdelle.
  2. Valitse Data-välilehdeltä se tapahtuma (Event), jonka kohdalla lukee jotakin.

    Valitse tapahtuma Event-välilehdeltä

  3. Klikkaa tapahtuman nimen perässä olevaa nappulaa.

    ...

  4. Etsi Visual Basic -listauksesta nappulan nimenmukaiset aliohjelmat.
    Private Sub Ensimmäinen_Click()
    On Error GoTo Err_Ensimmäinen_Click
    
    
        DoCmd.GoToRecord , , acFirst
    
    Exit_Ensimmäinen_Click:
        Exit Sub
    
    Err_Ensimmäinen_Click:
        MsgBox Err.Description
        Resume Exit_Ensimmäinen_Click
        
    End Sub
    Private Sub Ensimmäinen_Click()
    On Error GoTo Err_Ensimmäinen_Click
    
    
        DoCmd.GoToRecord , , acFirst
    
    Exit_Ensimmäinen_Click:
        Exit Sub
    
    Err_Ensimmäinen_Click:
        MsgBox Err.Description
        Resume Exit_Ensimmäinen_Click
        
    End Sub
    
    
  5. Poista ensimmäinen turha aliohjelma.
    Private Sub Ensimmäinen_Click()
    On Error GoTo Err_Ensimmäinen_Click
    
    
        DoCmd.GoToRecord , , acFirst
    
    Exit_Ensimmäinen_Click:
        Exit Sub
    
    Err_Ensimmäinen_Click:
        MsgBox Err.Description
        Resume Exit_Ensimmäinen_Click
        
    End Sub
    
    
  6. Sulje Visual Basic -ikkuna ja kokeile lomakkeen toimintaa.

Miten saan lomaketta luotaessa haluamani kentät automaattisesti comboboxeina?

Yleensä lomakkeilla halutaan combobokseina ne kentät joista on määritelty viite-eheyksiä. Kätevintähän on valita syötettävä tieto suoraan äiti-taulun sisältämistä tiedoista eikä yrittää muistella/keksiä itse sopivia arvoja. Taulujen luontivaiheessa voidaan määritellä missä muodossa kukin kenttä halutaan näyttää tietoja syötettäessä ja mistä syötettävä data halutaan hakea (Lookup):

  1. Siirry muokkaamaan (Design) haluamasi taulun rakennetta.
  2. Valitse kenttä, jonka haluat näkyvän comboboxina.
  3. Valitse Lookup-välilehti.
  4. Row Source -kohtaan voit valita sen taulun tai kyselyn josta haluat haettavan comboboxin sisällön
  5. Bound Column kohtaan pitää merkitä kuinka monennesta kentästä Row Source -kohdassa määritellystä taulusta halutaan ottaa arvo, joka sitten sijoitetaan kentän arvoksi. Useimmiten kyseessä on perusavain eli yleensä ensimmäinen kenttä (1).
  6. Column Count -kohtaan voit määritellä montaako kenttää Row Source -kohdassa määritellystä taulusta halutaan hyödyntää comboboxissa. Yleensä halutaan ainakin kaksi kenttää eli varsinaisen kenttään syötettävän tiedon lisäksi jokin arvoa selventävä kenttä esim. nimi.
  7. Column Widths -kohtaan voit määritellä kuinka leveästi kukin kenttä halutaan näyttää comboboxissa. Leveydet ilmoitetaan puolipisteellä (;) erotettuina. Määritä pituudeksi 0 jos et halua kentän näkyvän. Yleensä varsinainen kenttään sijoitettava sarake piilotetaan ja muut selventävät kentät näytetään.

Esimerkki

Henkilot-taulussa on tyonimike-kenttä, josta on määritelty viite-eheys Nimikkeet-tauluun. Jokaista henkilö syötettäessä pitäisi nyt siis osata syöttää tyonimike-kenttääm henkilon työkuvaa vastaavan nimikkeen koodi. Määrittelemme syöttämistä helpottamaan haku-tauluksi nimikkeet-taulun.

  1. Row Source -kohtaan valitaan hakutauluksi Nimikkeet.
  2. Bound Column -kohtaan määritellään 1 eli NimikeID-kenttä.
  3. Column Count -kohtaan syötetään 2 eli halutaan hyödyntää taulun kahta ensimmäistä kenttää eli NimikeID ja Nimi.
  4. Column Widths -kohtaan määritellään 0cm;10cm eli ensimmäistä kenttää (NimikeID) ei näytetä ollenkaan ja toinen kenttä (Nimi) esitetään 10 cm leveässä kentässä.
  5. Nyt käyttäjällä on tyonimikettä syöttäessä selkeä combobox, josta voi valita oikean nimikkeen selkeän nimen perusteella.

En osaa suunnitella tietokantaa, vinkkejä?

Tietokannan tauluja suunniteltaessa kannattaa pitää mielessään idea, että taulu laajenee VAIN korkeussuunnassa! Tämä tarkoittaa siis, että tauluun on helppo lisätä tietueita (korkeus kasvaa) mutta leveyssuunnassa taulu ei laajene (kenttiä ei siis voi lisäillä ihan milloin vain ja miten vain). Jos alkaa luetella kenttiä tyyliin pelaaja1, pelaaja2, pelaaja3 ... niin heti pitäisi hälytyskellojen soida! Tälläinen ratkaisu ei toimi eikä ole ollenkaan normaalimuotoinen.

Yleisesti virheitä esiintyy tilanteissa joissa pyydetään muodostamaan tietokanta, joka sisältää erilaisia tapahtumia ja sitten luetellaan näitä esimerkkinä (maali, kulma, rangaistuspotku, jne). Tässä vaiheessa kun näkee tuon sanan jne niin pitäisi heti unohtaa yritelmät tehdä jokaisesta tapahtumasta oma kenttänsä, koska emmehän tiedä mitä kaikkia tapahtumia halutaan rekisteröidä. Ratkaisuna on luoda yksinkertainen taulu jossa vain luetellaan omina tietueinaan (riveinä) kaikki mahdolliset tapahtumat ja jokaiselle tapahtumalle on määritelty jokin yksilöllinen tunniste (perusavain) esimerkiksi ihan vain numero. Sitten lopullisessa tilanteessa jossa halutaan tallettaa tapahtuneita asioita niin vain toisesta taulusta viitataan halutun tapahtuman tunnisteella tähän tapahtuma-tauluun. Tarvittavia tapahtumia on helppoa lisätä tarpeen mukaan vain lisäämällä uusia rivejä.

Jos kyseessä on pelaajat ja joukkue-tyylinen ongelma niin virhe johtunee alunperin siitä, että yritetään tunkea joukkue-tauluun tietoa siitä ketkä pelaajat joukkueeseen kuuluvat. Oikea ratkaisu olisi viitata pelaajasta aina siihen joukkueeseen johon pelaaja kuuluu. Eli siis aivan tyypillinen 1-to-M-tilanne. Yhdessä joukkueessa on monia pelaajia ja jokainen pelaaja tietää joukkueensa.

Toinen mahdollinen tilanne olisi esim. työprojekti ja työntekijät. Yhdessä projektissa on monta työntekijää (vrt. pelaajat ja joukkue) mutta sama työntekijä voi olla tekemässä montaa projektia. Nyt jos yritetään ylläolevaa ratkaisua niin ajetaan taas karille, koska työntekijään ei pystytä laittamaan oikeaa määrää kenttiä joista viitata projekteihin. taulu ei siis laajene helposti leveyssuunnassa eli kenttien lukumäärän suhteen. Ainut ratkaisu on luoda uusi taulu työprojektin ja työntekijöiden välille. Tähän tauluun kenttä josta viitataan työprojektiin ja kenttä josta työntekijään. Sen mukaan kuinka monessa projektissa kukin työntekijä on mukana niin tähän tauluun tulee uusia rivejä. Kyseessä siis aivan tavallinen M-to-M-tilanne.

Jos on piirtänyt ER-kaavionsa kunnolla ja osannut laittaa siihen oikein näkyviin 1-to-M- ja M-to-M-suhteet niin kumpikin ylhäällä esitetty ongelma ratkeaa aivan suoraan jos vain muuntaa ER-kaavionsa oikeiden sääntöjen perusteella tietokannan tauluiksi. Säännöt löytyvät kurssin monisteesta.

SQL menee ihan yli hilseen. Vinkkejä?

Muutamat perusvirheet SQL-kyselyissä on hyvin helposti vältetty jos muistaa seuraavat asiat:

  1. Jos tehdään kyselyä useammasta taulusta niin AINA kyselyssä pitää olla WHERE-lause, jossa kerrotaan minkä kentän tai kenttien suhteen taulut liittyvät toisiinsa! Jos kyselyn FROM-kohdassa on lueteltu kaksi taulua niin pitää löytyä AINAKIN YKSI rivi WHERE-osassa, joka yhdistää nämä taulut toisiinsa. Yhdistäviä ehtoja on aina yksi vähemmän kuin FROM-lauseessa lueteltuja tauluja. Elikkäs jos tietoja haetaan neljästä taulusta niin yhdistäviä ehtoja on kolme, jos kolmesta taulusta niin yhdistäviä ehtoja on kaksi! Tähän tietysti päälle sitten vielä muut hakutulosta rajaavat ehdot joita voi olla nolla tai enemmän. Lähes aina tauluja yhdistävät kentät ovat samat mitkä näkyvät viite-eheysmäärittelyissä.
  2. WHERE-lauseessa EI KOSKAAN voi käyttää SUM-, COUNT- tai AVG-funktioita! Näitä funktioita voi esiintyä vain joko suoraan SELECT-lauseen ensimmäisellä rivillä tai sitten HAVING-lauseessa.
  3. HAVING-lausetta pitää AINA edeltää GROUP BY-lause.
  4. Jos SELECT-lauseessa halutaan hakutulokseen sekä tavallisia kenttiä, että yhteenvetofunktioiden (SUM, COUNT, AVG) tuloksia niin kaikki tavalliset kentät pitää luetella GROUP BY-lauseessa.

Mitä tarkoittavat NO ACTION ja CASCADE?

Viite-eheysmääritysten tarkemmat asetukset tuntuvat olevan useille hieman hämäriä.

Uusia tietueita lisättäessä on huomattava, että lisääminen ei onnistu jos tietueen sisältö rikkoo viite-eheysmäärittelyjä!

Miten saan SQL:llä haettua N suurinta/pienintä?

Tämä onnistuu helpoiten alikyselyllä, joka on verrattavalla kentällä sidottu ylempään kyselyyn. Esim. halutaan etsiä kolme suurinta tenttisuoritusta:

SELECT *
FROM Tentit t
WHERE 3 > (
   SELECT COUNT(arvosana)
   FROM Tentit tt
   WHERE tt.arvosana > t.arvosana
)

Miten saa Excelillä piirretyn ER-kaavion liitettyä WWW-dokumenttiin?

Kuva täytyy kopioida leikepöydän avulla johonkin kuvankäsittelyohjelmaan ja muokata siellä sopivaan muotoon.

  1. Käynnistä jokin kuvankäsittelyohjelma
  2. Ota näkyville Excelissä piirtämäsi kuva.
  3. Valitse kaikki kaavioon liittyvät objektit piirtotyökaluista löytyvällä Select Objects-työkalulla.

    Select Objects

  4. Kopioi valitut objektit leikepöydälle Edit|Copy.
  5. Siirry kuvankäsittelyohjelmaan
  6. Liitä leikepöydältä kuva käsiteltäväksi (Edit|Paste)
  7. Pienennä kuvan värimäärä mahdollisimman vähäiseksi niin säästät muistia. Yleensä 16 väriä riittää.
  8. Jos olet liittämässä kuvaa HTML-dokumenttiin niin talleta se PNG-, tai GIF-muodossa. Joissakin ohjelmissa tallentaminen pitää tehdä Export-toiminnon avulla.
  9. Lisävinkkejä löytyy Tietoverkot työvälineenä -kurssin demotehtävistä.

Miten käytän SQL:ää OpenOffice Basessa?

SQL:n kanssa Base tuntuu olevan hieman sekava. Tietokannan luominen CREATE TABLE -lauseilla ei onnistu queries-valinnan kautta aukeavalla sql-ikkunalla vaan sen kautta voi suorittaa vain yksittäisiä kyselyjä jotka palauttavat tietueita tulokseksi (SELECT). Näitäkin kirjoitettaessa pitää yleensä laittaa päälle valinta "run sql command directly" tai Base herjaa kaikenlaista omituista aivan toimivista kyselyistä.

Tietokannan luominen onnistuu Tools-valikon SQL-valinnalla. Luodut taulut eivät kuitenkaan näytä suoraan päivittyvän Tables-listaukseen vaan tietokanta pitää ensin sulkea ja avata uudelleen.

Miten NUMERIC-tietotyyppi toimii?

NUMERIC-tietotyypille kerrotaan montako numeroa pitkä luku tallennetaan ja montako numeroa näistä käytetään luvun desimaaliosassa. esim. NUMERIC(5,3) tarkoittaa, että kyseiseen ominaisuuteen/kenttään voidaan tallentaa suurimmillaan luku 99,999 eli viisi numeroa joista kolme numero on varattu desimaaliosalle.

Tyypillinen virhe on kuvitella, että ensimmäinen luku tarkoittaisi kokonaisosan pituutta ja toinen desimaaliosan pituutta mutta näin ei ole!

NUMERIC-esimerkkejä
MääritysSuurin mahtuva numero
NUMERIC(6,2)9999,99
NUMERIC(3,3)ei laillinen määritys koska kokonaisosalle ei jäätilaa.
NUMERIC(1,3)ei laillinen määritys koska desimaaliosa on pitempi kuin koko luvulle varattu tila
NUMERIC(3,2)9,99
NUMERIC(4,2)99,99
NUMERIC(6,0)999999 ei järkevä koska INTEGER on tässä parempi

Miten saan sql-kyselyn lopputulokseen myös ne tietueet joille ei löydy vastinetta kaikista kyselyyn käytetyistä tauluista?

Tämä on tyypillinen ongelma kopioitaessa tietoja Accessista Exceliin. Yritys on tehdä kysely, joka listaisi kaikki tietokannan tiedot mutta sattuukin niin, että jossakin taulussa ei ole tietoja johonkin tiettyyn tietueeseen liittyen esim. tietokoneella ei olekkaan lisälaitteita. Tällöin käy niin, että kyseinen tietokone jää tulematta kyselyn vastaukseen koska kaikki sql-kyselyn WHERE-osan ehdot eivät toteudu sen kohdalla.

Ongelma pitää kiertää joko tekemällä useampi kysely ja viemällä kaikkien niiden tulokset Accessiin tai käyttämällä ulkoliitosta (OUTER JOIN) tai yhdistettä eli UNION-operaattoria. Kaksi jälkimmäistä ovat aiheita joita ei henkilökohtaisen tiedonhallinnan perusteet -kurssilla ole käsitelty.

UNION on melkoisen yksinkertainen käyttää:

SELECT sukunimi, etunimi, kurssitunnus, arvosana
FROM Oppilaat AS O, Tentit AS T
WHERE O.sotu = T.sotu
UNION
SELECT sukunimi, etunimi, '', ''
FROM Oppilaat O
WHERE O.sotu NOT IN
(SELECT sotu
FROM Tentit)
ORDER BY sukunimi

On syytä huomata, että kummankin kyselyn tuloksessa täytyy olla sama määrä kenttiä ja jos toisessa on niitä vähemmän täytyy ne korvata vakioilla. Ylläolevassa esimerkissä puuttuva kurssitunnus ja arvosana on korvatta tyhjällä merkkijonolla ''. Jos kyseessä olisi numeerinen arvo niin korvaaja voisi olla esim. 0. Myös NULL-sanaa voi käyttää.

UNION-operaattori estää saman rivin toistumisen tuloksessa. Jos haluaa säilyttää tuplarivitkin pitää kirjoittaa UNION ALL.

Taulukkolaskenta

Miksi Excel 2007 muuttaa pylväskaavioni pylväät kapeiksi viivoiksi?

Vika johtunee siitä, että x- tai y-akselilla on käytössä päivämäärä- tai aika-tyyppistä tietoa. Excel yrittää olla liian fiksu ja suhteuttaa kaaviota aikoihin. Ongelma on helppo korjata kun valitsee Format Axis|Axis Options|Axis type ja valitsee tyypiksi Text Axis.

Miten OpenOffice Calc:illa saa siirrettyä taulun tietokannasta?

Avaa OpenOffice Calc. Luo tietokantayhteys ODBC Query Toolilla kurssin tietokantapalvelimeen ellet ole jo luonut. Valitse Tools | Data Sources ja lisää valintanapilla ... luotu tietokantayhteys. Luo uusi taulukko, paina F4, avaa alalaidasta tietokannassa oleva taulu, valitse vasenta yläkulmaa napauttamalla kaikki tietueet ja napauta työkalupalkista Data to Text -kuvaketta, jolloin tiedot siirtyvät taulukkoon.

Miten saan taulukkolaskentaohjelman soluihin ajan minuutteina välittämättä tuntirajoista? Esim. 75 minuuttia 15 sekunttia muodossa 75:15.

Microsoft Excelissä ajan näyttäminen minuutteina onnistuu omien (Custom) muotoilujen avulla. Muotoilun tyypiksi (Type) laitetaan teksti [mm]:ss . Tällöin soluun tulevat minuutit lasketaan yhteen ja sekunnit näytetään sellaisenaan. Vastaavasti voidaan määritellä solussa oleva aika tunteina [t]:mm:ss välittämättä vuorokausirajasta tai sekunteina [ss] välittämättä minuuttirajasta.

Miten saadaan laskettua kilpailijoiden helposti sijoitus esimerkiksi ajan mukaan?

Kilpailijoiden sijoituksen laskemista varten on olemassa RANK-funktio, joka löytyy tilastollisten (statistical)-funktioiden joukosta. Funktion syntaksi on seuraava:

=RANK(arvo; vertailulista; jarjestys)

Esimerkki:
=RANK(C2; tuloslista; 0)

Esimerkin solussa C2 on kilpailijan lopputulos ja tuloslista on kaikkien kilpailijoiden lopputulokset sisältävä nimetty alue. Viimeinen parametri määrittelee määrittelee lasketaanko sijoitus nousevassa (1) vai laskevassa (0)järjestyksessä.

Miten MS-Excelissä voi muuttaa kaavion pystyakselin asteikkoa alkamaan jostakin muusta kuin nollasta?

Kaavion akselin asteikon muuttaminen onnistuu valitsemalla haluttu akseli hiirella aktiiviseksi, jonka jälkeen hiirein oikean alta löytyy valinta Muotoile akselia(Format Axis). Välilehdeltä Mittakaava (Scale) löytyy valinnat akselin arvojen muokkaamiseksi. Muuttamalla arvo Minimi(Minimun) toiseksi saadaan akselin asteikko alkamaan halutusta pisteestä.

Kaavion sarjojen päivittäminen

Kaavio ei päivity automaattisesti, jos data-alueelle tulee lisää sarjoja. Esimerkiksi jokaisen opiskelijoiden muodostaessa oman sarjansa opiskelijoiden lisääminen ei vaikuta ollenkaan kaavioon. Kaaviolle voi antaa data-alueen nimettynä solualueena, mutta silti ongelma ei poistu. Kaavionäet muuttaa nimetyn solualueen soluviittaukseksi.

Ongelman saa poistumaan tekemällä kaavion päivitysmakron. Makron tekeminen onnistuu nauhoittamalla kaavion data-alueen päivittäminen. Data-alueen päivittäminen voidaan tehdä napauttamalla hiiren oikealla kaaviota ja valitsemalla Source Data-kohdan. Kohdan alta voi valita uuden data-alueen. Data-alueena kannattaa käyttää nimettyä aluetta, mutta nimetty alue joudutaan lisäämään erikseen makroon. Esimerkin tapauksessa makro on nauhoitettu ja makroon on lisätty ainoastaan nimetyn alueen nimi JUTTU alkuperäisen soluviittauksen paikalle. Makroa kannattaa käyttää osana lisäämiseen käytettävää makroa.

Sub paivita_kaavio()
    ActiveSheet.ChartObjects("Chart 1").Activate
    ActiveChart.ChartArea.Select
    ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("JUTTU"), _
    PlotBy:=xlRows
End Sub

Makro voi antaa virheilmoituksen, jos makro on nauhoitettu englanninkielisellä versiolla ja se ajetaan suomenkielisessä versiossa. Suomenkieliseen versioon kaavion nimen Chart 1 kannattaa muuttaa nimelle Kaavio 1.

Miten päivämäärästä saa erilleen kuukauden, vuoden ja päivän?

Taulukkolaskentaohjelmista löytyy funktioita, joiden avulla päivämäärä voidaan hajoittaa osiin. Seuraavassa lyhyt esimerkki. Esimerkissä on solussa B11 päivämäärä 13.2.2001.

=DAY(B11) palauttaa soluun luvun 13
=MONTH(B11) palauttaa soluun luvun 2
=YEAR(B11) palauttaa soluun luvun 2001

Miten nimetyn alueen saa laajenemaan rivin lisäysten yhteydessä?

Ennen ensimmäistäkään rivinlisäystä nimetyssä alueessa pitää olla vähintään kaksi riviä. Tämän jälkeen uusi rivi lisätään aina nimetyn alueen sisälle eli valitaan nimetyn alueen alempi rivi aktiiviseksi, kun uusi rivi lisätään. Tällä tavoin nimettyalue laajenee automaattisesti rivin lisäysten yhteydessä. Kannattaa myös miettiä voiko nimettyä aluetta määritellä kattamaan kaikki tarvittavien sarakkeiden rivit, jolloin tuollaisia ongelmia ei pitäisi tulla.

Ongelmia funktioiden ja kaavojen arvojen päivittymisessä?

Jos funktioiden ja kaavojen arvot eivät päivity, niin tämä johtuu yleensä ohjelman asetuksista. Tällöin valikkokomennolla Tools | Options avautuvan ikkunan Calculation-välilehdellä kohdassa Calculation on valittuna kohta Manual. Valinta tarkoittaa, että laskenta tehdään manuaalisesti, joten kohtaan kannattaa valita automaattinen päivittyminen eli kohta Automatic.

Miten kaavasoluista saa kopioitua pelkät arvot?

Joissakin yhteyksissä tulee tarve kopioida kaavoja sisältävistä soluista ainoastaan solussa näkyvät. Tämä onnistuu PasteSpecial-ominaisuuden avulla. Solut kopioidaan normaalisti leikepöydälle, mutta liittämiseen käytetään PasteSpecial-ominaisuutta. Tällöin voidaan valita mitä halutaan liittää. Eräs vaihtoehdoista on arvot (engl. Values), mutta voidaan myös liittää muotoiluja, kaavoja, kommentteja, kelpoisuusehtoja ja sarakkeen leveys. Tarkemmin työkalun toimintaan voi perehtyä kurssin luentomonisteesta.

Miten saan helpoiten päivitettyä "pistetaulukkoon" tehdyt maalit?

Ongelmana on esimerkiksi SM-liigan jääkiekkoilijoiden tehopistetilastojen tai vastaavan päivittäminen ottelukierroksen jälkeen. Ongelman voisi ratkaista tekemällä monimutkaisen makron, jolla lisätään kullekin pelaajalle uudet pisteet ja lisäys tehtäisiin entisiin pisteisiin. On kuitenkin olemassa toinen ja hieman yksinkertaisempi tapa, joka vaatii hieman etukäteissuunnittelua. Tavassa tarvitaan erillinen laskentataulukko, johon käyttäjä syöttää kierroksen pisteet. Taulukon on oltava täsmälleen samaa muotoa kuin lopullinen pistetaulukko.

Kun pisteet on syötetty, niin pisteiden siirtäminen onnistuu kopioimalla syöttötaulukko leikepöydälle ja liittämällä se PasteSpecial-toiminnolla lopulliseen pistetaulukkoon. PasteSpecial-toiminnolla voidaan tehdä lisäysoperaatio (engl. Add) liittämisen yhteydessä, jos taulukot ovat täsmälleen saman muotoisia. Tällöin lisääminen tehdään aina syöttötaulukon vastinsoluun lopullisessa pistetaulukossa. Muita mahdollisia toimintoja on PasteSpecial-toiminnon yhteydessä ovat vähennyslasku- (engl. Substract), kertolasku- (engl. Multiply) ja jakolaskuopetaatiot (engl. Divide).

Miten saa tehtyä oman muotoilun (engl. Custom) päivämääriä sisältävään soluihin?

Päivämäärien laittamisssa soluun voi olla ongelmia saada päivämäärä muotoon päivä.kuukausi.vuosi. Välttämättä valmiista solun päivämäärämuotoiluista ei löydy oikeaa muotoa, joten tällöin täytyy käyttää solussa omaa muotoilua. Seuraavassa käydään läpi myös muitakin omia muotoiluja kuin päivämäärän antamiseen liittyviä muotoiluja.

Oman muotoilun soluihin muuttamalla tyylistä solun ominaisuuksia Number-välilehdeltä. Ominaisuudet voidaan toki laittaa myös tyylin ulkopuolelle. Muotoiluista valitaan Custom (suom. Omat)-muotoilu, johon voidaan määritellä solun muoto tarkemmin. Seuraavassa muutamia esimerkkejä asiasta. Esimerkeissä mukana myös englanninkielisillä ohjelman asetuksilla tehtävät muotoilut. Ohjelman kieli ei siis määrää käytettäviä asetuksia, vaan sen määräävät käyttöjärjestelmän maa-asetukset.

Kuinka merkkijonojen liittäminen onnistuu taulukkolaskennassa?

Merkkijonojen liittäminen toisiinsa onnistuu taulukkolaskennassa &-merkin avulla. Toinen vaihtoehto on käyttää CONCATENATE-funktiota. Seuraavassa esimerkissä havainnollistetaan asiaa hieman.

Soluviittauksen rakentaminen kahden solun perusteella onnistuu laittamalla &-merkin soluviittausten väliin eli seuraavasti =B1&A2. Jos solussa B1 on B-kirjain ja solussa A2 on luku 2, niin kaavan sisältävään soluun tulee arvo B2.

Seuraavassa esimerkissä otetaan kukkien lukumäärä solusta A2 ja halutaan kirjoittaa soluun lukumäärän perään teksti "kukkaa" (eli 2 kukkaa). Tällöin merkkijonojen liittäminen on tehtävä seuraavasti: =A2&" kukkaa".

Jos taas halutaan rakentaa soluviittaus ja viitata sillä solun sisältöön, niin se on tehtävä INDIRECT-funktiolla seuraavasti: =INDIRECT(B1&A2). Tällöin soluun saadaan rakennetun soluviittauksen solussa oleva arvo.

Miksi laskentataulukon soluissa näkyy pelkkää risuaitaa (#####)?

Risuaitamerkin (#) näkyminen solussa johtuu siitä, että solun sisältö ei mahdu soluun. Tällöin täytyy leventää hieman koko saraketta. Sarakeleveyden muuttaminen oikeaksi onnistuu helpoiten sarakeotsikoista hiren avulla. Mentäessä sarakeotsikoiden väliin muuttuu hiirikursori pystyviivaksi, jossa on poikittain kaksipäinen nuoli. Tällöin tuplanapauttamalla hiiren vasenta painiketta saadaan sarake automaattisesti sisällön levyiseksi. Saraketta voidaan myös leventää haluttuun mittaan hiiren vasemman painikkeen avulla raahamalla.

Kuinka laskentataulukon solun arvo saadaan mukaan kaavioon?

Kaavio tietenkin tehdään laskentataulukon arvojen perusteella. Jos kaavioon halutaan liittää jokin arvo (esimerkiksi kaavion pylväiden yhteissumma), niin arvon liittäminen onnistuu "kameratoiminnon" avulla. Kameratoiminto ei ole oletuksena valikoissa, vaan se pitää lisätä valikkokomennolla View | Toolbars | Customize avautuvasta ikkunasta. Command-välilehdeltä valitaan kategoria (engl. Categories) Tools. Tämän jälkeen Commands-listasta etsitään kohta Camera ja raahataan se jollekin työkalupainikeriville. Tämän jälkeen ikkuna voidaan sulkea Close-painikkeella.

Kameratoiminnon (engl. Camera) käyttäminen aloitetaan valitsemalla aktiiviseksi se solu, jonka arvon halutaan näkyvän kaaviossa. Tämän jälkeen valitaan työkalupainikeriviltä Camera-painike, jonka jälkeen napautetaan hiirellä kaavion tai laskentataulukon kohtaan, johon solun arvo halutaan näkyviin. Tämän jälkeen näkyville tullut objekti voidaan siirtää oikeaan kohtaan. Solun arvon muuttumisen myötä myös kaaviossa oleva kenttä muuttaa arvoaan.

Excel-taulukon muuttaminen HTML-taulukoksi?

Excel-taulukon voi muuttaa HTML-taulukoksi esimerkiksi tallentamalla sivun HTML-muotoon. HTML-muotoon tallentaminen antaa kuitenkin sen verran sekavan tiedoston, että sitä ei voi suositella kenellekään. Usein on tarpeen tehdä HTML-taulukko pienemmästä laskentataulukon osasta, jolloin koko laskentataulun tallentaminen on turhaa. Laskentataulukon osan muuttamisen HTML-muotoon voi tehdä kätevästi pienellä makrolla. Tekemäni makron voit halutessasi kopioida käyttöösi dokumentista "Excel-taulukon muuttaminen HTML-taulukoksi". Dokumentissa on ohjeita makron käyttämiseksi.

Miten ID-numeroinnin saa toimimaan automaattisesti?

Numeroinnin käyttötarkoituksesta ja kohteesta riippuen seuraavassa muutamia ideoita:

Excel-makrot

Miksi Excelini Visual Basic editorista ei löydy VBA (Visual Basic for Applications) avustusta (Help)??

Microsoft Office paketin asennuksen yhteydessä oletusasetuksilla ei asenneta VBA-avustustiedostoa, vaan se pitää asentaa erikseen. Asentaminen onnistuuStart | Conrol Panelin kuvakkeella Lisää | Poista sovellus (Add | Remove Program). Avautuvasta listasta valitaan MS-Office paketti, jonka jalkeen valinnalla Lisää | Poista (engl. Add | Remove) käyttöjärjestelmä pyytää asennus-CD:ta.
Asennuksessa valitaan ainoastaan ne osat, jotka halutaan asentaa eli VBA Help.

Miten pääsen makrossa tapahtuvasta virheestä eteenpäin? Esimerkiksi toiminan peruminen kesken makron suorittamisen aiheuttaa aivan käsittämättömiä virheitä.

Yksi tapa, joskaan ei kovinkaan hyvä, on kirjoittaa ennen virheen antavaa funktiota/riviä seuraava komento:

On Error Resume Next

Eli virhetilanteessa siirretään makron suoritus seuraavalle riville ja jätetään virhe kokonaan huomiotta. Tuota kannattaa käyttää harkiten!! Paras tapa on tietenkin käsitellä virhe eli ottaa virhekoodi talteen ja reagoida siihen kertomalla käyttäjälle vähintäänkin virheen aiheuttanut asia. Tämä vaatii kuitenkin enemmän ohjelmointia, mutta jos olet kiinnostunut asiasta lue VBA-avustusta kohdasta On Error, err ja error.

Miten saa tehtyä "tallenna nimellä" -makron, jossa käyttäjältä kysytään tiedoston nimi?? Nauhoittamalla tuo ei ainakaan näytä onnistuvan.

Makron saa tehtyä ainoastaan käsin kirjoittamalla. Makron syntaksi on seuraava:

Sub Tallenna_nimella()
    Fname = Application.GetSaveAsFilename
    If (Fname <> False) Then
       On Error Resume Next
       ActiveWorkbook.SaveAs FileName:=Fname
    End If
End Sub

Makrossa kysytaan nimellä tallentamista aivan kuten se tapahtuu valinnan File | Save As kautta. Mukaan on liitetty pieni testaus siitä annetaanko nimeä ollenkaan. Esimerkiksi Cancel painikkeen painaminen aiheuttaa ilman testaamista tyokirjan tallentumisen nimelle false.xls . Jos taas tiedosto on jo olemassa eika haluta tallentaa sen päälle, niin tällöin Cancel-näppäimen painaminen aiheuttaa virheen, josta selviydytään virhetestillä On Error Resume Next.

Miten saa liitettyä makron painikkeeseen?

Valmiiksi nauhoitetun makron liittäminen painikkeeseen on helppoa FORMS- (suom. Lomakkeet) työkalupalkin avulla. Työkalupalkin saa näkyville komennolla View | Toolbars | Forms (suom. Näytä | Työkalupalkit | Lomakkeet). Työkalupalkista kannataa valita Button (suom. Painike) ja raahata työpöydällä sopivan kokoinen painike. Hiiren painikkeen vapauttamisen jälkeen näkyviin avautuu Assign Macro -ikkuna, josta voidaan valita liitettäväksi jo olemassa oleva makro.

Päivämäärän kysymisessä ongelmia?

Päivämäärän kysyminen inputboxilla voi aiheuttaa ongelmia päivämäärämuotoiluissa. Seuraavassa kuitenkin ratkaisu, jonka avulla päivämäärän kysymisessä ei pitäisi tulla ongelmia.

 Sub kysy_paiva()
        Dim paiva As Date 'Alustetaan paiva-muuttuja päivämääräksi
        paiva = InputBox("Anna päivä") ' Kysytään päivä
        ActiveCell.Value = paiva ' Liitetään päivä aktiiviseen soluun
 End Sub

InputBoxin Cancel-painikkeen painaminen aiheuttaa virheen

InputBoxissa Cancel-painikkeen painamisesta voi seurata virheellinen toiminta. Esimerkiksi rivin poistamisen yhteydessä tuloksena voi olla aktiivisen rivin tai solualueen häviäminen. Seuraavassa lyhyt esimerkki, jonka avulla voi itse testata InputBoxin toimintaa.

Sub Cancel()
    testi = InputBox("Anna arvo tai paina Cancel-painiketta")
    If (testi <> "") Then
      testi2 = MsgBox(testi)
    Else
      testi2 = MsgBox("Ei arvoja")
    End If
End Sub

Miksi Datalomake (engl. DataForm) ei toimi makrossa?

Datalomake voi antaa makron suorittamisen aikana seuraavan virheen:

Run-time error '1004';
ShowDataForm method of Worksheet class failed

(suom. Suorituksen aikainen virhe `1004`;
Luokan Worksheet menetelmä ShowDataForm epäonnistui)

Nauhoitettaessa kyseistä virhettä ei tule ollenkaan. Virhe johtuu lomakkeen ylä- tai vasemmassa reunassa olevista tyhjistä riveistä tai sarakkeista ennen data-aluetta, joten virheen korjaamiseksi tyhjät rivit ja sarakkeet täytyy poistaa. Data-alueen nurkkasolu pitää siis olla alueella A1:B2.

Miksi lomakkeelta toiselle kopiointi antaa virheilmoituksen makrossa?

Makrossa tietojen kopioiminen lomakkeelta toiselle antaa virheen, joka näyttää johtuvan suojauksista. Suojaukset kannattaa poistaa lomakkeilta jo makron alussa, jolloin virhettä ei näytä tulevan.

Tulostuksen esikatselun ongelmat

Esikatselumakro on todella yksinkertainen makro, jossa riittää nauhoittaa tulostuksen esikatselussa käynti. Tulostuksen esikatseluun päästään valinnalla File | Print Preview. Nauhoituksessa tulee (Excel 2000) ainoastaan seuraava rivi.

ActiveWindow.SelectedSheets.PrintPreview

Rivin voi kopioida makroon myös suoraan, mutta seuraavassa tarkempi kuvaus mahdollisista ongelmista.

Jos käyttöjärjestelmään ei ole asennettu kirjoitinta, niin tulostuksen esikatseluun ei pääse. Vaikka koneessa ei ole kirjoitinta, niin kirjoitin voidaan kuitenkin asentaa Windowsiin. Kirjoittimen asentaminen Windowsiin onnistuu valinnan Start | Settings | Control Panel kautta löytyvällä kuvakkeella Printers. Printers ikkunasta löytyy kuvake Add Printer, jota tuplanapauttamalla saadaan kirjoittimen asennus käyntiin. Kirjoittimen asentamisen vaiheet poikkeavat hieman käyttöjärjestelmäversiosta riippuen. Tarkoituksena on kuitenkin valita lokaali (engl. Local) kirjoitin, joka on yhditettynä kirjoitinporttiin (LPT?). Tämän jälkeen voidaan valita kirjoittimen valmistaja (engl. Manufacturer) ja kirjoitin (engl. Printers). Kirjoittimen asennuksen yhteydessä joudutaan usein laittamaan koneeseen käyttöjärjestelmän asennus-CD, koska kirjoittimen ajurit asennetaan CD:ltä.

Painikkeiden häviäminen suodatuksen yhteydessä?

Makropainikkeiden häviämisen ja liikkumisen solujen mukana saa estettyä painikkeiden ominaisuuksista:

Ominaisuuksiin päästään aktivoimalla ensin painikkeen (ei tekstiä). Tämän jälkeen hiiren oikean painikkeen avulla päästään muokkaamaan painikkeen ominaisuuksia (engl. Format Control). Avautuneesta ikkunasta valitaan ominaisuudet (engl. Properties) -välilehti, jolta voidaan määritellä painikkeelle muutamia ominaisuuksia. Ominaisuudet ovat listattu seuraavassa:

Miten saadaan välkkyminen eli ruudun päivittyminen pois makrosta?

Ruudun eli näytön päivittäminen hidastaa makroa aika paljon joidenkin toimenpiteiden yhteydessä, joten se kannattaa laittaa pois päältä ennen kyseisiä toimenpiteitä. Aina päivitystä ei kannata poistaa heti makron alussa. Makron lopussa päivittäminen on laitettava takaisin päälle!

Ruudun päivitys pois päältä

Application.ScreenUpdating = False

Ruudun päivitys takaisin päälle

Application.ScreenUpdating = True

Miten voin makrossa estää tallentamisen tai tuhoamisen varmistuskyselyn?

Varmistuskyselyjen poistamisessa kannattaa olla tarkkana, koska kyselyjen tarkoitus on ehkäistä pahoja virheitä. Jos kyselyt otetaan pois makrossa, niin makron lopussa ne kannattaa ehdottomasti laittaa uudelleen päälle. Seuraavassa makroon sijoitettavat koodit:

Varmistuskysely pois päältä:

Application.DisplayAlerts = False

Varmistuskysely takaisin päälle:

Application.DisplayAlerts = True

Miten voin nauhoittaa makron, joka tallentaa yhden lomakkeen erilliseen työkirjaan?

Nauhoittaminen ei onnistu, mutta perusrungon voi toki nauhoittaa. Seuraavassa makro, jonka runko on nauhoitettu ja siihen on lisätty muutamia osia käsin. Makron toiminta kannattaa testata huolellisesti, koska se voi sisältää virheitä. Jos havaitset virheitä, niin kerro niistä Petri Heinoselle (peheinon@mit.jyu.fi).

Sub tallenna_lomake_nimella()
    
    Dim nimi As String
    Dim uusinimi As String
    Dim tiedosto As String
    Dim lomakkeet As Integer
    
    ' Poistetaan näytön päivitys
    Application.ScreenUpdating = False
    
    
    ' otetaan aktiivisen työkirjan nimi talteen
    nimi = ActiveWorkbook.Name
    
    ' Muotoillaan uutta työkirjaa etukäteen
    lomakkeet = Application.SheetsInNewWorkbook
    Application.SheetsInNewWorkbook = 1
            
    ' Lisätään uusi työkirja
    Workbooks.Add
    ' Otetaan nimi talteen
    uusinimi = ActiveWorkbook.Name
    
    Windows(nimi).Activate
    ActiveSheet.Copy Before:=Workbooks(uusinimi).Sheets(1)
    ' Tuhotaan ylimääräinen lomake työkirjasta
     
    Application.DisplayAlerts = False
       
    Workbooks(uusinimi).Sheets(2).Delete
    ' Kysytään käyttäjältä tiedoston nimi
    tiedosto = InputBox("Anna tiedoston nimi", "Anna tiedoston nimi")
    ' Tallennetaan tiedosto ohjelman oletushakemistoon
    ActiveWorkbook.SaveAs Filename:=tiedosto, FileFormat:= _
        xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
        , CreateBackup:=False
    ' Palautetaan asetukset
    Application.SheetsInNewWorkbook = lomakkeet
    ' Laitetaan varoitukset takaisin päälle
    Application.DisplayAlerts = True
    ' Laitetaan näytönpäivitys takaisin päälle
    Application.ScreenUpdating = True

End Sub

Miksi makroni eivät toimi?

Miksi makroni eivät toimi, vaan ohjelma antaa seuraavan virheilmoituksen: "The macros in this project are disabled. Please refer to the online help or documentation of the host application to determine how to enable macros."

Virheilmoitus johtuu korkeasta turvallisuustasosta. Kun dokumentin turvallisuustasoksi (engl. Security) on määritelty korkea (engl. High), sallitaan ainoastaan "turvallisesta" lähteestä tulevien makrojen suorittaminen. Makrot saa takaisin toimimaan seuraavan listan ohjeiden mukaisesti:

Miten makrossa saadaan anettua dokumentille tallennuspaikka ja nimi?

Seuraavan esimerkin mukaisella koodilla saadaan avattua tallenna nimellä (engl. Save As) -ikkuna, jossa voidaan valita tallennuspaikka ja tiedoston nimi.

Sub tallenna_nimella()
  Dim tallennusnimi As String
  tallennusnimi = Application.GetSaveAsFilename
End Sub

Miten makrossa voidaan hallitusti poistaa laskentataulukosta käyttäjän haluama rivi?

Makrossa poistaminen on hieman hankalampi tehtävä. Jos käyttäjälle riittää, että hän välitsee rivin ensin, jonka hän haluaa poistaa, niin toteutus on kohtuullisen yksinkertainen. Ongelmana on kuitenkin käyttäjän vahingon painallukset, jotka voivat tuhota tärkeitäkin tietoja ja kaavoja. Jos rivin poistaminen on pakko tehdä makrossa, niin makroon kannattaa liittää hieman tarkistuksia poistettavasta rivistä. Seuraavassa on lyhyt esimerkki poistomakrosta, jossa käyttäjältä varmennetaan poistettavat tiedot ennen niiden poistamista. Esimerkissä on pyritty vähentämään käyttäjän mahdollisuuksia virheellisiin valintoihin, mutta esimerkki ei ole aukoton.

Sub poista()
    Dim nimi As String
    
    Range("A1").Select
    ' Otetaan laskentataulukon suojaus pois
    ActiveSheet.Unprotect
    ' Kysytään poistettava nimi
    nimi = InputBox("Anna poistettavan nimi", "Tietojen poistaminen")
    
    ' Jos nimeä ei annettu tai annettiin tyhjä nimi, niin ei tehdä mitään!
    If nimi <> "" Then
      ' Ei takerruta etsimisen yhteydessä tulevaan virheeseen
      On Error Resume Next
      ' Etsitään poistettava rivi
      Cells.Find(What:=nimi, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
        :=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
        False).Activate
      
      If Err.Number = 0 Then ' Jos ei virhettä, niin jatketaan
        ' Otetaan aktiivisen solun nimi talteen
        nimi = ActiveCell.Value
        toiminta = MsgBox("Haluatko varmasti poistaa tiedot: " & nimi, vbYesNo, "Tietojen poistaminen")
        
        ' Testataan painoiko käyttäjä Yes-painiketta!
        If (toiminta = 6) Then
          ' Tuhotaan rivi!
          Selection.EntireRow.Delete
        Else
          MsgBox ("Tietoja " & nimi & " ei poistettu!")
        End If
      Else
         ' Jos etsinnässä ei löytynyt mitään
         MsgBox ("Tietoja " & nimi & " ei löytynyt!!")
      End If
    End If

' Suojataan lomake uudelleen
    ActiveSheet.Protect
End Sub

Miten makrossa voidaan testata rivi, jonka solu on aktiivinen?

Aktiivinen rivi tai rivi, jonka solu on aktivoitu voidaan testata seuraavan esimerkin mukaisesti.

Sub rivin_testaus()
      Dim rivi As Integer
      rivi = ActiveCell.Row
      ' Toimenpide sallistaan ainoastaan riveillä 1-5
      If (rivi> 5) Then
        MsgBox ("Toimenpide ei ole sallittu rivillä " & rivi)
      Else
        MsgBox ("Toimepide on sallittu rivillä " & rivi)
      End If
End Sub

Miten makrossa saadaan testattua laskentataulukon suojaus?

Laskentataulukon suojauksen tekstaaminen makrossa onnistuu seuraavan esimerkin avulla.

Sub suojauksen_testaus()
      If (ActiveSheet.ProtectContents) Then
        MsgBox ("Suojattu")
      Else
        MsgBox ("Suojaamaton")
      End If
End Sub

Miten voi Excelissä tai Wordissä voi suojautua makroviruksia vastaan?

Excelissäja Wordissa makroviruksia vastaan voi suojautua makrovirusvaroitusten avulla. Excel ja Word 97:ssä makrovirusvaroitukset saadaan päälle valinnalla Tools | Options (suom. Työkalut | Asetukset). Avautuvasta ikkunasta löytyy välilehti General (Suom. Yleinen), jolla sijaitsee kohta Macro virus protection (Suom. Makrovirusvaroitus). Jos kohdassa on rasti, niin makrovirusvaroitus on päällä!

Excel tai Word 2000:ssa makrovirusvaroitukset on laitettu hieman toiseen kohtaan. Makrovirusvaroitukset on jaettu kolmeen eri tasoon. Alimmalla tasolla makroista ei varoitella. Keskimmäisellä tasolla käyttäjältä kysytään varmistus makrojen sallimiseen. Korkeimmalla tasolla makrojen käyttöönotto riippuu tiedoston lähteen luotettavuudesta. Makroviruvaroitukset löytyvät valinnalla Tools | Macro | Security. Avautuvasta ikkunasta voidaan säätää makrovirusvaroitusten ilmestyminen.

Käyttäjien kommentit

Sampo Kalske ( 2010-10-25 21:20:54 )

Morjens! Yleishyödyllistä tekstiä, kiitos siis jo tähän asti, ja esitänkin lisäkysymyksen: Minulla on Excel taulukossa lista satamia kolumnilla D:D, ja käytän Comboboxia saadakseni k.o. satamat..no..boxiin, mikä ei sinälläänsä ole mikään ongelma vaan se on seuraava: 1. Satamat haluaisin aakkosjärjestykseen comboboxiin (käyttäen siis excelin visual basic ohjelmaa) 2. Tyhjät solut jäisivät pois (eli box ottaa listan alkaen D1:D(end)) eli vain aktiiviset solut Minulle voi myös vastata suoraan sähköpostiin, kiitokset jo etukäteen!

Kommentoi tätä sivua Lisää uusi kommentti
Kurssimateriaalien käyttäminen kaupallisiin tarkoituksiin tai opetusmateriaalina ilman lupaa on ehdottomasti kielletty!
http://appro.mit.jyu.fi/faq/tiedonhallinta/
© Antti Ekonoja (antti.j.ekonoja@jyu.fi) <http://users.jyu.fi/~anjoekon/>
Tommi Lahtonen (tommi.j.lahtonen@jyu.fi) <http://hazor.iki.fi/>
Jukka Mäntylä (jmantyla@iki.fi) <http://www.iki.fi/jmantyla/>
2011-03-24 10:33:54
Informaatioteknologia - Jyväskylän yliopiston informaatioteknologian tiedekunta