Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Textboxen über For ... next Schleife addieren

63 views
Skip to first unread message

Götz Alles

unread,
Jul 19, 2004, 9:31:31 AM7/19/04
to
Hallo zusammen,

als Fehlerabfrage würde ich gerne die eingegebenen Werte
einer Userfom addieren.

Da es genau 100% sein müssen, sollen die Eingaben
daraufhin gecheckt werden.

Ich wollte das wie folgt lösen:
***
Private Sub CmdErfassen_Collvert_Click()

Dim frm As Object
Dim i As Integer
Dim sngWert As Single

sngWert = 0
i = 2

For i = 2 To 11
sngWert = "TextBox" & i.Value + sngWer
Debug.Print sngWert
Next i

If sbgWert > "100" Then MsgBox "Fehlermeldung": End Sub

Set frm = frmCollateralverteilung

Application.ScreenUpdating = False


'hier beginnt die "Übertragssequenz (für die Frage nicht
'relevant)
Sheets("Historie Kennzf.").Activate
Range("AF65536").End(xlUp).Offset(1, 0).Select
With frm
ActiveCell.Value = .TextBox1.Value
ActiveCell.Offset(0, 1).Value = .TextBox2.Value
ActiveCell.Offset(0, 2).Value = .TextBox3.Value
ActiveCell.Offset(0, 3).Value = .TextBox4.Value
ActiveCell.Offset(0, 4).Value = .TextBox5.Value
ActiveCell.Offset(0, 5).Value = .TextBox6.Value
ActiveCell.Offset(0, 6).Value = .TextBox7.Value
ActiveCell.Offset(0, 7).Value = .TextBox8.Value
ActiveCell.Offset(0, 8).Value = .TextBox9.Value
ActiveCell.Offset(0, 9).Value = .TextBox10.Value
ActiveCell.Offset(0, 10).Value = .TextBox11.Value
End With

Sheets("2) Controlling").Activate

Application.ScreenUpdating = True

End Sub
***
Für i bekomme ich allerdings die Fehlermeldung "Ungültiger
Bezeichner"!?!

Ein Textfeld wird wie folgt eingelesen:
***
Private Sub Textbox2_Exit(ByVal Cancel As
MSForms.ReturnBoolean)

If TextBox2.Value = "" Then TextBox2.Value = "0"

If InStr(TextBox2, "%") = 0 Then
TextBox2 = Format(TextBox2 / 100, "Percent")
End If

End Sub
***
Wie muß ich es anstellen, dass ich über eine Schleife die
Textfelder mit einander addieren kann?

Vielen Dank schon einmal für Eure Hilfe.

cu
Götz
---
Excel 2000

Melanie Breden

unread,
Jul 19, 2004, 10:15:38 AM7/19/04
to
Hallo Götz,

Götz Alles schrieb:


> als Fehlerabfrage würde ich gerne die eingegebenen Werte
> einer Userfom addieren.
>
> Da es genau 100% sein müssen, sollen die Eingaben
> daraufhin gecheckt werden.
>
> Ich wollte das wie folgt lösen:
> ***
> Private Sub CmdErfassen_Collvert_Click()
>
> Dim frm As Object
> Dim i As Integer
> Dim sngWert As Single
>
> sngWert = 0
> i = 2
>
> For i = 2 To 11
> sngWert = "TextBox" & i.Value + sngWer
> Debug.Print sngWert
> Next i
>
> If sbgWert > "100" Then MsgBox "Fehlermeldung": End Sub

> Für i bekomme ich allerdings die Fehlermeldung "Ungültiger
> Bezeichner"!?!

> Wie muß ich es anstellen, dass ich über eine Schleife die


> Textfelder mit einander addieren kann?

dein Problem ist wieder mal, dass der Text einer TextBox eine Zeichenkette
vom Datentyp *String* ist und zudem noch ein nicht_numerisches Zeichen "%" enthält.

Zum Berechnen muss dieses Zeichen vorher entfernt werden.
Um ganz sicher zu gehen, sollte der Textwert noch in einen Single Wert umgewandelt werden

Dim i As Integer
Dim sngWert As Single

Dim obj As MSForms.TextBox

' TextBoxen von 16 bis 23
For i = 16 To 23
Set obj = Controls("TextBox" & i)
sngWert = sngWert + CSng(VBA.Replace(obj.Text, "%", ""))
Debug.Print sngWert
Next i

If sngWert > "100" Then
MsgBox "Fehlermeldung"
Exit Sub
End If

--
Mit freundlichen Grüssen

Melanie Breden
- Microsoft MVP für Excel -

http://excel.codebooks.de (Das Excel-VBA Codebook)
#Excel-Auftragsprogrammierung#


Melanie Breden

unread,
Jul 19, 2004, 10:21:15 AM7/19/04
to
Hallo Götz,

Nachtrag:

>> Dim sngWert As Single

> If sngWert > "100" Then
> MsgBox "Fehlermeldung"
> Exit Sub
> End If

hätte ich fast übersehen:

Die Variable sngWert ist vom Typ Single.
In der If...Then-Entscheidung prüfst du sie aber als Textwert.
Schreibe den Prüfwert deswegen auch als Zahl und nicht als String:

If sngWert > 100 Then
...

Götz Alles

unread,
Jul 19, 2004, 11:27:53 AM7/19/04
to
Hallo Melanie,

>dein Problem ist wieder mal, dass der Text einer TextBox
>eine Zeichenkette vom Datentyp *String* ist und zudem
>noch ein nicht_numerisches Zeichen "%" enthält.

D.h., auch wenn ich beim Verlassen dem Wert ein Format
zuweise, ist es immer noch ein String!?! O.k., dann
schreibe ich mir das mal hinter die Ohren.

>Zum Berechnen muss dieses Zeichen vorher entfernt werden.
>Um ganz sicher zu gehen, sollte der Textwert noch in
einen Single Wert umgewandelt werden
>
> Dim i As Integer
> Dim sngWert As Single
> Dim obj As MSForms.TextBox
>
> ' TextBoxen von 16 bis 23
> For i = 16 To 23
> Set obj = Controls("TextBox" & i)
> sngWert = sngWert + CSng(VBA.Replace
>(obj.Text, "%", ""))
> Debug.Print sngWert
> Next i
>
> If sngWert > 100 Then
> MsgBox "Fehlermeldung"
> Exit Sub
> End If

Herzlichen Dank für Deine Hilfe! So klappt es bestens. Ich
muß mal zusehen, dass ich ein Nachschlagewerk finde, in
dem das korrekte Ansprechen (wovon auch immer) gut
beschrieben ist.

cu
Götz

Götz Alles

unread,
Jul 19, 2004, 11:31:50 AM7/19/04
to
Hallo Melanie,

>hätte ich fast übersehen:
>
>Die Variable sngWert ist vom Typ Single.
>In der If...Then-Entscheidung prüfst du sie aber als
Textwert.
>Schreibe den Prüfwert deswegen auch als Zahl und nicht
als String:
>
> If sngWert > 100 Then
> ...

Habe ich so übernommen. Vielen Dank noch mal.

cu
Götz

Michael Zimmermann

unread,
Jul 19, 2004, 11:42:50 AM7/19/04
to
Hallo!

Melanie Breden:


> Nachtrag:
> > > Dim sngWert As Single
>
> > If sngWert > "100" Then
> > MsgBox "Fehlermeldung"
> > Exit Sub
> > End If
>
> hätte ich fast übersehen:
>
> Die Variable sngWert ist vom Typ Single.
> In der If...Then-Entscheidung prüfst du sie aber als
> Textwert. Schreibe den Prüfwert deswegen auch als Zahl
> und nicht als String:
>
> If sngWert > 100 Then
> ...

Besser noch wäre es, auf den Datentyp Single zu verzichten.
Die Prozentwerte sind wahrscheinlich maximal zweistellig
nach dem Komma, so daß kein echtes Fließkomma benötigt wird.

Da Fließkommazahlen wie Single und Double immer zu
Rundungsfehlern führen können, wäre eine Long-Variable,
die z. B. den 100fachen Prozentwert zugewiesen bekommt oder
eine skalierte Ganzzahl wie Currency besser geeignet,
da es dann nicht zu Fehlalarmen bzw. ausbleibender Meldung
trotz Fehler kommen kann.

Gruß aus Mainz
Michael

Melanie Breden

unread,
Jul 19, 2004, 11:54:19 AM7/19/04
to
Hallo Michael,

Michael Zimmermann schrieb:


>> Die Variable sngWert ist vom Typ Single.
>> In der If...Then-Entscheidung prüfst du sie aber als
>> Textwert. Schreibe den Prüfwert deswegen auch als Zahl
>> und nicht als String:
>>
>> If sngWert > 100 Then
>> ...
>
> Besser noch wäre es, auf den Datentyp Single zu verzichten.
> Die Prozentwerte sind wahrscheinlich maximal zweistellig
> nach dem Komma, so daß kein echtes Fließkomma benötigt wird.
>
> Da Fließkommazahlen wie Single und Double immer zu
> Rundungsfehlern führen können, wäre eine Long-Variable,
> die z. B. den 100fachen Prozentwert zugewiesen bekommt oder
> eine skalierte Ganzzahl wie Currency besser geeignet,
> da es dann nicht zu Fehlalarmen bzw. ausbleibender Meldung
> trotz Fehler kommen kann.

das ist sicher auch eine Möglichkeit.
Wenn Götz mit seiner jetzigen Variante Probleme bekommt,
kann er es ja mal ausprobieren.

Melanie Breden

unread,
Jul 19, 2004, 11:56:44 AM7/19/04
to
Hallo Götz,

Götz Alles schrieb:


> Herzlichen Dank für Deine Hilfe! So klappt es bestens. Ich
> muß mal zusehen, dass ich ein Nachschlagewerk finde, in
> dem das korrekte Ansprechen (wovon auch immer) gut
> beschrieben ist.

bittsehr, ist gern geschehen :-)

rein aus Neugierde.... gehören deine Fragen immer noch zum Projekt 'Kraftwerk'?

Götz Alles

unread,
Jul 20, 2004, 3:17:35 AM7/20/04
to
Hallo Melanie,

>rein aus Neugierde.... gehören deine Fragen immer noch
>zum Projekt 'Kraftwerk'?

Nein, ist ein völlig anderes Projekt. An der
Kraftwerkssache bin ich (allerdings sehr gebremst) noch
dran. Ich werde mal zusehen, mir die gesetzlich
beschlossenen Vergütungssätze zu besorgen und dann in das
Tool einzubauen. Soll ja dann auch mal fertig werden ;-)

Ich werde mich dann noch einmal bei Dir melden (soll keine
Drohung sein! ;-) )

cu
Götz

Götz Alles

unread,
Jul 20, 2004, 3:23:15 AM7/20/04
to
Hallo Michael,
hallo Melanie,

>> Besser noch wäre es, auf den Datentyp Single zu
>> verzichten. Die Prozentwerte sind wahrscheinlich
>> maximal zweistellig nach dem Komma, so daß kein echtes
>> Fließkomma benötigt wird.

Normalerweise richtig. Ich kann allerdings nicht
ausschließen, dass wir hier mit bis zu 6 Nachkommastellen
rechnen werden. Aus diesem Grund habe ich Single als
Datentyp gewählt.

>> Da Fließkommazahlen wie Single und Double immer zu
>> Rundungsfehlern führen können, wäre eine Long-Variable,
>> die z. B. den 100fachen Prozentwert zugewiesen bekommt
>> oder eine skalierte Ganzzahl wie Currency besser
>> geeignet, da es dann nicht zu Fehlalarmen bzw.
>> ausbleibender Meldung trotz Fehler kommen kann.

Welcher Art könnten denn die Fehler sein? Ich frage das
nur schon einmal im Voraus, um dann ggf. erkennen zu
können, dass es am Datentyp liegt.

>das ist sicher auch eine Möglichkeit.
>Wenn Götz mit seiner jetzigen Variante Probleme bekommt,
>kann er es ja mal ausprobieren.

Werde ich dann mit Sicherheit tun ;-)

cu
Götz

Michael Zimmermann

unread,
Jul 20, 2004, 4:44:45 AM7/20/04
to
Hallo!

Götz Alles:


> > > Besser noch wäre es, auf den Datentyp Single zu
> > > verzichten. Die Prozentwerte sind wahrscheinlich
> > > maximal zweistellig nach dem Komma, so daß kein echtes
> > > Fließkomma benötigt wird.
> Normalerweise richtig. Ich kann allerdings nicht
> ausschließen, dass wir hier mit bis zu 6 Nachkommastellen
> rechnen werden. Aus diesem Grund habe ich Single als
> Datentyp gewählt.
> > > Da Fließkommazahlen wie Single und Double immer zu
> > > Rundungsfehlern führen können, wäre eine
> > > Long-Variable, die z. B. den 100fachen Prozentwert
> > > zugewiesen bekommt

6 Nachkommastellen statt 2? Okay, 1.000.000 statt 100.
Regel erkannt? ;-)

> > > ...oder eine skalierte Ganzzahl wie


> > > Currency besser geeignet, da es dann nicht zu
> > > Fehlalarmen bzw. ausbleibender Meldung trotz Fehler
> > > kommen kann.
> Welcher Art könnten denn die Fehler sein? Ich frage das
> nur schon einmal im Voraus, um dann ggf. erkennen zu
> können, dass es am Datentyp liegt.

Dim s As Single
Dim i As Long

For s = 1 To 3 Step 0.1
Debug.Print s
Next s

For i = 1 To 30
Debug.Print i / 10
Next i

'Schlimmer noch:
s = 1
Do Until s = 3
s = s + 0.1
Debug.Print s
If s > 10 Then Exit Do
'Ohne diese vorsorgliche Sicherung würdest Du
'unbemerkt in einer Endlosschleife landen
Loop

Laß Dir das auf der Zunge zergehen: Wenn Du von 1 ausgehend
im Single-Bereich immer wieder 0.1 addierst, wird 3 nie
erreicht.

Man sollte sich eines immer vor Augen halten:

Single/Double sind *Fließ*kommazahlen, d.h. bei Bedarf
beliebig (naja fast) viele Ziffern in der Mantisse. Aber
dafür sind die Rechnungen auch ungenau (Rundungsfehler).

Das braucht man z. B. für periodische oder irrationale
Zahlen: 1/3; sqr(2) usw.

*Fest*kommazahlen sind mathematisch gesehen eigentlich
Ganzzahlen:

Stell Dir bei zweistelligen Währungsrechnungen, z. B.
1,23 Eur, einfach vor, es seien 123 Cent, dann siehst Du,
daß das keine echten Kommazahlen sind.

Man nennt solche Festkommazahlen daher auch skalierte
Ganzzahlen. Ganzzahlrechnungen kommen ohne Rundung aus
und sind daher genau.

Als Lehre kann man daraus ziehen:

- Man sollte möglichst Single/Double nur verwenden,
wenn dazu eine mathematische Notwendigkeit besteht
- Man sollte möglichst Single/Double nicht als
Steuervariablen benutzen
- Man sollte bei Verwendung von Single/Double Prüfungen
nicht mit = sondern allenfalls mit >, < vornehmen

Und noch als Anmerkung: Wenn Long nicht reicht, haben wir
mit Currency (wir vergessen mal, daß das Währung heißt,
weil uns das nur in die Irre führt) einen 64-Bit-Integer
und mit Decimal sogar einen 96-Bit-Integer zur Verfügung.
Das sollte eigentlich für alle normalen Anwendungsfälle
ausreichen.

Gruß aus Mainz
Michael

Götz Alles

unread,
Jul 20, 2004, 9:06:42 AM7/20/04
to
Hallo Michael,

>6 Nachkommastellen statt 2? Okay, 1.000.000 statt 100.
>Regel erkannt? ;-)

Aber nur mal gerade so (ist schon schwierig) ;-)

>> > > ...oder eine skalierte Ganzzahl wie
>> > > Currency besser geeignet, da es dann nicht zu
>> > > Fehlalarmen bzw. ausbleibender Meldung trotz Fehler
>> > > kommen kann.
>> Welcher Art könnten denn die Fehler sein? Ich frage das
>> nur schon einmal im Voraus, um dann ggf. erkennen zu
>> können, dass es am Datentyp liegt.
>

[snip]

>Laß Dir das auf der Zunge zergehen: Wenn Du von 1
>ausgehend im Single-Bereich immer wieder 0.1 addierst,
>wird 3 nie erreicht.

Hmm .... yep, da ist was dran.

>Man sollte sich eines immer vor Augen halten:
>
>Single/Double sind *Fließ*kommazahlen, d.h. bei Bedarf
>beliebig (naja fast) viele Ziffern in der Mantisse. Aber
>dafür sind die Rechnungen auch ungenau (Rundungsfehler).
>
>Das braucht man z. B. für periodische oder irrationale
>Zahlen: 1/3; sqr(2) usw.
>
>*Fest*kommazahlen sind mathematisch gesehen eigentlich
>Ganzzahlen:

[snip - Mathenachhilfe] ;-)

>Als Lehre kann man daraus ziehen:
>
>- Man sollte möglichst Single/Double nur verwenden,
> wenn dazu eine mathematische Notwendigkeit besteht
>- Man sollte möglichst Single/Double nicht als
> Steuervariablen benutzen
>- Man sollte bei Verwendung von Single/Double Prüfungen
> nicht mit = sondern allenfalls mit >, < vornehmen

Ist verständlich. Wo aber siehst Du das Problem, bei dem
Code von Melanie?
***


Dim frm As Object
Dim i As Integer
Dim sngWert As Single

Dim obj As MSForms.TextBox

' TextBoxen von 2 bis 11


For i = 2 To 11

Set obj = Controls("TextBox" & i)
sngWert = sngWert + CSng(VBA.Replace(obj.Text, "%", ""))

Next i

If sngWert > 100 Then
MsgBox "So so ... über 100% sollen verteilt werden!?!"
Exit Sub
End If
...
***
Bei der Single Variablen "sngWert" wird doch der Fall ">"
abgefragt. Hier dürfte es doch zu keinen Problemen kommen.
Die Variable wird nicht zur Steuerung benutzt. Hier werden
die einzelnen Werte nacheinander summiert. Oder meintest
Du es lediglich als allgemeinen Hinweis?

>Und noch als Anmerkung: Wenn Long nicht reicht, haben wir
>mit Currency (wir vergessen mal, daß das Währung heißt,
>weil uns das nur in die Irre führt) einen 64-Bit-Integer
>und mit Decimal sogar einen 96-Bit-Integer zur Verfügung.
>Das sollte eigentlich für alle normalen Anwendungsfälle
>ausreichen.

Stimmt.

Danke schon einmal für die Hinweise.

cu
Götz

Michael Zimmermann

unread,
Jul 20, 2004, 12:34:02 PM7/20/04
to
Hallo!

Götz Alles :


> > Laß Dir das auf der Zunge zergehen: Wenn Du von 1
> > ausgehend im Single-Bereich immer wieder 0.1 addierst,
> > wird 3 nie erreicht.
> Hmm .... yep, da ist was dran.

In erster Linie. Aber auch im konkreten Fall:

So, wie 1 + 0.1 + 0.1 + 0.1 .... so irgendwie
2.999754 o. ä. statt 3 ergibt, könnte es passieren, daß
bei einer ausreichenden Anzahl Textboxen und
passenden Zahlenwerten die tatsächliche Summe
100,000037 beträgt (was zuviel wäre), die Schleife
mit der Single-Akkumulation aber nur auf 99,99935
kommt und daher fälschlich keinen Alarm auslöst.

Oder umgekehrt könnte tatsächliches 99.99954 (okay)
durch Rundungsfehler zu 100.00046 o. ä. aufsummiert
werden und so ein blinder Alarm ausgelöst werden.

Je nach Rigorosität der Prozedur können dann an sich
korrekte Werte nicht gespeichert werden.

Ergebnis aus Test-Code:

37,10001 'eigentlich 37,1; berechneter Wert zu /groß/
37,2
...
37,8
37,89999 'eigentlich 37,9; berechneter Wert zu /klein/

Mit etwas Pech können sich Fehler auch akkumulieren:
Wenn Du 10 Werte, die 0,00001 zu groß sind, addierst,
kommst Du auf einen Gesamtfehler von 0,00010, d.h.
der Fehler hat sich verzehnfacht!

Du willst ja nicht einen gelben Bereich, der je nach
Lust und Laune irgendwo zwischen 99,997 und 100,008
Alarm schlägt, sondern eine exakte Grenze genau bei
100,0000... Und die geht in der Fließkomma-Schwammigkeit
halt unter.

Gruß aus Mainz
Michael

0 new messages