Namen aus .txt-Datei zufällig auf auf Labels verteilen

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    Namen aus .txt-Datei zufällig auf auf Labels verteilen

    Wie mann im Titel schon lesen kann, möchte ich eine Art Plan erstellen, in dem z.B. 3 Label sind. In einer Textdatei (liegt im Verzeichnispfad) sind in 3 Zeilen jeweils 1 Name, also:

    Hugo1
    Hugo2
    Hugo3

    Muss ich die einzelnen Namen in Strings speichern und diese Strings dann zufällig in die Labels schreiben lassen oder wie macht man das am Besten?
    Vielen Dank schonmal :)
    Lies dir die Namen zeilenweise ein und speicher es in einem String-Array. Mit Random.Next(0,Array.GetUpperBound bekommst du eine zufälligen Member im Array. Prüf ob der Member schon benutzt wurde, falls nicht setz es ins Label und mach mit dem nächst. Label weiter.
    Läuft alles darauf hinaus ein Array/eine Liste zufällig zu sortieren:

    VB.NET-Quellcode

    1. ' Namen einlesen
    2. Dim names() As String = IO.File.ReadAllLines("C:\names.txt")
    3. 'Dim names() As String = {"Apfel", "Birne", "Pflaume", "Rotkohl"}
    4. ' zufällig sortieren
    5. Dim r As New Random
    6. Dim randomNames = (From s As String In names Order By r.NextDouble).ToList ' oder toArray
    7. ' anzeigen oder an Label vergeben
    8. randomNames.ForEach(Sub(s) Debug.Print(s))
    Hier mal ein kleines Beispiel von mir, es geht davon aus dass du 3 Labels hast benannt "lbl1", "lbl2" & "lbl3".
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    2. For i = 1 To 3
    3. Me.Controls("lbl" & i.ToString).Text = Nothing ' text aller lbls löschen
    4. Next
    5. Dim txtlns() As String = IO.File.ReadAllLines("Pfad", System.Text.Encoding.Default)
    6. Dim rnd As New Random
    7. Dim temp As Integer = 1 'counter startet bei 1 für lbl1
    8. Do 'labels durchgehen
    9. Dim bnds As Integer = rnd.Next(0, txtlns.GetUpperBound(0) + 1)
    10. If Not TextExists(txtlns(bnds)) Then
    11. Me.Controls("lbl" & temp.ToString).Text = txtlns(bnds)
    12. temp += 1
    13. End If
    14. Loop Until (temp = 4) 'prüfen ob temp counter nicht größer als anzahl der lbls ist
    15. End Sub
    16. Function TextExists(ByVal txt As String) As Boolean
    17. For Each c As Control In Me.Controls
    18. If c.GetType().FullName = "System.Windows.Forms.Label" Then
    19. If c.Text = txt Then Return True
    20. End If
    21. Next
    22. Return False
    23. End Function

    Das kannst du aber auch problemlos auf mehr Labels übertragen.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. End Sub
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. For i = 1 To
    6. Me.Controls("lbl" & i.ToString).Text = Nothing ' text aller lbls löschen
    7. Next
    8. Dim txtlns() As String = System.IO.File.ReadAllLines(Application.StartupPath & "\files\Menge.txt", System.Text.Encoding.Default)
    9. Dim rnd As New Random
    10. Dim temp As Integer = 1 'counter startet bei 1 für lbl1
    11. Do 'labels durchgehen
    12. Dim bnds As Integer = rnd.Next(0, txtlns.GetUpperBound(0) + 1)
    13. If Not TextExists(txtlns(bnds)) Then
    14. Me.Controls("lbl" & temp.ToString).Text = txtlns(bnds)
    15. temp += 1
    16. End If
    17. Loop Until (temp = 4) 'prüfen ob temp counter nicht größer als anzahl der lbls ist
    18. End Sub
    19. Function TextExists(ByVal txt As String) As Boolean
    20. For Each c As Control In Me.Controls
    21. If c.GetType().FullName = "System.Windows.Forms.Label" Then
    22. If c.Text = txt Then Return True
    23. End If
    24. Next
    25. Return False
    26. End Function
    27. End Class


    Me.Controls("lbl" & i.ToString).Text = Nothing ' text aller lbls löschen [Hier ist ein Fehler: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

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

    Du musst deine Labels auch dementsprechend bennenen. Er such nach einem Label mit dem Namen lbl1. Benenn die Labels von lbl1 - lbl3 dann klappts auch.
    Die Farbe Rot ist übrigens nur für Mods könntest du den Text andersfarbig machen ?

    VB.NET-Quellcode

    1. For Each s As Label In Me.Controls
    2. s.Text = Nothing
    3. Next


    Sollte klappen.
    Grüße

    Spoiler anzeigen
    Oder du nimmst nen Counter, falls du noch mehr Labels inner Form hast.
    Deine Labels heißen hier Label1, Label2, Label3.

    VB.NET-Quellcode

    1. Dim count As Integer = 0
    2. Do Until count = 3
    3. Me.Controls("Label" & count.ToString).Text = Nothing
    4. Loop
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!
    Wozu bitte sehr soll das Löschen der Label-Texte gut sein ?

    VB.NET-Quellcode

    1. Imports System.Linq
    2. Public Class Form1
    3. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    4. ' Namen einlesen
    5. Dim names() As String = IO.File.ReadAllLines("C:\names.txt")
    6. 'Dim names() As String = {"Apfel", "Birne", "Pflaume", "Rotkohl"}
    7. ' zufällig sortieren
    8. Dim r As New Random
    9. Dim randomNames = (From s As String In names Order By r.NextDouble).ToList ' oder toArray
    10. ' anzeigen oder an Label vergeben
    11. Dim count As Integer = 0
    12. For Each c As Control In Me.Controls
    13. If TypeOf (c) Is Label AndAlso c.Name.ToLower.StartsWith("label") Then c.Text = randomNames(count) : count += 1
    14. Next
    15. End Sub

    Voraussetzung:
    -.NET 3.5 (für LinQ)
    - die zufällig zu bennenden Label sind mit einem bestimmten Namen gekennzeichnet
    - genügend Namen vorhanden , sonst müsste noch eine Prüfung im If-Block erfolgen

    Gonger96 schrieb:

    Sonst wird die Schleife nicht verlassen, da er solange sucht bis er einen Text findet der noch nicht existiert.
    Das ist klar: Du 'schiesst zufällig' auf beliebige Label und setzt die Texte in aufsteigender Reihenfolge der gelesenen Namen.

    Umgekehrt ist es schneller/eleganter: Du 'schüttelst' die gelesenen Namen und vergibst sie dann aufsteigend den vorhandenen Label.

    Gonger96 schrieb:

    Mit Linq ja.
    Ohne LINQ geht es genauso, nur mit einem HilfsArray und der Array.Sort Methode (2 Zeilen mehr)

    VB.NET-Quellcode

    1. Dim names() As String = {"Apfel", "Birne", "Pflaume", "Rotkohl"}
    2. ' zufällig sortieren OHNE LinQ
    3. Dim r As New Random
    4. Dim tmpDouble(names.Length - 1) As Double
    5. For i As Integer = 0 To names.Length - 1 : tmpDouble(i) = r.NextDouble : Next i
    6. Array.Sort(tmpDouble, names)
    7. ' anzeigen oder an Label vergeben
    8. Dim count As Integer = 0
    9. For Each c As Control In Me.Controls
    10. If TypeOf (c) Is Label AndAlso c.Name.ToLower.StartsWith("label") Then c.Text = names(count) : count += 1
    11. Next

    Wozu man dabei prüfen sollte ob der Label-Text schon existiert ist mir immer noch unklar.