/ Forside / Teknologi / Udvikling / VB/Basic / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
VB/Basic
#NavnPoint
berpox 2425
pete 1435
CADmageren 1251
gibson 1230
Phylock 887
gandalf 836
AntonV 790
strarup 750
Benjamin... 700
10  tom.kise 610
Hvad gør jeg galt?!
Fra : Mathias


Dato : 20-10-03 15:57

Hej NG.

Hvad gør jeg galt?
Jeg har en ComboBox cmbRunBox, og menupunktet mnuKoer.
I kender vel ShellEx (starter et program / en fil), og AddToINI og
GetFromINI henter fra og skriver til en INI.
Jeg har denne kode:

Private Sub mnuKoer_Click()
Dim Generate As Boolean
Dim INIFile As String
INIFile = "C:\MPIPrgs.ini"

ShellEx cmbRunBox.Text, , , , , Me.hWnd
Generate = False
For Count2 = 0 To cmbRunBox.ListCount
If cmbRunBox.Text = cmbRunBox.List(Count2) Then
Generate = True
Exit For
End If
Next
If Generate = True Then
AddToINI "RunList", "Run" & (GetFromINI("RunList", "RunCount", "0",
INIFile) + 1), cmbRunBox.Text, INIFile
End If
End Sub

.... som burde, når man skriver noget som ikke er i comboboxen, lægge det
til INIen så den loader Run1, Run2, Run3 osv. fra INIen ved næste load
af programmet. Jeg har lagt koden til at loade fra INIen ind (og dén
kode virker i det mindste), men hvad gør jeg galt? Download mit project:
http://mathiasside.users.whitehat.dk/vb/INITest.zip

Hilsen Mathias

 
 
Tomas Christiansen (21-10-2003)
Kommentar
Fra : Tomas Christiansen


Dato : 21-10-03 22:18

Mathias skrev:
> Hvad gør jeg galt?

Det er svært at svare på. Du skriver jo rent faktisk ikke rigtig hvad der
(efter din mening) går galt.

Jeg har dog et par bud:

> For Count2 = 0 To cmbRunBox.ListCount
> If cmbRunBox.Text = cmbRunBox.List(Count2) Then

Du kan ikke cmbRunBox.List(Count2) når Count2 er lig cmbRunBox.ListCount !
Værdien cmbRunBox.ListCount er hvor mange elementer du har ialt i din liste,
og når du itererer fra 0 til cmbRunBox.ListCount, itererer du altså over
ialt cmbRunBox.ListCount + 1 elementer (ét element MERE end der er i
listen).

> If Generate = True Then

Blot en kommentar: ((((((Generate) = True) = True) = True) = True) = True) =
....

En anden kommentar: Din kode er temmelig svær at læse!
Gør dig selv den tjeneste at rykke ind i forbindelse med
procedurer/funktioner, If-sætning, løkker (Do...Loop, While...Wend,
Loop..Until og hvad de nu ellers hedder).

En sidste ting: Det projekt som du har liggende til download, indeholder
ikke den kode, som du har citeret i dit indlæg. Helt specifikt indeholder
proceduren mnuKoer_Click følgende:

Private Sub mnuKoer_Click()
Shell cmbRunBox.Text
End Sub

Hvor vil anbefale dig at rykke ind "inde" i proceduren. Jeg bruger altid en
indrykning på 2 spaces og ikke 4 som er standard i VB, idet det efter min
mening er fuldt ud læseligt med 2 spaces:

Private Sub mnuKoer_Click()
Shell cmbRunBox.Text
End Sub

-------
Tomas


Mathias (23-10-2003)
Kommentar
Fra : Mathias


Dato : 23-10-03 15:38

"Tomas Christiansen" <toc-01-nospam@blikroer.dk> wrote in
news:bn47pt$2vvt$1@news.cybercity.dk:

> Mathias skrev:
>> Hvad gør jeg galt?
Det skulle jeg nok have skrevet nederst...
>
> Det er svært at svare på. Du skriver jo rent faktisk ikke rigtig hvad
> der (efter din mening) går galt.
>
> Jeg har dog et par bud:
>
>> For Count2 = 0 To cmbRunBox.ListCount
>> If cmbRunBox.Text = cmbRunBox.List(Count2) Then
>
> Du kan ikke cmbRunBox.List(Count2) når Count2 er lig
> cmbRunBox.ListCount ! Værdien cmbRunBox.ListCount er hvor mange
> elementer du har ialt i din liste, og når du itererer fra 0 til
> cmbRunBox.ListCount, itererer du altså over ialt cmbRunBox.ListCount +
> 1 elementer (ét element MERE end der er i listen).
Ok. Dvs. hvis jeg har List(0) To List(2) i en listbox, så er ListCount
ikke 2 men 3 (Med Base 1 i ListCount, og Base 0 i List)
>
>> If Generate = True Then
>
> Blot en kommentar: ((((((Generate) = True) = True) = True) = True) =
> True) = ...
Ehhm, hvad mener du?
>
> En anden kommentar: Din kode er temmelig svær at læse!
> Gør dig selv den tjeneste at rykke ind i forbindelse med
> procedurer/funktioner, If-sætning, løkker (Do...Loop, While...Wend,
> Loop..Until og hvad de nu ellers hedder).
Det skal jeg nok huske ;)
>
> En sidste ting: Det projekt som du har liggende til download,
> indeholder ikke den kode, som du har citeret i dit indlæg. Helt
> specifikt indeholder proceduren mnuKoer_Click følgende:
>
> Private Sub mnuKoer_Click()
> Shell cmbRunBox.Text
> End Sub
Jeg havde prøvet at flytte koden ind under den samme procedure, for at
mit indlæg fyldte mindre. Det havde jeg bare glemt at sige ;)
>
> Hvor vil anbefale dig at rykke ind "inde" i proceduren. Jeg bruger
> altid en indrykning på 2 spaces og ikke 4 som er standard i VB, idet
> det efter min mening er fuldt ud læseligt med 2 spaces:
>
> Private Sub mnuKoer_Click()
> Shell cmbRunBox.Text
> End Sub
Skal jeg nok huske :D
>
> -------
> Tomas
>
>

Tak for svaret.
--
Mathias

Tomas Christiansen (23-10-2003)
Kommentar
Fra : Tomas Christiansen


Dato : 23-10-03 21:22

Mathias skrev:
> Ok. Dvs. hvis jeg har List(0) To List(2) i en listbox, så er ListCount
> ikke 2 men 3 (Med Base 1 i ListCount, og Base 0 i List)

Hvis du har syv køer er der syv, uanset om du tæller fra 0 til 6 eller om du
tæller fra 1 til 7 (eller om du starter med -37 for den sags skyld).
Det samme gør sig gældende for gulerødder.
Et _antal_ (som f.eks. ListCount) er _ikke_ baseret en base-værdi.

Derimod kan et indeks (som f.eks. List(X)) i MS's verden, være 0-baseret
eller 1-baseret.
Hvis det er 0-baseret, tæller man altså fra 0 til antal minus 1, og hvis det
er 1-baseret, tæller man fra 1 til antal.


> >> If Generate = True Then
> >
> > Blot en kommentar: ((((((Generate) = True) = True) = True) = True) =
> > True) = ...
> Ehhm, hvad mener du?

Jeg mener at når du spørger på om på om en variabel har værdien True, bliver
resultatet den samme værdi som variablen har.

Med andre ord er:
If Generate Then
det samme som:
If Generate = True Then
igen det samme som:
If (Generate = True) = True Then
osv. osv. osv.

Det forvirrer (efter min mening) begreberne, hvis man begynder at foretage
én eller anden form for beregning på en variabel, og resultatet af
beregningen altid giver NØJAGTIG samme værdi som værdien der er i variablen!

> Tak for svaret.

Selv tak. Håber at det var løsningen på dit problem!

-------
Tomas


Jens Vestergaard (23-10-2003)
Kommentar
Fra : Jens Vestergaard


Dato : 23-10-03 21:47

"Tomas Christiansen" <toc-01-nospam@blikroer.dk> skrev i en meddelelse
news:bn9d7d$21g2$1@news.cybercity.dk...
> Med andre ord er:
> If Generate Then
> det samme som:
> If Generate = True Then
> igen det samme som:
> If (Generate = True) = True Then
> osv. osv. osv.
>
> Det forvirrer (efter min mening) begreberne, hvis man begynder at foretage
> én eller anden form for beregning på en variabel, og resultatet af
> beregningen altid giver NØJAGTIG samme værdi som værdien der er i
variablen!

Du har naturligvis teknisk set ret, men er det ikke lettere læseligt at
medtage = True? Især, hvis man - som spørgeren - *ikke* prefixer sine
variabler...

Sub EtEllerAndet( x as variant, y as variant)
Dim a as Integer
Dim b as boolean
a = 2 * x
b = y = 10
If a And b Then
'...
End If
End Sub

.... så synes jeg, at
If (a <> 0) And (b = True) Then
.... er mere 'læseligt', bl.a. fordi det angiver (antyder) datatypen på de
ikke særligt heldigt deklarede variabler. Men sådan er der jo nu engang en
del, der bruger variabelnavne...


--
mvh
Jens Vestergaard (mailadr i dette indlæg er ikke gyldig!)
www.railsoft.dk
Døgnets jernbanenyheder: www.railsoft.dk/medier.asp




Tomas Christiansen (23-10-2003)
Kommentar
Fra : Tomas Christiansen


Dato : 23-10-03 22:36

Jens Vestergaard skrev:
> Du har naturligvis teknisk set ret, men er det ikke lettere læseligt at
> medtage = True? Især, hvis man - som spørgeren - *ikke* prefixer sine
> variabler...
....
> If (a <> 0) And (b = True) Then

Nej., jeg vil klart foretrække formen:

If a <> 0 And b Then

Jeg ville aldrig nogensinde basere mig på at en værdi i én eller anden form
for heltalsvariabel tilfældigvis ville kunne opfattes som en
sand/falsk-værdi, idet man så lige pludselig bliver afhængig af at alle
fremtidige versioner altid vil benytte det samme værdisæt til henholdsvis
sand og falsk (i VB 6 er det 0 => falsk og alt-andet => sand).

Med andre ord vil du aldrig se:

If a And b Then

i mine programmer, men gerne en linie som:

If BehandlAntal And Antal <> 0 Then

-------
Tomas


Jens Vestergaard (23-10-2003)
Kommentar
Fra : Jens Vestergaard


Dato : 23-10-03 22:48

"Tomas Christiansen" <toc-01-nospam@blikroer.dk> skrev i en meddelelse
news:bn9hid$28bb$1@news.cybercity.dk...
> Jeg ville aldrig nogensinde basere mig på at en værdi i én eller anden
form
> for heltalsvariabel tilfældigvis ville kunne opfattes som en
> sand/falsk-værdi, idet man så lige pludselig bliver afhængig af at alle
> fremtidige versioner altid vil benytte det samme værdisæt til henholdsvis
> sand og falsk (i VB 6 er det 0 => falsk og alt-andet => sand).

Helt enig - vi er vist kun uenige om tilføjelsen = True/False til en
boolean.

Til ovenstående om heltal som True/False... noget pudsigt, som jeg først
lige har set:
Hvis vi koder:
a = 7
If a Then...
- så evalueres a som True. So far, so good.

Men hvis man i Immediate Window (VB6) skriver
? 7 = True
så får man....tada: False.

Samme hvis man skriver
a=7:print a=True

Er der noget her, jeg ikke kan gennemskue?


--
mvh
Jens Vestergaard (mailadr i dette indlæg er ikke gyldig!)
www.railsoft.dk
Døgnets jernbanenyheder: www.railsoft.dk/medier.asp



Tomas Christiansen (23-10-2003)
Kommentar
Fra : Tomas Christiansen


Dato : 23-10-03 23:26

Jens Vestergaard skrev:
> Til ovenstående om heltal som True/False... noget pudsigt, som jeg først
> lige har set:
> Hvis vi koder:
> a = 7
> If a Then...
> - så evalueres a som True. So far, so good.

Ikke så mærkeligt. Når man skriver et udtryk i betingelsen af If-sætningen,
vil VB 6 _altid_ prøve at konvertere udtrykket til en sandhedsværdi. Altså
implicit en CBool.
Du kan også spørge:

If 7 Then ...

> Men hvis man i Immediate Window (VB6) skriver
> ? 7 = True
> så får man....tada: False.
>
> Samme hvis man skriver
> a=7:print a=True

Her vil VB implicit prøve at konvertere det der står efter lighedstegnet til
en type, som svarer til typen på som det der står foran lighedstegnet. VB
konverterer altså True til en Integer, og det giver værdien -1.

Check selv i Immediate Window med:

? -1 = True

> Er der noget her, jeg ikke kan gennemskue?

Jeg _HADER_ VB's implicitte konverteringer og uigennemskuelige krumspring.

-------
Tomas


Jens Vestergaard (24-10-2003)
Kommentar
Fra : Jens Vestergaard


Dato : 24-10-03 09:17

"Tomas Christiansen" <toc-01-nospam@blikroer.dk> skrev i en meddelelse
news:bn9kfn$2cqh$1@news.cybercity.dk...
>
> Jeg _HADER_ VB's implicitte konverteringer og uigennemskuelige krumspring.

Hæ!

Som selvlært udi VB kommer jeg af og til til kort overfor kodenormer
og -konventioner (og programteori, men et lader vi lige ligge nu) - og
inspireret af den gamle tråd kunne jeg godt tænke mig at få nogle
synspunkter på 'overflødig' kode, som blot er der for læsbarhedens skyld.
Også fordi jeg som regel sidder alene og koder og ikke har nogle at 'bokse'
med...

Eksempel:
Public MyFunction(objNoget As myClsObject) As Boolean
On Error Resume Next
'...kode
'...kode
MyFunction = Err.Number = 0
End Function.

- er vel OK, men i andre situationer kunne jeg godt finde på:

On Error Goto FuncErr
'...kode
'...kode
MyFunction = True
Ud:
Exit Function

FuncErr:
MyFunction = False
Resume Ud
End Function

- hvor det jo f.eks. er overflødigt at skrive MyFunction = False i
Err-handleren, men hvor det for mig at se øger læsbarheden, at gøre det
implicitte explicit.

Hva' siger 'de kloge' om den sag (og lignende)?

--
mvh
Jens Vestergaard (mailadr i dette indlæg er ikke gyldig!)
www.railsoft.dk
Døgnets jernbanenyheder: www.railsoft.dk/medier.asp



Tomas Christiansen (24-10-2003)
Kommentar
Fra : Tomas Christiansen


Dato : 24-10-03 22:07

Jens Vestergaard skrev:
> Som selvlært udi VB kommer jeg af og til til kort overfor kodenormer
> og -konventioner (og programteori, men et lader vi lige ligge nu)

Skal det forstås sådan at du ikke har kendskab til andre programmeringssprog
end VB?

> Public MyFunction(objNoget As myClsObject) As Boolean
> On Error Resume Next
> '...kode
> '...kode
> MyFunction = Err.Number = 0
> End Function.

Dette er en måde at håndtere (eller rettere: ignorere) fejl på, som jeg kun
ser anvendelse for i nogle _ganske_ få, specielle tilfælde. Jeg kan faktisk
overhovedet ikke komme i tanke om ét eneste selv.

> On Error Goto FuncErr
> '...kode
> '...kode
> MyFunction = True
> Ud:
> Exit Function
>
> FuncErr:
> MyFunction = False
> Resume Ud
> End Function

Lad mig kommentere:

1) Jeg bryder mig ikke om din konstellation med en label Ud og en Resume Ud
i din errorhandler. Hvorfor dog spilde 2 kodelininer og CPU-cycler under
udførelsen af programmet på at hoppe et andet sted hen, hvor det eneste som
sker er, at funktionen afsluttes. Hvis man ikke havde denne kode, ville
funktionen jo også slutte på ganske normal vis.

2) Hvis man _vil_ have at ens funktioner altid slutter ét og samme sted,
ville jeg nok snarere gøre det anderledes: Sæt en Ud-label lige før End
Function og erstat Exit Function med Goto Ud. Jeg foretrækker dog selv at
have to exit-points i mine procedurer og funktioner. Én til "normal" exit og
én til "error" exit.

3) Du bør naturlig (mener jeg) altid sætte MyFunction = False (eller
lignende) i din errorhandler, idet du jo ikke ved _hvor_ i din kode, at
fejlen er opstået. Hvis MyFunction sættes True, og der _derefter_ kommer en
fejl, vil den kaldende part fejlagtigt kunne tro at alt er gået godt.

4) En af de ting, som jeg prøver at tænke på, når jeg programmerer, er
robustheden af programmet. Det kan godt være at man i 30% af funktionerne
kan barbere en MyFunction = False væk fra errorhandleren, men det betyder så
også, at hvis forudsætningerne for barberingen ændrer sig (ændringer i koden
kræver at MyFunction sættes til False i errorhandleren), så er der en reel
risiko for at programmøren glemmer at indsætte denne kode i errorhandleren.
Især hvis det allerede _er_ indsat i 70% af funktionerne!

5) Noget helt andet er, hvad vil du gøre ved fejlen? Kan programmet godt
tilllade sig at fortsætte eller har fejlen opsættellig virkning på
udførelsen?

Jeg bruger typisk en metode til fejlhåndtering der kunne således ud:

Function Str2Long(ByVal StrVal As String) As Long
On Error GoTo ErrorHandler
Str2Long = CLng(StrVal)
Exit Function
ErrorHandler:
Str2Long = -99999999
ReportError "Str2Long"
Err.Raise Err.Number, Err.Source, Err.Description, _
Err.HelpFile, Err.HelpContext
End Function

Problemet er ofte at man opdager at der er fejl i ens program, men man ved
ikke lige præcis i hvilken procedure/funktion at fejlen opstår. Derfor har
jeg næsten altid en fejl-log i mine programmer. Typisk logger jeg til en
Collection, og når programmet slutter (uanset om det var p.gr.a. en fejl
eller det var en normal afslutning), så tilføjer jeg alle linierne i min
log-Collection til en tekst-fil med yderligere oplysninger om program-start,
version, evt. parametre angivet på kommandolinien m.m.

I den ovenstående funktion ved jeg ikke bedre end at rapportere fejlen
videre.
Hvis det drejer sig om en procedure som forsøger at slette en fil, vil jeg
nok rapportere fejlen således:

Err.Raise cExternalError, Err.Source, "Error " & Err.Number & _
" in " & Origin & " trying to delete file """ & FileName & ""."
& _
vbNewLine & Err.Description, Err.HelpFile, Err.HelpContext

Jeg skylder måske lige at vise hvordan en ReportError-procedure kan se ud:

Sub ReportError(ByVal Origin As String)
LogError "Error " & Err.Number & " in " & Origin & ": " &
Err.Description
End Sub

Så må du selv tænke over indholdet af LogError, men HUSK at du ikke kan
tillade dig at have fejl i ReportError og LogError, for så løber
fejlrapporteringen helt af sporet!

> Hva' siger 'de kloge' om den sag (og lignende)?

Jeg er sgu' (UPS - jeg mener: sørme) ikke særlig klog, men jeg har
programmeret i mange sprog i mange år, så _noget_ er der da hængt ved...

-------
Tomas


Jens Vestergaard (25-10-2003)
Kommentar
Fra : Jens Vestergaard


Dato : 25-10-03 09:35


"Tomas Christiansen" <toc-01-nospam@blikroer.dk> skrev i en meddelelse
news:bnc491$dek$1@news.cybercity.dk...

[en masse]

Tak for synspunkter. Du kommer langt længere omkring, end jeg lagde op til,
og i langt de fleste af dine betragtninger er jeg enig - mine eksempler var
naturligvis skeletter, som manglede væsentlige dele. Dele, som jeg ikke
lagde op til debat omkring.

Men det skader jo aldrig at få synspunkterne alligevel...

--
mvh
Jens Vestergaard (mailadr i dette indlæg er ikke gyldig!)
www.railsoft.dk
Døgnets jernbanenyheder: www.railsoft.dk/medier.asp



Mathias (24-10-2003)
Kommentar
Fra : Mathias


Dato : 24-10-03 09:30

"Tomas Christiansen" <toc-01-nospam@blikroer.dk> wrote in
news:bn9d7d$21g2$1@news.cybercity.dk:

> Mathias skrev:
>> Ok. Dvs. hvis jeg har List(0) To List(2) i en listbox, så er
>> ListCount ikke 2 men 3 (Med Base 1 i ListCount, og Base 0 i List)
>
> Hvis du har syv køer er der syv, uanset om du tæller fra 0 til 6 eller
> om du tæller fra 1 til 7 (eller om du starter med -37 for den sags
> skyld). Det samme gør sig gældende for gulerødder.
> Et _antal_ (som f.eks. ListCount) er _ikke_ baseret en base-værdi.
Så forstår jeg...
>
> Derimod kan et indeks (som f.eks. List(X)) i MS's verden, være
> 0-baseret eller 1-baseret.
> Hvis det er 0-baseret, tæller man altså fra 0 til antal minus 1, og
> hvis det er 1-baseret, tæller man fra 1 til antal.
Det vidste jeg godt ;) men ellers tak :).
>
>
>> >> If Generate = True Then
>> >
>> > Blot en kommentar: ((((((Generate) = True) = True) = True) = True)
>> > = True) = ...
>> Ehhm, hvad mener du?
>
> Jeg mener at når du spørger på om på om en variabel har værdien True,
> bliver resultatet den samme værdi som variablen har.
>
> Med andre ord er:
> If Generate Then
> det samme som:
> If Generate = True Then
> igen det samme som:
> If (Generate = True) = True Then
> osv. osv. osv.
Ok...
>
<snip>
>
>> Tak for svaret.
>
> Selv tak. Håber at det var løsningen på dit problem!
Det var det.
Tak for det ;).
>
> -------
> Tomas
>
>

---
Mathias

Søg
Reklame
Statistik
Spørgsmål : 177459
Tips : 31964
Nyheder : 719565
Indlæg : 6408191
Brugere : 218881

Månedens bedste
Årets bedste
Sidste års bedste