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.
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ä...
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.
Kertokaahan.. mitä tapahtuu jos vb-projektiin upotetaan OLE-objektina excel-työkirja? Tarvitseeko sovellus käännettynä sitten excelin? Oletan että tarvitsee.
Juu tarvitsee.
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 SubMoi 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 Subja avaamalla luodun tiedoston Excelillä...
-Nea
Aihe on jo aika vanha, joten et voi enää vastata siihen.