VisualBasic Der Befehl Focus in VB.NET will nicht

_CH_K_1991_

Lieutenant
Registriert
Nov. 2008
Beiträge
772
Hallo zusammen
Ich habe vor kurzem zu Programmieren angefangen (Jetzt kenne ich VBA und etwas VB.NET).
Im VBA funktioniert folgender Code ohne Probleme (Text markieren und Curser in Eingabefeld setzen):
Code:
With txtEingabe
    .SelStart = 0
    .SelLength = Len(.Text)
    .SetFocus
End With
In VB.NET heisst das ganze ja (ich hoffe ich habe es richtig reingetippt, dieser Code habe ich nicht gerade zur Hand):
Code:
With txtEingabe
    .SelectionStart = 0
    .SelectionLength = Len(.Text)
    .Focus()
End With
Dieses .Focus() will bei mir nicht richtig funktionieren, der Text wird zwar nach der Eingabe und nach der Berechnung markiert, aber ganz am Anfang wird in kein Feld der Cursor gesetzt. Wie kann ich das beheben?

Hier noch der komplette Code den ich mal ausprobiert habe, damit ihr versteht in welchem Feld und so ich das Eingegeben habe (das ist der funktonierende VBA Code):
Code:
Private Sub cmdVerarbeiten_Click()

'Variabeln definieren
Dim sngGeschwindigkeit As Single
Dim sngDauer As Single

Const cDistanz = 2 * 384403

'Geschwindigkeit ermitteln
On Error GoTo KeineZahl
sngGeschwindigkeit = txtEingabe.Text

'Dauer der Reise berechnen
On Error GoTo kein0
sngDauer = cDistanz / sngGeschwindigkeit / 24

'Ergebnis anzeigen
txtAusgabe.Text = sngDauer

GoTo Schluss

'Fehlerbehandlung
KeineZahl: MsgBox "Die Geschwindigkeit muss eine Zahl sein!"
GoTo Schluss
kein0: MsgBox "Die Rechnung kann nicht durch 0 dividiert werden!"

Schluss:

'Eingabetext markieren

With txtEingabe
    .SelStart = 0
    .SelLength = Len(.Text)
    .SetFocus
End With
    
End Sub

Vielen Dank für Tipps oder Hilfe
Gruss
 
Wieso soll der Cursor am Anfang stehen?
Unter VB.net würde ich das übrigens eher so machen:
Code:
txtEingabe.Focus()
txtEingabe.SelectAll()

Denn Len benutzt man dort nicht mehr, da veraltet. Richtig würde es so aussehen:
Code:
txtEingabe.Text.Length
 
1668mib schrieb:
Und die GoTos sind State-of-the-Art?
Wenn du das so interpretierst, dann hast du leider ein Problem ;) Auf solche Schlampereien gehe ich nicht ein. Ich will dem TE aber keinen Vorwurf machen. Er hat scheinbar - wie er auch selbst sagt - kein tieferes Wissen, was ja auch nicht schlimm ist, denn jeder hat mal angefangen. Wenn er sich irgendwann mal richtig mit VB.net auseinander setzt, dann wird er sich solche "Dummheiten" schnell abgewöhnen.
 
@qHiL
Danke für die Info, werde das mal ausprobieren.
Der Cursor sollte, wenn ich das Programm öffne, direkt in das erste Eingabefeld springen, so dass ich sofort zu schreiben anfangen könnte.

EDIT:// leider hat dein Vorschlag, das Problem nicht gelöst... Aber es sieht wohl schöner aus ;)
Ich denke mal, dass ganze könnte man auch zwischen With und EndWith schreiben oder?

Das heisst Len oder txtEingabe.Text.Length kann ich direkt weglassen?

@beide
Ich habe mom einen Einsteigerkurs für VB und VBA und dort wird aber nicht mir Visual Basic gearbeitet sonder mit dem VB Editor im Word - also mit VBA.
Und in VBA ist das glaubs die einzige Methode für die Fehlerbehebung nicht?

Aber wenn's schon angesprochen wird, wie würde ich denn das in VB.Net korrekt machen?

Vielen Dank
 
Zuletzt bearbeitet:
Es gibt bei den Form-Elementen eine Eigenschaft names TabIndex.

Versuch die mal ordentlich zu ordenen, also in das gewünschte Textfeld eine 0 rein.

Wenn es dir bei den GoTos nur um Fehlerbehandlung ging, versuchs einfach mitm

PHP:
Try

Catch ex as Exception

End Try

Ansonsten ändere die Struktur so, dass die Funktionen in der richtigen Reihenfolge ausgeführt werden.
 
Ich habe die Elemente so angeordnet, dass das erste mit 1 anfängt (aber beim proggen ist wohl immer die 0 erster :D). Werde das mal ändern. Und soll ich den Eingabetextcode jeweils eher ganz am Anfang reinschreiben, als eher am Schluss?

Wenn du dir den Code oben nochmals durchliest, wirst du sehen, dass ich die Go to so angesetzt habe, damit ich Rechenfehler wie eine Dividsion durch 0 oder Buchstaben anstatt Zahlen aussortieren konnte.
Ansonsten gibt die Software ja sofort ein Laufzeitfehler aus.

Die Go To's habe ich nicht gesetzt weil der Code falsch nacheinander gereit war!

Merci für die Info.
Gruss
 
Du könntest eine einfache if-Abfrage um die Berechnung bauen oder einen 2. Try-Catch Block drumherum setzen.

Code:
Try
wert = textfeld.text
'Nun gehts mit einer Abfrage
  if not wert = 0 and isnumeric(wert) then
    berechnung = zahl / wert
  else
    MsgBox("Das wäre eine Division durch 0 gewesen!")
    'Wenn du nichts mehr in der Funktion tun kannst oder willst -> exit sub()
    exit sub()
  end if

'Hier gehts lustig weiter
catch ex as Exception
  msgbox(ex.Message)
end try
Code:
Try
wert = textfeld.text
try
  berechnung = zahl / wert
catch ex2 as Exception
  MsgBox("Inner Exception: " & ex2.Message)
  'Wenn du nichts mehr in der Funktion tun kannst oder willst -> exit sub()
  exit sub()
end try

'Hier gehts lustig weiter
catch ex as Exception
  msgbox("Outer Exception: " & ex.Message)
end try

Mal nen bischen angepasst.
Und nochmal geändert, trycast geht leider nicht mit Integer
 
Zuletzt bearbeitet:
hmmm das funktoniert bei mir irgendwie nicht. Dann bekomme ich eine Fehlermeldung betreffend des Konvertieren in Single

Code:
Public Class Form1

    Private Sub cmdVerarbeiten_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdVerarbeiten.Click

        ' Definieren der Variabeln

        Dim sngGeschwindigkeit As Single
        Dim sngDauer As Single

        ' Berechnung

        Try
            sngGeschwindigkeit = txtEingabe.Text
            sngDauer = txtAusgabe.Text

            If Not sngGeschwindigkeit = 0 Then
                sngDauer = 2 * 284402 / sngGeschwindigkeit / 24
            Else
                MsgBox("Die Geschwindikeit darf nicht 0 betragen")
                Exit Sub
            End If
            catch ex As Exception
            MsgBox(ex.Message)

        End Try

    End Sub
End Class
Weisst du was das sein könnte?
Danke

Edit: Ops nicht gesehen, dass du noch einige Sachen angepasst hast.
Werde das auch noch genauer anschauen...
 
Das Problem ist, dass textbox.text natürlich String zurück gibt und nicht Single.
Du musst sie erstmal als String aufnehmen und dann ggf. eine Typenumwandlung machen (ist nicht explizit nötig, wenn man die Eingaben ordentlich eingrenzt)
Die Abfrage IsNumeric() aus dem angepassten Beispiel oben sollte für ordentliche Eingaben sorgen.
 
_CH_K_1991_ schrieb:
@qHiL
Der Cursor sollte, wenn ich das Programm öffne, direkt in das erste Eingabefeld springen, so dass ich sofort zu schreiben anfangen könnte.

EDIT:// leider hat dein Vorschlag, das Problem nicht gelöst... Aber es sieht wohl schöner aus ;)
Ich denke mal, dass ganze könnte man auch zwischen With und EndWith schreiben oder?
Wenn du möchtest, dass die Textbox direkt beim Start der Anwendung aktiv ist, musst du den Befehl
Code:
txtEingabe.Focus()
in das Form-Load-Event packen. Damit sollte es funktionieren.
_CH_K_1991_ schrieb:
Das heisst Len oder txtEingabe.Text.Length kann ich direkt weglassen?
Wenn du die Funktion .SelectAll() verwendet, brauchst du die Länge der Zeichenkette natürlich nicht, weil so oder so alles in der Textbox markiert wird.

_CH_K_1991_ schrieb:
@beide
Ich habe mom einen Einsteigerkurs für VB und VBA und dort wird aber nicht mir Visual Basic gearbeitet sonder mit dem VB Editor im Word - also mit VBA.
Und in VBA ist das glaubs die einzige Methode für die Fehlerbehebung nicht?

Aber wenn's schon angesprochen wird, wie würde ich denn das in VB.Net korrekt machen?

Vielen Dank
Um Fehler abzufangen nimmt man üblicherweise die Try-Catch-Anweisung. Allerdings nur, wenn die Fehler unerwartet sind. Wenn du schon weißt, welche Fehler auftreten können, wie z.B. eine Division durch 0 solltest das vorher abfangen und keine Try-Catch-Anweisung nutzen. Das macht erstens keinen Sinn und ist ein eher "unschöner" Stil.

_CH_K_1991_ schrieb:
hmmm das funktoniert bei mir irgendwie nicht. Dann bekomme ich eine Fehlermeldung betreffend des Konvertieren in Single

Versuch es mal mit
Code:
sngGeschwindigkeit = CSng(txtEingabe.Text)
sngDauer = CSng(txtAusgabe.Text)
Damit wird der Text (String) in Single konvertiert.
 
Zuletzt bearbeitet:
Hallo zusammen
Danke für die Geduld :)

Zur Info: ich habe es jetzt mit der angepasste oben beschriebenen Variante probiert.
Jedoch kommt immernoch der Fehler mit der Kovertierung in Single (siehe Code unten).
Ich denke, dass noch etwas im Dim Befehl falsch ist. Könnte das sein?

Wegen dem Focus Befehl... Ich habe diesen jetzt direkt in das Loadteil reingepackt (ich nehme an Doppelklick auf das Formular und dann den Befehl dort eintippen oder?)
Jedoch "pöggt" VB auch irgendwie diese Variante nicht.

Vielen Dank

@Krafty
darf ich dich noch fragen, was eigentlich diese Code hier genau machen soll?
Code:
catch ex As Exception             MsgBox(ex.Message)
Merci

Hier nochmals meinen aktuellen Code:
Code:
Public Class Form1

    Private Sub cmdVerarbeiten_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdVerarbeiten.Click

        ' Definieren der Variabeln

        Dim sngGeschwindigkeit As Single
        Dim sngDauer As Single

        ' Berechnung

        Try
            sngGeschwindigkeit = CSng(txtEingabe.Text)
            sngDauer = CSng(txtAusgabe.Text)

            If Not sngGeschwindigkeit = 0 And IsNumeric(sngGeschwindigkeit) Then
                sngDauer = 2 * 284402 / sngGeschwindigkeit / 24
            Else
                MsgBox("Die Geschwindikeit darf nicht 0 betragen")
                Exit Sub
            End If
            catch ex As Exception
            MsgBox(ex.Message)

        End Try

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        txtEingabe.Focus()
    End Sub
End Class
 
Morgen,

mit dem Try-Catch-Block werden (unerwartete) Laufzeitfehler so verarbeitet, dass das Programm trotzdem weiterläuft und man sich ggf. den Fehler ausgeben lassen kann. Bei einem Fehler springt er in den Catch-Block und tut dort, was du für angemessen hälst, in dem Fall wird die von .NET generierte Fehlermeldung ausgegeben und die Funktion explizit verlassen.

Wie ich weiter oben bereits geschrieben habe, ist es wenig verwunderlich, dass es einen Fehler gibt, wenn du versuchst jeden String(Buchstaben, Zahlen die vorerst als Zeichen gesehen werden) in Single(Gleitkommazahlen) zu konvertieren/casten.

Wenn du mit Strings rechnest, wird versucht diese implizit in Zahlen umzuwandeln, darum musst du dich vorerst nicht kümmern, du musst nur dafür sorgen, dass keine Buchstaben in die Rechnung kommen, was die Funktion IsNumeric() ziemlich gut abfangen sollte.

Wenn du eine explizite Umwandlung machen möchtest, um auf der sicheren Seite zu sein könntest du sowas probieren:

PHP:
Dim zahl as single
if IsNumeric(textbox.text) then
  zahl = textbox.text
else
  'kann man möglicherweise auch weglassen, hat den standardwert nothing nach dem dim, bin mir aber über die Warnings in VB.NET nicht sicher gerade
  zahl = nothing
end if

if not zahl is nothing then
  'hier die berechnung
else
  msgbox("konnte wegen fehlerhafter EIngabe nicht rechnen")
end if
 
dazu sollte gesagt werden das try catch blöcke nicht zum steuern eines programms verwendet werden solln
dafür is If-Else If-Else da ;P
 
Probiere es mal so:
Code:
    Private Sub cmdVerarbeiten_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdVerarbeiten.Click
        Dim sngGeschwindigkeit As Single
        Dim sngDauer As Single

        Try
            If IsNumeric(txtEingabe.Text) And IsNumeric(txtAusgabe.Text) Then
                sngDauer = CSng(txtAusgabe.Text)
                sngGeschwindigkeit = CSng(txtEingabe.Text)

                If Not sngGeschwindigkeit = 0 Then
                    sngDauer = 2 * 284402 / sngGeschwindigkeit / 24
                    MessageBox.Show("Ergebnis: " & sngDauer)
                Else
                    MessageBox.Show("Die Geschwindikeit darf nicht 0 betragen")
                End If
            Else
                MessageBox.Show("Bitte geben Sie gültige Werte ein, um die Berechnung durchzuführen.")
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
 
Besten Dank an alle :D
Es funktioniert..... fast ^^
Ich habe mir jetzt mal alles durchgelesen hier von euch und habe jetzt mehrere Sachen ausprobiert, jetzt zum Schluss noch die Variante von qHiL. Bei dieser werden jetzt aber übrigens auch die Zahlen aussortiert :D
Auch wenn man jetzt Zahlen eingibt kommt die Meldung bitte geben Sie einen gültigen Wert ein ^^
Aber übrigens, der Befehl Focus() vergesse ich jetzt einfach mal :P

Bei der der Idee von Krafty kommt bei meiner "Zahl" der Fehler (noch im Editor) "Der Is-Operator akzeptiert keine Operanden vom Typ "Single". Die Operanden müssen Referenztypen sein oder Typen, die NULL-Werte zulassen." Ich habe dannach mehrere verschiedene Dateitypen durchprobiert (z.B. auch Long) und das im Dim Befehl angepasst, jedoch brachte er dann einfach den Fehler anstatt mit "Single" einfach mit z.B. "Long".
Diese Dateitypen unterstützen doch eingentlich die Zahl Null oder? Oder habe ich hier etwas durcheinander gemacht?

Vielen Dank :D
 
Ah, vorsicht, bitte nicht NULL mit 0 verwechseln. NULL oder Nothing bedeutet, dass die Variable keine Referenz besitzt, bzw. kein Wert zugewiesen wurde. Kein Wert bedeutet nicht, dass dort 0 steht, sondern wirklich kein Wert.

Wenn es mit nothing nicht funktioniert, dann deklariere die Variable und setze den Standardwert wirklich auf 0.
Also dim wert as Single = 0

Dann kommt die einfache Abfrage ob die Textbox einen numerischen Wert enthält und ggf. die neue Zuweisung ohne Else-Zweig. (Denn sie behält anderenfalls den Wert 0)

Unten wird dann mit der Abfrage ob der Wert ungleich 0 ist die Division sowieso verhindert.

Eben nochmal geschaut und diesmal auch getestet: man könnte
dim wert as nullable(of single)
definieren, um die "referenziert nichts" Abfrage zu nutzen, aber das dürfte wohl den Rahmen sprengen.
 
Zuletzt bearbeitet:
Mh, also ich hab es hier getestet und es funktioniert vollkommen problemlos. Sprich ich habe es vorher ausprobiert. Was gibst du denn genau ein? Damit man das mal nachstellen kann :)
Bzgl. der Focus()-Funktion: Wie Krafty schon gesagt hat, gibst du der entsprechenden Textbox den Tabstop 0 und dann passt das. Das Ganze im Form-Lead--Event klappt leider nicht. Macht aber auch Sinn, weil die Form dort noch geladen wird.
 
Vielen Dank für die Antworten.
Ich bin übers Weekend weg, werde aber nachher probieren diese Tipps nochmals anzuwenden ^^
Melde mich wieder.

Schönes Wochenende
Gruss
 
Also nochmals danke vielmals an alle beide.
Ich habe von qHil nochmals den Code von oben angeschaut und diesen durchlaufen lassen.
Dieser stimmt schon soweit, aber bei mir kommt der Fehler "Bitte geben Sie eine gültigen Wert ein, ..." immer auch wenn ich eine Zahl eingebe!

@Krafty Danke für deine Erklärung, aber ich habe am Schluss die Lösung von QHil als übersichtllicher empfunden (habe noch nicht so geüpte Augen ^^)

Noch eine andere Frage zu einer andere Übung.
Dort möchte ich über eine inputbox z.b. das Alter abfragen und dann prüfen.
Dies funktioniert eigentlich gut. Aber ich habe hier noch ein Problem mit dem Befehl Nothing.
Gibt es hier eine bessere Lösung?
Danke vielmals.

Hier noch der Code vom zweiten Bsp.:
Code:
Public Class frmFormulareingabe

    Private Sub cmdStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdStart.Click
        Dim strInputausgabe As String

        strInputausgabe = InputBox("Bitte geben Sie Ihr Alter ein", "Altersabfrage")
        If strInputausgabe Is Nothing Then MsgBox("Bitte geben Sie ein Alter ein!")
        If strInputausgabe = 0 Then MsgBox("Geben Sie bitte ein gültiges Alter ein!")
        If strInputausgabe <= 17 Then MsgBox("Sie sind nicht genug alt!")
        If strInputausgabe >= 18 Then MsgBox("OK")

    End Sub
End Class
Gruss

Edit:/ Wäre glaub klüger wenn ich in diesem Fall die Variable anstatt als String in Integer definieren würde oder?
 
Zurück
Oben