![]() |
An welcher Position war/ist die Variable im Template
Hallo zusammen,
ich habe folgende Ausgangssituation. Ich habe ein Template, welches wie folgt aussieht : Zitat:
Wie muss ich jetzt darangehen um rauszubekommen, wie hoch mein Wert in der Variable %counter% ist ? Ich will den Wert für den Counter neu setzen, zum Beispiel nach einem Import von Datensätzen. |
AW: An welcher Position war/ist die Variable im Template
Das Jahr ist immer 4-stellig?
Vorne ist immer ein Zeichen, was nicht dazugehört? Hört sich trivial an ... :stupid:
Delphi-Quellcode:
counter := Integer.Parse( str.SubString( 1, str.Length - 5 ) );
|
AW: An welcher Position war/ist die Variable im Template
Das Template kann aber auch so aussehen :
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Zitat:
Ich hab da irgendeine beliebige Zeichenfolge und will daraus den counter Wert ermitteln. Antwort: No way |
AW: An welcher Position war/ist die Variable im Template
Das ist Schade. Dann muss ich mir etwas anderes überlegen.
|
AW: An welcher Position war/ist die Variable im Template
Das Template ist aber doch irgendwo gespeichert, oder?
Vor der eigentlichen Verarbeitung müßte man also im Template den %counter%-Text und den %year%-Text suchen und anhand ihrer Positionen sieht man, was der Anwender rundherum dazudefiniert hat. Dies wiederum muß man nun weglöschen und landet bei %counter%%year%, bei dem nun noch die letzten vier Characters weg müssen. |
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Oder anders gesagt: Wenn es wirklich eine feste (möglicherweise komplizierter als du bisher denkst) Regel für die Zusammensetzung gibt, es keine Trennzeichen gibt und du höchstens 1 Wert variabler Größe hast, dann geht es.
Und ein Template impliziert eigentlich ein vorgegebenes, festes Muster, sonst ist es kein Template. |
AW: An welcher Position war/ist die Variable im Template
Könntest Du mir (oder vielleicht lieber dem Sir oder so ;-) ) denn erklären, wie ich die Korrektur händisch zuverlässig erledigen könnte?
Gibt es also klare Kriterien dafür? Wenn DAS zutrifft, dann nimm DIESE Ziffern bzw. wenn als Muster FOLGENDE Datei benutzt wurde dann DIESE Ziffern... Wenn ja, sollte es einfach zu lösen sein, wenn nicht, dann nicht. |
AW: An welcher Position war/ist die Variable im Template
Also das Template (z.B. 100%counter%3081%year%) steht so in der Datenbank. Der Inhalt des Templates wird in ein Eingabefeld eingefügt, wobei die Variablen %year% und %counter% mit StringReplace entsprechend mit Werten ersetzt wird. Jetzt ist es so, dass Datensätze über eine Importdatei importiert werden können. Ein Feld in den Datensätzen enthält das Template (z.B.100130812016). Wenn ich jetzt die Anfrage auf dieses Feld ausführe sollte er mir als Wert für %counter% = 1 ausgeben.
Hier noch ein paar Beispiele : 1001030812016 --> %counter% = 10 10012530812016 --> %counter% = 125 100217830812016 --> %counter% = 2178 10047930812016 --> %counter% = 479 Das heißt, wenn diese 4 Datensätze importiert wurden, muss ich als Endergebnis 2178 erhalten. So dass wenn ich jetzt wieder manuell einen Datensatz hinzufüge als nächstes das Template gefüllt wie folgt aussieht : 100217930812016 Ich hoffe, es ist etwas klarer geworden, was ich erreichen will. Ansonsten fragt nochmal nach. |
AW: An welcher Position war/ist die Variable im Template
Wäre es denkbar, daß du dir den Counter selbst irgendwie merkst? Das würde sogar eine Änderung des Templates überstehen.
|
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Aus dem Kopf ungetestet ungefähr so: ?
Delphi-Quellcode:
const
TMP_COUNTER = '%counter%'; TMP_YEAR = '%year%'; function ExtractCounterFromString(const AString: string; const ATemplate: string): integer; var liPosCounter, liLengthCounter: integer; liLengthYear: integer; lsResult: string; begin liPosCounter := Pos(TMP_COUNTER, ATemplate); liLengthCounter := Length(TMP_COUNTER); liLengthYear := Length(TMP_YEAR); lsResult := Copy(AString, liPosCounter + liLengthCounter + 1, Length(AString)); lsResult := Copy(lsResult, 1, Length(lsResult) - liLengthYear); Result := StrToIntDef(lsResult, -1); end; procedure ImportiereDatensaetze; var liMaxCounter: integer; begin liMaxCounter := -1; while EinDatensatzErfolgreichGelesen do begin liMaxCounter := max(liMaxCounter, ExtractCounterFromString(GelesenerDatensatz.CounterString); end; DoWhateverWith(liMaxCounter); end; |
AW: An welcher Position war/ist die Variable im Template
Ich denke, Du musst das Problem mal zerlegen.
1) Du bekommst folgende Strings 1001030812016 10012530812016 100217830812016 10047930812016 aus einer Datenbank? 2) Du willst den höchsten Counter heraus finden? 3) Es können unterschiedliche Templates benutzt worden sein, also wäre als String auch 1232016 denkbar, wo Counter 23 oder 3 sein kann? 4) Du hast keine Ahnung, welche Template zu Grunde lag und wie das strukturiert war? 5) An den aktuellen Gegebenheit kannst Du nichts umstellen? |
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
@ringli
Delphi-Quellcode:
StringReplace( '100%counter%234', '%counter%', '42' ) => '10042234'
|
AW: An welcher Position war/ist die Variable im Template
Man kann so einen String auseinandernehmen, wenn das Template bekannt ist und es nur eine Variable gibt.
Wenn im Template also
Delphi-Quellcode:
und
'%counter%'
Delphi-Quellcode:
enthalten sind, dann kann ich jede Kombination aus einem beliebigen Template erkennen, wenn zugleich gewährleistet ist, dass
'%year%'
Delphi-Quellcode:
immer 4-stellig ist. (Die Platzhalter für counter sollte allerdings nur einmal vorkommen).
'%year%'
Das Template selber muss aber bekannt sein. Oder anders ausgedrückt, das Template muss für jeden counter-Wert einen eindeutigen Wert liefern, dann kann man es auch zurückrechnen. |
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Ich könnte mir das etwa so vorstellen:
Delphi-Quellcode:
counterValue := '42';
highestValue := 0; StringReplace('100%counter%234', '%counter%', counterValue); if IntToStr(counterValue) > highestValue then begin hightestValue := IntToStr(counterValue); end; |
AW: An welcher Position war/ist die Variable im Template
Ich habe ein Problem. Ich verstehe die Diskussion um die Herkunft der Werte für die Variablen %year% und %counter% nicht. Ich möchte doch nur eine einfache String Bearbeitung haben, die mir aus dem Ergebnis den Wert einer Variable vom Template zurückgibt.
Warum muss man jetzt wissen, woher die Variablen Ihre Werte bekommen ? Nach meiner Meinung, ist das doch völlig irrelevant oder übersehe ich hier etwas ? |
AW: An welcher Position war/ist die Variable im Template
Es ist halt nicht klar, was zum Zeitpunkt der benötigten Funktion vorliegt und was nicht und ob Du an den Gegebenheiten noch etwas optimieren kannst.
Beantworte doch mal meine 5 Fragen. Vielleicht hilft das weiter... Wenn Du NUR die Ergebnisstrings hast ohne irgendwelche Infos zu den zu Grunde liegenden Templates, dann wird es schwierig. Die Frage ist, wozu diese Strings dann gespeichert werden, wenn man diese nachher eh nicht mehr vernünftig interpretieren kann. |
AW: An welcher Position war/ist die Variable im Template
Hallo,
ich versuche mal ein bisserl "rumzuspinnen". Dazu mache ich folgende Annahmen: 1. Dir sind alle Templates bekannt. 2. Dir sind für alle Variabeln die möglichen Maximalwerte bekannt. 3. Alle aus den Templates erstellten Werte sind rein nummerische Werte. Stimmt eine der Annahmen nicht, dann vergiss den Rest. Für jedes Template werden folgende Schritte ausgeführt: 1. Das Template wird mit den Maximalwerten befüllt. 2. Per SQL suchst Du nun in der Datenbank den höchsten Wert, der kleiner als der soeben erstellte Wert ist.
Code:
3. Da Dir zu diesem Zeitpunkt der Aufbau des Templates und der deraus erstelle Wert bekannt sind, müsstest Du nun durch entfernen aller der Teile, die nicht durch %counter% in den Wert "hineingekommen" sind, den von Dir gesuchten %counter%-Wert erhalten.
Select max(Spalte) from tabelle where Spalte < "Ergebnis von 1."
Sollte ich um zu viele (und vor allem fehlerhafte) Ecken gedacht haben, dann vergiss das Geschreibsel von mir bitte. |
AW: An welcher Position war/ist die Variable im Template
Das bringt mir doch alles nichts. Es geht doch nur lediglich um den Importvorgang und nach diesem den Counter entsprechend hochzusetzen. Die ganzen Spekulationen und Fragen habe ich in meinen Beiträge beantwortet oder bestätigt.
Ich formuliere es nochmal als letzten Versuch: Ich möchte aus einem Ergebniswert (kann alle Zeichen enthalten) mit Hilfe des Templates den Wert des Counters bestimmen. Alles andere muss und soll so bleiben. Welche Möglichkeiten habe ich ? |
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
@Sir Ruf: Auf welche Frage antwortest Du jetzt ?
|
AW: An welcher Position war/ist die Variable im Template
Ich versuche dann mal etwas konstruktives (nur die Theorie):
Wir haben das Template, was irgendwo die Zeichenfolge
Delphi-Quellcode:
enthält.
'%counter%'
Oder anders betrachtet besteht das Template aus 3 Abschnitten:
Code:
100%counter%3081%year%
Vorne 100 => 3 Zeichen Hinten 3081%year% (year immer 4 Ziffern) => 30810000 => 8 Zeichen
Code:
100217830812016
3 Zeichen vorne entfernen => 217830812016 8 Zeichen hinten entfernen => 2178 heureka! |
AW: An welcher Position war/ist die Variable im Template
Also noch ein Versuch einer Lösung:
Du musst für jedes Template den entsprechenden höchsten Wert aus Deinen Daten ermitteln, alles aus diesem Wert entfernen, was nicht durch den Platzhalter %counter% in den Wert eingeflossen ist und schon hast Du den Wert für %counter%. Da wir keine konkreteren Informationen über den Ursprung der Daten und den Aufbau der Templates haben als: "kann so P%counter%%year% oder so ähnlich aussehen", können wir auch keine konkretere Lösung entwickeln, als es könnte so oder so ähnlich gehen. Und Vorschläge für so oder so ähnlich gibt es jetzt schon einige. Sir Rufo beschrieb in seinem letzten Beitrag das, was ich mit meinem Vorschlag meinte. Man nehme aus dem größten vorhandenen Wert alles heraus, was "fest" im Template enthalten ist, entferne das Jahr und schon hat man den Counter. Da es unterschiedliche Templates gibt, muss für jedes Template eine eigene Counterextrahiermethode her. Die bisherigen Informationen lassen nicht erkennen, dass es eine allgemeingültige Lösung für beliebige Templates geben könnte. |
AW: An welcher Position war/ist die Variable im Template
Eigentlich bin ich ja der Letzte, der sowas vorschlagen würde, aber nach dem Vortrag von Daniel bei der CodeRage DE:
Delphi-Quellcode:
uses
System.RegularExpressions; function ExtractCounter(const Template, Value: string): Integer; var pattern: string; begin pattern := Template.Replace('%counter%', '([\d]+)', [rfIgnoreCase]).Replace('%year%', '(?:[\d]{4})', [rfIgnoreCase]); result := TRegEx.Match(Value, pattern).Groups[1].Value.ToInteger; end; |
AW: An welcher Position war/ist die Variable im Template
Oder eben nach alter Väter Sitte:
Delphi-Quellcode:
PS: leider allgemeingültig :mrgreen:
program Project4;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; function GetCounterFromTemplatedString( const Str, Template: string ): Integer; const CCounter = '%counter%'; CYear = '%year%'; CYearDefault = '0000'; var tmp : string; lFirst, lTail, lLength: Integer; begin tmp := Template.Replace( CYear, CYearDefault ); lFirst := tmp.IndexOf( CCounter ); if lFirst = -1 then raise Exception.Create( 'Fehlermeldung' ); lTail := tmp.Length - lFirst - CCounter.Length; lLength := Str.Length - lFirst - lTail; tmp := Str.Substring( lFirst, lLength ); Result := Integer.Parse( tmp ); end; procedure Check( const Str, Template: string; expected: Integer ); begin if GetCounterFromTemplatedString(str,template) <> expected then raise Exception.Create('Fehlermeldung'); end; procedure Test; begin Check( '1001030812016', '100%counter%3081%year%', 10 ); Check( '10012530812016', '100%counter%3081%year%', 125 ); Check( '100217830812016', '100%counter%3081%year%', 2178 ); Check( '10047930812016', '100%counter%3081%year%', 479 ); Check( 'P12016', 'P%counter%%year%', 1 ); Check( 'P1002016', 'P%counter%%year%', 100 ); end; begin try Test; except on E: Exception do Writeln( E.ClassName, ': ', E.Message ); end; ReadLn; end. |
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Hallo,
verwirrend das alles ist. Das Ausgangs- Template ist bekannt? Auch das Ergebnis? Wo ist jetzt das Problem? Es muss Startindex und Endindex von %counter% ermittelt werden und dann auf den Ergebnisstring angewendet werden. Dazu gab es eine Menge Infos. Heiko |
AW: An welcher Position war/ist die Variable im Template
Ich möchte nochmal erwähnen, daß vermutlich alle Vorschläge hier fehlschlagen werden, wenn es neben den angegebenen Variablen counter und year noch andere variable Elemente in einem Template geben sollte.
|
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Sind die Templates schon fix betoniert, oder kann man da noch eine Struktur vorgeben? Wenn Letzteres, dann sollte eine Konvention für die Formulierung geben, die Dir das Auseinanderklamüsern erleichtert.
zB daß bei [irgendwas]%counter%[irgendwasanderes]%year% die eckigen Klammern sein müssen o.Ä. |
AW: An welcher Position war/ist die Variable im Template
Die Templates sind doch, so wie die jetzt sind, leicht auseinanderzubauen (siehe Beispiel von Uwe und von mir).
|
AW: An welcher Position war/ist die Variable im Template
Generell wäre mein Ansatz, die Variablen in den Templates durch angemessene reguläre Ausdrücke mit benannten Gruppen zu ersetzen.
Wenn die Templates und Variablen passend aufgebaut sind (entweder Trennzeichen und/oder Variablen mit fester Länge), dann sollte eine RegEx-Engine ohne Probleme die richtigen Ergebnisse in den Gruppen matchen. |
AW: An welcher Position war/ist die Variable im Template
Zitat:
|
AW: An welcher Position war/ist die Variable im Template
Habe das Ganze nur überflogen, vielleicht stehe ich auf dem Schlauch: aber warum benutzt du nicht einfach Trennzeichen ?
Delphi-Quellcode:
Das ist doch ein String, richtig, oder möchtest du keine überflüssigen Zeichen drinhaben ?
1001030_81_2016 oder 1001030;81;2016
Rollo |
AW: An welcher Position war/ist die Variable im Template
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:49 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