IIf on kätevähkö toiminto VB:ssä, antaen näppärän yhden rivin syntaksin yksinkertaisille if-lausekkeille. Ongelma on siinä, että se on aivan järkyttävän hidas: sitä ei yksinkertaisesti kannata käyttää missään runsaasti suoritettavassa koodissa.
IIfillä on kaksi selvää ongelmaa: ensinnäkin se käyttää Variant-muuttujatyyppiä. Tämä on "älykäs" ja helppokäyttöinen, mutta samalla järkyttävän hidas muuttujatyyppi.
Toinen ongelma on siinä, että IIf suorittaa molemmat sille annetut lausekkeet, sekä tosi-, että etätosilausekkeen. Alla tästä esimerkki:
Debug.Print IIf(True, MsgBox("Terve!", vbRetryCancel), MsgBox("Näinhän tämä käy.", vbYesNo))
Kun suoritat koodin, huomaat että näet kaksi viestilaatikkoa ja debuggeriin palautuva arvo riippuu siitä, kumpaa nappulaa painoit ensimmäisessä viestilaatikossa. IIf on yksinkertaisesti tavanomainen funktio ja toimii tavanomaisen funktion tapaan; mutta on vielä sitäkin järkyttävästi hitaampi.
Viisaimmat taisivat jo hoksata miten ongelman voi ratkaista: luomalla oman funktion. Siispä olen alle listannut muutaman valmiin funktion ja kukin voi tehdä tarpeidensa mukaan sopivia muuttujatyyppejä itselleen, vaiva on äärimmäisen vähäinen.
Nopeusmittauksissa IIf suoriutui kymmenestä miljoonasta kutsusta reilussa kahdessa ja puolessa sekunnissa (2500 ms). Vastaavasti IfLng selviytyi vastaavasta urakasta kuudessa kymmenessä millisekunnissa (60 ms)! Ero on järkyttävä. Jopa IfVar selviytyi samasta taakasta noin sekunnissa, vaikka on toimintalogiikaltaan täysin yhteensopiva IIf:n kanssa.
Lopputulos: IIf on täysin käyttökelvoton, omalla koodilla selviää samasta tehtävästä paljon nopeammin.
Lisäksi monimutkaisia laskutehtäviä ei kannata antaa IIf:lle, vaan pysyttäytyä erittäin yksinkertaisissa laskuissa tai vain syöttää etukäteen laskettuja/määritettyjä arvoja.
Public Function IfByte(ByVal Expression As Boolean, ByVal TruePart As Byte, ByVal FalsePart As Byte) As Byte If Expression Then IfByte = TruePart Else IfByte = FalsePart End Function Public Function IfInt(ByVal Expression As Boolean, ByVal TruePart As Integer, ByVal FalsePart As Integer) As Integer If Expression Then IfInt = TruePart Else IfInt = FalsePart End Function Public Function IfLng(ByVal Expression As Boolean, ByVal TruePart As Long, ByVal FalsePart As Long) As Long If Expression Then IfLng = TruePart Else IfLng = FalsePart End Function Public Function IfVar(ByVal Expression As Boolean, ByVal TruePart As Variant, ByVal FalsePart As Variant) As Variant If Expression Then IfVar = TruePart Else IfVar = FalsePart End Function
Ai, VB:ssä on tollanenki funkkari. Oppia ikä kaikki. Tosin tämän opin joutuu samantien unohtamaan :P
Että tämmösiä...
Eikös se ole .NET?
Tarkoitatko että löytyisi vain .NETistä? Kyllä tämä ihan VB6:sta löytyy.
VB.Netissä (2008 alkaen) voi käyttää ternary-operaattoriakin joka on kuten Iif mutta yhdellä I:llä, jolloin ei tule hitausongelmaa eikä myöskään tämän purkkaratkaisun ongelmaa, että molemmat arvot yhä lasketaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.