Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VBA: VB ja tietojen lukeminen excel-taulukosta

Otto Chorin [04.06.2009 10:02:30]

#

Haluaisin lukea VB:llä excel-tiedoston (tai jonkin muun vastaavankaltaisen tiedostotyypin) sisällön taulukkomuuttujaksi.. mahdollisimman toimintavarmasti ja mielellään jollakin sellaisella tavalla joka ei vaatisi, että excel on asennettu. Miten tämä onnistuisi?

Tiedosto sisältää siis sekä tekstiä(muuttujien nimet) että numeerisia arvoja.

Tämä vaikuttaa tyypillseltä ongelmalta, mutta vastauksen löytäminen on osoittautunut yllättävän hankalaksi.

neau33 [04.06.2009 13:00:22]

#

NO MOI Otto Chorin!

Kaikki onnistuu (käy) kun on sokeria, hivaa ja vettä...mutta varmaa on, että aivan ensimmäisellä yrittämällä et onnistu poimimaan VB:llä suoraan .xls -tiedostosta muutujien tyyppejä/arvoja yhteenkään taulukkoon, varsinkaan jos Excel ei ole asennettuna systeemiisi!!!

Mutta jos OFFICE & EXCEL ovat sinulle läpikotaisin tuttuja ja olet muutenkin todella hyvin perillä ohjelmoinnista niin voit impata Microsoft Office Database Engine (2007) -paketin täältä ja alkaa operoimaan OFFICE-kamaa ilman, että järjestelmään on asennettu OFFICEa tai EXCELiä...

Mikäli taas tykkäät operoida .NET ympäristössä niin voit käyttää hyväksesi vaikkapa OFFICE 2007 PIAs -paketin suomia mahdollisuuksia...

No himan helpotusta...

a) Mikäli Excel-tiedosto on tallennettu CSV-muodossa voidaan se lukean VB:llä, kuten mikä tahansa tekstitiedosto, jolloin varsinaisen taulukon ulottuvuudet saadaan määriteltyä helposti lukemalla ko. CSV-tiedosto sellaisenaan merkijonomuuttujaan...rivimäärä saadaan splitataamaalla merkkijono taulukoksi käyttäen erottimena rivinvaihtoa (=taulukon alkioiden määrä)
Sarakemäärä saadaan taas selville splittaamalla esim. em. splitatun taulukon ensimmäisen alkion merkkijo toiseen taulukkoon käyttäen erottimena puolipistettä
(=toisen taulukon alkioiden määrä)...sitten määritellään uusi, vaikkapa variant-tyyppinen taulukko, johon luetaan kaksiulotteisessa luupissa splitattujen rivien splitatut sarakearvot...ja sen jälkeen vaikkapa tuhotaan kaden ensimmäisen splittauksen tuloksena syntyneet taulukot ja sitä rataa...

b) Toinen tapa on tallentaa Excel-työkirja XML-muodossa, jolloin homma on periaatteessa aivan yhtä helppoa, mikäli vain XML-rakenteen käsittely sujuu jokseenkin jouhevasti...

Lopuksi: Sanoisimpa, ettei ongelmasi ole ehkä ihan niitä kaikkein tyypillisimpiä...

Otto Chorin [04.06.2009 13:29:08]

#

Kiitos vastauksestasi, Nea..

Jotenkin kuvittelin, että numeerisen datan lukeminen tiedostosta olisi tyypillinen (alku)vaihe hyvin monessa ohjelmassa..

Olen vastikään aloittanut tutustumisen VB-ohjelmointiin. Tulin itsekin ajatelleeksi että CSV-tyyppinen tiedosto voisi olla soveltuva tiedostotyyppi syötteen säilyttämiseen, mutta en vielä löytänyt kovin hyviä ohjeita sellaistenkaan lukemiseen.

Otto Chorin [04.06.2009 17:53:23]

#

Kertokaahan.. mitä tapahtuu jos vb-projektiin upotetaan OLE-objektina excel-työkirja? Tarvitseeko sovellus käännettynä sitten excelin? Oletan että tarvitsee.

Grez [04.06.2009 18:09:37]

#

Juu tarvitsee.

neau33 [04.06.2009 18:30:45]

#

Moi taas Otto Chorin!

oheisesta esimerkistä löydät hieman osviittaa...

Private Sub Command1_Click()

   ' alustetaan 4 merkkijonomuuttujaa
   Dim polku As String
   Dim tiedosto As String
   Dim kokopolku As String
   Dim sisalto As String

   ' annetaan em. muuttujille tekstiarvot
   polku = Environ("userprofile") & "\Työpöytä"
   tiedosto = "taulukko.csv"
   '(.csv-muodossa tallennettu Excel-taulukko)

   kokopolku = polku & "\" & tiedosto

   ' tutkitaan löytyykö tiedosto...
   If Dir(kokopolku) <> "" Then
      ' ...jos löytyy avataan lukutilassa...
      Open kokopolku For Input As #1
      ' luetaan tiedoston koko sisältö kerralla
      ' ja tallennetaan merkkijonomuuttujaan...
      sisalto = Input$(LOF(1), 1)
      'ja suljetaan tiedosto
      Close #1
   Else
      ' muutoin (jos tiedostoa ei löydy)
      ' ilmoitetaan asiasta viesti-ikkunassa
      MsgBox "Tiedostoa " & kokopolku & " ei löydy!"
      ' ja poistutaan aliohjelmasta.
      Exit Sub
   End If

   ' tutkitaan muodostaako tiedostosta luetun
   ' merkkijonon kaksi viimeistä merkkiä rivinvaihdon
   If Right(sisalto, 2) = vbCrLf Then
      ' jos muodostaa, poistetaan merkkijonon
      ' kaksi viimeistä merkkiä.
      sisalto = Left(sisalto, Len(sisalto) - 2)
   End If

   ' alustetaan kaksi 2 merkkijonotyyppistä
   ' taulukkomuuttujaa sekä 2 kokonaislukumuuttujaa
   Dim apu() As String
   Dim apu2() As String
   Dim rivit As Integer
   Dim sarakkeet As Integer

   ' erotellaan merkkijonomuuttujan tekstiarvo
   ' taulukkomuuttujan alkioiksi käyttäen
   ' erottimena rivinvaihtomerkkiä
   apu = Split(sisalto, vbCrLf)

   ' annetaan kokonaislukumuuttujan arvoksi
   ' aputaulukon ylimmän indeksin ulottuvuus
   rivit = UBound(apu)

   ' erotellaan aputaulukon ensimmäisen indeksin
   ' sisältö toisen aputaulukon alkioiksi käyttäen
   ' erottimena puolipistettä...
   apu2 = Split(apu(0), ";")

   ' ja annetaan toisen kokonaislukumuuttujan
   ' arvoksi toisen aputaulukon ylimmän indeksin
   ' ulottuvuus
   sarakkeet = UBound(apu2)

   ' nollataan toinen aputaulukoista...
   Erase apu2

   ' alustetaan varsinainen taulukko
   ' ja asetetaan ulottuvuuksiksi edellä
   ' märiteltyjen kokonaislukumuuttujien arvot
   ReDim taulukko(sarakkeet, rivit) As Variant

   ' erotellaan ulommassa silmukassa
   ' kulloisellakin kierroksella...
   For i = 0 To rivit
      ' toisen (nollattuun) aputaulukon alkioiksi
      ' ensimmäisestä aputaulukosta, laskuriarvon
      ' osoittaman alkio-indeksin tekstiarvo
      ' käyttäen erottimena puolipistettä...
      apu2 = Split(apu(i), ";")
      For j = 0 To sarakkeet
         ' ja sijoitetaan toisen aputaulukon,
         ' sisemmän silmukan laskuriarvon määräämän
         ' indeksin tekstiarvo varsianaisen taulukon
         ' sekä sisemmän että ulomman laskurin arvon
         ' määräämän alkio-indeksin arvoksi...
         ' (* Koska varsinainen taulukko on määritelty
         ' variant tyyppiseksi voidaan taulukkoon sijoitta
         ' sekä numeerista että ei-numeerista dataa
         ' *** Tutkitaan...
         ' onko toisen aputaulukon kulloisenkin alkion
         ' arvo tekstiä vaiko numeerista tietoa...)
         If Not IsNull(apu2(j)) Then
            'Dim IsNotNum As Boolean

            'For k = 1 To Len(CStr(apu2(j)))
               'If Not IsNumeric(Mid(CStr(apu2(j)), k, 1)) Then
                  'IsNotNum = True: Exit For
               'End If
            'Next k

            'If NotIsNum Then
               taulukko(j, i) = apu2(j)
            'Else
               'taulukko(j, i) = CLng(Val(apu2(j)))
            'End If '***
         End If
      Next j
      ' nollataan toinen aputaulukko
      ' (ulomman silmukan jokaisella kierroksella)
      Erase apu2
   Next i

   'Testataan taulukon sisältö...
   For i = 0 To rivit
      For j = 0 To sarakkeet
         If Not IsNull(taulukko(j, i)) Then
            MsgBox taulukko(j, i)
         End If
      Next j
   Next i

End Sub

neau33 [04.06.2009 19:45:57]

#

Moi taas Otto Chorin!

voit myös testata taulukon sisältöä muuttamalla edellisen esimerkin loppuosan koodin
seuraavaanlaiseksi...

'...

'Testataan taulukon sisältö...

   Erase apu: tiedosto = "taulukko2.csv"
   kokopolku = polku & "\" & tiedosto
   merkkijono = ""

   For i = 0 To rivit
      For j = 0 To sarakkeet
         If Not IsNull(taulukko(j, i)) Then
            merkkijono = merkkijono & CStr(taulukko(j, i))
         End If
         If j < sarakkeet Then
            merkkijono = merkkijono + ";"
         Else
            merkkijono = merkkijono & vbCrLf
         End If
        Next j
    Next i

    If merkkijono <> "" Then
       Open kokopolku For Output As #1
       Print #1, merkkijono: Close #1
    End If

End Sub

ja avaamalla luodun tiedoston Excelillä...

-Nea

Vastaus

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

Tietoa sivustosta