DataTable Select mit DateTIME

  • VB.NET
  • .NET (FX) 4.0

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von us4711.

    DataTable Select mit DateTIME

    Hallo,

    ich habe in einer DataTable eine DateTime Spalte... Diese möchte ich gerne EXAKT filtern. Also auf die Sekunde genau.
    Nun hapert es hier an etwas ganz simplen... Wie übergebe ich ihm die Formatierung der Uhrzeit?
    Aktuell schaut es so aus:

    VB.NET-Quellcode

    1. Grid.DataSource = _DataTable.Select("[DATE_CREATED] = '1999-06-14 22:12:25'").CopyToDataTable

    Nur... mag er das irgendwie nicht...
    Solange im DateTime keine Stundenangabe steht macht er brav was er soll... Steht dort aber was... "Die Quelle enthält keine DataRows."
    Ich sehe aber dass dort exakt der Wert steht. Ich hab mir Testweise sogar mal einen SELEKTIERTEN Wert im DataGrid gegriffen und entsprechend umformatiert.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    Filter-Ausdrücke verwenden die Invariant-Culture. Also konvertiere das Ziel-Datum damit, dann kriegst du auch den richtigen String.
    Und lies nochmal die Doku der Filter-Ausdrücke, Zeitliterale werden glaub mit # apostrophiert, nicht mit '.
    Dummerweise ist die Expression-Syntax da Fehler-Tolerant, aber besser ist, man macht es richtig.
    Hi,

    auch das hatte ich schon (mit selbem Ergebnis) probiert. Dort lautet dann der Filter "[DATE_CREATED] = #06/14/1999 22:12:25#" kommt aber auch zum Ergebnis: Die Quelle enthält keine DataRows.
    Den Value den ich umformatiere habe ich mir testweise mit Grid.SelectedCells(0).Value ausgelesen. Also muss der Wert auch vorkommen.

    EDIT:
    Ich habe mir nen Testbutton gestrickt der folgendes tut:

    VB.NET-Quellcode

    1. Dim cell = Grid.SelectedCells(0)
    2. Dim filter = "["c & cell.OwningColumn.HeaderText & "] = #"
    3. filter += DateTime.Parse(cell.Value.ToString).ToString(System.Globalization.CultureInfo.InvariantCulture) & "#"
    4. Grid.DataSource = _DataTable.Select(filter).CopyToDataTable​
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

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

    Hallo,

    wenn ich das jetzt richtig verstanden habe, dann häng mal an deine Variable in der das zu suchende Datum steht .ToString("dd/MM/yyyy HH:mm:ss") dran.

    Also in etwa so:

    VB.NET-Quellcode

    1. Dim DateToSearch As Date = CDate("1999-06-14 22:12:25") ' wird zu 14.06.1999 22:12:25
    2. Grid.DataSource = _DataTable.Select("[DATE_CREATED] = '" & DateToSearch.ToString("dd/MM/yyyy HH:mm:ss") & "'").CopyToDataTable


    Musst halt schauen das du beim ToString das richtige Format angibst, oder speicherst es in der DB direkt im deutschen üblichen Format, dann sollte es mit dem Beispiel von mir funktionieren.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „rdmguy“ ()

    Hmm..

    also mir zeigt er beim Überwachen das Ganze als DateTime an...


    EDIT:
    Er scheint es als DateTime zu erkennen.
    Wenn ich nen String filtern lasse kommt:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

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

    Also ich weiß nichts weiter - ich verwende DataTable.Select auch nie.

    Meist setze ich halt einen Filter auf eine BindingSource - wäre das nicht auch in deim Fall viel einfacher?

    Oder ich selektiere typisiert mit Linq, aus typisierten Tabellen.

    Ansonsten kannste auch dein Sample mal anhängen, ich find das Verhalten auch eigentümlich.
    Welchen Inhalt hat denn filter vor der Zuweisung an die Datatable? Die Fehlermeldung in Post #6 deutet darauf hin das ein DateTime-Wert mit einem String verglichen wird. Spalte [DATE_CREATED] scheint ja des Typs DateTime zu sein.
    Dann ist der Filterausdruck wohl vom Typ String. Deshalb die Überprüfung der filter-Variablen.
    Hallo,

    naja am Anfang hatte "Filter" den Wert "[DATE_CREATED] = '1999-06-14 22:12:25'"
    Bzw. es gab "Filter" nicht, sondern ich hatte da eine andere Abfrage, habe es wegen des Fehlers hart codiert und der letzte Schritt war dann das generische Auslesen des Values und OwnerColumnType um sicher zu gehen, dass es auch ne DateTime ist. Diese hab ich dann in Filter zusammengesetzt und in den Select geschmissen.

    Mittlerweile hab ich es so gebaut um mal alle Eventualitäten durchzuprobieren:

    VB.NET-Quellcode

    1. Private Sub Suchen(sender As System.Object, e As System.EventArgs)
    2. Dim cell = dgvGrid.SelectedCells(0)
    3. If Not String.IsNullOrEmpty(_Filter) Then _Filter += " AND "
    4. If sender Is tsmiSearch Then
    5. If cell.Value.ToString = "" Then
    6. _Filter += "["c & cell.OwningColumn.HeaderText & "] IS NULL "
    7. Else
    8. Select Case cell.OwningColumn.ValueType.ToString
    9. Case "System.Text", "System.String"
    10. _Filter += "["c & cell.OwningColumn.HeaderText & "] = '"
    11. _Filter += cell.Value.ToString & "'"
    12. Case "System.Int16", "System.Int32", "System.Int64", "System.Double", "System.Decimal", "System.Single", "System.Boolean"
    13. _Filter += "["c & cell.OwningColumn.HeaderText & "] = "
    14. _Filter += cell.Value.ToString
    15. Case "System.DateTime"
    16. _Filter += "["c & cell.OwningColumn.HeaderText & "] = #"
    17. _Filter += DateTime.Parse(cell.Value.ToString).ToString(System.Globalization.CultureInfo.InvariantCulture) & "#"
    18. End Select
    19. End If
    20. ElseIf sender Is tsmiExclude Then
    21. If cell.Value.ToString = "" Then
    22. _Filter += "NOT [" & cell.OwningColumn.HeaderText & "] IS NULL "
    23. Else
    24. Select Case cell.OwningColumn.ValueType.ToString
    25. Case "System.Text", "System.String"
    26. _Filter += "["c & cell.OwningColumn.HeaderText & "] <> '"
    27. _Filter += cell.Value.ToString & "'"
    28. Case "System.Int16", "System.Int32", "System.Int64", "System.Double", "System.Decimal", "System.Single", "System.Boolean"
    29. _Filter += "["c & cell.OwningColumn.HeaderText & "] <> "
    30. _Filter += cell.Value.ToString
    31. Case "System.DateTime"
    32. _Filter += "["c & cell.OwningColumn.HeaderText & "] <> #"
    33. _Filter += DateTime.Parse(cell.Value.ToString).ToString(System.Globalization.CultureInfo.InvariantCulture) & "#"
    34. End Select
    35. End If
    36. End If
    37. dgvGrid.DataSource = Nothing
    38. dgvGrid.DataSource = _DataTable.Select(_Filter).CopyToDataTable
    39. End Sub


    tsmiSearch und Exclude sind dabei einfach zwei Menüeinträge... _Filter ist global als "String" Definiert.
    Mit der Funktion kann ich mich jetzt zutode filtern... Aber bei ner Datetime mit Zeitangabe macht er ne Grätsche.

    Ich werde gleich mal schauen ob ich nen Testprojekt bauen kann, indem man das Verhalten nachvollziehen kann.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    So,

    Ich kann natürlich nicht Firmendaten zum Testen mitschicken. Nun habe ich mal nen Beispiel gebaut. Da kann man quasi jede Datenbank dran hauen... Es muss nur nen DateTime Feld angelegt werden. Oder einfach auf die Schematabelle zugreifen und da hat ja die Tabelle "Tables" immer ein Created drin. (zumindest in Access).

    EDIT:
    Neues Sample unten
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

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

    oh,

    ich hab mal die DLLs als lokale Kopie mitgegeben.

    Im Zweifel kannst aber auch das Excel Gedöns einfach rausklatschen. Ich hab nur nen kleines Tool zum Testen vergewohltätigt. Da war das noch drin.
    Dateien
    • Dataspy.zip

      (5,91 MB, 308 mal heruntergeladen, zuletzt: )
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „MemoAnMichSelbst“ ()

    Also, das funktioniert bei mir:

    VB.NET-Quellcode

    1. Dim value = CDate(cell.Value).Date.ToShortDateString
    2. Dim Filter = String.Format("CONVERT([{0}],System.String) LIKE '{1}*'", "MeinSpaltenName", value)
    3. Me.DataTable1BindingSource.Filter = Filter
    4. '
    5. ' Geht auch mit DataTable.Select(String)
    6. '

    Allerdings werden dann alle Datensätze mit dem Datum gefiltert. Zeitfilterung scheint nicht vorgesehen zu sein.
    Also wenn ich das richtig deute, würde aber ja nur das Datum geprüft.
    Mir geht es aber gerade um die genaue Zeit.
    Das ToShortDateString würde das doch einfach abkappen.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    Stimmt, hab' ein bischen experimentiert, und das klappt wunderbar:

    VB.NET-Quellcode

    1. Dim Filter = String.Format("CONVERT([{0}],System.String) = '{1}'", "MeinSpaltenName", cell.Value.ToString)
    2. Me.DataTable1BindingSource.Filter = Filter
    Ich gebs jetzt auf XD
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    Vielleicht zunächst:

    VB.NET-Quellcode

    1. Dim rows=_DataTable.Select(Filter)
    um zu sehen, ob überhaupt ein Filtererfolg vorliegt.

    @MemoAnMichSelbst
    Hab' gerade eine Beispielanwendung erstellt, schau' Dir die mal an.
    Dateien

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

    Ne, er filtert nix raus.

    Und da er nach dem selektierten Wert filtert MUSS es ja an der Formatierung hängen.

    EDIT:
    Also ohne Witz... Wenn ich das sooooo übergebe:

    VB.NET-Quellcode

    1. _Filter = String.Format("CONVERT([{0}],System.String) = '{1}'", dgvContent.SelectedCells(0).OwningColumn.HeaderText, CDate(dgvContent.SelectedCells(0).Value.ToString).ToString("MM\/dd\/yyyy HH:mm:ss"))

    Dann geht es... Also ich fall langsam vom Glauben ab!
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

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

    Hmm. Also würd ich gern. Aber mein VS sagt "Nicht kompatibel" ;D
    EDIT:
    Wenn man direkt das vbproj öffnet machters. Komische. Ich gucke mal. Wobei ich das Formatierungsgedönse noch nicht nachvollziehen kann.

    EDIT2:
    Ich versteh es nu erst recht nicht mehr.
    Typ des Cell.Value ist identisch... Bei dir gehts mit dem Code... in meinem Projekt tuter nix.
    Gut, wenn ich es nu formattechnisch umbiege scheint er es auch zu machen, aber schön is anders.
    Dateien
    • Dataspy.zip

      (5,91 MB, 130 mal heruntergeladen, zuletzt: )
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

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