Hallo,
aus einer Sub soll die Prüfroutine in eine Funktion ausgelagert und in der Sub die Funktion aufgerufen werden:
Private Sub cbo1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
Select Case KeyAscii
Case vbKey0 To vbKey9, vbKeyBack, 46 'Pkt
Case Else
KeyAscii = 0
MsgBox „Datumsformat!“
End Select
End Sub
Wie muss die Funktion selbst und der Funktionsaufruf in der Sub aussehen?
Danke u. Gruß
Wilhelm
Funktion: erledigen eine Arbeit und nutzen dazu die ggfls. übergegebenen Parameter. Sobald die Function ihre Arbeit erledigt hat, kehrt sie zurueck und liefert der Sub etc. welche die Function aufgerufen hat einen Wert zurueck!
Proceduren: erledigen eine Arbeit und kehren danach zur Sub zurueck, die sie aufgerufen hat. Proceduren (Sub) liefern hingegen Funktionen KEINEN Wert zurueck!
In Funktionen oder Proceduren sollte man Programmteile auslagern die mehrmals von verschiedenen Proceduren / Function aus gebraucht werden!
Funtionen ruft man wiefolgt auf:
Variable=FunktionsName(Argumente)
oder
If FunktionsName(Argumente) then … 'Nur wenn sie True oder False zurueckliefert
So, nun einmal zu deinem Problem. Du willst du denn nun genau erreichen?
Eine Funktion aufrufen oder eine Sub? Gesetz dem Falle eine Funktion, was soll sie zurueckliefern?
du übergibst ja KeyAscii als Byval, mir unklar ob dir da
KeyAscii = 0
was bringt.
Auch bei ByRef komme ich da leicht ins Grübeln, vielleicht kann ja Rainer mal was dazu sagen.
Seie es wie es sei, ich sehs so, egal ob bei ByVal oder ByRef löschst du damit nicht eine evtl. Fehleingabe.
Aber sehr sicher bin ich mir da nicht.
Mal KeyAscii=0 weglassend, probiers mal so:
Der Code der Funktion gehört in ein Standardmodul, Modul1 o.ä.
Private Sub cbo1\_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If Pruef(KeyAscii) "" Then MsgBox Pruef(KeyAscii)
End Sub
'
Function Pruef(ByVal Wert As Integer) As String
Select Case Wert
Case vbKey0 To vbKey9, vbKeyBack, 46 'Pkt
Case Else
Pruef = "Datumsformat!"
End Select
End Function
ich hatte mal vor einiger Zeit etwas zu dem Speicher geschrieben. Dort bin ich auch mal auf Byval und ByRef eingegangen!
Handelt es sich um eine Refernz spielt es keine Rolle ob ByVal oder ByRef, da zwar der Zeiger im Stack kopiert wird. Aber BEIDE Zeiger auf die selbe Adresse im Heap zeigen und somit die Orginaldaten ändern!
Anders ist es bei primitiven Datentypen. Diese liegen im Stack und da kannst du gerne die Kopie ändern, wenn du die Variable als ByVal übergibst. Am Wert aendert sich da aber nichts. Anders ist es dort bei ByRef dort arbeitest du dann mit den Orginal Daten. Wird weder Byref noch ByVal angegeben so ist der wert Standardmaessig ByRef!
Handelt es sich um Objecte so bekommst du immer nur eine Refernz auf das Object geliefert. Sprich egal ob Byval oder Byref … du aenderst immer die Orginaldaten!
du übergibst ja KeyAscii als Byval, mir unklar ob dir da
KeyAscii = 0
was bringt.
VB6:
Private Sub Text1\_KeyPress(KeyAscii As Integer)
DoEvents
End Sub
der Originalcode ist also nicht VB6.
Keyascii wird nicht übergeben, das kommt vom System.
Das zu überschreiben ändert, welche Taste an VB übergeben wird.
Beispiel:
Option Explicit
Private Sub Text1\_KeyPress(KeyAscii As Integer)
If KeyAscii = 66 Then KeyAscii = 67
End Sub
Tipp da mal ‚ABCD‘ ein. Im Textfeld kommt ‚ACCD‘ an.
Und das ist nicht nur optisch!
wenn ich Deinen Code richtig verstehe, willst Du sicherstellen, daß ein gültiges Datum eingegeben wird.
Dazu müsste man aber nicht jedes einzelne Zeichen prüfen.
Die Prüfung der einzelnen Zeichen verhindert auch nicht, daß der 31. Februar eingegeben wird.
In VB würde ich das so schreiben:
Option Explicit
Private Sub Text1\_Validate(Cancel As Boolean)
If Not IsDate(Text1.Text) Then
MsgBox "Bitte ein gültiges Datum eingeben!", vbCritical
Cancel = True
End If
End Sub
Hallo Reinhard,
Dein code zeigt zwar bei Eingabe eines Buchstabens die msgbox, wenn sie bestätigt ist wird aber der Buchstabe in die cbo geschrieben, was ja in meinem Code mit Keyascii=0 unterbunden wird. Keyascii=0 in Deine Funktion eingebaut funktioniert nicht. Du siehst mich ratlos.
Gruß Wilhelm
Hallo Anno74,
es handelt sich, zur Klarstellung, um VBA. Ich brauche die Prüfroutine, die nur die Eingabe von den Ziffern 1 - 9, Punkt und Backspace zulässt, in vielen Comboboxen, die ein Datum aufnehmen sollen. Bisher habe ich die Prüfroutine, wie in meiner Frage, in jedes Keypress-Ereignis der jeweiligen cbo geschrieben.
Was im Prinzip in einer Funktion geschieht, habe ich weiter unten (Code aus einer Sub in eine Funktion auslagern, 17.10.09) gelernt, aber das Prinzip scheint (bei mir) bei Keyascii nicht zu greifen, oder weißt Du Rat?
Gruß Wilhelm
das es sich um VBA handelt dachte ich mir.
Aber wie du gesehen hast, wenn man die Frage nicht richtig stellt, dann wird das nichts. Meistens sind es die kleinen Sachen die wichtig sind um eine Lösung zu finden.
Aber nun zu Deinem Problem.
Die Funktion schiebe in ein Modul
Public Function CheckKey(ByVal Key As Integer) As Boolean
Case vbKey0 To vbKey9, vbKeyBack, 46 'Pkt
CheckKey = False
Case Else
CheckKey = True
'Hier könntest du noch eine Meldung anzeigen
End Select
in das KeyPress Ereignis der Combobox schreibst du dann folgendes
If CheckKey(KeyAscii) Then KeyAscii = 0
oder halt
If CheckKey(KeyAscii) then
KeyAscii=0
'Hier kannst du eine Meldung anzeigen
End If
Hallo,
in VBA 6.0 gibt es _validate nicht und das Datum soll tatsächlich nur in der Form z.B 10.11.2009 und nicht anders eingegeben werden. Vor allem benötige ich den entsprechend modifizierten code auch für viele andere Prüfroutinen, z.B „ja/nein“, „Käufer/Verkäufer“, „Einer/Mehrere“ "bebaut/unbebaut"pp
Alex hat unten einen Lösungsvorschlag entwickelt, den ich morgen gleich ausprobieren will.
Herzlichen Dank an Dich und
liebe Grüße Wilhelm
Option Explicit
Private Sub cbo1\_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
KeyAscii = Filter(KeyAscii)
End Sub
Private Function Filter(ByVal Taste As Integer) As Integer
Select Case Taste
Case vbKey0 To vbKey9, vbKeyBack, 46 'Pkt
Filter = Taste
Case Else
Filter = 0
MsgBox "Datumsformat!"
End Select
End Function
Ungetestet! Ich habe kein VBA. Müsste aber laufen.