Problem Mit Stringfunktion Right

  • VB.NET
  • .NET (FX) 4.0

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von VB1963.

    Problem Mit Stringfunktion Right

    Hallo
    Ich habe ein merkwürdiges Problem. Hier erstmal die Stelle im Code um die es geht.

    Quellcode

    1. Dim t As Integer = CInt(Val(Right(tof_NuKrAnf.ToString, 9)))
    2. If CInt(Val(Mid(tof_NuKrAnf.ToString, 9, 1))) = "0" Then
    3. tof_PZ = tof_PZ + 4
    4. Else
    5. tof_PZ = tof_PZ + 1
    6. End If

    Zeile 1 gehört nicht zum Programm Code, ist nur zum testen.
    Ich möchte von einem 9stelligen StringText die letzte Zahl haben.
    Folgendes passiert.
    In Zeile 1 bekomme ich bei Left (als auch bei Right) die Fehler Meldung:
    Fehler 1 "Public Property Left As Integer" hat keine Parameter, und der Rückgabetyp kann nicht indiziert werden.
    In Zeile 2 benutze ich Mid merkwürdigerweise geht es damit.
    Wer kann da einen Rat geben woran es liegt?
    Hilfe den Nichtwissenden :thumbsup:
    *hust* Visual Studio - Empfohlene Einstellungen
    *räusper* Böses aus VB6/VB2003 - und die richtigen VB.NET-Alternativen

    Zu der genauen Fehlermeldung (komisch, dass da "Public Property Left As Integer" steht, in dem Code aber nirgends "Left" vorkommt): Klick mal mit der rechten Maustaste auf das problematische "Left" und dann auf "Gehe zu Definition". Dann wird dort hin gesprungen, wo Left deklariert ist. Entweder direkt im Code, wenn der Code von dir stammt, oder der ObjectBrowser geht auf und markiert die Property.
    Meine Kristallkugel prophezeit, dass Du den Code in einer Form stehen hast. Forms haben eine Left-Eigenschaft. Die sagt, wie weit entfernt sie vom linken Bildschirmrand positioniert sind. Deshalb geht dann auch der Object-Browser auf, weil die Property nicht von Dir geschrieben wurde.

    Aber ja. Val, Mid, Right und so weiter sind Banane (siehe zweiter Link oben).
    Dazu kommt, dass Du einen Text erst mit Val zu Double parst, den dann mit CInt zu einem Integer konvertierst und das dann mit einem String vergleichst. Daraus schließe ich, dass Du Option Strict Off hast (siehe erster Link oben).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Hi
    Ich habs irgentwo stehen, das ich Basic Spaghetti Code Programmierer bin. Ich denke wenn Du den Code von meinem Programm siehst, würdest Du die Hände über denn Kopf zusammen schlagen und...
    Ich habe mein Programm fast fertig, und es läuft soweit. Ich bin 62 und fürchte das ich Objektorientiert nicht mehr kapieren werde. Wenn mein Chef und mein Kollege demnächst einen Haufen Eingabearbeit nicht mehr machen müssen, fragt keiner danach wie der Code aussieht. Ich bewundere alle die bei VB, C++, C# usw den absoluten Durchblick haben, also Tadel Leute wie mich und die, die nur so aus Spass ein wenig programmieren wollen, nicht zu sehr. Ach so, natürlich Strict Off, sonst könnte ich mich vor Fehlermeldungen kaum noch retten.
    Nochmal zu meinem Problem, Mid Right und Left arbeiten doch nach dem gleichen Prinzip, warum geht dann bei mir Mid, da müsste der Fehler doch auch kommen.
    Hilfe den Nichtwissenden :thumbsup:
    Der Knackpunkt ist, dass Right und Left nicht als MS.VB-Funktion, sondern als Form-Property (worauf ja auch die Fehlermeldung schon hinweist) erkannt werden. Setz mal vor die beiden ein Strings., dann wird es dem Compiler klar, was Du meinst, und probiere es nochmal.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Wie gesagt: Left und Right sind Properties von Forms. Und ich vermute mal, dass Dein Code in einer Form steht. Mid ist halt keine Property, deshalb wird sozusagen weitergesucht, bis Mid im Microsoft.VisualBasic-Namespace gefunden wird.
    Codemäßig kann man das so reproduzieren:

    VB.NET-Quellcode

    1. Namespace Microsoft.VisualBasic 'In Microsoft.VisualBasic.dll (vom .NET Framework bereitgestellt)
    2. Public Module Strings
    3. Public Function Left(str As String, Length As Integer) As String
    4. '...
    5. End Function
    6. Public Function Right(str As String, Length As Integer) As String
    7. '...
    8. End Function
    9. Public Function Mid(str As String, Start As Integer) As String
    10. '...
    11. End Function
    12. End Module
    13. End Namespace
    14. Namespace System.Windows.Forms 'In System.Windows.Forms.dll (vom .NET Framework bereitgestellt)
    15. Public Class Form
    16. Public Property Left As Integer
    17. Public Property Right As Integer
    18. End Class
    19. End Namespace
    20. Namespace WindowsApplication1 'In WindowsApplication1.exe (von Dir programmiert)
    21. Public Class Form1
    22. Inherits Form
    23. Sub Test()
    24. MessageBox.Show(Left.ToString) 'Findet die System.Windows.Forms.Form.Left-Property. Funktioniert.
    25. MessageBox.Show(Right.ToString) 'Findet die System.Windows.Forms.Form.Right-Property. Funktioniert.
    26. MessageBox.Show(Mid.ToString) 'Es gibt keine System.Windows.Forms.Form.Mid-Property. Stattdessen wird die Microsoft.VisualBasic.Strings.Mid-Funktion gefunden. Die benötigt aber Parameter, deshalb kompiliert das hier nicht.
    27. MessageBox.Show(Left("Hallo", 1)) 'Findet die System.Windows.Forms.Form.Left-Property. Die kann man aber so nicht verwenden, deshalb kompiliert das hier nicht.
    28. MessageBox.Show(Right("Hallo", 1)) 'Findet die System.Windows.Forms.Form.Right-Property. Die kann man aber so nicht verwenden, deshalb kompiliert das hier nicht.
    29. MessageBox.Show(Mid("Hallo", 1)) 'Es gibt keine System.Windows.Forms.Form.Mid-Property. Stattdessen wird die Microsoft.VisualBasic.Strings.Mid-Funktion gefunden. Funktioniert.
    30. End Sub
    31. End Class
    32. End Namespace

    Dazu gibt's noch folgendes zu sagen:

    In VB sind Module komisch. Wenn man das Modul selbst sieht, sieht man automatisch auch alles, was drin ist. Schreibt man also Microsoft.VisualBasic. hin, sieht man sowohl das Modul selbst (Strings), als auch alles, was drin ist (Left, Mid, etc.). Standardmäßig gibt es einen projektweiten Import des Microsoft.VisualBasic-Namespaces. Das heißt, man sieht überall, wo man im Projekt Code schreibt, den Inhalt dieses Namespaces. Und deshalb auch das Strings-Modul und deshalb auch alles, was drin ist. Deshalb kann man einfach so überall Mid aufrufen.

    Aber es gibt gewisse Regeln/Reihenfolgen, nach denen Namen gesucht werden. Schreibst Du einfach so Left hin, wird zuerst geguckt, ob es eine lokale Variable mit dem Namen gibt. Gibt's die nicht, wird nach anderen Membern in der gleichen Klasse gesucht (Methoden, Properties, etc.). Dann wird die Vererbungshierarchie nach oben durchsucht (dadurch, dass Du den Code in einer Klasse stehen hast, die von System.Windows.Forms.Form erbt, wird dort eben die Left-Property der System.Windows.Forms.Form-Klasse gefunden). Erst später irgendwann werden projektweite Importe durchsucht, wodurch dann das Strings-Modul und dadrin die Left-Funktion gefunden wird.

    Die Fehlermeldung "[...] hat keine Parameter, und der Rückgabetyp kann nicht indiziert werden" kommt dadurch zustande, dass der Code Foo(Bar), wobei Foo eine Property ist, nur in folgenden Fällen Sinn macht:

    VB.NET-Quellcode

    1. Dim _Foo As Integer()
    2. Public Property Foo(Index As Integer) As Integer
    3. Get
    4. Return _Foo(Index)
    5. End Get
    6. End Property
    7. Sub Test()
    8. MessageBox.Show(Foo(10).ToString)
    9. End Sub

    Oder:

    VB.NET-Quellcode

    1. Dim _Foo As Integer()
    2. Public Property Foo() As Integer()
    3. Get
    4. Return _Foo
    5. End Get
    6. End Property
    7. Sub Test()
    8. MessageBox.Show(Foo(10).ToString)
    9. End Sub

    In ersterem Fall hat die Property einen Parameter, in letzterem hat die Property einen Typ, der indexiert werden kann (hier ein Array).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Niko Danke das Du dir so viel Mühe gemacht hast es mir so ausführlich erklären. Vieleicht komme ich doch noch hinter die Geheimnisse.
    Hilfe den Nichtwissenden :thumbsup:
    Hallo,

    bin zwar nicht der genaue Erklärer und nicht Profi aber ich versuch es mal.
    Wenn du schon weißt das es an einer bestimmten Stelle steht und die Länge auch bekannt ist dann einfach deinText.Substring(startIndex, length), nach möglichkeit immer die Eigenschaften die bereits existieren nutzen.
    Bei Variable.ToString(), stehen dir die String Eigenschaften zu verfügung

    VB.NET-Quellcode

    1. Dim text As String = ""
    2. text = "ABCDEFGH0"
    3. Dim lastValue As Integer = CInt(text.Substring(text.Length - 1, 1))
    4. If text.Substring(text.Length - 1, 1) = "0" Then
    5. Dim ola = False
    6. End If
    7. Dim olaoal = True


    Bei dir steht einiges wie
    If Hier machst du Integer-> CInt(Val(Mid(tof_NuKrAnf.ToString, 9, 1))) = Hier vergleichst du mit String->"0" Then

    Versuch die Typsicherheit über Optionen als Standard zu definieren oder schreibe am Anfang jeder Klasse "Option Strict On" .

    *Bitte kein reines Rot verwenden (siehe Regeln), Admin*

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Marcus Gräfe“ ()

    mindanao schrieb:

    Ach so, natürlich Strict Off, sonst könnte ich mich vor Fehlermeldungen kaum noch retten.
    Wenn dein Projekt fast fertig ist, solltest du trotzdem die Sache mit den Grundeinstellungen noch einmal gut überlegen.
    Du hast dein Projekt von Beginn weg nicht auf Option Strict On eingestellt und ist somit mit vielen versteckten Fehlern und Warnungen kontaminiert.
    Dein Projekt ist vor der Fertigstellung daher schon instabil. Du kannst das aber immer noch schrittweise beheben...
    In folgender Diskussion geht es auch um das gleiche Problem...
    Zwei Fragen: Aufteilung eines Programms und VB 2017
    Schau einmal ab Post #13 - da wird's interessant...
    Ist nur eine Empfehlung von meiner Seite