Goto-Befehl ersetzten

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von Westerwälder.

    Goto-Befehl ersetzten

    Hallo zusammen,
    zur Zeit schreibe ich meine Programme um. Teilweise stammt der Code aus meiner ersten Vision mit VB5 und wurde in VB 2008 übernommen. Nun in der neuen Version mit VB 2010 möchte ich es eigentlich richtig machen. Option Strict auf On geschaltet und nun möchte ich die goto-Befehle raus haben. Mir ist nicht immer klar, welche Methode die richtige ist. Do .. loop oder doch besser select case. Da solche Sachen öfters in meinem Code vorkommen, hier ein Beispiel. Ich speichere seit Jahren die Lottozahlen in einer Datenbank ab und kann eine Statistik nach Häufigkeit der gezogenen Zahlen drucken.

    Hier mal der gesamte code der Sub
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Sub Statistik()
    2. Formular.Lottostatistik_Initalisieren()
    3. Formular.Zeile = 1
    4. With Formular
    5. .Zeilenschaltung(2)
    6. .B = "Deutscher Lottoblock 6 aus 49"
    7. .Excel_Eintragen(True, False, True)
    8. .Zeilenschaltung(2)
    9. End With
    10. Dim VonDatum As Date = CDate(Datum.Kurz)
    11. Dim BisDatum As Date = CDate("01.01.1901")
    12. Dim AnzahlZiehungen As Integer = 0
    13. Dim GezoLottozahlen(49) As Integer
    14. Dim TmpLottozahlen(50) As Integer
    15. Dim TmpZusatzzahlen(50) As Integer
    16. Dim FestLottozahlen(49) As Integer
    17. Dim GezoZusatzzahlen(49) As Integer
    18. Dim FestZusatzzahlen(49) As Integer
    19. For FLZ As Integer = 0 To 49
    20. FestLottozahlen(FLZ) = FLZ
    21. Next
    22. Dim GezoSuperzahlen(9) As Integer
    23. BankName = Programm.FinanzBank.BankName
    24. BankPfad = Programm.FinanzBank.BankPfad
    25. IdentNummer = 200003
    26. Initalisieren()
    27. ConIntern = New OleDb.OleDbConnection
    28. CmdIntern = New OleDb.OleDbCommand
    29. ConIntern.ConnectionString = BankVerbindung
    30. CmdIntern.Connection = ConIntern
    31. ConIntern.Open()
    32. CmdIntern.CommandText = "Select * from " & Banktabelle & " where Ident_Nummer like 200003"
    33. ReaderIntern = CmdIntern.ExecuteReader
    34. ' Ermitteln der bereits gezogenen Lottozahlen
    35. Do While ReaderIntern.Read
    36. AnzahlZiehungen = (AnzahlZiehungen + 1)
    37. If CDate(ReaderIntern("FN01").ToString) < VonDatum Then VonDatum = CDate(ReaderIntern("FN01").ToString)
    38. If CDate(ReaderIntern("FN01").ToString) > BisDatum Then BisDatum = CDate(ReaderIntern("FN01").ToString)
    39. GezoLottozahlen(CInt(Val(ReaderIntern("FN03").ToString))) = GezoLottozahlen(CInt(Val(ReaderIntern("FN03").ToString))) + 1
    40. GezoLottozahlen(CInt(Val(ReaderIntern("FN04").ToString))) = GezoLottozahlen(CInt(Val(ReaderIntern("FN04").ToString))) + 1
    41. GezoLottozahlen(CInt(Val(ReaderIntern("FN05").ToString))) = GezoLottozahlen(CInt(Val(ReaderIntern("FN05").ToString))) + 1
    42. GezoLottozahlen(CInt(Val(ReaderIntern("FN06").ToString))) = GezoLottozahlen(CInt(Val(ReaderIntern("FN06").ToString))) + 1
    43. GezoLottozahlen(CInt(Val(ReaderIntern("FN07").ToString))) = GezoLottozahlen(CInt(Val(ReaderIntern("FN07").ToString))) + 1
    44. GezoLottozahlen(CInt(Val(ReaderIntern("FN08").ToString))) = GezoLottozahlen(CInt(Val(ReaderIntern("FN08").ToString))) + 1
    45. GezoZusatzzahlen(CInt(Val(ReaderIntern("FN09").ToString))) = GezoZusatzzahlen(CInt(Val(ReaderIntern("FN09").ToString))) + 1
    46. GezoSuperzahlen(CInt(Val(ReaderIntern("FN10").ToString))) = GezoSuperzahlen(CInt(Val(ReaderIntern("FN10").ToString))) + 1
    47. Loop
    48. ConIntern.Close()
    49. For UL As Integer = 1 To 49
    50. TmpLottozahlen(UL) = GezoLottozahlen(UL)
    51. TmpZusatzzahlen(UL) = GezoZusatzzahlen(UL)
    52. Next
    53. Dim Zähler, Max As Integer
    54. Dim i, j As Integer
    55. Dim HL(49) As Integer
    56. Dim ML(49) As String
    57. Dim SL(49) As Boolean
    58. Dim Speicher(2) As String
    59. Dim n As Integer = 0
    60. ' Listbox1 wird durch ein Listoff ersetzt
    61. Finanz.ListBox1.Items.Clear()
    62. Finanz.ListBox1.Sorted = False
    63. 250: n = 0
    64. 260: n = n + 1
    65. If n = 50 Then GoTo 300
    66. SL(n) = False
    67. GoTo 260
    68. Stop
    69. 300: Max = 0
    70. n = 0
    71. 310: n = (n + 1)
    72. If n = 50 Then GoTo 350
    73. If TmpLottozahlen(n) > Max Then Max = TmpLottozahlen(n)
    74. GoTo 310
    75. Stop
    76. 350: Zähler = (Max + 1) : i = 0 : j = 0 : n = 0
    77. 360: Zähler = (Zähler - 1)
    78. If Zähler < 0 Then GoTo 600
    79. 370: i = (i + 1)
    80. If i = 50 Then i = 0 : GoTo 360
    81. If TmpLottozahlen(i) = Zähler Then GoTo 380
    82. GoTo 370
    83. Stop
    84. 380: If SL(i) = True Then GoTo 370
    85. SL(i) = True
    86. Speicher(2) = CStr(i)
    87. Speicher(1) = CStr(TmpLottozahlen(i))
    88. Anzeige = Speicher(1) + " x die " + Speicher(2)
    89. Finanz.ListBox1.Items.Add(Anzeige)
    90. GoTo 370
    91. Stop
    92. 600: ' Lottozahlen Häufigkeiten aufbereitet
    93. Finanz.ListBox2.Items.Clear()
    94. Finanz.ListBox2.Sorted = False
    95. 650: n = 0
    96. 660: n = n + 1
    97. If n = 50 Then GoTo 700
    98. SL(n) = False
    99. GoTo 660
    100. Stop
    101. 700: Max = 0
    102. n = 0
    103. 710: n = (n + 1)
    104. If n = 50 Then GoTo 750
    105. If TmpZusatzzahlen(n) > Max Then Max = TmpZusatzzahlen(n)
    106. GoTo 710
    107. Stop
    108. 750: Zähler = (Max + 1) : i = 0 : j = 0 : n = 0
    109. 760: Zähler = (Zähler - 1)
    110. If Zähler < 0 Then GoTo 800
    111. 770: i = (i + 1)
    112. If i = 50 Then i = 0 : GoTo 760
    113. If TmpZusatzzahlen(i) = Zähler Then GoTo 780
    114. GoTo 770
    115. Stop
    116. 780: If SL(i) = True Then GoTo 770
    117. SL(i) = True
    118. Speicher(2) = CStr(i)
    119. Speicher(1) = CStr(TmpZusatzzahlen(i))
    120. Anzeige = Speicher(1) + " x die " + Speicher(2)
    121. Finanz.ListBox2.Items.Add(Anzeige)
    122. GoTo 770
    123. Stop
    124. 800: ' Zusatzzahlen Häufigkeiten aufbereitet
    125. With Formular
    126. .B = "Die Statistik enthält Lottoziehungen vom " & VonDatum & " bis " & BisDatum & "."
    127. .Excel_Eintragen(False, False, False)
    128. .Zeilenschaltung(1)
    129. .B = "Es wurden insgesamt " & AnzahlZiehungen.ToString & " Ziehungen berücksichtigt."
    130. .Excel_Eintragen(False, False, False)
    131. .Zeilenschaltung(2)
    132. .B = "Zahlenauswertung"
    133. .F = "Häufigkeitsauswertung"
    134. .Excel_Eintragen(True, False, True)
    135. .Zeilenschaltung(1)
    136. .B = "Zahl"
    137. .C = "Lottozahl"
    138. .D = "Zusatzzahl"
    139. .E = "Superzahl"
    140. .F = "Lottozahl"
    141. .G = "Zusatzzahl"
    142. .H = "MZ"
    143. .Excel_Eintragen(False, False, False)
    144. .Zeilenschaltung(1)
    145. End With
    146. For Awertung As Integer = 0 To 49
    147. With Formular
    148. .Zeilenschaltung(1)
    149. .B = FestLottozahlen(Awertung)
    150. .C = GezoLottozahlen(Awertung)
    151. .D = GezoZusatzzahlen(Awertung)
    152. If Awertung < 10 Then
    153. .E = GezoSuperzahlen(Awertung)
    154. End If
    155. If Awertung > 0 And Awertung < 50 Then
    156. .F = Finanz.ListBox1.Items(0)
    157. With Finanz.ListBox1
    158. .Items.RemoveAt(0)
    159. .Refresh()
    160. End With
    161. .G = Finanz.ListBox2.Items(0)
    162. With Finanz.ListBox2
    163. .Items.RemoveAt(0)
    164. .Refresh()
    165. End With
    166. Ausdruck = Nothing
    167. Ausdruck = Basis.Right(.F, 2)
    168. If Val(Basis.Left(Ausdruck, 1)) < 1 Then Ausdruck = Basis.Right(.F, 1)
    169. Statistik_EigeneZahlen_Pruefung(Ausdruck)
    170. If MeineZahlStatistikDabei = True Then .H = "X"
    171. If MeineZahlStatistikDabei = False Then .H = Nothing
    172. End If
    173. .Excel_Eintragen(False, False, False)
    174. End With
    175. Next
    176. With Formular
    177. .Drucken_Tabellenblatt()
    178. .Speichern_und_Schliessen()
    179. .Excel_Speicher_Entfernung()
    180. .Excel_Speicher_Entfernung()
    181. End With
    182. MsgBox("Die Lottostatistik wurde erstellt. ", MsgBoxStyle.Information, PRGM.Meldung)








    [/vb]
    Gruß Markus
    oh, oh - kann komplett in die Tonne ;(

    Für leidlich modernen DB-Zugriff gugge "Datenbank in 10 Minuten" auf Movie-Tuts

    Auch inhaltlich kann man eiglich nix dazu sagen, ohne das DAtenmodell zu kennen.
    Dazu könnteste einen DB-Zugriff nach genanntem Tut einrichten, und dann hast du ein typisiertes DAtaset, und kannst davon einen Screenshot posten - dass man weiß, worüber gesprochen wird.
    Immer wieder lese ich hier, dass ich mit dem falschen Datenbankzugriff auf meine Access-Datenbank arbeite.
    Erlernt habe ich dieses aus dem Buch "Einstieg in Visual Basic 2008 von Thomas Theis / Galileo Computing" Seite 275 uff.
    Komme sehr gut damit zurecht und bisher sind auch keine Fehler aufgetreten.
    Die Daten übernehme ich dann meist in eine Klasse. Funkioniert alles super.
    Was spricht eigentlich dagegen?
    Gruß Markus
    Was spricht eigentlich dagegen?
    Dass du dir den Weg zu Databinding verbaut hast.

    guck dirmal die Sample-Solution von "Datenbank in 10 Minuten" auf Movie-Tuts, uind versuche, dieselbe Funktionalität mit deinem Ansatz umzusetzen.
    Dann zähl die Codezeilen, die du aufwendest, und wieviele ich aufwende.
    Und das ist noch ein ganz ganz einfacher View.

    Übrigens: Das VB-Openbook von Galileo ist Mist

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Um das Programm komplett in die Tonne zu werfen ist es dahingehend zu spät, dass Du bereits damit gearbeitet hast und so nicht frei genug bist, das ganze völlig neu aufzuziehen (Du bist nun voreingenommen).
    Allerdings lässt sich das ganze, wenn Du alles neu machst, relativ einfach testen, da Du mit dem neuen Programm und den alten Daten dieselben Ergebnisse erzielen musst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Gut, der Einwand ist berechtigt. Bei mir schaut das halt so aus:

    VB.NET-Quellcode

    1. Property Gewinnzahl1() As String
    2. Get
    3. Return Feld(3).Wert
    4. End Get
    5. Set(ByVal value As String)
    6. Feld(3).Wert = value
    7. End Set
    8. End Property
    9. Property Gewinnzahl2() As String
    10. Get
    11. Return Feld(4).Wert
    12. End Get
    13. Set(ByVal value As String)
    14. Feld(4).Wert = value
    15. End Set
    16. End Property

    Und habe bei Bedarf hier direkt die Möglichkeit noch was zu hinzu zugeben

    Return "Gewinnzahl 2 " & Feld(4).Wert

    Nur hilft mir dieses ja nun nicht weiter.
    Gruß Markus

    RodFromGermany schrieb:

    Um das Programm komplett in die Tonne zu werfen ist es dahingehend zu spät, dass Du bereits damit gearbeitet hast und so nicht frei genug bist, das ganze völlig neu aufzuziehen
    Versteh ich nicht.
    Neues Projekt anfangen, als erstes den DB-Zugriff konfigurieren, und los.
    Das habich schneller erledigt, als der TE auch nur ein einziges GoTo ausgewechselt hat ;)

    "Datenbank in 10 Minuten" auf Movie-Tuts heißt deshalb so, weil man mit dem KnowHow tatsächlich in 10 Minuten eine schon lauffähige Basis einer DB-Anwendung hinkloppen kann.

    Natürlich dauerts wesentlich länger, sich das KnowHow erstmal zu erarbeiten, aber hat mans erstmal, dann gilt das mit den 10 Minuten ungefähr für alles, was man anfasst.
    Die bestehenden Datenbanken kann ich nicht aufgeben.
    Und RodFromGermany hat schon Recht, da ich bereits zwei Monate an der Neuprogrammierung sitze.

    Mir geht es eigentlich nur um die nummerische Filterung der Zahlen nicht um deren Speicherung.
    Gruß Markus
    ich hab nicht gesagt, "die bestehenden Datenbanken aufgeben".

    Nur einen modernen Zugriff einrichten. Dass du da schon 2 Monate dran sitzt, spricht in meinen Augen nochmal dafür, es mal endlich richtig anzufangen.

    Du kannstes ja einfach mal probieren - das kostet dich vlt. einen Tag, um so weit zu kommen, abschätzen zu können, ob sich die Umstellung amortisieren wird.

    Und wenn du weiter in .Net machen willst, annere Projekte - willst du immer so weiter-wursteln?
    Ich sehe zum Umlernen keine Alternative. Es ist nie zu spät, aber je früher man anfängt, hat man doch Zeit gespart.

    ErfinderDesRades schrieb:

    Das habich schneller erledigt, als der TE auch nur ein einziges GoTo ausgewechselt hat
    Korrekt, denn Du bist nicht voreingenommen.
    Am besten ist es natürlich, die Datenbank und die Aufgabenstellung in die Hand zu nehmen und das alte Programm nicht anzusehen, wenn ein neues gemachtt wird.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    OK, wollte es mir anschauen, jedoch sind beim Konvertieren einige Fehler aufgetreten.

    Ich weiss ja nicht, ob deine Lösung mein System unterstützt. Zur Zeit arbeite ich mit so genannten Identnummern. D.h. jede meiner Datenbanken hat das gleiche Format und eine Tabelle namens CDS - ControlDatenSystem. Dort stehen die Kopfdatensätze, d.h. Informationen in welcher Tabelle der eigentliche Datensatz steht. Die Namensbeschrifter der Datenfelder 1 - 44 und bei erweiterbaren Datensatzsystem die nächste freie Nummer für den nächsten Datensatz.
    Wie gesagt wird dies alles über eine Identnummer gesteuert. So muss ich beim Lesen oder Suchen nur die Identnummer und das Feld(1) angeben.
    Gruß Markus

    RodFromGermany schrieb:

    Am besten ist es natürlich, die Datenbank und die Aufgabenstellung in die Hand zu nehmen und das alte Programm nicht anzusehen, wenn ein neues gemachtt wird.
    Naja - ich hab mich gelegentlich auch gewundert, wie schnell ich vorankam mit dem Neu-Schreiben eines VB6-Teiles, eben weil ich eine konkrete Vorstellung vom Anwendungs-Konzept hatte, und auch jederzeit spickeln konnte.
    Also eine bestehende Vorlage nachprogrammieren (und dabei partiell auch verbessern) geht wesentlich zügiger als eine Entwicklung, bei der sich die End-Form erst während des Wachstums herauskristallisiert.

    Westerwälder schrieb:

    D.h. jede meiner Datenbanken hat das gleiche Format und eine Tabelle namens CDS - ControlDatenSystem. Dort stehen die Kopfdatensätze, d.h. Informationen in welcher Tabelle der eigentliche Datensatz steht. Die Namensbeschrifter der Datenfelder 1 - 44 und bei erweiterbaren Datensatzsystem die nächste freie Nummer für den nächsten Datensatz.
    Das scheint mir ein wirres Datenmodell, auf dem man nix gescheites drauf aufbauen kann.
    Vermutlich enthält es sehr viele Design-Fehler, also sieh zu, wiede damit klar kommst.

    Inne Datenbänkerei muss man schon einen sehr sehr guten Grund haben, einen Datenbestand auf mehrere Datenbanken aufzuteilen. Und wo die bei dir auchnoch strukturell gleich sind, erscheint das besonders abstrus.

    aber ich frag mal: Warum sind deine Daten über mehrere DBs verstreut?
    Nun das hat mehrere Gründe,
    A) nutzt mein Sohn ein Teil des Programmes, hat aber nichts in den Mieterdaten verloren und
    B) möchte ich die Datenbanken nicht zu sehr anwachsen lassen.

    Also ich finde gerade das mein Modell eine besondere Ordnungsstruktur enthält und Verwechslungen absolut ausschliesst.
    Komplizierte Abfrage habe ich selten. Diese mache ich dann in den entsprechendne Klassen.
    Gruß Markus
    Das mit dem Sohn lässt sich sicherlich auch anners lösen.

    Das mit dem Anwachsen verstehe ich nicht. Datenbanken sind dazu da, riesige Datenbestände zu verwalten - das ist doch der Witz an der Sache.
    Für popelige 10000 Datensätze brauchst du keine Datenbank - die lädtste einfach so in den Speicher, und schreibst sie komplett auch wieder auf Platte (DB-Programmierung ohne Datenbank)
    Vllt jetzt nochmal als ernst gemeinter Hinweis:

    Die Verwendung von Goto und der daraus resultierende Spaghetticode führen zu einem extrem unwartbaren Code, da es sehr schwer nachzuvollziehen ist, wie der Programmfluss gerade verläuft. Statt Goto (das quasi nur als Relikt aus alten BASIC Zeiten überlebt hat) sollte man auf die von VB und allen anderen höheren Programmiersprachen bereigestellte Kontrollstrukturen zurückgreifen, vor allem "If" und "While" sowie "Select".
    ok, irgendwie kommen wir so nicht weiter.
    Leider kann ich keine lauffähige Version zur Verfügung stellen, da dies zu umfangreich und auch zu vertraulich ist.
    Kann dir aber eine DLL zukommen lassen, wo eigentlich alle wichtige Sachen ablaufen.

    Hallo Quadsoft:
    Diese Geschichte war auch mal Bestandteil eines GWBasic codes aus den 80 ziger von mir.
    Nun fragte ich ja bereits bei meinem ersten Post nach einer dieser Möglichkeiten.
    Gruß Markus

    Westerwälder schrieb:

    VB.NET-Quellcode

    1. 250: n = 0
    2. 260: n = n + 1
    3. If n = 50 Then GoTo 300
    4. SL(n) = False
    5. GoTo 260
    6. Stop
    7. 300: Max = 0
    8. n = 0
    9. 310: n = (n + 1)
    10. If n = 50 Then GoTo 350
    11. If TmpLottozahlen(n) > Max Then Max = TmpLottozahlen(n)
    12. GoTo 310
    13. Stop
    lässt sich so zusammenfassen:

    VB.NET-Quellcode

    1. Max = 0
    2. For n = 0 To 49
    3. SL(n) = False
    4. If TmpLottozahlen(n) > Max Then Max = TmpLottozahlen(n)
    5. Next
    und da gibt es noch etliche Strukturen, die genau so aussehen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!