Autor |
Beitrag |
LuMa86
      
Beiträge: 76
|
Verfasst: Di 14.05.13 23:14
Moin,
ich betreibe Leistungssport, daher führe ich auch ein Trainingsprotokoll. Unser Trainer bekommt das von uns wöchentlich als Excel Datei zugeschickt, um dann einen Monats- bzw. Jahresüberblick zu erstellen/berechnen, funktioniert ja wunderbar mit Excel. Ich habe mir ein Programm geschreiben, was dieses Protokoll ausfüllt. Dafür nutze ich OLE, und das klappt auch alles. Allerdings möchte ich die Excel.DAteien auch lesen können. DAfür habe ich folgendes gemacht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
|
if Excel.Cells[row, 8].Value <> '' then TPDataDauer.AsFloat := Excel.Cells[row, 8].Value; |
Die "if-" Abfrage soll verhinder, das durch das ".AsFloat" aus einem LeerString eine Null wird. Beim abspeichern würden man dann alle leeren Felder in der Excel Datei mit Nullen füllen (sollte man die Excel Datei vorher importiert haben und dabei alle '' zu Nullen gemacht haben). Das ist unübersichtlich und nervig. Allerdings gibt es, wenn ich die "if-" Anweisung NICHT ausklammere/entferne folgenden Fehler: "Exception [...] Variante des Types (UnicodeString) konnte nicht in Typ (Double) konvertiert werden."
Ich hoffe ihr versteht was ich meine und ic hab mich einigermaßen verständlich ausgedrückt
Danke 
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mi 15.05.13 06:23
Die Umwandlung von nicht Zahlen in den entsprechenden Excel-Zellen in Zahlen erzeugt immer einen Fehler. Du kannst folgendes machen:
Delphi-Quelltext 1: 2: 3: 4: 5:
| try TPDataDauer.AsFloat := Excel.Cells[row, 8].Value; except TPDataDauer.AsFloat := 0; end; |
Dann fängt Delphi den Fehler ab und macht dann - statt die Variable mit dem Wert - der ja keiner ist (z.B. '' oder 'Startzeit' ....) das, was Du willst. Du kannst den Except-Teil auch leer lassen. Ich denke, Du willst bei "fehlerhaften" Zellen keine Datenübergabe machen. Dann fällt die Anweisung TPDataDauer.AsFloat := 0; einfach weg. Der Fehler wird durch das try weggefangen.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 15.05.13 06:50
Wie wäre es mit TryStrToFloat?
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 15.05.13 17:26
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 15.05.13 19:28
Das würde ja gerade die Nullen in die Felder schreiben, was ja nicht gewünscht ist, soweit ich das verstanden habe. Vielleicht lässt sich auch mit VarIsNull oder so abfragen, ob da ein Wert ist.
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mi 15.05.13 20:39
jaenicke hat folgendes geschrieben : | Vielleicht lässt sich auch mit VarIsNull oder so abfragen, ob da ein Wert ist. |
Man kann abfragen, was für ein Typ im Variant enthalten ist.
Beispiel:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56:
| procedure TMainform.Button2Click(Sender: TObject); var Excel : Variant; Blatt : Variant; ExcelWS : Variant; Ergebnis : Variant; ErgebnisTyp : integer; StringTyp : string; begin try Excel := GetActiveOleObject('Excel.Application'); except Excel := CreateOleObject('Excel.Application'); end; Excel.Visible := True;
Excel.WorkBooks.Open('C:\Test.xlsx'); Blatt := Excel.Worksheets.Item['Tabelle1'];
Blatt.Activate; ExcelWS := Excel.ActiveSheet;
Ergebnis := ExcelWS.Cells[1, 2].Value; ErgebnisTyp := VarType(Ergebnis) and VarTypeMask;
case ErgebnisTyp of varEmpty : StringTyp := 'varEmpty'; varNull : StringTyp := 'varNull'; varSmallInt : StringTyp := 'varSmallInt'; varInteger : StringTyp := 'varInteger'; varSingle : StringTyp := 'varSingle'; varDouble : StringTyp := 'varDouble'; varCurrency : StringTyp := 'varCurrency'; varDate : StringTyp := 'varDate'; varOleStr : StringTyp := 'varOleStr'; varDispatch : StringTyp := 'varDispatch'; varError : StringTyp := 'varError'; varBoolean : StringTyp := 'varBoolean'; varVariant : StringTyp := 'varVariant'; varUnknown : StringTyp := 'varUnknown'; varByte : StringTyp := 'varByte'; varWord : StringTyp := 'varWord'; varLongWord : StringTyp := 'varLongWord'; varInt64 : StringTyp := 'varInt64'; varStrArg : StringTyp := 'varStrArg'; varString : StringTyp := 'varString'; varAny : StringTyp := 'varAny'; varTypeMask : StringTyp := 'varTypeMask'; end;
ShowMessage('StringTyp: ' + StringTyp);
end; |
Quelle: www.delphibasics.co....RTL.asp?Name=VarType
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 15.05.13 22:07
jaenicke hat folgendes geschrieben : | Das würde ja gerade die Nullen in die Felder schreiben, was ja nicht gewünscht ist, soweit ich das verstanden habe. |
Dann nimmt man als Fehlerwert eben "0" und vergleicht dann das Ergebnis auf "0". In dem Fall wird die Zuweisung übersprungen.
Es geht ja hier auch darum, dass ein paar mehr Werte übernommen werden sollen. Das mit einer Try-Variante zu machen ist nicht besonders performant. Wobei ich zugebe, dass ich die Performanz von TryStrToFloat nicht geprüft habe.
Ich halte die Lösung von Tranx jedenfalls nicht für besonders gut. Try..Except sollte wirklich nur Ausnahmen behandeln.
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 16.05.13 06:16
jasocul hat folgendes geschrieben : | Das mit einer Try-Variante zu machen ist nicht besonders performant. Wobei ich zugebe, dass ich die Performanz von TryStrToFloat nicht geprüft habe.
Ich halte die Lösung von Tranx jedenfalls nicht für besonders gut. Try..Except sollte wirklich nur Ausnahmen behandeln. |
Öhm... wenn es um die Performance geht, solltest du dir mal dringend die beiden Funktionen anschauen... Die haben rein gar nichts mit try..except zu tun und nutzen intern den selben Code.
Denn: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| function StrToFloatDef(const S: string; const Default: Extended; const AFormatSettings: TFormatSettings): Extended; begin if not TextToFloat(PChar(S), Result, fvExtended, AFormatSettings) then Result := Default; end;
function TryStrToFloat(const S: string; out Value: Extended; const AFormatSettings: TFormatSettings): Boolean; begin Result := TextToFloat(PChar(S), Value, fvExtended, AFormatSettings); end; |
Deshalb ist deine Lösung mit StrToFloatDef sogar langsamer, weil erstens intern geprüft wird, ob die Umwandlung erfolgreich ist und dann der Defaultwert genommen wird und du dann zusätzlich erneut vergleichst und ggf. anders zuweist.
Für diesen Beitrag haben gedankt: jasocul
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Do 16.05.13 07:09
Ich hatte ja geschrieben, dass ich mir die Funktion noch nicht angesehen hatte. Durch die Namensgebung bin ich von einer falschen Annahme ausgegangen. Danke für deine Aufklärung. 
|
|
LuMa86 
      
Beiträge: 76
|
Verfasst: So 19.05.13 18:25
Ah, von "Try" hatte ich noch nie gehört. Damit geht es wunderbar  Danke
|
|
|