Zeitleiste Grafisch darstellen Vb.net

werner_sg

Erfahrenes Mitglied
Code:
 Private Sub PictureBox1_Paint()
    
        Dim rec As Graphics
        Dim x, y As Single
        rec = PictureBox1.CreateGraphics()
        
                Try
            Sql = "SELECT Fahrzeugnummer, Modell, Mietbegin, Mietende FROM tblreservierung"

            conn.Open()
            With dbcmd
                .CommandText = Sql
                .Connection = conn
            End With

            dbda.SelectCommand = dbcmd
            dbda.Fill(dbdt)
        -------------------------------------------------------------------
        
        'minimum/kleinste Datum über alle Fahrzeuge, wandeln wir in eine Zahl
        Dim zeitleisteMin = (((Year(Date.Now()) * 10000) + Month(Date.Now()) * 100) + Day(Date.Now()))

        'maximum/höchste Datum über alle Fahrzeuge, wandeln wir in eine Zahl
        Dim zeitleisteMax = (((Year(Date.Now()) * 10000 + 10000) + Month(Date.Now())) * 100) + Day(Date.Now())))

        'Minum abziehen damit wir unsere 100% zeitleiste haben (Achtung, unten wird auch Minimum immer abgezogen)
        Dim zeitleisteMaxBereich = zeitleisteMax - zeitleisteMin + 1

        Dim bildBreite = X

        Liste FahrzeugeMitZeiten
durchlaufe FahrzeugeMitZeiten(fahrzeug 1 bis N)
{
    Dim fahrzeugNr = "Fahrzeugnummer"
        Dim fahrzeugBeginn = (((Year("Mietbegin") * 10000) + Month("Mietbegin")) * 100) + Day("Mietbegin")
        Dim fahrzeugEnde = (((Year("Mietende") * 10000) + Month("Mietende")) * 100) + Day("Mietende")

        Dim prozentualBeginn = ((fahrzeugBeginn - zeitleisteMin) / zeitleisteMaxBereich)
        Dim prozentualEnde = ((fahrzeugEnde - zeitleisteMin) / zeitleisteMaxBereich)

        Dim rec = neues Rechteck
   Dim rec.Left = (prozentualBeginn * bildBreite)
   Dim rec.Top = fahrzeugNr * 10
    Dim rec.Width = ((prozentualEnde * bildBreite) - (prozentualBeginn * bildBreite))
    Dim rec.Height = 10

   Dim zeichnen.ZeichneRechteck(rec, Grün)
}
  
        
        -------------------------------------------------------------------
            
        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            conn.Close()
        End Try

    End Sub

bin fleisig am suchen habe aber noch nicht so viel dazu gefunden

dein Code Beispiel lässt sich auch nicht einfach in Vb.net umwandeln daher sind da noch einige Fehler drinn

aber Mühsam ernährt sich halt das Eichhörnchen

der erste Schritt welchen ich nirgends richtig finde ist das übergeben an die PictureBox1 was ich dazu gefunden habe lässt sich im oberen Teil erkennen

im zweiten Teil mein Ansatz die Daten zur Vefügung zu stellen aus der Access Datenbank

Dann zwischen den Linien den grob angepassten Code von Dir

Der Zeitleisten Anfang ist Date.Now*10000 und das Ende Date.Now*10000+10000 was 1 Jahr mehr ergibt

Hast du eine gute Quelle für VB.net zu dem Thema?
 

Spyke

Premium-User
das war Pseudocode was ich dir gab.
In die entsprechende VB Syntax mit den entsprechenden Befehlen müsstest es dann natürlich selbst umwandeln.

Da ich mit C# Programmier und nicht mit VB.Net hab ich mal kurz gegoggelt wie der Syntaktische Aufbau von Schleifen in VB.Net ist.
Für mein Schleifen Beispiel könntest es z.B. mit DO LOOP oder DO WHILE entsprechend anpassen
Visual Basic .NET: Einfache Schleifen – Wikibooks, Sammlung freier Lehr-, Sach- und Fachbücher
oder hier noch was zur FOR Schleife
For...Next-Anweisung - Visual Basic
und FOREACH
For Each...Next-Anweisung - Visual Basic

Und wie man mit der PictureBox zeichnet könnteste hier mal schauen.
Control.Paint Ereignis (System.Windows.Forms)
(Sollte im Link die C# Syntax angezeigt sein, schau mal bissi über den Artikel da kannst du als Sprache dann auch VB auswählen)
Du musst nämlich das Paint Ereignis der PictureBox abonnieren und im EventArgs dann mit dem Graphics Objekt arbeiten.

Wie du an Tag, Monat und Jahr auf .Net Seite im DatetTime Objekt ran kommst sieht du hier
DateTime.Year Eigenschaft (System)
(Wieder, sollte im Link die C# Syntax angezeigt sein, schau mal bissi über den Artikel da kannst du als Sprache dann auch VB auswählen)
 
Zuletzt bearbeitet:

werner_sg

Erfahrenes Mitglied
das war Pseudocode was ich dir gab.
In die entsprechende VB Syntax mit den entsprechenden Befehlen müsstest es dann natürlich selbst umwandeln.

Da ich mit C# Programmier und nicht mit VB.Net hab ich mal kurz gegoggelt wie der Syntaktische Aufbau von Schleifen in VB.Net ist.
Für mein Schleifen Beispiel könntest es z.B. mit DO LOOP oder DO WHILE entsprechend anpassen
Visual Basic .NET: Einfache Schleifen – Wikibooks, Sammlung freier Lehr-, Sach- und Fachbücher
oder hier noch was zur FOR Schleife
For...Next-Anweisung - Visual Basic
und FOREACH
For Each...Next-Anweisung - Visual Basic

Und wie man mit der PictureBox zeichnet könnteste hier mal schauen.
Control.Paint Ereignis (System.Windows.Forms)
(Sollte im Link die C# Syntax angezeigt sein, schau mal bissi über den Artikel da kannst du als Sprache dann auch VB auswählen)
Du musst nämlich das Paint Ereignis der PictureBox abonnieren und im EventArgs dann mit dem Graphics Objekt arbeiten.

Wie du an Tag, Monat und Jahr auf .Net Seite im DatetTime Objekt ran kommst sieht du hier
DateTime.Year Eigenschaft (System)
(Wieder, sollte im Link die C# Syntax angezeigt sein, schau mal bissi über den Artikel da kannst du als Sprache dann auch VB auswählen)
Ms ist ja immer sehr sparsam mit Erklärung ( Der Code zeichnet. Wieso und Warum ist ja mal egal)

Ok das mit dem Text ist logisch und kennt man von anderem ( warum aber das F oder bzw wofür steht es?)
Code:
        ' Draw a string on the PictureBox.
        g.DrawString("Zeitleiste folgt",
        fnt, Brushes.Red, New PointF(40.0F, 200.0F))
Das zeichnet die Linie ist ja fein egal was man ändert es bleibt bei einer Linie von links oben nach rechts unten oder es gibt gar nichts
Die Farbe ist klar wo nimmt er aber seine bezugspunkte her? im load Teil dockt er die PictureBox ja nur an

Code:
        ' Draw a line in the PictureBox.
        g.DrawLine(System.Drawing.Pens.BlueViolet, PictureBox1.Right,
        PictureBox1.Bottom, PictureBox1.Left, PictureBox1.Top)
 

werner_sg

Erfahrenes Mitglied
Hab schon mal einen Teil erstellt

damit erhalte ich im Dim AnfangKurz und Dim EndeKurz das Datum in Form von 20210718

habs mir in der Textbox2 anzeigen lassen

Er zeigt selbstverständlich nur eine einzige Buchung an

der Versuch :
DbReader = dbcmd.ExecuteReader
dt.Load(DbReader)
scheitert kläglich da zur Ausführung der Reader schon geschlossen ist ????


Code:
    Private Sub pictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)

        ' Variablen für die PictureBox.

        Dim g As Graphics = e.Graphics

        'der erste horizontale Abstand
        Dim horizontal = 50


        'Auswahl aus allen Buchungen
        conn.Open()

        Try
            dbcmd = New OleDbCommand("SELECT BuchungsNr, Kunde, Fahrzeugnummer, Modell, YEAR(Mietbegin) AS Jahr1, MONTH(Mietbegin) AS Monat1, DAY(Mietbegin) AS Tag1, YEAR(Mietende) AS Jahr2, MONTH(Mietende) AS Monat2, DAY(Mietende) AS Tag2 FROM tblreservierung ", conn)
            Dim DbReader As OleDbDataReader
            DbReader = dbcmd.ExecuteReader
            While DbReader.Read

                'Der Mietbegin als Zahl 20210518
                Dim JahrAnfang = (DbReader("Jahr1").ToString)
                Dim JahrAnfangI = Convert.ToDecimal(JahrAnfang)
                Dim MonatAnfang = (DbReader("Monat1").ToString)
                Dim MonatAnfangI = Convert.ToDecimal(MonatAnfang)
                Dim TagAnfang = (DbReader("Tag1").ToString)
                Dim TagAnfangI = Convert.ToDecimal(TagAnfang)
                Dim Anfang = ((JahrAnfangI * 10000) + (MonatAnfangI * 100) + TagAnfangI)

                'Das Mietende als Zahl 20210518
                Dim JahrEnde = (DbReader("Jahr2").ToString)
                Dim JahrEndeI = Convert.ToDecimal(JahrEnde)
                Dim MonatEnde = (DbReader("Monat2").ToString)
                Dim MonatEndeI = Convert.ToDecimal(MonatEnde)
                Dim TagEnde = (DbReader("Tag2").ToString)
                Dim TagEndeI = Convert.ToDecimal(TagEnde)
                Dim Ende = ((JahrEndeI * 10000) + (MonatEndeI * 100) + TagEndeI)

                Me.TextBox2.Text = Ende

                For Each Row As DataRow In dbdt.Rows

                    ' Zeitleisten für die PictureBox.

                    g.DrawLine(New Pen(System.Drawing.Color.DarkRed, 10), Anfang, horizontal, Ende, horizontal)



                Next
                ' Text für die PictureBox.

                g.DrawString("Zeitleiste folgt",
            fnt, Brushes.Red, New PointF(40.0F, 200.0F))

            End While


            'Die Zeilenabfrage





        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            conn.Close()
        End Try








    End Sub
 
Zuletzt bearbeitet:

Spyke

Premium-User
wenn du das F meinst 40.0F, das F steht für float, sprich die 40.0 sollen als Datentyp float gehalten/behandelt werden

zu DrawString
Graphics.DrawString Methode (System.Drawing)

zu DrawLine
Graphics.DrawLine Methode (System.Drawing)

am besten erstell erstmal mal ein neues Projekt mit dem du mit den zeichnungselementen bissl rumspielen kannst.
Ändere dabei die Point Angaben (X,Y) und schau dir an was das Graphics Objekt noch für Methoden hat.
z.B. DrawRectangle
Graphics.DrawRectangle Methode (System.Drawing)
oder FillRectangle
Graphics.FillRectangle Methode (System.Drawing)
was ich eher zum Zeichnen einer Beginn/Ende Zeitangabe verwenden würde.


Er zeigt wahrscheinlich nur eine Buchung da ev. Anfang und Ende immer den gleichen Wert haben (müssteste mal im Debuggen Breakpoint setzen und die Werte anschauen und vorallem ob die Schleife auch öfters durchlaufen wird.
 

werner_sg

Erfahrenes Mitglied
wenn du das F meinst 40.0F, das F steht für float, sprich die 40.0 sollen als Datentyp float gehalten/behandelt werden

zu DrawString
Graphics.DrawString Methode (System.Drawing)

zu DrawLine
Graphics.DrawLine Methode (System.Drawing)

am besten erstell erstmal mal ein neues Projekt mit dem du mit den zeichnungselementen bissl rumspielen kannst.
Ändere dabei die Point Angaben (X,Y) und schau dir an was das Graphics Objekt noch für Methoden hat.
z.B. DrawRectangle
Graphics.DrawRectangle Methode (System.Drawing)
oder FillRectangle
Graphics.FillRectangle Methode (System.Drawing)
was ich eher zum Zeichnen einer Beginn/Ende Zeitangabe verwenden würde.


Er zeigt wahrscheinlich nur eine Buchung da ev. Anfang und Ende immer den gleichen Wert haben (müssteste mal im Debuggen Breakpoint setzen und die Werte anschauen und vorallem ob die Schleife auch öfters durchlaufen wird.
Ok dann verstehe ich jetzt auch das F in diesem Bezug konnte es nicht zuordnen.

Alles andere habe ich soweit voll verstanden er zeichnet auch was ich möchte und ihm gebe, und ich weis warum er es macht.

Was mich stört ist die Datenbank Anbindung ich hole mir ja die Daten mittels Reader

nur wenn ich mir jetzt mit : dt.Load(DbReader) die Daten für die Schleife ( For Each Row As DataRow In dt.Rows) holen möchte meckert er das der Reader bereits geschlossen ist

in dem geposteten Code ist noch eine andere datatable eingebunden, daher war das klar das dort nur eine Zeile vorhanden war und nicht mehr, hatte mich zum testen nicht gestört.
 

Spyke

Premium-User
Wie verwendest du genau dt.Load, verwendest du es in Verbindung mit der while Schleife (laut deinem oberen Code)?
Wenn ja ist ev. das problem das er den Reader quasi schon fertig gelesen hat
 

werner_sg

Erfahrenes Mitglied
Wie verwendest du genau dt.Load, verwendest du es in Verbindung mit der while Schleife (laut deinem oberen Code)?
Wenn ja ist ev. das problem das er den Reader quasi schon fertig gelesen hat
Also habe ich das load hier
Code:
        Try
            dbcmd = New OleDbCommand("SELECT BuchungsNr, Kunde, Fahrzeugnummer, Modell, YEAR(Mietbegin) AS Jahr1, MONTH(Mietbegin) AS Monat1, DAY(Mietbegin) AS Tag1, YEAR(Mietende) AS Jahr2, MONTH(Mietende) AS Monat2, DAY(Mietende) AS Tag2 FROM tblreservierung ", conn)
            Dim DbReader As OleDbDataReader
            DbReader = dbcmd.ExecuteReader
            Dim dt = New DataTable
            dt.Load(DbReader)

            While DbReader.Read

                'Der Mietbegin als Zahl 20210518
                Dim JahrAnfang = (DbReader("Jahr1").ToString)
erhalte ich die fehlermeldung: Ungültiger Versuch Read aufzurufen da der Datenleser bereits geschlossen wurde

setze ich es mit ins Wile rein
Code:
            Dim dt = New DataTable
            dt.Load(DbReader)

            While DbReader.Read
                dt.Load(DbReader)

                'Der Mietbegin als Zahl 20210518

erhalte ich keine Daten für die Zeile Spalte
 

werner_sg

Erfahrenes Mitglied
Probiers ev. mal über den OleDbDataAdapter mit seiner Fill Methode.

Auffüllen eines 'DataSets' durch einen 'DataAdapter' - ADO.NET
Ist mir eigentlich auch lieber bleibe aber dabei die ganze Zeit hängen, hatte es ja am Anfang aber dort dann immer den fehler mit dem Format in einem der vorherigen Post und dann auf DBReader umgestiegen

Mein Problem ist hier, haben auch einige andere im Netz weil Beiträge in Forem gibt es genug, nur sind die dann meisten so schlau das sie nur irgendwann schreiben hab den Fehler gefunden und tschau, scheiß auf den nächsten der das gleiche oder ähnliches Problem hat :mad: deswegen bin ich hier ja so zufrieden da findet man dann auch ne erklärung

Ok zum Problem

Code:
'richtige Konvertierung und Anzeige des Wertes in der Textbox kein Meckern von Windows
Dim JahrEnde = (DbReader("Jahr2").ToString)
Dim JahrEndeI = Convert.ToDecimal(JahrEnde)

'die Eingabe Zeichenfolge hat das falsche Format
Dim JahrEnde = (("Jahr2").ToString)
Dim JahrEndeI = Convert.ToDecimal(JahrEnde)

'klammer ich das Convert aus erhalte ich in der Textbox zum Prüfen Jahr1
Dim JahrAnfang = "Jahr1"
'Dim JahrAnfangI = Convert.ToDecimal(JahrAnfang)

Ich finde an jeder Straßenecke die Erklärung wie ich die Textbox an die Datenbank weitergebe aber nirgends wo ich Sie mir direkt aus der Datenbank hole (Google ist auch nicht mehr was es war, zuviel sinnloses Zeug)

Also wie bekomme ich jetzt den Tabellen Inhalt aus der Spalte Jahr1 in mein Dim JahrAnfang das ich es Anschließend wieder Convertieren kann