Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VBA: Excelin funktio

Sivun loppuun

xr2o4NAusiC2 [16.12.2007 19:24:19]

#

Hei,

Testaan 18-22 välistä puuttuvaa osaa. Tämä koko juttu liittyy aikalaskentaan. Pitäisi saada selville, kuinka paljon on välillä taukoa.

Haluaisin testata solun C10 ja C11 väliä.
Solussa C10 esim. luku 18,75
Solussa C11 esim. luku 21,00.

Alla olevalla funktiolla saan eri tulokset, jos laitan kaavan tarkastamaan solua C10
ja toisen kaavan tarkastamaan solua C11. C10 tulee luku 1,75 ja C11 luku 2.

Jos erotan laskennassa Range("C10") - 18, antaa se oikean tuloksen. Samoin 22 - Range("C11").
Yhdessä ne tekevät eri arvot.

Public Function lisaCase( _
    ByVal lisa As Variant) As Variant
    Dim summa As Variant
 Select Case lisa
     Case Is < 18: summa = 0
     Case 18 To 22: summa = (Range("C10") - 18) + (22 - Range("C11"))
     Case Is > 22: summa = 0
     Case Else: summa = 0
     End Select
 lisaCase = summa

End Function

Minua hämää, että tulokset ovat erisuuret, vaikka mielestäni ne pitäisi olla samat testaa sitten, mitä tahansa solua.

Jos käyn muuttamassa kaavassa viittausta C10 -> C11 tai päinvastoin, antaa se heti oikean tuloksen. F9 uudelleen laskenta ei auta.


t:henkka

(Mod. Edit. Kooditagit.)

groovyb [16.12.2007 23:27:40]

#

miten sä olet määrittänyt tuon lisa:n


missä vaiheessa sä asetat jotain lukua tohon lisa varianttiin?

Public Function lisaCase(ByVal lisa As Variant) As Variant

dim lisa1 as variant
dim lisa2 as variant
dim summa as variant

lisa1 = (range("C10")
lisa2 = (range("C11")

If Lisa1 > 18 And lisa1 < 22 And lisa2 > 18 And lisa 2 < 22 Then
        LisaCase = (Lisa1 - 18) + (22 - lisa2)

End Function

En nyt tiedä ihan tarkkaan mitä haluat mutta tuon lisa:n määrityksen haluan tietää mitä select casella kattelet.

xr2o4NAusiC2 [17.12.2007 08:24:01]

#

Kiitos vastauksesta.

Pienellä muokkauksella sain tuon toimimaan.

Edelleenkin sama vika. Nyt testasin kumpaakin funktiota, niin tulos oli kummankin solussa identtinen. C10 ja C11 antoivat saman arvon, tuli se Case:n tai If:n kautta.

Se tässä on hauskinta, että en ymmärrä nykyisestä VBA:sta paljoakaan. Olen kirjoitellut 20 vuotta sitten pelkällä Basic –kielellä muutamia ohjelmia. Enää ei ole sekään hallussa.

Tämän olen kopioinut ihan muusta esimerkistä omaan tarpeeseeni.

t:henkka

neau33 [17.12.2007 10:19:14]

#

Moikka henkka!

Kyse on muuttujatyyppien määrittelyistä - suosittelisin välttämään Variant-tyypin käyttämistä suoraan laskemisessa. Tsekkaa täältä putkan sivuilta: Oppaat -> Visual Basic -opas -> Osa 3 - Muuttujat ja taulukot -> Muuttujatyypit...
hoitaisin jutskan kuitenkin excelissä ilman erillistä funktiota seuraavasti...

Private Sub CommandButton1_Click()
If Range("C9").Value >= 18 And Range("C9").Value <= 22 Then
'* tai esim...
' If Range("C9").Value >= Range("B10").Value And _
' Range("C9").Value <= Range("B11").Value Then

  'jos vaikka kaava palauttaisi negatiivisen luvun...
   'Abs - absoluuttinen arvo...
  Range("C12").Value = _
  Abs((Range("C10").Value - 18) + (22 - Range("C11").Value))
  '*tai esim...
  ' Range("C12").Value = _
   Abs((Range("C10").Value - Range("B10").Value ) + _
  (Range("B11").Value  - Range("C11").Value))
Else
  Range("C12").Value = Empty
End If
End Sub

xr2o4NAusiC2 [17.12.2007 14:06:08]

#

Kiitos Nea vastauksesta.

Kiitos jälleen vinkistä. Komentopainikkeella ei oikein voi testata kyseistä kohtaa.

Työkirjoja on yhteensä 16, josta 14 laskee yhden päivän työtä. Kyseisessä laskennassa tulee eri kelloajoilla erinäisiä lisiä. Taulukkoon syötetään alku-, ja lopetusaika sen jälkeen se laskee niiden mukaan kaikki tunnit ja lisät erilliseen yhteenvetotaulukkoon.

Homman olen hoitanut useammalla IF –funktiolla, josta sitten olen Hakufunktiota käyttäen hakenut oikea arvon. Toistaiseksi se on toiminut riittävän hyvin.

Luettuani vähän Excelin makroista huomasin, että voin käyttää CASE –lausetta, joka tuntuu yksinkertaisemmalta kuin tuo IF –lause. Innokkaana entisajan koodinkirjoittajana halusin tehdä testauksen omasta mielestäni helpommaksi.

Koodi toimii oikein, kun sitä testaa. Se huomaa rajakohdat hyvin, mutta sen jälkeinen laskenta ei toimi. Jos lasken solun 22-C11 ja C10-18 erikseen ne antavat oikean tuloksen. Aikaisemmin mainitsemani uudelleen funktion haku tuottaa oikean tuloksen, mutta ei edes uudelleen laskenta sitä tee.

Muuttujista ja niiden esittelyistä ei minulla vielä tässä vaiheessa ole kunnon käsitystä, jotta osaisin niitä kommentoida. Ainoastaan hyvä kopiointitaito:-).

Rajakohdat ovat 18 – 22 ja 22 – 6.

t:henkka

neau33 [17.12.2007 18:18:25]

#

Moikka taas henkka!

'pikku terapiaa...

ekakas: sun funktios:
Public Function lisaCase(ByVal lisa As Variant) As Variant
pläjäyttää sille syötetyn arvon joka kerta variant tyyppiin, jota tyyppiä ei kannata (kuten jo edellä mainitsin) käytellä laskennassa VARSINKAAN JOS KÄYTELLÄÄN LIUKULUKUJA...

tokaks:

'Molemmat rakennelmat suorittavat tismalleen saman vertailun...
 If Range("C9").Value >= 18 And Range("C9").Value <= 22 Then
   'plaa plaa plaa...
 Else: 'plaa plaa...
 End if

 Select case Range("C9").Value
   Case Is >= 18 'ekan raja-arvon vertailu
     Select case Range("C9").Value
       Case Is <= 22 'tokan raja-arvon vertailu
         MsgBox "muuttuiko tehokkaammaksi vai yksinkertaisemmaksi?"
       Case Else: 'plaa plaa plaa...
     End Select
   Case Else: 'plaa plaa...
 End Select

xr2o4NAusiC2 [17.12.2007 19:52:08]

#

Moikka Nea!

Terapiassa ollaan oltu. Hyvä on uskon tuon If – Then – Else -lauseen olevan yksinkertaisempi. Kaiken lisäksi se siirtää oikean arvon soluun C12:sta.

Kerro miten päästään eroon siitä komentopainikkeesta. Laskennan pitäisi olla automaattista, jos aikoja muutetaan muuttuu arvot samalla.

Nyt joudun työterapiaan muutamaksi päiväksi, joten en voi niin tiiviisti seurata asiaa.

t:henkka

neau33 [17.12.2007 21:21:59]

#

Moikka taas henkka!

jos nyt sit vaikka näin...

ilman funktiota:

'ThisWorkbook
Private Sub Workbook_SheetSelectionChange(ByVal _
Sh As Object, ByVal Target As Range)
  If Range("C9").Value >= 18 And _
  Range("C9").Value <= 22 Then
    Range("C12").Value = _
    Abs((Range("C10").Value - 18) + _
    (22 - Range("C11").Value))
  Else: Range("C12") = Empty
  End If
End Sub

funktiolla

  'ThisWorkbook
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, _
ByVal Target As Range)
   Range("C12").Value = lisaCase(Range("C9").Value) 'esim.
End Sub

'Moduuli
Public Function lisaCase(ByVal lisa As Double) As Double
  Dim summa As Double
  If lisa >= 18 And lisa <= 22 Then
    summa = _
    Abs((Range("C10").Value - 18) + _
    (22 - Range("C11").Value))
  Else: summa = 0
  End If
  lisaCase = summa
End Function

Sivun alkuun

Vastaus

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

Tietoa sivustosta