Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6 + Excel (VBA)

Extreme [31.08.2006 09:50:32]

#

Moi!

Minulla on excel tiedosto muodossa:

1 | Date | User |
2 |01.08.2006 | pekka |
3 |01.08.2006 | jouni |
4 |02.08.2006 | ville |


Mikä olisi helpoin tapa lukea VB6:ssa kuinka monta eri useria on merkitty kullekki päivälle?

-hannu-

BadSource [31.08.2006 13:19:34]

#

Jos tiedostosi on oikea excel-tiedosto (.xls), niin sovella seuraavaa.

Formilla siis yksi Command-nappula. Lisäksi joudut lisäämään projektiisi instanssin Exceliin, eli Project->References...->Microsoft Excel x.0 Object Library, jossa x viittaa käyttämääsi Excel-versioon.

Option Explicit

Private Sub Command1_Click()
    Dim objExcel As Object
    Dim objWorkbook As Excel.Workbook
    Dim solu As Excel.Range
    Dim ala As Excel.Range
    Dim osa As Excel.Range
    Dim path As String
    Dim osat() As String
    Dim pvm() As String
    Dim i As Integer

    'alustetaan taulukkomuuttuja
    ReDim pvm(1, 0)
    'määritetään polku tiedostomme luo
    path = "C:\Documents and Settings\bad\My Documents\Test.xls"
    'luodaan excel-muuttuja, jonka kautta kaikki loput exceliin viittaavat muuttujat luodaan
    Set objExcel = CreateObject("EXCEL.APPLICATION")
    'avataan haluamamme excel-tiedosto
    Set objWorkbook = objExcel.Workbooks.Open(path)
    'etsitään tiedostosta kaikki solut, joissa on arvo/tietoa
    Set ala = objWorkbook.Sheets(1).Cells.SpecialCells(xlCellTypeConstants, 23)
    'jos ala sisältää useita erillisiä alueita sivulla,
    'niin ne on eroteltu pilkulla Address:ssa.
    'jos pilkkua ei ole (pelkästään yksi alue),
    'niin osat saa arvokseen tuon Addressin arvon sellaisenaan
    osat = Split(Replace(ala.Address, "$", ""), ",")
    'käydään osat läpi osa kerrallaan
    For i = 0 To UBound(osat)
        Set osa = Excel.Range(osat(i))
        'tarkistetaan osan solut eksi kerrallaan että sisältääkö se päivämäärää
        For Each solu In osa
            If IsDate(solu.Value) Then
                'päivämäärä löytyi, joten tarkistetaan,
                'onko pvm-taulukossa ennestään arvoa viimeisimmässä solussa.
                'jos viimeisin on varattu, niin lisätään taulukkoon lisää tilaa
                If LenB(pvm(0, UBound(pvm, 2))) > 0 Then _
                  ReDim Preserve pvm(1, UBound(pvm, 2) + 1)
                'otetaan talteen päivämäärän sisältäneen solun arvo
                pvm(0, UBound(pvm, 2)) = solu.Value
                'otetaan päivämäärää seuraavasta sarakkeesta talteen arvo
                pvm(1, UBound(pvm, 2)) = solu.Offset(0, 1).Value
            End If
        Next solu
    Next i
    'suljetaan avaamamme excel-tiedosto.
    'False vastaa kysymykseen "Tallennetaanko muutokset?", jos sellaista kysyttäisiin
    objWorkbook.Close False
    'tulostetaan pvm-taulukon arvot Immediate-ikkunaan VB:n puolella
    For i = 0 To UBound(pvm, 2)
        Debug.Print pvm(0, i) & ": " & pvm(1, i)
    Next i
    ' Vapautetaan muuttujien varaama muisti
    Set solu = Nothing
    Set osa = Nothing
    Set ala = Nothing
    Set objWorkbook = Nothing
    Set objExcel = Nothing
End Sub

Extreme [31.08.2006 14:28:09]

#

Kiitän ja kumarran. Eteenpäin päästiin roimasti.

Kuinka pystyn laskemaan keskiarvon että montako nimeä on kullekkin päivää? Vinkkiä?

Eli jos 01.08.2006 on vaikka 10 eri nimeä ja 02.08.2006 on 4 eri nimeä.
Noiden keskiarvo pitäisi saada selville.

BadSource [31.08.2006 14:42:31]

#

Eikö tuo nyt ole normaalin keskiarvon laskeminen, eli 14 nimeä jaetaan kahdella päivällä?

Extreme [31.08.2006 15:01:23]

#

BadSource kirjoitti:

Eikö tuo nyt ole normaalin keskiarvon laskeminen, eli 14 nimeä jaetaan kahdella päivällä?

On on :) Mutta siinä päivämääriä on 1,5v ajalta. Kyllä minä laskimella osaan laskea mutta en vb:llä :D

BadSource [31.08.2006 15:29:17]

#

Jos nyt otetaan esimerkiksi tuo edellä oleva koodini, niin tuossa välissä, jossa löytynyt arvo viedään taulukkoon samoin kuin sitä seuraavan sarakkeen arvo, niin korjataan tuota niin, että tarkistetaan onko löytynyt päivämäärä jo lisätty taulukkoon. Jos on, niin kasvatetaan vain pvm(1, UBound(pvm, 2)):n arvoa yhdellä. Jos päivämäärää ei löydy, niin lisätään se kantaan ja tuo edellä mainittu saa arvon 1.

Kun koko taulukko on käyty läpi, niin muutetaan tuo lopun tulostusrutiini laskemaan keskiarvo.

Dim Summa As Long
Dim KKarvo As Single 'muutama desimaali mukaan...

For i = 0 To UBound(pvm, 2)
    Summa = Summa + CLng(pvm(1, i))
Next i
KKarvo = Round(Summa / Ubound(pvm, 2), 2) 'pyöristetään kahden desimaalin tarkkuuteen

Vastaus

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

Tietoa sivustosta