Office: 2 Syntaxprobleme

Helfe beim Thema 2 Syntaxprobleme in Microsoft Excel Hilfe um das Problem gemeinsam zu lösen; Hallo zusammen, ich habe 2 probleme bezüglich der codierung. Die logik sollte passen jedoch schließe ich da natürlich keine fehler aus. Im Problem 1... Dieses Thema im Forum "Microsoft Excel Hilfe" wurde erstellt von N123456789, 18. Juli 2013.

  1. N123456789 Erfahrener User

    2 Syntaxprobleme


    Hallo zusammen,

    ich habe 2 probleme bezüglich der codierung. Die logik sollte passen jedoch schließe ich da natürlich keine fehler aus.

    Im Problem 1 geht es schon wieder um die Berechnung der Rechnungsbeträge. Mit Hilfe des Forums habe ich ja einen tollen code hinbekommen. Nur nach der Einführung der "Gutschrift" - Option klemmt die Sache.

    Das Problem ist folgendes:
    Wann immer das Makro ausgelöst wird, wird alles berechnet (so weit so gut). Jetzt habe ich auf der userform die möglichkeit 3 Veränderungen vorzunehmen:
    1. Rabattsatz eintragen
    2. Gutschrift eintragen
    3. MwSt. Satz eintragen

    Wie ihr im Code sehen könnt wird nun der Netto u. Gesamtbetrag berechnet. Wenn ich nun aber erneut auf den command button klicke dann verändert sich der Gutschrifts-wert. Bei jedem click kommen 2 Vorkommastellen hinzu. Daraufhin verändert sich natürlich fälschlicher weise mein Netto u. Bruttobetrag.
    Nun wollte ich fragen ob Jemand im unten aufgeführten Code die Fehlerquelle bestimmen kann? Ich habe viel herum probiert mit Csng() und Format(). Aber jede änderung bewirkt nichts. Es ändert sich zwar korrekterweise das Format aber nichts an der Tatsache dass die Gutschrift weitere Vorkommastellen erhält.
    Ein Sahnehäupchen wäre, wenn es gelingt das Format "#,##0.00" für alle Zwischensummen (txtzw) auszugeben. Bei den Versuchen das hinzubekommen habe ich aber immer das selbe problem, Die aufsummierung passt hinten und vorne nicht.
    Code:
    'Berechnung der Zwischensummen in den Reitern der Rechnung/Angebot
    Private Sub cmdBerechnung_Click()
    'Variablendeklaration
    Dim K As Integer
    Dim t As Integer
    Dim NettoW As Single
      Dim sngNetto As Single
      Dim sngMwSt As Single
      Dim sngGesamt As Single
      Dim sngRabatt As Single
      Dim sngNettoNeu As Single
      Dim sngGutschrift As Single
      
      If txtGutschrift.Value = "" Then
        txtGutschrift.Value = 0
      Else
      End If
    'Schleife für die Zwischenwerte und den Nettobetrag
        For K = 1 To 20
             With Me.Controls("txtZw" & K)
                .Value = CSng(NzBl(Me.Controls("txtMenge" & K).Text)) * CSng(NzBl(Me.Controls("txtP" & K).Text))
                'Me.Controls("txtZw" & K).Value = Format(Me.Controls("txtZw" & K), "#,##0.00")
             End With
        Next K
    'Beechnung Nettobetrag
        NettoW = 0
          For t = 1 To 20
                With Me.Controls("txtNetto")
                    NettoW = NettoW + CSng(NzBl(Me.Controls("txtZw" & t).Value))
                    '.Value = Format(NettoW, "0.00")
                End With
          Next t
          
    'Definierung Gutschrift
            'sngGutschrift = txtGutschrift
            txtGutschrift = Format(txtGutschrift, "#,##0.00")
    'Berechnung Rabatt
            sngRabatt = (NettoW * (txtRabattSatz.Value / 100))
            txtRabatt.Text = Format(sngRabatt, "#,##0.00")
    'Berechnung Netto inkl Rabatt
            sngNettoNeu = NettoW - sngRabatt - sngGutschrift
            txtNetto = Format(sngNettoNeu, "#,##0.00")
     'Berechnung MwSt
            sngMwSt = NettoW * (txtMwStSatz.Value / 100)
            txtMwSt.Text = Format(sngMwSt, "#,##0.00")
    'Berechnung Gesamt
            sngGesamt = NettoW + sngMwSt - sngRabatt - sngGutschrift
            txtGesamt.Text = Format(sngGesamt, "#,##0.00")
            
    'Sichtbarkeit der Commandbuttons
    cmdNeuesAngebot.Visible = True
    cmdAngebotÜberschreiben.Visible = True
    cmdKonvertieren.Visible = True
    cmdReEntf.Visible = True
    cmdRechnungErstellen.Visible = True
    cmdAngReNeuAnzeigen.Visible = True
    
    
    End Sub
    Das zweite Problem ist für mich eher etwas beschähmend da es mit sicherheit nur an einer kleinigkeit liegt.
    das auslösen des command button soll eine inputbox öffnen inder ich einen Zahlungseingang eintragen kann. Nun ist die bedingung dass, die eingabe ein datum im format "dd.mm.yyyy" ist. Bei falscheingabe soll sich die inputbox erneut öffnen.

    Über If und elseif verknüpfungen habe ich versucht das hinzubekommen. Aber wenn das elseif - option "AA = vbchancel then" greifen soll passiert nichts. Und auch so scheint mir die programmierung etwas wackelig.
    Ich würde nur gerne wissen wie ich den vbChancel button der inputbox nutzen kann. Denn bisher kann ich das leider nicht. Wenn ich auf "Abbrechen" klicke dann öffnet sich sofort die zweite inputbox obwohl ich doch eig. die procedur mit exit sub beenden möchte. Das erscheinen der zweiten Inputbox ist also falsch.
    Weiß jemand wie ich vbChancel richtig ansprechen muss?

    Code:
    Private Sub cmdZahlungseingang_Click()
    Dim m_lngZeile As Long
    Dim AA As Variant
    Dim BB As Variant
    
    
    With Sheets("Auftragsdatenbank")
      If ListBoxAusZahl.ListIndex = -1 Then
    MsgBox "Bitte zuerest einen Auftrag aus der Liste auswählen.", vbInformation, "Kein Auftrag ausgewählt"
      Else
            'Erstes Mal öffnen der Inputbox
            AA = Format(InputBox("Bitte geben Sie den Zahlungseingang folgendermaßen an: TT.MM.YYYY", "Zahlungseingang bestätigen"), "dd.mm.yyyy.")
            If AA = Format("dd.mm.yyyy") Then
                m_lngZeile = CLng(ListBoxAusZahl.Column(6))
                .Range("H" & m_lngZeile) = AA
                MsgBox "Zahlungseingang bestätigt"
            Else
                ' Zweites mal Öffnen der Inputbox
                BB = Format(InputBox("Bitte geben Sie den Zahlungseingang folgendermaßen an: TT.MM.YYYY", "Zahlungseingang bestätigen"), "dd.mm.yyyy.")
                If BB = Format("dd.mm.yyyy") Then
                    m_lngZeile = CLng(ListBoxAusZahl.Column(6))
                    .Range("H" & m_lngZeile) = AA
                 MsgBox "Zahlungseingang bestätigt"
                 Else
                    MsgBox "Bitte geben Sie das Datum im Format TAG.MONAT.JAHR ein", vbExclamation, "Eintragung fehlgeschlagen"
                    Exit Sub
                 End If
            End If
        End If
    End With
    'Lade Listbox "Ausstehende Zahlungen" neu
    AusstehendeZahlungen
    End Sub
    Für hilfestellungen wäre ich wirklich sehr Dankbar.

    Liebe Grüße
    Nico
     
    N123456789, 18. Juli 2013
    #1
  2. Exl121150 Erfahrener User
    Hallo Nico,

    ad 1) bei Deinem 1. Problem ist mir im Code aufgefallen, dass Du 2x die Variable "sngGutschrift" verwendest, obwohl Du dieser Variablen keinen Wert zugewiesen hast - die Zeile
    sngGutschrift = txtGutschrift
    ist infolge eines Kommentarzeichens nur Kommentar. Vielleicht ist dies das Problem?

    ad 2) bei Deinem 2. Problem:
    Drückt man in einer Inputbox den Abbrechen-Button, liefert die Inputbox als Rückgabewert eine leere Zeichenkette "". Einzig daran erkennt man, dass der Abbrechen-Button gedrückt wurde. Beiliegend habe ich Deinen Code dadurch vereinfacht, indem ich die Eingabeüberprüfung in eine benutzerdef. Funktion ausgelagert habe. Diese Funktion liefert jetzt einen Datumswert zurück, oder aber eben 0, falls der Abbrechen-Button gedrückt wurde. Aus diesem Grund habe ich den Variablentyp von "AA" in "Date" umgeändert.

    Code:
    Private Sub cmdZahlungseingang_Click()
    Dim m_lngZeile As Long
    Dim AA As Date
    
    With Sheets("Auftragsdatenbank")
      If ListBoxAusZahl.ListIndex = -1 Then
         MsgBox "Bitte zuerest einen Auftrag aus der Liste auswählen.", vbInformation, "Kein Auftrag ausgewählt"
      Else
         AA = InputDatum()
         If AA = 0 Then Exit Sub  'Abbrechen-Button wurde gedrückt
            
         m_lngZeile = CLng(ListBoxAusZahl.Column(6))
         .Range("H" & m_lngZeile) = AA
         MsgBox "Zahlungseingang bestätigt"
      End If
    End With
    'Lade Listbox "Ausstehende Zahlungen" neu
    AusstehendeZahlungen
    End Sub
    
    Function InputDatum() As Date
      Dim Ret As String, Dt As Date, DtS$()
      InputDatum = 0
      On Error GoTo Err_InputDatum
    Noch_Einmal:
      Ret = InputBox(Prompt:="Bitte geben Sie den Zahlungseingang folgendermaßen an: TT.MM.JJJJ", _
                     Title:="Zahlungseingang bestätigen", _
                     Default:=Format(Date, "DD.MM.YYYY"))
      'Wenn Button 'Abbrechen' gedrückt wurde, ist der Rückggabewert Ret=""
      If Ret = "" Then Exit Function
      If Not IsDate(Ret) Then Err.Raise 13        '13 = Typen unverträglich
      DtS = Split(Ret, "."): If UBound(DtS) <> 2 Then Err.Raise 13
      Dt = DateSerial(DtS(2), DtS(1), DtS(0))
      If Dt <> CDate(Ret) Then Err.Raise 13
      InputDatum = Dt
      Exit Function
    Err_InputDatum:
      MsgBox Prompt:="Der Wert '" & Ret & "' ist kein gültiges Datum. " & vbCrLf & vbCrLf & _
                     "--> nochmals korrekt eingeben!", _
             Buttons:=vbCritical + vbOKOnly, _
             Title:="Datumseingabefehler"
      Resume Noch_Einmal
    End Function
    
     
    Exl121150, 18. Juli 2013
    #2
  3. N123456789 Erfahrener User
    Hallo Anton,

    vielen herzlichen Dank für die Lösung über die Function. Dadurch bekommt das ganze etwas mehr sinn und ist einiges stabiler programmiert. Mir gefällt das wirklich sehr gut dass sich die Inputbox solange neu öffnet bis das richtige Datum eingetragen oder die Inputbox abgebrochen wurde. Wirklich vielen Dank dafür.

    Zu dem Problem #1: Ich finde es interessant wie du das Problem ansprichst
    Gehen wir von der Situation aus dass das Kommentar-Apostroph bei "sngGutschrift = txtGutschrift" richtig gesetzt ist. Demnach weise ich wie du sagst der Variablen keinen Wert zu. Wie ist es dann möglich dass bei jedem Click auf den Commandbutton sich die variable verändert und zwar immer um den Faktor 100. Das bedeutet ja dass an irgendeiner stelle im Code die Variable ihren wert verändert.
    Meine beste Vermutung ist, dass es etwas mit dem Format "#,##0.00" zu tun hat. Ansonsten passt der code schon.
    Hast du vielleicht noch einen Tipp den ich probieren könnte?

    Liebe Grüße und ein schönes Wochenende
    Nico
     
    N123456789, 19. Juli 2013
    #3
  4. Exl121150 Erfahrener User

    2 Syntaxprobleme

    Hallo,

    das kann durchaus so sein. Es müssen nämlich da 2 Dinge zusammenpassen:
    1) Das Zeichen, das VBA in der Format-Funktion als Kommazeichen (bzw. Tausenderzeichen) erwartet;
    2) Das Zeichen, das Du in den TextBox-Feldern dann tatsächlich verwendest als Kommazeichen (bzw. Tausendertrennzeichen).
    Zwar ist das Problem nicht die von Dir zitierte Formatmaske - die ist sinnvoll und ok -, aber es kann indirekt der Auslöser des Problems sein:
    Angenommen, Dein VBA erwartet in der Format-Funktion als Kommazeichen "," und als Tausendertrennzeichen "." (so wie es auch bei mir der Fall ist), Du aber verwendest jedoch tatsächlich in den Textbox-Feldern "." (den Punkt) als Kommazeichen, dann meint die Format-Funktion, dass die 2 Stellen hinter dem "." 2 Vorkommastellen (und nicht 2 Nachkommastellen) sind - was das Hunderterproblem durchaus erklären würde.
    Zur Demonstration des Problems habe ich bei meinem VBA-Editor im Direktbereich-Fenster Folgendes eingegeben:
    Code:
    txt$="2345.34"
    ? "Resultat=";format(txt$,"#,##0.00")
    Resultat=234.534,00
    
    Mein VBA erwartet nämlich in der Formatfunktion als Tausendertrennzeichen den Punkt "." und als Kommazeichen den Kommabeistrich "," - obwohl die Formatmaske in der Format-Funktion stets in der englischen Schreibweise anzugeben ist.
    Das, was ich vorhin der Variablen txt$ zugewiesen habe, würde Deinem Textbox-Inhalt entsprechen und, darauf die Format-Funktion angewendet, bewirkt, dass das Resultat in 100-facher Größe erscheint.
    Stelle ich das Ganze wie folgt um:
    Code:
    txt$="2345,34"
    ? "Resultat=";format(txt$,"#,##0.00")
    Resultat=2.345,34
    
    erhalte ich schließlich das erwartete Resultat.

    Nachtrag:
    Dieses Falsche-Komma-Problem in Textbox-Feldern ist auch ohne Format-Funktion reproduzierbar.
    Ich gebe wieder im Direkt-Fenster von VBA Folgendes ein:
    Code:
    txt2!="2345.34"
    ? "Resultat="; txt2
    Resultat= 234534 
    
    und schon ist wieder der Fehler da, indem ich der Single-Variable "txt2!" eine Zeichenkette mit falschem Kommazeichen zugewiesen habe. VBA muss bei dieser Wertzuweisung an txt2! implizit eine Typkonversion von String auf Single durchführen. Beim anschließenden Ausgeben des Wertes von txt2! mittels "?"-Befehl kommt die falsche Wertkonversion zutage.
    Dagegen ist Folgendes wieder ok:
    Code:
    txt2!="2345,34"
    ? "Resultat="; txt2!
    Resultat= 2345,34 
    
     
    Zuletzt bearbeitet: 20. Juli 2013
    Exl121150, 20. Juli 2013
    #4
  5. N123456789 Erfahrener User
    Hallo Anton,

    erst einmal wieder vielen vielen Dank für die aufschlüsselung des Problems. Dein post inkl. Nachtrag ist nur leider nicht sehr ermutigend. Ich sehe da doch leider ein hohes potential für falscheingaben. Ich habe für jede beschreibbare textbox bei meinen Rechnungsposten folgendes Makro erstellt
    Code:
    Private Sub txtMengeP1bis20(Nr)
        Dim Abfrage As Boolean
        Dim Abfrage2 As Boolean
        
        
        Abfrage = IsNumeric(ReProg.Controls("txtMenge" & Nr))
        Abfrage2 = IsNumeric(ReProg.Controls("txtP" & Nr))
        
        
        'Mengenabfrage
        If Abfrage = False And ReProg.Controls("txtMenge" & Nr) <> "" Then
            MsgBox ("Bitte nur Ziffern eingeben!")
                   With ReProg.Controls("txtMenge" & Nr)
                    .SetFocus
                    .SelStart = 0
                    .SelLength = Len(.Text)
            End With
        Else
        End If
         'Preisabfrage
        If Abfrage2 = False And ReProg.Controls("txtP" & Nr) <> "" Then
            MsgBox "Bitte nur Ziffern eingeben!", vbExclamation, "Falsche Eingabe"
                   With ReProg.Controls("txtP" & Nr)
                    .SetFocus
                    .SelStart = 0
                    .SelLength = Len(.Text)
            End With
        Else
        End If
    
    End Sub
    
    Hier kannst du dann sehen wie ich das Unterprogramm in jeder Textbox auffrufe (Als Beispiel 3-txt, in Echt ca. 40)
    Code:
    Private Sub txtMenge1_Change()
        txtMengeP1bis20 (1)
    End Sub
    Private Sub txtMenge2_Change()
        txtMengeP1bis20 (2)
    End Sub
    Private Sub txtMenge3_Change()
        txtMengeP1bis20 (3)
    End Sub
    
    is es sinnvoll, hier eine Abfrage nach dem Format einzubauen? Ist sowas überhaupt möglich? Ich meine wenn ich Punkt und Komma falsch setze, beides aber vorhanden ist, dann hab ich ja wieder das selbe Problem. Es wird irgendwie das Format erkannt aber eben nicht so wie wir uns das vorstellen.
    Oder ist das nun einfach ein Punkt andem man sich an die Eingabekonvention 1,000,000.00 halten muss um 1 Million zu erhalten.

    Liebe Grüße Nico
     
    N123456789, 21. Juli 2013
    #5
  6. Exl121150 Erfahrener User
    Hallo Nico,

    1) Nachdem die Zeichen "." und "," innerhalb von Zahlen keine beliebigen Zeichen ist, sondern jedes seine genau definierte Bedeutung hat, wird nichts anderes übrig bleiben, als sich genau daran zu halten.
    2) Du verwendest für die Schreibweise der Million die englische Schreibweise. Ist das so von Dir beabsichtigt? Normalerweise ist in den Excel-Versionen für Deutschland bzw. Österreich die Schreibweise (falls man das Tausendertrennzeichen mit verwendet) folgendermaßen:
    1.000.000,00
    Davon zu unterscheiden ist die Angabe der Formatmaske in der Format-Funktion (diese hat stets englisch zu erfolgen):
    Format(1000000,"#,##0.00") ergibt dann "1.000.000,00"

    Eine Überprüfung, ob eine manuelle Eingabe korrekt ist, ist natürlich überall sinnvoll, sofern eine solche Überprüfung möglich ist !!
    Im folgenden Code habe ich Dir eine solche Prüffunktion für Zahlen erstellt:
    Function IstZahl(strZahl$, Optional TrZ$=".,") As Boolean
    Diese Prüffunktion geht von deutsch/österr. Zeichensetzung innerhalb von Zahlen aus. Falls Deine Excel-Version tatsächlich eine englische Schreibweise bei Zahlen vorsieht, müsstest Du den Funktionskopf folgendermaßen abändern:
    Function IstZahl(strZahl$, Optional TrZ$=",.") As Boolean
    Im Folgenden habe ich Dir Deinen Code etwas angepasst und um meine Prüffunktion ergänzt:
    Code:
    Option Explicit
    
    Private Sub txtMengeP1bis20(Nr)
      With ReProg
        'Mengenabfrage
        Do Until IstZahl(.Controls("txtMenge" & Nr))
            MsgBox "Bitte nur Ziffern eingeben!"
            With .Controls("txtMenge" & Nr)
                .SetFocus
                .SelStart = 0
                .SelLength = Len(.Text)
            End With
        Loop
    
        'Preisabfrage
        Do Until IstZahl(.Controls("txtP" & Nr))
            MsgBox "Bitte nur Ziffern eingeben!", vbExclamation, "Falsche Eingabe"
            With .Controls("txtP" & Nr)
                .SetFocus
                .SelStart = 0
                .SelLength = Len(.Text)
            End With
        Loop
      End With 'ReProg
    End Sub
    
    '
    'Syntax-Test von "strZahl$" als Zahl
    '  [+|-]123[.]456[.]789[,0123]
    'Übergabeparameter:
    '  strZahl$    enthält die zu testende Zahl als Zeichenkette
    '  TrZ$        optional, enthält 2 Zeichen:
    '                       1.Zeichen = Tausendertrennzeichen (meist ".")
    '                       2.Zeichen = Kommazeichen (meist ",")
    'Rückgabewert: Boolean: True,  falls strZahl$ nicht als ungültige Zahl erkannt wurde
    '                       False, falls strZahl$ keine gültige Zahl ist
    '
    Function IstZahl(strZahl$, Optional TrZ$ = ".,") As Boolean
      Dim strTeile() As String
      Dim K As String            'enthält das Kommazeichen, meist ","
      Dim T As String            'enthält das Tausendertrennzeichen, meist "."
      Dim I As Integer
      
      'Vorbesetzung:
      IstZahl = False
      T$ = Left(TrZ$, 1): K$ = Right(TrZ$, 1)
      
      'Falls kein Zeichen oder nur Leerzeichen enthalten sind:
      If Len(Trim$(strZahl$)) = 0 Then strZahl$ = "0"
      'strZahl$ enthält Zeichen, die in Zahlen nicht erlaubt sind:
      If Not IsNumeric(strZahl$) Then Exit Function
      
      'Falls kein K$ enthalten ist, füge eines an
      If InStr(strZahl$, K$) = 0 Then strZahl$ = strZahl$ & K$ & "00"
      'Zerlege Zahl in Einzeilteile, wobei K$ das Trennzeichen ist:
      strTeile = Split(strZahl$, K$)
      
      'strZahl$ enthält mehr als ein K$
      If UBound(strTeile) > 1 Then Exit Function
      
      'strZahl$ enthält nach dem K$ noch weitere T$
      If InStr(strTeile(1), T$) Then Exit Function
      
      'Test, ob im Vorkommabereich das T$ verwendet wird
      'zum Bilden von 3er-Gruppen von Ziffern
      strTeile = Split(strTeile(0), T$)
      For I% = UBound(strTeile) To 1 Step -1
        'Falls eine Zifferngruppe keine 3er-Gruppe ist:
        If Len(strTeile(I%)) <> 3 Then Exit Function
      Next I%
      
      IstZahl = True
    End Function
    
     
    Zuletzt bearbeitet: 21. Juli 2013
    Exl121150, 21. Juli 2013
    #6
  7. N123456789 Erfahrener User
    Hallo Anton,

    herzlichen Dank für deinen Lösungsvorschlag. Bei korrekter eingabe funktioniert der Code sehr gut. Nur bei einer beabsichtigten Falscheingabe befinde ich mich am Ende in einer Endlosschleife.
    Ich würde sehr gerne meine Datei uploaden aber Sie ist viel zu groß für das Forum (selbs gezippt bin ich bei fast 700kb).
    Gibt es eine mögliochkeit die Datei trotzdem irgendwie in das Forum zu bekommen?

    und noch einmal vielen Dank dass du schon dein zweites Wochenende so unermütlich für unsere Lösungsfindung opferst. Ich weiß das wirklich sehr zu schätzen.

    LG Nico
     
    N123456789, 21. Juli 2013
    #7
  8. Exl121150 Erfahrener User

    2 Syntaxprobleme

    Hallo Nico,

    Du hast recht, es gibt leider eine Endlosschleife, falls eine falsche Zahl eingegeben wird.

    Ich habe daher 2 Maßnahmen ergriffen, um diesen Übelstand zu beenden:

    1) Ich habe die allgemeine Test-Sub "txtMengeP1bis20(Nr)", die bisher für 2 Textfelder zuständig war, vereinfacht, dass sie zwar weiterhin sowohl "txtMenge"-Felder als auch "txtP"-Felder testet, aber nur mehr jeweils 1 Feld gleichzeitig und nicht 2.

    2) Ich habe aus dieser SUB eine Boolean-Funktion gemacht, die den jeweiligen Feldnamen als Parameter erhält und nicht bloß die Feldsubnummer.
    Code:
    Private Function txtMengeP1bis20(txtMengeP$) As Boolean
      Dim IstZahlMenge As Boolean
      
      With ReProg
        'Mengenabfrage
        IstZahlMenge = IstZahl(.Controls(txtMengeP$))
        If Not IstZahlMenge Then
            MsgBox "Fehler in '" & txtMengeP$ & "'." & vbCrLf & "Bitte nur Ziffern eingeben!"
            With .Controls(txtMengeP$)
                .SetFocus
                .SelStart = 0
                .SelLength = Len(.Text)
            End With
        End If
      End With 'ReProg
      txtMengeP1bis20 = IstZahlMenge
    End Function
    3) Ich habe den Ereignistyp, aus dem diese allgem. Testfunktion aufgerufen wird, geändert von "Change" auf "Exit".
    Das Change-Ereignis tritt bei jeder Änderung des Feldinhaltes auf, während das Exit-Ereignis nur auftritt, wenn versucht wird, das Feld zu verlassen.
    Das Exit-Ereignis hat den Parameter "Cancel", der auf True gesetzt werden muss, wenn der Feldinhalt fehlerhaft ist.
    Ist Cancel = True dann kann man das Feld nicht verlassen. Erst wenn Cancel einen False-Wert erhält, kann das Feld verlassen werden und zum nächsten gegangen werden.
    Beispielhaft habe ich das für 2 "txtMengeX"- und "txtPX"-Felder im folgenden Code dargestellt:
    Code:
    Private Sub txtMenge1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = Not txtMengeP1bis20("txtMenge1")
    End Sub
    
    Private Sub txtMenge2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = Not txtMengeP1bis20("txtMenge2")
    End Sub
    
    Private Sub txtP1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = Not txtMengeP1bis20("txtP1")
    End Sub
    
    Private Sub txtP2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = Not txtMengeP1bis20("txtP2")
    End Sub
    
    4) Die eigentliche Funktion zum Testen der Zahlen "IstZahl(....)" ist identisch zu meinem vorigen Posting. Aus diesem Grund habe ich sie hier nicht nochmals angefügt.
    Diese Funktion kann natürlich nicht alle Fehler in einer Zahl entdecken: zB. falls die Zahl "123.456" ist und der Punkt eigentlich ein Beistrich sein müsste.
     
    Exl121150, 21. Juli 2013
    #8
  9. N123456789 Erfahrener User
    Hallo Anton,

    super! Herzlichen Dank. Jetzt funktioniert es viel besser. Jetzt ist das Kommaproblem denke ich beseitigt. Du gibst mir mit
    und anderen Stellen im Code, die Möglichkeit die Schreibweise zu ändern. Das ist klasse.
    Jetzt wollte ich noch eines im Anschluss Fragen. Wir haben jetzt das Kommaproblem für alle Textelder bis auf eines gelöst. Und zwar das Textfeld "txtGutschrift". Hier habe ich immer noch das selbe Problem wie zu beginn. Vielleicht sollten wir den Ursprungscode den ich gepostet habe noch einmal überdenken. Außerdem wäre es schon nun zu sehen (ist aber kein muss) wenn die Felder der Zwischensumme (die werden über eine Schleife berechnet) auch im selben Format wie alle anderen dargestellt werden würden. Das wäre zwar toll ist aber in der Priorität hinten angestellt.

    Eine weitere Idee wäre dass ich die funktionen kopiere und für das textfeld txtGutschrift umschreibe. Wenn du das für eine gute Idee hälst mache ich mich gleich ans werk.

    Ich wünsche noch einen schonen Tag und abermals herzlichen Dank für deine Hilfe bisher.

    Viele Grüße
    Nico
     
    N123456789, 23. Juli 2013
    #9
  10. Exl121150 Erfahrener User
    Hallo Nico,

    Grundsätzlich gilt, dass es ein TextBox-Feld der UserForm ist. Und damit kann es mit dem gleichen Verfahren überprüft werden wie alle anderen TextBox-Felder.
    Code:
    Private Sub txtGutschrift_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = Not txtMengeP1bis20("txtGutschrift")
    End Sub
    
    Denn eines muss Dir klar sein: Sobald Du eine Wertzuweisung folgender Art machst:
    sngGutschrift = txtGutschrift
    löst Du damit eine implizite Wertumwandlung vom Typ String (txtGutschrift) zum Typ Single aus, bevor der so umgewandelte Wert der Single-Variablen sngGutschrift übergeben werden kann. Damit bei dieser Umwandlung die Single-Variable den richtigen Stellenwert erhält, muss zuvor in der String-Variablen eine korrekte Kommasetzung erfolgt sein und zwar mit dem Kommazeichen, das von Deiner VBA-Version als solches erkannt wird. Das ist normalerweise bei einer deutschen bzw. österreichischen Version das Beistrichzeichen (","), während es in vielen anderen Sprachversionen der Punkt (".") ist oder manchmal sogar das Hochkommazeichen ("'"). Dieses Zeichen muss auf jeden Fall richtig platziert sein bzw., falls es nicht enthalten ist, wird es als am Ende des String-Wertes gesetzt angenommen.
    Davon zu unterscheiden ist das Tausendertrennzeichen. Dieses darf gesetzt werden, muss aber nicht. Wird es gesetzt, darf es nur im Vorkommabereich des Zahlen-Strings enthalten sein und dort die Ziffern in 3er-Gruppen unterteilen. Im Nachkommabereich darf es nicht enthalten sein.
    Wird das Tausendertrennzeichen fälschlicherweise als Kommazeichen verwendet im Zahlenstring, erfolgt eine falsche Zahlenumwandlung. Angenommen: es befinde sich an der drittletzten Stelle im Zahlenstring dieses falsche Kommazeichen, so wird es bei der Typumwandlung einfach entfernt, am Schluss des Zahlenstrings dann das richtige Kommazeichen angefügt und dieser so modifizierte Zahlenstring in eine (Single)zahl umgewandelt - und schon hat man sich eine 100er-Multiplikation eingehandelt.

    Zum Schluss noch eine Bemerkung zum Datentyp "Single":
    Single ist ein Gleitkommatyp von 4 Byte Länge, wobei 1 Byte für den Exponenten und das Vorzeichen verwendet wird, sodass 3 Byte für die Mantisse übrig bleiben. Damit ist ein relativ bescheidener Datenbereich in der Mantisse darstellbar. Insbesondere wirkt sich die Knappheit in der Mantisse dann aus, wenn die ursprüngliche Dezimalzahl Nachkommastellen hatte. Da bei diesem Datentyp eine Umwandlung vom Dezimalsystem ins Hexadezimalsystem (System mit 16 Ziffern) erfolgt, gibt es im Bereich der Nachkommastellen der Dezimalzahl Rundungsdifferenzen, die umso mehr ins Gewicht fallen, je weniger Platz für Hex-Ziffern für diesen Nachkommabereich zur Verfügung steht.
    Daher sollte man diesen Datentyp nur verwenden, wenn man sich sicher ist, dass man nur relativ kleine (= mit bescheidener Genauigkeit) Dezimalzahlen darstellen will. Daher sollte man in der Regel den Datentyp "Double" verwenden (Länge 8 Byte) oder eventuell den Datentyp "Currency" (8-Byte-Zahlen in einem Ganzzahlenformat mit einer Skalierung von 10000). Bei den heutigen Geräten sollte in den wenigsten Fällen der Speicherbedarf durch den doppelt so großen Bytebedarf ausschlaggebend sein.
    (Der Datentyp "Decimal" steht im Excel-VBA nur als Untertyp des Typs "Variant" zur Verfügung - Einsatz der Funktion "CDec(Ausdruck)").
     
    Exl121150, 24. Juli 2013
    #10
Thema:

2 Syntaxprobleme

  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Auf dieser Website werden Cookies für die Zugriffsanalyse und Anzeigenmessung verwendet.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden