![]() |
Delphi-Version: 7
Frage zum Substring in Delphi
Hallo zusammen,
ich habe eine Frage zu den Substrings... Ich möchte mir ein kleines Programm schreiben mit dem ich die 9. Ziffer(Prüfziffer) einer 8 stelligen Zahl ausrechnen kann. Ich würde quasi eine 8 Stellige Zahl in ein Editfeld eintragen und daraufhin soll mir die eingetragene Zahl dann inkl. fehlender 9 Prüfziffer ausgegeben werden. Ich habe für den Anfang folgendes geschrieben:
Delphi-Quellcode:
Delphi gibt mir nun immer die Meldung zurück
unit Pruefziffer;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Schliessen: TButton; Edit1: TEdit; Berrechnung: TButton; Label1: TLabel; procedure ButtonSchliessenClick(Sender:Tobject); procedure ButtonBerrechnungClick(Sender:TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; PNR: String; NR1: String; implementation {$R *.dfm} procedure TForm1.ButtonSchliessenClick(Sender: TObject); begin close; end; procedure TForm1.ButtonBerrechnungClick(Sender:TObject); var PNR, NR1: String; begin PNR:= edit1.text; NR1:= PNR.SubString(1,1); Label1.Caption := NR1; end; end. [Fehler] Pruefziffer.pas(42): Record, Objekt oder Klassentyp erforderlich Es handelt sich um diese Zeile NR1:= PNR.SubString(1,1); Könnt ihr mir sagen was ich falsch mache? :cry: Grüße Oernie |
AW: Frage zum Substring in Delphi
Zitat:
Zitat:
Grüße |
AW: Frage zum Substring in Delphi
PNR ist ein String und keine Klasse, Du kannst das Zeichen an der Stelle k mit
Delphi-Quellcode:
abrufen.
PNR[k]
|
AW: Frage zum Substring in Delphi
String ist keine Klasse und verfügt daher nicht über eine Methode SubString. Du kannst entweder die Copy()-Funktion verwenden oder direkt indiziert auf einzelne Zeichen des Strings zugreifen.
Delphi-Quellcode:
var
NR1: String; ... NR1 := Copy(PNR, 1, 1); (* alternativ *) var NR1: Char; ... NR1 := PNR[1]; |
AW: Frage zum Substring in Delphi
ein String ist kein Objekt, hat also keine Methoden. Du willst die Funktion Copy verwenden:
![]() |
AW: Frage zum Substring in Delphi
Um eine einzelne Stelle eines Strings zu erhalten, kannst Du Label1.Caption := PNR[1]; (erste Stelle) verwenden.
|
AW: Frage zum Substring in Delphi
4 (eigentlich ja 5, gell TBx? ;)) Antworten innerhalb von 2 Minuten. Ist das neuer Rekord?
[edit] Und noch eine mehr *g* [/edit] |
AW: Frage zum Substring in Delphi
Wow ihr seid aber schnell. Vielen Dank für die wirklich "sehr" schnelle Hilfe.
Ich versuche eure Vorschläge direkt mal umzusetzen. :thumb: @Lemmy ja genau ich möchte an dieser Stelle die 1. Ziffer der Zahl ausgeben. Danke Örnie |
AW: Frage zum Substring in Delphi
Was hat die Funktion SubString mit dem Ermitteln einer Prüfziffer zu tun? Substring ist doch identisch mit Copy, soweit ich das beurteilen kann?
Zitat:
Delphi-Quellcode:
oder
Label1.Caption := Copy(MeinString,1,1);
Delphi-Quellcode:
Label1.Caption := SubString(MeinString,1,1);
|
AW: Frage zum Substring in Delphi
Folgendes funktioniert unter Delphi XE5:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var PNR, NR1: String; begin PNR:= edit1.text; NR1:= PNR.SubString(0,1); // Startindex ist 0 basierend Label1.Caption:= NR1; end; |
AW: Frage zum Substring in Delphi
@ Perlsau
Naja ich bin ja noch nicht fertig. Ich habe fürs erst einmal nach einer Möglichkeit gesucht Zugriff auf die einzelnen Ziffern meiner Zahl zu bekommen weil ich mit jeder einzelnen noch weiter rechnen muss. Hier nur mal so zur Info was dahinter steckt ;-) 8-stellige Nummer von links nach rechts auseinander nehmen und Einfach, Doppelt, Einfach, Doppelt, usw. die einzelnen Ziffern addieren. Besonderheit: Kommt eine der doppelt genommenen Einzelzahlen über 9 (wird also zweistellig), werden die beiden Stellen dieser Zahl wiederum addiert (statt dass die zweistellige Zahl für die Gesamt-Addition verwendet wird). Das Ergebnis der Gesamt-Addition wird von der nächst höheren durch 10 teilbaren Zahl abgezogen. Das Ergebnis ist die Prüfziffer. Beispiel: PNR8 = 12161110 Teil 1 Einfach = 1 Teil 2 Doppelt = 4 Teil 3 Einfach = 1 Teil 4 Doppelt = 12 = 3 Teil 5 Einfach = 1 Teil 6 Doppelt = 2 Teil 7 Einfach = 1 Teil 8 Doppelt = 0 Ergebnis = 13 20 ./. 13 = 7 PNR9 = 121611107 Grüße Oernie |
AW: Frage zum Substring in Delphi
|
AW: Frage zum Substring in Delphi
Zitat:
(was ich mir schon von Anfang an lautstark gewünscht hatte ... wann wurden Record-Helper nochmal eingeführt? D2006? ) |
AW: Frage zum Substring in Delphi
Zitat:
|
AW: Frage zum Substring in Delphi
Hallo noch einmal,
Ich habe heute endlich mal wieder Zeit gehabt an meinen Programm weiter zu wurschteln... Ich habe es mit dem mir zur Verfügung stehenden Wissen zum laufen bekommen (für Anregungen wie ich es einfacher oder besser schreiben kann bin ich immer dankbar :oops::oops::-D). Ich habe jetzt nur noch ein Problem. Ich möchte gerne eine Abfrage einbauen mit der ich Denjenigen, der eine zu Prüfende Zahl eingibt dazu zwinge eine 8 Stellige Zahl in das Editfeld zu tippen. Ich erhalte aber immer eine Exception wenn ich testweise eine nicht 8 Stellige Zahl eintippe (EConvertError ''' ist kein gültiger Integerwert). Meine Programm sieht nun folgendermaßen aus:
Delphi-Quellcode:
Kann mir wer sagen was ich falsch mache?
unit Pruefziffer;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Math; type TForm1 = class(TForm) Schliessen: TButton; Berrechnung: TButton; edit1: TEdit; Label1: TLabel; procedure ButtonSchliessenClick(Sender:Tobject); procedure ButtonBerrechnungClick(Sender:TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.ButtonSchliessenClick(Sender: TObject); begin close; end; procedure TForm1.ButtonBerrechnungClick(Sender:TObject); var PNR: String; NR1,NR2,NR3,NR4,NR5,NR6,NR7,NR8: String; NR1INT,NR2INT,NR3INT,NR4INT,NR5INT,NR6INT,NR7INT,NR8INT: Integer; NR2STR, NR4STR, NR6STR, NR8STR: String; NR2TEST1, NR2TEST2, NR4TEST1, NR4TEST2, NR6TEST1, NR6TEST2, NR8TEST1, NR8TEST2: Integer; NR1B,NR2B,NR3B,NR4B,NR5B,NR6B,NR7B,NR8B: Integer; Pruefziffer: Integer; Pruefziffershow: String; begin PNR:= edit1.text; if length(PNR) <>8 then ShowMessage ('Nummer muss 8. Stellig sein') else NR1 := Copy (PNR, 1, 1); NR2 := Copy (PNR, 2, 1); NR3 := Copy (PNR, 3, 1); NR4 := Copy (PNR, 4, 1); NR5 := Copy (PNR, 5, 1); NR6 := Copy (PNR, 6, 1); NR7 := Copy (PNR, 7, 1); NR8 := Copy (PNR, 8, 1); NR1INT:= StrToInt(NR1); NR2INT:= StrToInt(NR2); NR3INT:= StrToInt(NR3); NR4INT:= StrToInt(NR4); NR5INT:= StrToInt(NR5); NR6INT:= StrToInt(NR6); NR7INT:= StrToInt(NR7); NR8INT:= StrToInt(NR8); NR1B:= NR1INT*1; if NR2INT*2<10 then begin NR2B:=NR2INT*2 end else begin NR2STR:= INTtoStr(NR2INT*2); NR2TEST1 := StrToInt (Copy (NR2STR,1,1)); NR2TEST2 := StrToInt (Copy (NR2STR,2,1)); NR2B:= NR2TEST1+NR2TEST2 end; NR3B:= NR3INT*1; if NR4INT*2<10 then begin NR4B:=NR4INT*2 end else begin NR4STR:= INTtoStr(NR4INT*2); NR4TEST1 := StrToInt (Copy (NR4STR,1,1)); NR4TEST2 := StrToInt (Copy (NR4STR,2,1)); NR4B:= NR4TEST1+NR4TEST2 end; NR5B:= NR5INT*1; if NR6INT*2<10 then begin NR6B:=NR6INT*2 end else begin NR6STR:= INTtoStr(NR6INT*2); NR6TEST1 := StrToInt (Copy (NR6STR,1,1)); NR6TEST2 := StrToInt (Copy (NR6STR,2,1)); NR6B:= NR6TEST1+NR6TEST2 end; NR7B:= NR7INT*1; if NR8INT*2<10 then begin NR8B:=NR8INT*2 end else begin NR8STR:= INTtoStr(NR8INT*2); NR8TEST1 := StrToInt (Copy (NR8STR,1,1)); NR8TEST2 := StrToInt (Copy (NR8STR,2,1)); NR8B:= NR8TEST1+NR8TEST2 end; Pruefziffer:= NR1B+NR2B+NR3B+NR4B+NR5B+NR6B+NR7B+NR8B; Pruefziffershow:= IntToStr (ceil(Pruefziffer/10)*10-Pruefziffer); Label1.Caption := PNR+Pruefziffershow; end; end. Grüße Örnie |
AW: Frage zum Substring in Delphi
Benutze doch bitte die Delphi-Tags (das ist die "Helm"-Schaltfläche im Beitragseditor), dann ist der Code besser zu lesen. Auf den ersten Blick fällt mir schon einmal ein fehlender begin-end-Block nach der Längenprüfung auf, so dass die späteren StrToInt-Aufrufe auch bei kürzeren Strings ausgeführt werden.
|
AW: Frage zum Substring in Delphi
Ja, setzte deinen Code in Delphi-Tags
Code:
sieht dann so aus
[DELPHI]
procedure foo; begin end; [/DELPHI]
Delphi-Quellcode:
Ach ja, deinen Beitrag kannst du auch bearbeiten
procedure foo;
begin end; |
AW: Frage zum Substring in Delphi
Zitat:
Und was du falsch machst: Du versuchst einen Leerstring in einen Integer umzuwandeln und da dort nunmal keine "Zahl" drin steht, knallt es eben. Lösung: Mach das nicht. > man nann auch ![]() ![]() Aber in deinem Fall liefert wohl eines der Copy nichts rucück, weil es an der Stelle nunmal keine Zeichen in dem zu kurzen String gibt. Und welche Stelle im Quellcode das ist, wird dir der Debugger sagen. |
AW: Frage zum Substring in Delphi
DeddyH hat's ja schon geschrieben:
Delphi-Quellcode:
Und dann würde ich gleich eine Prüf/Korrektur Routine nutzen
if length(PNR) <>8 then
ShowMessage ('Nummer muss 8. Stellig sein') else begin NR1 := Copy (PNR, 1, 1); NR2 := Copy (PNR, 2, 1); .... etwa so
Delphi-Quellcode:
(ist nicht soo optimal aber übersichtlich)
type
tpnr:string[8]; function PNR_Angleichen(pnr:tpnr):boolean; var i : integer; begin result:=true; while length(mystring)<8 do mystring:='0'+Mystring; for i:=1 to 8 do if not(mystring[i] in ('0','1','2'....'9')) then result:=false; end; Gruß K-H |
AW: Frage zum Substring in Delphi
Das ist aber ein schönes Beispiel, wo man es sich mit einer Schleife und den Funktionen mod und div ersparen kann, mit den vielen Variablen zu arbeiten. Das Folgende ist nur hingetippt und wahrscheinlich nicht so ganz richtig mit den mods und divs, aber das Prinzip sollte so gehen.
Delphi-Quellcode:
Noch besser wäre natürlich die Prüfziffernberechnung in eine eigene Funktion zu packen, die Prüfung, ob die Eingabe brauchbar ist in eine andere, usw.
var nr:String;
i:integer; temp:integer; summe:integer; ergebnis:integer; //oder String begin nr=EditNr.Text; if Length(nr)<>8 then showmessage('Nicht 8 Zeichen!') else begin for i:=1 to 8 do begin if not IsNumeric(nr[i]) then showmessage('Eingabe enthält nicht numerische Zeichen') else begin temp:=StrToInt(nr[i]) ; temp:=temp*(2-(i mod 2)); temp:=(temp mod 10) + (temp div 10); summe:=summe+temp; end; end; ergebnis:=(summe mod 10); //oder falls als Gesamtstring: ergebnis=nr+IntToStr(summe mod 10); end; end; |
AW: Frage zum Substring in Delphi
Das mit den einzelnen Funktionen sehe ich genauso. Ungetesteter Vorschlag:
Delphi-Quellcode:
function ValidNumber(const s: string; out IntVal: integer): Boolean;
begin Result := (Length(s) = 8) and TryStrToInt(s, IntVal); if Result then Result := IntVal > 0; end; function CharToIntValue(c: char; DoubleValue: Boolean): integer; begin Result := StrToInt(c); if DoubleValue then begin Result := Result * 2; if Result > 9 then Result := Result mod 10 + 1; end; end; function CalculateChecksum(const InStr: string; out CheckSum: integer): Boolean; var IntVal, i: integer; begin CheckSum := 0; Result := ValidNumber(InStr, IntVal); if Result then begin IntVal := IntVal div 10 * 10 + 10; for i := 1 to Length(InStr) do inc(CheckSum, CharToIntValue(InStr[i], not Odd(i))); CheckSum := IntVal - CheckSum; end; end; (* Im ButtonClick bleibt dann noch das hier übrig *) procedure TForm1.Button1Click(Sender: TObject); var CheckSum: integer; begin if not CalculateChecksum(Edit1.Text, CheckSum) then ShowMessage('Ungültige Eingabe: nur 8-stellige Zahlen erlaubt') else ShowMessage(IntToStr(CheckSum)); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz