Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Frage zum Substring in Delphi (https://www.delphipraxis.net/177918-frage-zum-substring-delphi.html)

Oernie1984 5. Dez 2013 14:13

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:
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.
Delphi gibt mir nun immer die Meldung zurück
[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

Lemmy 5. Dez 2013 14:20

AW: Frage zum Substring in Delphi
 
Zitat:

Zitat von Oernie1984 (Beitrag 1238643)
Könnt ihr mir sagen was ich falsch mache? :cry:

quasi alles ;-)

Zitat:

Zitat von Oernie1984 (Beitrag 1238643)
Es handelt sich um diese Zeile
NR1:= PNR.SubString(1,1);

sag mal kurz, was Du hier erwartest? Soll in Nr1 die erste Ziffer stehen?

Grüße

Mikkey 5. Dez 2013 14:21

AW: Frage zum Substring in Delphi
 
PNR ist ein String und keine Klasse, Du kannst das Zeichen an der Stelle k mit
Delphi-Quellcode:
PNR[k]
abrufen.

DeddyH 5. Dez 2013 14:21

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];

joachimd 5. Dez 2013 14:22

AW: Frage zum Substring in Delphi
 
ein String ist kein Objekt, hat also keine Methoden. Du willst die Funktion Copy verwenden: http://www.delphi-treff.de/tutorials...en-funktionen/

baumina 5. Dez 2013 14:22

AW: Frage zum Substring in Delphi
 
Um eine einzelne Stelle eines Strings zu erhalten, kannst Du Label1.Caption := PNR[1]; (erste Stelle) verwenden.

DeddyH 5. Dez 2013 14:23

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]

Oernie1984 5. Dez 2013 14:30

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

Perlsau 5. Dez 2013 14:33

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:

Zitat von Oernie1984 (Beitrag 1238651)
@Lemmy ja genau ich möchte an dieser Stelle die 1. Ziffer der Zahl ausgeben.

Delphi-Quellcode:
Label1.Caption := Copy(MeinString,1,1);
oder
Delphi-Quellcode:
Label1.Caption := SubString(MeinString,1,1);

Pfaffe 5. Dez 2013 14:36

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;

Oernie1984 5. Dez 2013 14:42

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

p80286 5. Dez 2013 15:22

AW: Frage zum Substring in Delphi
 
Dann schau doch mal hier herein.

ggf. mußt du Deine Ziffernfolge als ansistring übergeben.

Gruß
K-H

himitsu 5. Dez 2013 15:23

AW: Frage zum Substring in Delphi
 
Zitat:

Zitat von Pfaffe (Beitrag 1238653)
Folgendes funktioniert unter Delphi XE5:

Weil man endlich mal den RecordHelper auch für generische Typen "freigegeben" hat.
(was ich mir schon von Anfang an lautstark gewünscht hatte ... wann wurden Record-Helper nochmal eingeführt? D2006? )

Neutral General 6. Dez 2013 08:23

AW: Frage zum Substring in Delphi
 
Zitat:

Zitat von Pfaffe (Beitrag 1238653)
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;

In XE4 funktioniert es auch schon :)

Oernie1984 10. Dez 2013 15:22

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:
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.
Kann mir wer sagen was ich falsch mache?

Grüße
Örnie

DeddyH 10. Dez 2013 15:29

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.

Sir Rufo 10. Dez 2013 15:33

AW: Frage zum Substring in Delphi
 
Ja, setzte deinen Code in Delphi-Tags
Code:
[DELPHI]
procedure foo;
begin
end;
[/DELPHI]
sieht dann so aus
Delphi-Quellcode:
procedure foo;
begin
end;
Ach ja, deinen Beitrag kannst du auch bearbeiten

himitsu 10. Dez 2013 16:20

AW: Frage zum Substring in Delphi
 
Zitat:

Zitat von Oernie1984 (Beitrag 1239300)
EConvertError '' ist kein gültiger Integerwert.
Kann mir wer sagen was ich falsch mache?

PS: Mit Strg+C kann man die Texte von MessageBoxen und auch von Compilermeldungen (markierte Zeilen) kopieren.


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 Delphi-Referenz durchsuchenStrToIntDef oder Delphi-Referenz durchsuchenTryStrToInt verwenden

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.

p80286 10. Dez 2013 16:30

AW: Frage zum Substring in Delphi
 
DeddyH hat's ja schon geschrieben:
Delphi-Quellcode:
if length(PNR) <>8 then
  ShowMessage ('Nummer muss 8. Stellig sein')
else begin
 NR1 := Copy (PNR, 1, 1);
 NR2 := Copy (PNR, 2, 1);
....
Und dann würde ich gleich eine Prüf/Korrektur Routine nutzen
etwa so
Delphi-Quellcode:
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;
(ist nicht soo optimal aber übersichtlich)

Gruß
K-H

Jumpy 10. Dez 2013 16:55

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:
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;
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.

DeddyH 10. Dez 2013 17:30

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