Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: [VB6] Ohjattu 'True' Boolean-tila aiheuttaa "Invalid property value"

Sivun loppuun

rautamiekka [18.04.2009 10:32:57]

#

Ohjelmassani tein yhden pitkän funktion Private Function funkt(ToEnable As Boolean, strType As String) jonne laitoin Select Casen joka tietyn merkkijonon kohdalla suorittaa satsin automatisoituja komentoja joissa, joko indexiä manipuloidaan For...Next-silmukalla TAI suoraan annettuja numeroita käytetään indexinä, ja ToEnable käytetään muuttamaan kontrollin Boolean-tyyppinen ominaisuus olemaan joko True tai False. Tämä järjestely toimii loistavasti niin kauan kun ToEnablen arvo on False. Kun sama funktio ajetaan ja ToEnablen arvo on True, VB heittää herjan jonka löydätte tredin nimestä. Itse katsoin koodin moneen kertaan läpi lukemalla sitä ja debugtoimalla, ei auta.

Merri [18.04.2009 11:26:20]

#

Muuta funktio siten, että ByVal ToEnable As Boolean – epäilen vielä näillä infoilla että saatat syöttää fuktiota kutsuessa väärää muuttujatyyppiä. Parempi olisi tietysti korjata kutsu, eli syöttää funktioon vain varmasti Boolean-muuttuja. ByVal luo syötettävästä muuttujasta paikallisen kopion funktioon, minkä takia se myös muutetaan tarvittaessa oikeaan muuttujatyyppiin.


Palauttaako funktiosi mitään? Jos ei, silloin olisi parempi määrittää se Subina.

rautamiekka [18.04.2009 11:52:06]

#

ByVal antaa saman virheen.

Voi minua aasia, funktionini onkin Sub (**släps**). Eikä palauta mitään.

Grez [18.04.2009 11:56:13]

#

Vika on Subin niissä osissa, joita et ole laittanut tänne näkyville. Suoritat jotain virheellistä koodia, kun ToEnable on tosi.

rautamiekka [18.04.2009 12:05:41]

#

Kokeilin laittaa kursorin sen Falsen/Truen päälle jonka annan parametreihin, siinä ei tullut False = True tai True = False.

Grez kirjoitti:

Vika on Subin niissä osissa, joita et ole laittanut tänne näkyville. Suoritat jotain virheellistä koodia, kun ToEnable on tosi.

Kävi mielessä että VB ehkä erehtyy luulemaan että ToEnable olisi se Boolean-tila joksi haluisin sen muuttuvan ... Koodit ovat samoja, ota alla oleva esimerkkinä ( jos vain mahdollista, pitäisin softan koodin yksityisenä :/ )

Private Sub funkt(ByVal ToEnable As Boolean, strType As String)
    Select Case strType
        Case "all"
            For i = 0 to 61
                chkBox(i).Value = ToEnable
            Next
    End Select
End Sub

Grez [18.04.2009 12:14:04]

#

Checkboxin value voi olla 0, 1 tai 2. False on 0, joten se kelpaa suoraan.

True on -1, ja koska Checkboxin Value ei voi olla -1, saat virheilmoituksen.

Miten olisi

chkBox(i).Value = Iif(ToEnable,1,0)

VB6 Help kirjoitti:

Value Property
...
Settings

The settings for value are:

CheckBox control — 0 is Unchecked (default), 1 is Checked, and 2 is Grayed (dimmed).

rautamiekka [18.04.2009 12:20:19]

#

Grez kirjoitti:

Checkboxin value voi olla 0 tai 1. False on 0, True on -1. Koska Checkboxin value ei voi olla -1, saat virheilmoituksen.

Miten olisi

chkBox(i).Value = Iif(ToEnable,1,0)

False = 0, True = -1 ? Tuohan sotii kaikkia perussääntöjä vastaan, itse olen oppinut että ohjelmoinnissa Boolean-arvoissa 0/False ovat sama asia, ja 1/True ovat sama asia, eli wtf.

Kokeilin äsken että muutin kaikissa kutsuissa Falset -> 0 ja Truet -> 1, edelleen sama herja. Kun laitan kursorin ToEnablen päälle kutsuttani Subbia 1:n kanssa, tulee ToEnable = True.

Grez [18.04.2009 12:22:44]

#

lainaus:

Kokeilin äsken että muutin kaikissa kutsuissa Falset -> 0 ja Truet -> 1, edelleen sama herja.

Eihän se mitään siellä kutsussa auta, kun castaat sen implisiittisesti Booleaniksi, niin mikä tahansa muu kuin 0 saa arvoksi True (joka taas on -1 jos taas castaat sen luvuksi)

lainaus:

False = 0, True = -1 ? Tuohan sotii kaikkia perussääntöjä vastaan

No mitäs perussääntöjä vastaan se nyt sotii? Ihan normaalisti jos etumerkillisen kokonaisuluvun nollasta komplementin (Not) otat, niin se on -1.

Eli vertaa vaikka:
Not(0)=-1
Not(False)=True

Voit kokeilla ihan käytännössä mitä Truesta tulee luvuksi muutettuna

Dim Luku as Integer
Luku = True
MsgBox(Luku)

Lisäksi se, että True saa arvoksi kaikki bitit päälle helpottaa käyttöä erilaisissa loogisissa operaatioissa.

Esimerkiksi:

Dim Päällä As Boolean
Dim Luku As Long
Dim Tulos As Boolean

Päällä = True
Luku = 6
Tulos = (Luku And Päällä) <> 0

Koska True = -1 Tulokseksi tulee True. Jos True olisi 1, niin tulokseksi tulisi False.

lainaus:

itse olen oppinut että ohjelmoinnissa Boolean-arvoissa 0/False ovat sama asia, ja 1/True ovat sama asia, eli wtf.

Virheelisiäkin asioita voi oppia. Joskus virheellisten käsitysten poisoppiminen on vaikeaa.

Ainoa tilanne, missä True voisi ajatella olevan 1 on, jos Boolean tulkitaan etumerkittömäksi bitiksi. Jos Boolean tulkitaan etumerkilliseksi bitiksi tai miksi tahansa muuksi etumerkilliseksi kokonaisluvuksi, niin silloin se on -1.

VB6:ssa kaikki luvut Byteä lukuunottamatta on etumerkillisiä. Ja bytessä Not(0)=255.

Merri [18.04.2009 12:46:20]

#

Itse asiassa ohjelmointikielet käsittelevät Boolean-arvoja eri tavoin. Muistaakseni REALbasicissa Boolean voi tosiaan olla vain 1 ja 0, eikä se edes ole ainut kieli jossa moista esiintyy.


VB6:n tapauksessa Boolean sallii jonkinmoisia kikkailuja. Yksi tapa on tehdä muuttujatyyppipakottaminen Integeriksi:

chkBox(i).Value = Abs(ToEnable)

Abs() palauttaa True:lle arvon 1.


Voi myös tehdä semmoisia kieroiluja kuin:

chkBox(i).Value = -ToEnable


VB6:n muuttujatyyppien vaihdokset lennossa on niin ihanaa seurattavaa :)

Jos haluaa ehdottomasti välttää muuttujatyyppien muunnokset ja käsittämättömän hitaan IIf:n käytön, että olla mahdollisimman oikeaoppinen oikeiden arvojen käytössä, niin:

If ToEnable Then
    chkBox(i).Value = vbChecked
Else
    chkBox(i).Value = vbUnchecked
End If

Grez [18.04.2009 12:53:13]

#

Merri kirjoitti:

Itse asiassa ohjelmointikielet käsittelevät Boolean-arvoja eri tavoin. Muistaakseni REALbasicissa Boolean voi tosiaan olla vain 1 ja 0, eikä se edes ole ainut kieli jossa moista esiintyy.

Boolean voi ihan luontevasti ollakin 1 kielissä, joissa on käytössä etumerkittömätkin numerot. No, VB6:ssakin on tietysti Byte, joka rikkoo muuten niin kauniin pelkkien etumerkillisten lukujen harmonian.

Varsinkin jos tarjolla on tietotyyppi bit, ja boolean on määritelty olemaan unsigned bit, niin tuosta ei ole mitään epäselvää.

Tarkoitukseni ei ollut missään tapauksessa sanoa, että boolean olisi kaikissa kielissä -1, vaan puhuin puhtaasti VB6:sta.

Merri kirjoitti:

If ToEnable Then
    chkBox(i).Value = vbChecked
Else
    chkBox(i).Value = vbUnchecked
End If

Etuna tässä on varsinkin selkeys siitä, mitä ollaan tekemässä.

Sinänsä nuo vb:n vakioarvot on vähän huonosti toteutettu. Ensinnäkin Value ottaa arvon Integer (vaikka teknisesti se voisi ottaa tuon enumeraattorin VBRUN.CheckBoxConstants) mutta kaiken lisäksi tuolla Valuen helpissä ei edes puhuta halaistua sanaakaan noista vbChecked, vbUnchecked ja vbGrayed arvoista vaan ihan vaan arvoista 0, 1 ja 2.

rautamiekka [18.04.2009 15:11:20]

#

Hohhoh, ohjelmoinnissa ei todellakaan pääse helpolla. Täytynee paiskata nykyinen automatisoitu koodi tekstitiedostoon talteen ja antaa aivojen ajatella omaa tahtiaan ratkaisua ... En nähtävästi ole tarpeeksi pitkälle edistynyt VB6:sessa että pääsisin helpommalla kokonaan kun pääsen vain pienissä osissa ...

rautamiekka [24.04.2009 16:36:05]

#

Noin, softa pelittää nyt kun sillä on (yksitoikkoisen itseääntoistava) suora suoritettava koodi eikä automatisoitu. Harmi, softan koko meinaan nousi 60kt -> 92kt eli ~1.54 -kertaistui.

Merri [24.04.2009 21:16:50]

#

Humm, en muuten katsonut viimeksi threadia lukiessa tarpeeksi tarkasti millaisesta funktiosta oli tarkalleen kyse. En tiedä nytkään tarpeeksi taustoja siitä mitä kaikkea se tekee, mutta pystyn kyllä tarjoamaan "itsekommentoivan" version mallin:

Option Explicit

Private Enum ChecksEnum
    [Check All]
End Enum

Private Sub SetChecks(ByVal Target As ChecksEnum, ByVal Value As CheckBoxConstants)
    If Target = [Check All] Then
        For i = 0 To chkBox.UBound
            chkBox(i).Value = Value
        Next i
    Else
        ' ... en tiedä muista tapauksista mitään ...
    End If
End Sub

Enum mahdollistaa sen, että kirjoitettaessa SetChecks-funktiota saat listan mahdollisista vaihtoehdoista. Samoin CheckBoxConstans antaa listan kelvoista arvoista, joten sekä Target että Value tulevat automaattitäytettyinä. Riittävän kuvaavilla muuttujien ja vakioiden nimillä voi varmistaa sen, että koodilla on suht hyvä luettavuus jo ilman ainuttakaan kommenttia.

Enumiin on mahdollista säätää vaikkapa bittien avulla jonkinlaisia ryhmiä, jotka kukin vaikuttavat tietyllä tavalla. Esim. jos [Check All] on poikkeustapaus joka vaikuttaa kaikkiin, niin sitten bitit 1, 2, 4, 8, 16 jne. voivat kukin sytyttää tietyn ryhmän. Sitten Or-operaattoria käyttäen voi kytkeä useamman ryhmän kerralla, jokaisen Or:n kirjoittamisen jälkeen ilmestyy lista vaihtoehdoista.

Grez [25.04.2009 11:50:05]

#

rautamiekka kirjoitti:

Noin, softa pelittää nyt kun sillä on (yksitoikkoisen itseääntoistava) suora suoritettava koodi eikä automatisoitu. Harmi, softan koko meinaan nousi 60kt -> 92kt eli ~1.54 -kertaistui.

En kyllä yhtään ymmärrä mitä selität. Vaikea uskoa että softan koko olisi muuttunut 60->92 kt vain sen takia että olisit muuttanut:

chkBox(i).Value = ToEnable

muotoon:

chkBox(i).Value = -ToEnable

Metabolix [25.04.2009 11:58:15]

#

Minusta kuulostaa, että kysyjä on nyt ymmärtänyt jotain pahasti väärin ja naputellut satoja ellei jopa tuhansia rivejä turhaa koodia, joka on ennen hoitunut muutamalla silmukalla tai yleistetyllä funktiolla.

rautamiekka [27.04.2009 13:06:43]

#

Grez kirjoitti:

chkBox(i).Value = -ToEnable

Tuon kun olisi keksitty aiemmin. Toistaiseksi toimii ja koodi lyhentyi merkittävästi, kiitos siitä.

Toivon mukaan toivottavasti toimii vastakin eikä päätä taas alkaa v-mittaria nostamaan.

Metabolix kirjoitti:

Minusta kuulostaa, että kysyjä on nyt ymmärtänyt jotain pahasti väärin

En olisi yllättynyt.

Metabolix kirjoitti:

ja naputellut satoja ellei jopa tuhansia rivejä turhaa koodia, joka on ennen hoitunut muutamalla silmukalla tai yleistetyllä funktiolla.

Niinhän olen tehnytkin.

Merri [27.04.2009 15:48:00]

#

rautamiekka: tuo -ToEnable kerrottiin kyllä jo samana päivänä, kun aloitit tämän keskustelun :)

rautamiekka [27.04.2009 15:57:29]

#

Merri kirjoitti:

rautamiekka: tuo -ToEnable kerrottiin kyllä jo samana päivänä, kun aloitit tämän keskustelun :)

Ainakaan en löydä sitä.

Blaze [27.04.2009 16:12:20]

#

rautamiekka kirjoitti:

Ainakaan en löydä sitä

Selaimissa on hakutoiminto, sitä kannattaa hyödyntää.

Merri [18.04.2009 12:46:20]

rautamiekka [27.04.2009 17:01:54]

#

Blaze kirjoitti:

rautamiekka kirjoitti:

Ainakaan en löydä sitä

Selaimissa on hakutoiminto, sitä kannattaa hyödyntää.

Merri [18.04.2009 12:46:20]

Sepä mukavaa, tuota ei tuossa ollut. Sama se.

Grez [27.04.2009 17:18:25]

#

rautamiekka kirjoitti:

Sepä mukavaa, tuota ei tuossa ollut.

Kyllä se siinä koko ajan on ollut.


Sivun alkuun

Vastaus

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

Tietoa sivustosta