| 

.NET C# Java Javascript Exception

1
Ich habe eine gebundene DataGridView. Eine Spalte enthält die Berechnungsweise (Festpreis/%). Eine ander enthält einen Decimal-Wert.

Hat der Benutzer "Festpreis" gewählt, dann sollte hinter dem Decimal-Wert im DGV ein " €" angefügt werden. Bei "Prozent" natürlich nur " %"

In VB.NET 2010 wollte ich das wie folgt lösen:

Private Sub dgvProductCalculation_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgvProductCalculation.CellFormatting
Select Case dgvProductCalculation.Columns(e.ColumnIndex).Name
Case "CalculatedPriceDataGridViewTextBoxColumn"
If e.Value.ToString = System.Guid.Empty.ToString Or e.Value Is Nothing Or e.Value = CType("1.1.1900", Date) Then
e.Value = ""
Else
Select Case dgvProductCalculation("dgvProductCalculationDiscountTypeGUID", e.RowIndex).Value.ToString
Case "F5DCBC22-31C4-4a33-94D8-6424B61F0291" ' Festpreis
e.Value = e.Value & " €"
Case "9CF2F009-4560-4caf-AB3A-DC4B1015009F" ' Prozent
e.Value = e.Value & " %"
Case Else

End Select
End If
End Select
End Sub


Leider kommt dabei aber der Fehler:
Der Operator = ist für Typ Decimal und Typ Date nicht definiert.


Kann ich den Wert an dieser Stelle nicht formatieren/anpassen?
News:
24.07.2012
MyKey0815 1,6k 2 9
3 Antworten
3
Ich habe ein kleines Testprojekt aufgesetzt, in dem ich dein Problem nachgestellt habe. Wie Matthias und ich schon gesagt haben führt die Prüfung in Zeile 4 schon zu einem Fehler. Der Code führt dort zu einer InvalidCastException, wenn e.Value nicht vom Typ Date. Wenn e.Value Nothing ist, bekomme ich eine NullReferenceException. In keinem Fall komme ich bis in das Select Case. (Hier muss ich die Frage von Matthias wiederholen: Warum führst du eine Prüfung auf Date durch, wenn du einen Decimal in der Zelle erwartest?)

Dass bei dir im If keine Exception geworfen wird, muss übrigens nicht heißen. VB reicht nicht alle Exceptions weiter. Teilweise werden die Exception gefangen und lediglich eine Meldung im Output-Tab von Visual Studio ausgegeben. Ich habe zwar bis heute noch keine wirkliche Systematik hierzu herausgefunden, aber es scheint, dass dies für Exceptions, die in User-Controls oder im .NET-Framework auftreten, gilt.

Ich würde dir empfehlen "Option Strict On" zu setzen. Damit zwingst du VB, eine strengere Typprüfung bei Zuweisungen vorzunehmen. In deinem Codefragment würdest du 3 Fehler sehen. Der erste würde sich auf deine Datumsprüfung in der If-Anweisung beziehen (Option Strict On disallows operands of type Object for operator '='. Use the 'Is' operator to test for object identity.) Die beiden weiteren auf die beiden Zuweisungen mit "€" bzw. "%" (Option Strict On prohibits operands of type Object for operator '&').

Ich weiss warum ich eigentlich lieber in C# als in VB programmiere. Die automatischen Konvertierungen, die VB im Hintergrund durchführt, können zu inkonsistenten Zuständen führen, die dann nur sehr schwer zu debuggen sind. Deshalb achte ich auch in VB immer darauf, dass ich mit den korrekten Typen arbeite und führe, wenn notwendig, Typkonvertierungen explizit durch und verlasse mich nicht datauf, dass VB es schon richten wird.

Gruß
Klaus
01.08.2012
luedi 1,7k 1 9
1
Wenn Du Dir, wie in Deinem Kommentar zu luedis Antwort, wirklich ganz sicher bist, dass der Fehler in einer der beiden Zuweisungszeilen steckt, so gib bitte genau an, woher Du diese Sicherheit nimmst. Ich glaub's nämlich nicht.

Die einzige Stelle in Deinem Code, die meiner Meinung nach den Fehler hervorrufen kann, ist

... e.Value = CType("1.1.1900", Date) ...

in der 4. Zeile. Aus Deinen Erläuterungen geht hervor, dass e.Value initial mit einem Decimal gefüllt sein müßte, und den vergleichst Du hier mit einem Date (wozu eigentlich???). Das kann nicht gut gehen.

Übrigens: ließ Dir mal die Erläuterungen zum CellFormatting-Event durch. Was Du erreichen willst, ließe sich möglicherweise einfacher über die Format-Property und einen passenden CellStyle regeln. Und Du solltest wohl auch noch auf die FormattedValueType- und FormattingApplied-Eigenschaften achten.
31.07.2012
Matthias Hlawatsch 13,2k 4 9
Die Sicherheit nehm ich aus folgenden Beobachtungen:

1. Wenn ich dass SelectCase nach dem Else (das untere also) auskommentiere, dann läuft die Sache durch.

2. Wenn ich einen Breakpoint auf das selbe Select-Case setze dann hält er dort an - wertet meienen Wert aus - springt in das richtige CASE und bringt dann bei der Zuweisung des Textes den Fehler

Die beiden Links von dir, werd ich mir sofort mal durch lesen - danke
MyKey0815 31.07.2012
Strange... Die von mir angeführte Stelle müßte (wenn ich nicht grad auf der Leitung stehe) immer zu dem Fehler führen, denn wie luedi schrieb, hat der OR-Operator in VB.NET kein "short circuit"-Verhalten, der Vergleich wird also immer ausgeführt. Und die Fehlermeldung bezieht sich m.E. auf "=" als Vergleichs-, nicht als Zuweisungsoperator, und in den anderen Zeilen findet nun mal kein Vergleich statt. Irgendwas ist da faul.
Schau Dir mal im Debugger den Stack-Trace an. Siehst Du da noch irgendwelche .NET-internen Aufrufe? Evtl. ist der Setter von e.Value ja etwas komplizierter...
Matthias Hlawatsch 31.07.2012
0
Ich denke, das Problem ist, dass e.Value einen Decimal-Wert enthält und dieser natürlich nicht mit einem Date verglichen werden kann. Da VB bei "Or" immer alle Bedingungen prüft, wird der Fehler ausgegeben. Besser wäre es zu prüfen, ob die Zelle einen Decimal-Wert enthält:

Module Module1

Sub Main()

Dim result As Boolean

result = IsDecimal(New Decimal(42.0))
result = IsDecimal("Not a decimal")

End Sub

Function IsDecimal(ByRef pValue As Object) As Boolean

If TypeOf pValue Is Decimal Then
Console.WriteLine("I'm a decimal")
Return True
End If

Console.WriteLine("I'm not a decimal")
Return False

End Function

End Module


Gruß
Klaus
26.07.2012
luedi 1,7k 1 9
luedi 1,7k 1 9
Danke für deinen Tipp.

Aber der Fehler tritt entweder in der zeile

e.Value = e.Value & " €"

oder in der Zeile

e.Value = e.Value & " %

auf. Also dort, wo ich die Ausgabe "formatieren" möchte.
MyKey0815 31.07.2012

Stelle deine Datagridview-Frage jetzt!