Ohjelmassani tein yhden pitkän funktion Private Function funkt(ToEnable As Boolean, strType As String)
jonne laitoin Select Case
n 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 ToEnable
n arvo on False
. Kun sama funktio ajetaan ja ToEnable
n 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.
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.
ByVal
antaa saman virheen.
Voi minua aasia, funktionini onkin Sub (**släps**). Eikä palauta mitään.
Vika on Subin niissä osissa, joita et ole laittanut tänne näkyville. Suoritat jotain virheellistä koodia, kun ToEnable on tosi.
Kokeilin laittaa kursorin sen False
n/True
n 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
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
...
SettingsThe settings for value are:
CheckBox control — 0 is Unchecked (default), 1 is Checked, and 2 is Grayed (dimmed).
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 False
t -> 0 ja True
t -> 1, edelleen sama herja. Kun laitan kursorin ToEnable
n päälle kutsuttani Subbia 1
:n kanssa, tulee ToEnable = True
.
lainaus:
Kokeilin äsken että muutin kaikissa kutsuissa
False
t -> 0 jaTrue
t -> 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.
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
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.
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 ...
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.
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.
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
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.
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.
rautamiekka: tuo -ToEnable kerrottiin kyllä jo samana päivänä, kun aloitit tämän keskustelun :)
Merri kirjoitti:
rautamiekka: tuo -ToEnable kerrottiin kyllä jo samana päivänä, kun aloitit tämän keskustelun :)
Ainakaan en löydä sitä.
rautamiekka kirjoitti:
Ainakaan en löydä sitä
Selaimissa on hakutoiminto, sitä kannattaa hyödyntää.
Blaze kirjoitti:
rautamiekka kirjoitti:
Ainakaan en löydä sitä
Selaimissa on hakutoiminto, sitä kannattaa hyödyntää.
Sepä mukavaa, tuota ei tuossa ollut. Sama se.
rautamiekka kirjoitti:
Sepä mukavaa, tuota ei tuossa ollut.
Kyllä se siinä koko ajan on ollut.
Aihe on jo aika vanha, joten et voi enää vastata siihen.