isdate bewertet Zahl als Datum

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    isdate bewertet Zahl als Datum

    Hallo liebe Community,

    ich finde den Fehler einfach nicht.
    Anstatt bei einer Zahl =false auszugeben, wirft isDate bei der Zahl 627,02 = true aus.
    beim nächsten Durchlauf funktioniert es aber z.B. für die Zahl 274,62

    Das ganze scheint vollkommen willkürlich zu sein

    VB.NET-Quellcode

    1. with griedviewuebersicht
    2. If IsDate(.Rows(Zeile).Cells(Spalte).Value.ToString) = True Then
    3. 'enthält Datum
    4. oSheet.getCellByPosition(Spalte, Zeile + 1).string = Format(CDate(.Rows(Zeile).Cells(Spalte).Value), "d")
    5. 'enthält Zahl
    6. ElseIf IsNumeric(.Rows(Zeile).Cells(Spalte).Value) = True Then
    7. ...
    8. end if


    Ich exportiere die Daten nach OpenOffice. Das Ergebnis sieht so aus ...

    01.02.0627
    274,62
    616,61
    1.118,84
    476,63
    272,22

    Könnt Ihr mir helfen? ... mir gehen die Ideen aus.
    Schon mal danke!
    @Thomas_uebt_noch Die IntelliSense-Beschreibung von IsDate gibt eine fast gelungene Aussage zu Deinem Problem. "Gibt einen Boolean-Wert zurück, der angibt, ob ein Ausdruck einen gültigen Date-Wert darstellt." Diese Funktion versucht also mit allen Mitteln, in Deine angegebenen zu-String-konvertierten Zahlen ein Datum reinzuinterpretieren. Und wenn Du die Funktion mit 627,02 fütterst, kommt eben das Jahr 627 mit Monat 02 raus. 1999,12 ergibt somit Dezember 1999. Da Deine anderen Zahlen mit Nachkommawert > 0,12 sind, kann die Funktion diese Werte nicht mehr als Datum interpretieren und sie wirft False zurück.

    Mein erster Ansatz wäre zwar, eine String-Prüfung wie folgt durchzuführen, aber ich kratze selber noch an der VB.NET-Wissensoberfläche und bin mir sicher, dass es da deutlich effektivere Methoden gibt, die andere Forennutzer hier sicherlich auch bald zur Verfügung stellen.

    VB.NET-Quellcode

    1. Private Function StringIstEinDatum(fp_Wert As String) As Boolean
    2. Dim tp_Datumsabschnitte() As String = fp_Wert.Split("."c)
    3. If tp_Datumsabschnitte.GetUpperBound(0) <> 2 Then Return False
    4. Dim tp_Tag = CInt(tp_Datumsabschnitte(0)), tp_Monat = CInt(tp_Datumsabschnitte(1)), tp_Jahr = CInt(tp_Datumsabschnitte(2))
    5. If tp_Tag < 1 OrElse tp_Tag > 31 OrElse tp_Monat < 1 OrElse tp_Monat > 12 OrElse tp_Jahr < 0 OrElse tp_Jahr > Date.MaxValue.Year OrElse CDate(tp_Jahr & "." & tp_Monat & "." & tp_Jahr).Month <> tp_Monat Then Return False
    6. Return True
    7. End Function


    Es sollte noch überprüft werden, ob die Teilstrings von fp_Wert, die später über CInt zu den Tages-, Monats-, und Jahreswerten gecastet werden, nur Ziffern enthalten. Ich habe mir für solche Überprüfungen zwar eine eigene DLL-Funktion gebastelt, um die Nutzer meiner Programme bei diversen Eingaben auf die Finger zu klopfen, wenn sie verbotene Zeichen eingeben, aber auch das geht sicherlich schnell mit einer existenten, mir aber bis jetzt noch unbekannten Framework-Funktion.

    Ach ja, meine Variablennamenskonvention ist sicherlich nicht allgemein akzeptierter Standard, aber zur Erklärung: "fp_Name" ist bei mir ein Parameter, der einer Funktion übergeben wurde, tp_Name eine lokale Variable, damit ich schnell einschätzen kann, aus welchem Bereich die Variable kommt.
    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.

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „VaporiZed“ ()

    Warum haben die Zellen/Spalten nicht bereits den korrekten Datentyp?
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @Thomas_uebt_noch Tja, wie umfangreich die ich-muss-alles-konvertieren-was-mir-der-Benutzer-gibt-Funktionalität von IsDate ist, weiß wohl nur Microsoft. 1.235,16 wird eben zum 16.01.0235 und 2.235,16 zum 16.02.0235. Wobei Dein Tausender-Trennpunkt beim Aufruf der Funktion absolut wichtig ist, da ohne diesen Punkt die Funktion kein Datum reininterpretieren kann und false zurückgibt.
    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.
    Ok, woher kommen die Daten und wie kommen sie in das Grid?
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    .. die Daten stammen aus einer Anwendung. Sie sind dort auch validiert.
    Ich weiß nur nicht, ob in dieser Spalte bei diesem Export eine Zahl´, ein Datum, ein Text enthalten ist. Das schwankt je nach Exportvariante (Umsatzsteuer, Einzelkonten, Einnahmeübersicht, Gesamtkontenanlayse, usw.)
    Wenn ein Datum kommt, will ich es eben auch als solches ausgeben - mir wird schon das korrekte Datum z.B. "01.901.2017" geliefert. Damit klappt es auch - aber bei manchen Bruttobeträgen erkennt die eben als Datum und wandelt mir die dann natürlich auch in ein Datum um.
    Da fällt mir ein: Alternativ könnte ich prüfen ob das Datum in dem Format dd.mm.yyyy vorliegt. Das hab ich aber noch nicht gemacht ... (Idee ? :)

    Thomas_uebt_noch schrieb:

    Alternativ könnte ich prüfen ob das Datum in dem Format dd.mm.yyyy vorliegt.


    In meiner ersten Antwort habe ich ja schon genau den VB.NET-Überprüfungscode geliefert, den Du zu brauchen scheinst. Fehlt da was Relevantes an benötigter Funktionalität? ?(
    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.
    DANKE!
    das funzt - und habe in den paar Zeilen Code viel gelernt zur Codevereinfachung :)

    (übrigens - in dem Code oben ist ein Fehler (kleiner Test für mich? :-)). Es muss
    statt
    CDate(tp_Jahr & "." & tp_Monat & "." & tp_Jahr).Month
    heißen
    CDate(tp_Tag & "." & tp_Monat & "." & tp_Jahr).Month )



    ... wen es interessiert:
    die geniale Funktion von Vaporized fängt (vermutlich mangels Bedarf) den folgenden Fehler nicht ab:

    Feld enthält: Rechnung vom 10.10.2016 - da wird die Eingangsbedingung auch erfüllt und die Funktion läuft in einen Fehler.

    Das kann man mit dem Schnipsel ergänzen

    VB.NET-Quellcode

    1. if
    2. IsNumeric(tp_Datumsabschnitte(0)) = False Or IsNumeric(tp_Datumsabschnitte(1)) = False Or IsNumeric(tp_Datumsabschnitte(2)) = False Then
    3. Return False
    4. End If

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

    Ah, danke. Hab da schlampig gecoded und nicht ausreichend getestet. Shame on me. :/
    Da stellt sich doch gleich mal die Frage (die ich ggf. nochmal an passender Forenstelle wiederhole) an die Moderatoren, was eher gewünscht ist:

    falschen Code nach Korrekturhinweis eines anderen Forenmitglieds stehen lassen
    • Vorteil: der Sinn des Fehlerhinweises des anderen Forenmitglieds bleibt erhalten
    • Nachteil: man muss den kompletten Thread lesen, um den sauber laufenden Code zu bekommen
    • vermeintliche Lösung: korrigierten Code nochmals posten; führt zu scheinbaren Doppelposts, die nicht sonderlich gern gesehen sind
    falschen Code korrigieren
    • Vorteil: sofortig brauchbarer Code
    • Nachteil: der Korrekturbeitrag weist auf einen Fehler hin, der im Nachhinein nicht mehr zu erkennen ist
    • eventuelle Lösung: im korrigierten Beitrag einen Dankeshinweis an das korrigierende Forenmitglied hinterlassen
    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.

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

    Thomas_uebt_noch schrieb:

    die geniale Funktion von Vaporized fängt (vermutlich mangels Bedarf) den folgenden Fehler nicht ab:

    Feld enthält: Rechnung vom 10.10.2016 - da wird die Eingangsbedingung auch erfüllt und die Funktion läuft in einen Fehler.


    Das ist richtig, dass dieser Fehler in meinem ersten Ursprungsbeitrag nicht abgefangen wurde, daher hatte ich ihn nochmal ergänzt, bevor weitere Antworten kamen. Allerdings ging ich aufgrund Deines ersten Posts davon aus, dass es nur um Zahlenwerte geht. Desweiteren hat man mit IsNumeric das gleiche Problem, was man sich auch schon bei IsDate eingehandelt hat. Die Funktion frisst alles, was man ihm gibt und spuckt es wieder aus. Für IsNumeric ergibt sich (kulturabhängig) auch ein gültiger Wert bei einer Aufstückelung eines Anfangsstrings von "11,5.12.1999,01" in 11,5 + 12 + 1999,01. 11,5 gibt zwar bei IsNumeric eine Bestätigung, dass es sich um einen Zahlenwert handelt. Das ergibt jedoch keine sinnvolles Tagesangabe. Meine Hilfsfunktion für solche Prüfungen wäre in etwa so:

    VB.NET-Quellcode

    1. Public Function TextIstEineGanzeZahl(fp_zuPrüfenderText As String) As Boolean
    2. If String.IsNullOrEmpty(fp_zuPrüfenderText) Then Return False
    3. Dim tp_zuFindendeZeichen = "0123456789"
    4. For Each lp_Zeichen In fp_zuPrüfenderText
    5. If Not tp_zuFindendeZeichen.Contains(lp_Zeichen) Then Return False
    6. Next
    7. Return True
    8. End Function


    Niko Ortner schrieb:

    Wäre DateTime.TryParseExact nicht genau das richtige?


    Ja, auf jeden Fall. Meine bisherigen Tests damit (ich habe vorher noch nicht mit der Funktion gearbeitet) waren erfolgreich.
    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.

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

    Thomas_uebt_noch schrieb:

    Das kann man mit dem Schnipsel ergänzen
    Kannst Du bitte mal das komplette Problem beschreiben?
    Warum nimmst Du nicht das DateTimePicker-Control?
    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!