![]() |
verlinkte datenbank, ohne feste karteikartengröße
Liste der Anhänge anzeigen (Anzahl: 1)
Also nuja, ist nicht ganz leicht zu erklären für mich..
Ich will mal so anfangen: Ich habe eine Personaldatenbank programmiert (wie wahrscheinlich jeder delphi Anfänger) und nun will ich 2 weitere datenbanken anfügen, welchedie Kranktage/Urlaubstage speichert und gestattet, mit ihnen rumzurechnen. Nun weiss ich aber nur, wie ich datenbanken mit fester Recordgröße erstelle, indem ich den record mit den festgelegten variabeln in eine Datei schreibe. Was aber, wenn ich beliebig viele neue einträge in eine einzige karte schreiben will? und die nicht nur als einen langen string, sondern als einzelne Werte, aus denen ich nachher die Gesamt-fehlzeit/urlaubszeit errechnen kann. Weiterhin soll diese db nicht zusätzliche komponenten benötigen, sondern mit einer einzigen datei auskommen, so wie die personaldatei, die ich angelegt habe. Das Projekt soll also nachher aus 3 DBs bestehen, die jeweils 1 datei haben. So, nachdem ich mir jetzt einen Knoten in die Zunge erklärt hab, hoffe ich mal, dass jemand meine Problematik erkennt und mir weiterhelfen kann :] so far: mfg Jan |
Hallo Jan, 8)
ich denke, dass sich hier bei Dir um eine tipische 1:n Beziehung handelt. Nehmen wir an, dass Deine Tabelle mit der Karteien KARTEI heißt. Darüber hinaus werden alle Einträge (zu den Karteien) in der Tabelle KARTEIEINTRAG festgehalten. Folgend jede Deine Tabelle die Du verwendest muss/sollte einen festen- Feld mit dem Namen ID Integer NOT NUL besitzen Also wenn Deine einzelne Karte in der Tabelle KARTEI (z.B. für den Herr Maier) eine ID... sagen wir gleich 14 hat dann alle Einträge in der Tabelle KARTEIEINTRAG (die neben dem eigenem Feld ID auch ein verweis Feld (KARTEIINTRAG_ID Integer NOT NULL) besitzt) die in dem Feld KARTEIEINTRAG_ID gleich 14 sind werden sich auf den Namen Maier beziehen. Somit kannst Du für eine Kartei (in der Tabelle KARTEI) beliebig viele Einträge erstellen in der Tabelle KARTEIEINTRAG Gruß Paul Jr. |
Hallo Paul Jr.,
also erstmal vielen dank, dass du auf meine Frage geantwortet hast, aber irgendwie ist mir das etwas zu sehr theoretisch, ich blick da nix und wieder nix, was wohl an mir liegt. Ich hab ja das Prog hinzugefügt, welches ich bisher gemacht hab. da kann man ja sehen, was ich bislang von Datenbanken verstehe. ich will ja eigentlich nichts anderes machen als nochmal genau so eine DB zu erstellen, nur dass ich während der Laufzeit weitere elemente in eine Karteikarte einfügen können will. Geht das? Falls du genau das schon vorher beantwortet hast, und es nicht leichter zu erklären ist, dann muss ich wohl irgendwie erstmal noch ein bisschen Erfahrung sammeln. Aber danke trotzdem für alle Antworten im Vorraus. mfg Jan |
Hallo Jan,
mir ist nicht ganz klar, ob du wirklich über Datenbanken (z.B. eine Paradoxdatenbank) sprichst oder über eine typisierte Datei!? Wenn du eine Datenbank meinst, dann musst du 2 zusätzliche Tabellen anlegen. Falls du typisierte Dateien meinst, ist das auch machbar. Also was von den beiden Optionen meinst du? Oder hab ich jetzt gar nix kappiert :nerd: ? |
Hallo MrSpock,
also ich glaub kaum dass du was nicht verstanden hast, sondern wenn dann wohl eher ich, ich weiss es selber nicht, was das genau ist, was ich meine, aber ich hab ja mein Prog oben angefügt, es dürfte wohl weniger lange dauern dir das so anzugucken, als wenn ich das erkläre :] ich speichere einfach nur in eine datei per:
Code:
das ist alles. und so soll das mit den 2 weiteren dateien auch gehen, nur dass ich halt oben erwähntes damit anstellen will.
assign(f,Dateipfad);
reset(f); seek(f,pos); write(f,Karte); close(f); besser so? mfg Jan[/code] |
Hallo Jan,
das hilft ja schon weiter. Du willst also mit typisierten Dateien arbeiten. Das geht natürlich. Problematisch ist dabei tatsächlich die Verknüpfung der Informationen in den verschiedenen Dateien. Ich werde dir dazu morgen Abend mal einen Vorschlag machen. Da es aber etwas länger dauert, das zu erklären und Vulkanier so gegen 22:45 Uhr müde werden, müssen wir das auf morgen verschieben :mrgreen: . |
Hallo MrSpock,
*vorspannungfastausdemstuhlfall* ich bin mal gespannt, ob das dann sogar für mich zu verstehen ist, ich werd in der zeit mal mein delphi Wissen vertiefen :) so long.. Jan |
Hallo Jan,
fangen wir mal an, ich gehe mal davon aus, dass zu einen Personenrecord erstellt hast, dieser könnte etwa so aussehen:
Code:
Worauf ich hinaus will ist, du solltest wie Paul Jr schon angemerkt hat jeder Karteikarte (Person) eine ID zuordnen.
type
Karte = record ID : Integer; Nachname : String[30]; Vorname : String[30]; PLZ : String[10]; Ort : String[30]; Strasse : String[30]; end; Die Daten speicherst du dann ja in einem:
Code:
Nehmen wir jetzt mal die Urlaubsdatei, du solltest jetzt jedem Eintrag mitgeben, zu welcher Person er gehört.
var
KarteiFile : File of Karte; Also z.B.:
Code:
Jetzt kannst du für jede Person beliebig viele Einträge in eine Datei : File of Urlaub schreiben. Diese werden nicht sortiert, sondern einfach hintereinander geschrieben.
type
Urlaub = record Person : Integer; Von : TDate; Bis : TDate; end; Wird ein Eintrag später gelöscht, setzt du dessen ID z.B. auf -1, was eine Art Löschkennzeichen ist. Soweit alles klar? |
Hallo MrSpock,
Soweit schon, danke für die infos, ich hab das tatsächlich genau so gemacht, aber du sagst, dass ich jetzt beliebig viele eintrage für eine person schreiben kann, meinst du damit, dass ich für jede urlaubszeit einen neuen record speichern soll, und beim auslesen der urlaubstage für eine bestimmte person die typisierte datei komplett durchlaufen soll und alle tage , die zu einer person gehören ausgeben soll? Ich kann mir das schon vorstellen. Werde ich mal ausprobieren, aber eigentlich ist das ja nur eine umgehung meines Problems, denn ich willte dass die beiden variabeln die du da angegeben hast ("von", "bis") beliebig hinzugefügt werden können, also dann "von1" "bis1" usw, ich also während der laufzeit neue vars der karteikarte hinzufüge, und wenn das nicht geht es irgendwie anders löse, dass der das halt in eine einzige karteikarte/person schreibt, so dass ich nachher in der Urlaubsdatei genausoviele Karten habe wie in der Personaldatei. Aber wenn das nicht geht, dann ist deine Lösung glaube ich gerade gut genug. Vielen Dank hast mir echt weitergeholfen. gruss Jan |
@Daniel B: Ich hatte PLZ größer als 5 angenommen, damit man ggf. auch ein Länderkennzeichen davor setzen kann. Z.B. CS-1000 oder A-12345, etc.
@Jan: Grundsätzlich habe ich mir das genau so vorgestellt. Ich hätte dir nur noch ein bisschen was über Indices erklärt, mit denen man die Suche beschleunigen kann. Das macht aber nur Sinn, wenn du sehr viele Datensätze erwartest. Was du auch machen kannst ist so genannte Comma Separated Values (CSV). Dabei werden die einzelnen Felder eines Datensatzes durch einen Trenner (z.B. ";") von einander getrennt. Die Sätze liest du dann in einem Rutsch als Text ein und zerlegst dann den Satz. Willst du dann später alle Datensätze um ein weiteres Feld erweitern, ist das kein Problem. Du musst dann nur einmalig das neue Feld an alle Datensätze anhängen. Die Namen der Felder könnten im ersten Datensatz abgelegt werden. Solche Dateien lassen sich übrigens sehr gut in Datenbanksysteme oder Tabellenkalkulationen importieren. |
Zitat:
ja natürlich, hast wiedermal weiter gedacht als ich. ;) Hast natürlich recht. Schon rückg. Grüsse, Daniel :hi: |
Hallo Mr.Spock
Danke vielmals für die Hilfe, eine kleine Frage hätte ich da aber noch: Wie sollte ich die Kranktage/Urlaubstage in delphi am besten ausgeben? sowas wie ein Textfeld scheint es ja nicht zu geben, einfach in einen Label? Und gibt es die Möglichkeit 2 Forms gleichzeitig darzustellen, wobei dann im 2. nur 2 grosse textfelder wären, innerhalb denen ich die tage darstelle? Danke im Vorraus für alle Antworten. Gruss Jan |
Hallo Jan,
eine oder zwei TLabel Komponenten sind dafür hervorragend geeignet. Es wären auch TEdit Komponenten möglich, deren Eigenschaft ReadOnly auf True steht. Es ist möglich beliebig viele Fenster gleichzeitig zu öffnen. Soll das eine Fenster nur innerhalb des großen Fensters dargestellt werden können, sollte der Style des Fensters auf fsMDIChild gesetzt werden. Das Hauptfenster müsste dann vom Typ fsMDIForm sein. Das Fenster kann dann über einen Aufruf von Show angezeugt werden (nicht ShowModal). Ist es nicht gewünscht dass die beiden Fenster ineinander dargestellt werden, fügst du einfach ein neues Formular in deine Anwendung ein. Es wird dann automatisch erstellt und kann, nachdem du die beiden Labels wie gewünscht geändert hast über Show angezeigt werden. |
Hi MrSpock,
also, danke nochmal für den tip mit dem show, daran hats gelegen. Und jetzt (welch frust) hänge ich schon wieder fest. also in meinen Augen ist das Programm fertig, bis auf ein paar Schutzmechanismen um falsche Datumsangaben zu verhindern, und das Programm lässt sich auch einwandfrei kompilieren, ABER: wenn ich versuche einen einen Datensatz für eine Fehlzeit zu erstellen schmiert das Proramm mit der Verlautbarung, dass eine EAccess Violation in irgendeiner speicherstelle vorliegt ab, welches ja noch nicht sooo schlimm wäre, gäbe es da nicht ein kleines Problem. Undzwar bleibt der Programmzeiger nach dem absturz da sthen, wo ich den ID-Wert von der Karteikarte setzte. Die funktion schaut so aus:
Code:
und die Karteikarte sieht so aus:
procedure TForm2.Button1Click(Sender: TObject);
var id:integer; begin DateSeparator := '-'; ShortDateFormat := 'm/d/yyyy'; id:=4; udaten.Karte.Person:=id; //hier ist der Programmzeiger stehengeblieben udaten.Karte.von:=strtodate(form2.Edit1.Text); udaten.Karte.bis:=strtodate(form2.Edit1.Text); udaten.schreiben; showmessage('hello'); end;
Code:
Ich habe in der Funktion einfach mal eine feste Zahl genommen, um anderen Fehlern vorzubeugen.
type
TUrlaub = record Person : integer; Von : TDate; Bis : TDate; end; Kann es sein, dass integer ein nicht unterstützer Typ für Records ist? Anders kann ich mir das nämlich nicht vorstellen. Also: Plz Help a noob! MFG LANJAN |
Hallo Jan,
nein, ein Integer ist in einem Record erlaubt. Es liegt bestimmt an uDaten, wie und wo hast du diese Variable deklariert? Da du udaten.schreiben aufrufst, ist uDaten entweder ein Objekt oder eine Unit. Im ersten Fall muss es irgendo ein uDaten := TDaten.Create; oder so etwas geben. |
Hallo MrSpock,
ich habe Udaten in der unit2 über dem implementation teil definiert:
Code:
var
Form2: TForm2; anderedaten:tdatensatz; udaten:Tdatenobjekt; implementation und in der unit3 befndet sich Tdatenobjekt:
Code:
aber wie gesagt, das kompilieren funktioniert ja.. daher verstehe ich das nicht ganz.
TDatenobjekt = class(TObject)
private ps:integer; Datei:string; public Karte : TUrlaub; constructor create; procedure Schreiben; Procedure Lesen(stelle:integer); Function DateiEnde:integer; end; Gruss Jan |
Hallo Jan,
das ist es! uDaten ist ein Objekt. Irgendwann hat Borland einmal statische Objekte abgeschafft. Das bedeutet, dass
Code:
nicht den Speicher für ein Objekt mit dem Namen udaten reserviert, sondern udaten ist nur so etwas wie eine Referenz. uDaten belegt nur den Speicher für die Größe eines Zeigers. Du musst aber nicht mit udaten^ auf die Daten zugreifen, sondern kannst den Namen als Referenz auf das Objekt benutzen. ABER du musst erst Speicher reservieren und das geht mit Create. Bevor du auf die Eigenschaften oder Methoden von udaten zugreifen kannst musst du folgendes schreiben:
var
udaten:Tdatenobjekt;
Code:
Jetzt existiert das Objekt und du kannst auf seine Teile zugreifen.
udaten := Tdatenobject.Create;
|
Hallo alle,
ich bins mal wieder. hab immernoch Probleme bei diesem Programm, nachdem ich leider eine weile wegen anderer Beschäftigungen nicht weiterprogrammieren konnte. ich habe jetzt alles so programmiert wie ich meine es müsste doch alles funktionieren, aber wie es bei mir üblich ist tut es das natürlich... nicht! Also, zu meinem problem: Wer die vorherigen posts gelesen hat, der weiß worum es in meinem Programm geht. Ich habe jetzt eine procedur geschrieben um die kranktage auszulesen, und eine um sie zu speichern: Auslesen:
Code:
schreiben:
Procedure tform2.tageauslesen(id:integer);
var y,x,z:integer; begin form2.Show; form2.memo1.clear; x:=0; z:=udaten.DateiEnde; for y:=0 to z-1 do begin udaten.lesen(y); if udaten.Karte.Person=id then begin form2.memo1.lines[x]:=udaten.karte.von + udaten.karte.bis; x:=x+1; end; end; end;
Code:
(ich habe vorerst nicht den date-typ verwandt, sondern mich auf srings beschränkt um erstml damit fertig zu werden.)
procedure TForm2.Button1Click(Sender: TObject);
begin //DateSeparator := '-'; //ShortDateFormat := 'm/d/yyyy'; udaten.Karte.Person:=anderedaten.lesepos; //udaten.Karte.von:=strtodate(form2.Edit1.Text); //udaten.Karte.bis:=strtodate(form2.Edit2.Text); udaten.Karte.von:=form2.edit1.text; udaten.Karte.bis:=form2.edit2.text; udaten.schreiben; end; so, dann noch die verwendeten proceduren/funktionen: udaten.dateiende:
Code:
udaten.lesen:
function tDatenobjekt.DateiEnde:integer;
var f:File of tUrlaub; begin Datei:='c:\urlaub.ddb'; assign(f,Datei); if not fileexists('c:\Urlaub.ddb') then begin rewrite(f); close(f); end; reset(f); Dateiende:=filesize(f); close(f); end;
Code:
udaten.schreiben:
Procedure Tdatenobjekt.lesen(stelle:integer);
var f:File of tUrlaub; begin Datei:='c:\urlaub.ddb'; assign(f,Datei); reset(f); seek(f,stelle); read(f,Karte); close(f); end;
Code:
so, ich hoffe, dass da nicht an wichtigem code zum Beheben meiner Fehler fehlt.
procedure tdatenobjekt.schreiben;
var f : file of tUrlaub; begin ps:=DateiEnde; Datei:='c:\urlaub.ddb'; assign(f,Datei); reset(f); seek(f,ps); write(f,Karte); close(f); end; nun zumn auftretenden Problem: Anstatt zu der jeweils aufgerufenen Person alle abgespeicherten strings auszugeben wird nur zu der 1. Person, zu der ich etwas abgespeichert habe der 1. Eintrag ausgegeben, nicht mehr und nicht weniger. habe ich da etwas mit den indexen falsch gemacht? was mir aufgefallen ist: wenn ich die typisierte Datei öffne, in welcher die Kranktage abgespeichert werden, so finde ich die date-strings alle korrekt abgespeichert, nur die zahl des users, zu welchem diese daten gehören wird nicht abgespeichert, stattdessen steht ein "gh" hinter dem 1. datum eines jeden Eintrags, kann das irgendetwas damit zu tun haben? Nun ja, ich stehe vor einem Rätsel und vorallem Termindruck *auweia*. Naja, hoping 4 Help. euer Jan |
Hallo Jan,
hier ein paar Kommentare: 1. Du solltest einem Memo nur Daten über
Code:
hinzufügen. Der Versuch direkt auf Lines zuzugreifen ist sehr gefährlich, weil ein Memo zunächst einmal gar keine Lines hat. :mrgreen: Mit jedem Add addierst du eine Zeile. Danach kannst du auf den n-ten Eintrag über Lines[n-1] zugreifen, aber erst dann!
Memo1.Lines.Add(...);
2. Beim Schreiben ist die Kernzeile des möglichen Problems:
Code:
Woher kommt und was ist anderedaten.lesepos?
udaten.Karte.Person:=anderedaten.lesepos;
3. Da du ja gar keinen Index angelegt hast, musst du die Datei sequentiell durchlaufen:
Code:
Ein Index ist eine Tabelle, in der die Zuordnung von IDs und zugehöriger Satznummer in der Datei abgelegt wäre. Z.B. ID 5 steht an Stelle 17 in der Datei. Hättest du diese Info, könntest du einfach den 17. Satz lesen und hättest den Datensatz zu Person 5. In deinem Fall ist aber ein sequentieller Durchlauf wie oben beschrieben sinnvoll.
Datei:='c:\urlaub.ddb';
assign(f,Datei); reset(f); while not EOF(f) do begin read(f, satz); if satz.ID = gesuchteID then .... end; So das war's zunächst für heute. |
Hallo MrSpock,
also zu deinen Fragen: Zitat:
Code:
Das bedarf glaube ich einiger Erklärung:
function tDatensatz.LesePos:integer;
begin LesePos:= pos; end; Diese Funktion ist aus einer anderen unit und gehört zu dem Objekt, welches für die verwaltung meiner personaldatenbank zuständig ist. Die Variable pos ist ein Zeiger für die derzeitige Personalkarte auf die im Moment zugegriffen wird. Jetzt lag es mir nah, einfach die Variable pos als festen Wert für eine Person zu benutzen, weil ja jede Person einen eindeutig zugewiesenen pos-wert hat, nämlich jeweils seine eigene Karteikartennummer. Durch anderedaten.lesepos versuche ich jetzt die derzeitige Position der Personaldatenbank auszulesen und lese/schreibe dann die zu dieser Person gehörenden Kranktage, wobei ich den durch anderedaten.lesepos ausgelesenen Wert weiterverwend und als "Personenkürzel" weiterverwende. Soviel dazu. *Zungeentknot* Der Tipp mit dem memo feld ist Gold Wert, vielen Dank! Allerdings verstehe ich nicht warum du mich darauf hinweist, dass ich die typisierte datei sequentiell auslesen solle, genau das habe ich doch gemacht. hier:
Code:
Weiterhin vielen Dank für jegliche Hilfestellung.
Procedure tform2.tageauslesen(id:integer);
var y,x,z:integer; begin form2.Show; form2.memo1.clear; x:=0; z:=udaten.DateiEnde; for y:=0 to z-1 do begin udaten.lesen(y); if udaten.Karte.Person=id then begin form2.memo1.lines.add(udaten.karte.von + udaten.karte.bis); x:=x+1; end; end; end; mfg Jan |
Hallo nochmal,
ich habe das jetzt alleine hinbekommen, aus irgendeinem Grund hat die funktion lesepos wenn mann sie von der unit1 aus aufrief den korrekten wert ausgegeben, wenn ich ihn aber von der unit2 aufrief, so gab sie grundsätzlich 0 aus. Ich habe mir ganz einfach beholfen indem ich ich eine variable mit dem korrekten von unit1 ausgelesenen Wert gespeichert hab, und habe diese variable zum abspeichern verwandt, anstatt nochmal auf die Funktion Lesepos zuzugreifen. So, jetzt hab ich nurnoch ein ganz kleines Problem: Irgendwie klappt der try befehl nicht so wie er soll:
Code:
anstatt bei einer nicht-datums-eingabe meine message abzuspielen bekomme ich einen exception error und erst wenn ich wieder auf das Programm gehe sehe ich meine message.. wie kann ich den exception error unterbinden, so dass nur meine feine message auftaucht und nicht diese tödliche meldung, die einem Laien nichts sagt un ihn vermutlich nur verwirrt? Ich dachte mit try wäre diese möglichkeit gegeben.
procedure TForm2.Button1Click(Sender: TObject);
begin DateSeparator := '.'; ShortDateFormat := 'd/m/yyyy'; udaten.Karte.Person:=positio; try udaten.Karte.von:=strtodate(form2.Edit1.Text); udaten.Karte.bis:=strtodate(form2.Edit2.Text); udaten.schreiben; except showmessage('Bitte geben sie ein korrektes Datum an!'); end; end; nunja, ich habe mal wieder zu danken. mfg Jan |
Hallo Jan,
zunächst zu der Frage des sequentiellen Lesens. Du benutzt eine Schleife, in der du den Satzzeiger nacheinander jeweils auf den Anfang des nächsten Satzes stellst und dann den Satz ausliest. Würdest du einfach in einer While Schleife von Anfang der Tabelle bis zum EOF Ereignis lesen, würde der Satzzeiger nach jedem Lesevorgang automatisch am Anfang des nächstenb Satzes stehen. Aber dein Code funktioniert auch. Bei deinem try ... except Block ist alles in Ordnung. Vermutlich startest du deine Anwendung aus Delphi und Delphi fängt deine Exception ab und meldet den Fehler zuerst. Dieses Verhalten kannst du ausschalten. Je nach verwendeter Delphi Version ist der Menüeintrag an einer anderen Stelle. Bei D3 unter Tools|Umgebungsoptionen...|Vorgaben|bei exceptions anhalten. Bei D5 bei den Debuggeroptionen. |
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo MrSpock,
wie recht du doch hast, ausserhalb von Delphi funktioniert es ganz so wie es soll. *Vulkanieranbet* Und mein Programm ist nun dank Deiner Hilfe endlich zu einem erfolgreichen Ende gekommen, thx alot! Wenn einer das prog haben will, stelle ich es zur Verfügung, wenn man das überhaupt hier darf. Ist ganz nützlich für Personalverwaltung (hoffe ich). Für zusätzliche Informationen zu einer Person kann sich ja jeder ganz einfach weitere Informationen hinzufügen, das sollte ein leichtes sein. So, das wars denn, hab noch ein paar minor Dinge verbessert. Comments erwünscht!!! Also dwnld and test it!! mfg Jan |
Hallo Jan,
freut mich, wenn ich helfen konnte und ... kleine Programme darfst du jederzeit hier zur Verfügung stellen. Da freuen wir uns sogar drüber :mrgreen: . Bis zum nächsten Problem. |
Hallo Jan,
es wäre Nett wenn Du Dein programm in der Sparte Freeware oder OpenSopurce vorstellen würdest. So hätten alle was davon. Vielleicht liest nicht jeder die Sparte Datenbanken, Dein programm könnte dennoch von nutzen sein. Danke. Grüsse, Daniel :hi: |
Hallo Daniel,
kein Problem, das mache ich doch gerne, hab jetzt auch noch ein paar kleine Verbesserungen gemacht, 2 Dinge nurnoch: 1.: Als *.exe, oder als *.zip mit allen Delphi units und dem Projekt? und 2.: Ich wäre euch sehr zu Dank verpflichtet, wenn ihr mal einen Blick in mein Programm werft und euch die Suchfunktion anschaut, welche zugegeben nicht toll ist, aber mittlerweile auch verbessert ist, und mir sagen könntet, warum die Suche nur für Name, Vorname, Strasse, nicht aber für Stadt und Telefonnummer klappt. Das ist mir ein vollkommenes Rätsel. Naja, weiterhin könnte ich noch eine Hilfestellung bezüglich dem Suchen eines strings, der aber nur in einem anderen string enthalten sein muss, und bei dem es nicht auf Gross - und Kleinschreibung ankommt, gebrauchen. Ein Link zu diesem Thema würde ja auch reichen. Danke für alle Antworten. Gruß Jan |
Zitat:
wenn es mehrere Dateien sind, dann lieber als .zip. Nur die .exe hat bei Delphi schon mind. 300-400Kb. Lieber auch gezippt. :mrgreen: Wenn Du Deine Codes hinzufügen möchtest, dann Poste Dein programm in der Sparte: Open-Source. Stellst Du nur die .exe zur Verfügung, so benutze die Sparte: FreeWare. Die entscheidung bleibt Dir überlassen. :!: Grüsse, Daniel :hi: |
Hi Alle,
guckt bitte mal 2 Einträge weiter oben, ich brauche diesbezüglich immernoch help. thx MFG Jan |
Moin Jan,
falls Du die Suche eines Strings in einem String meinst:
Code:
Durch AnsiUpperCase werden auch Umlaute umgesetzt.
Pos(AnsiUpperCase(sZuSuchenderString),AnsiUpperCase(sStringInDemGesuchtWird))
|
Hallo Herr Seehase,
der Tip ist ja ganz nützlich, abe irgendwie komme ich damit nicht zurecht, er funktionier nur, wenn ich ihn in eine komplett neues projekt, oder in eine komplett leere unit einfüge, wenn ich ihn einfach so in mein Programm übernehme, dann kommt nach Pos( eine Fehlermeldung: "Missing operator or semicolon." ich habe aber keine ahnung warum... hier der qtext:
Code:
function tDatensatz.Suchen(suchbegriff:shortstring; Itemindex, start:integer):boolean;
var count, endpos, startpos:integer; begin endpos:=-1; startpos:=pos; suchen:=false; count:=start; while count<=(dateiende-1) do begin pos:=count; lesen; case Itemindex of 0 : if Pos(AnsiUpperCase('bla'),AnsiUpperCase('wubla'))<>0 then begin endpos:=count; Suchen:=true; count:=dateiende; end; 1 : if Karte.Name=Suchbegriff then begin endpos:=count; Suchen:=true; count:=dateiende; end; 2 : if Karte.Strasse=Suchbegriff then begin endpos:=count; Suchen:=true; count:=dateiende; end; 3 : if Karte.Ort=Suchbegriff then begin endpos:=count; Suchen:=true; count:=dateiende; end; 4 : if Karte.Telefon=Suchbegriff then begin endpos:=count; Suchen:=true; count:=dateiende; end; end; count:=count+1; end; if endpos=-1 then pos:=startpos else pos:=endpos; end; wobei nur der erste teil der case abfrage mit deinem Beispiel ist, zu testzwecken. ok, das wars für heute. Gruss Jan |
Hallo Jan,
ich denke, dass du "Herrn Seehase" trotz seines hohen Alters :lol: durchaus als Christian ansprechen darfst. Hier duzen sich eigentlich alle und / oder reden sich mit dem Pseudonym an. Ein Fehler in deinem Quellcode ist das Fehlen der Deklaration von "pos". Pos ist in der Unit System als Funktion deklariert. Wenn du also pos benutzt und die Unit System in dein Programm eingebunden hast (mit uses), versucht Delphi zunächst diese Deklaration, wundert sich aber über das ";" nach Pos, weil es dort eigentlich eine "(" erwartet. Ich benutze, um Pos nicht als System.Pos benutzen zu müssen, immer "posi" als lokal deklarierte Variable. Außerdem ist in deiner Zuweisung
Code:
pos noch gar nicht initialisiert. Ich guck mir das Ganze nachher noch einmal an, ich muss jetzt weg.
startpos:=pos;
Scotty beameeeeeeeeeeeeeeeeen... |
Hallo MrSpock,
das mit der Anrede war nicht ernst gemeint gewesen, sollte einfach voller Ehrfurcht über all dieses Wissen klingen. :wink: So und jetzt: *indiefaustbeiss* Mann bin ich doof, hab nicht gecheckt, dass ich pos bereits als Variable deklariert hatte, und er deswegen probleme mit der funktion Pos hattte. Mal sehen obs jetzt einwandfrei klappt. Aber bei mir spinnt immernoch die searchroutine, hatte ich ja auch schon erwähnt, nämlich, dass das searchen nur nach den ersten drei Kriterien klappt, bei den anderen gibt es kein Suchergebnis. Dabei unterscheiden sich die kriterien überhaupt nicht in der Programmierung, und das gibt mir zu denken... :roll: Nun ja, wenn dieses problem dann fertig ist bin ich auf dem besten Wege zur finalen Verfollständigung meines Projekts *freu*. :bounce2: bis bald Jan |
Hallo Nochmal!
Also das mit dem Pos klappt jetzt. aber kann mir einer sagen wie ich die differenz in tagen zwischen 2 daten herausbekomme? In der Delphi help steht ja ne Menge drin über date, aber das ist alles ungeordnet und nichtssagend, zumindest für mich, ich habe also auch nach langem Suchen nichts gefunden, leider. Ich weiss nur, dass ich, wenn ich 1 datum vom anderen subtrahiere, dass ich dann den 31.12.99 + die differenz der beiden Daten herausbekomme, aber wie ich das jetzt in die differenz bringe... ka! Danke an alle aufmerksamen Zuhörer! Gruss Jan |
Hallo Jan,
die Differenz in Tagen zwischen zwei Werten vom Type TDateTime erhälst Du am einfachsten mit der Funktion "DaysBetween" aus der Unit "DateUtils". Deklariert ist sie wie folgt:
Code:
Beachten solltest Du Folgendes:
[b]function[/b] DaysBetween([b]const[/b] ANow, AThen: TDateTime): Integer;
Zitat:
|
PS: schon erledigt, habs nach einigem stöbern gefunden: die funktion heisst: daysbetween();
aber ich rätsle immernoch an den suchkriterien rum Bye! Jan |
Moin Jan,
also eigentlich bevorzuge ich ja "Sehr geehrter ...", statt des flapsigen "Hallo..." :mrgreen: (@Mr.Spock: Jungspund vulkanischer ;-)) Aber noch mal kurz zu Deinem Pos Problem, auch wenn's jetzt etwas Off Topic wird: Man kann in der Regel kaum alle bereits vergebenen Bezeichner kennen, so dass eine solche Überschneidung, wie sie in diesem Falle passiert ist, vorkommen kann. Um dieses, zumindest bei der Deklaration von Variablen und Konstanten zu vermeiden ist es ganz nützlich, diese mit einem einem Präfix beginnen zu lassen, der den Typ kennzeichnet, also z.B. i für integer, s für String, p für Pointer, oder auch frm für Formulare. Feste Regeln gibt es hierfür nicht, nur, mehr oder weniger, übliche Abkürzungen. Solltest Du es in Erwägung ziehen auch Präfixe zu verwenden, kannst Du z.B. unter dem Suchbegriff "Ungarische Notation" einiges zu diesen Thema im Internet finden. (Oder es findet hier eine Diskussion darüber statt, wie's jeder so hält ;-)) |
Problem gelöst: ich hatte die edit felder von telefon und Stadt vertauscht *indenbauchbeiß* :oops:
bis zum nächsten Programmiererfehler :] Jan |
Moin Jan,
ist doch immer schön die Fehler selber zu finden. Ich find's auch gut, dass Du diese hier benennst, und nicht nur "Problem gelöst". So haben andere auch etwas davon, und müssen u.U. nicht raten wie sich denn nun eine Lösung ergeben hat. |
Hallo Jan,
du bist mir ja einer. Kaum bin ich zurück von meinem Weltraumtripp, da ist dein Problem schon gelöst :lol: . Naja, wenn Opa C. S. :mrgreen: hilft ... Also dann bis zum nächsten Problem :roll: . |
Definiere Fertig! So, ich stelle das Prog jetzt mal online, sowohl als freeware, als auch open source.
Ich hab gerade gemerkt, dass ich die Antwort zu meinen eigenen Problemen immer geschrieben hab, nachdem schon jemand anders mein Problem gelöst hatte, sry! Das nächste mal versuch ich vielleicht noch ein bisschen mehr zu stöbern, bevor ich sowas frage. Mir ist was in den Sinn gekommen: Ihr arbeitet ja gerade noch an der tutorial section, soweit ich das mitbekommen hab. Ich finde das, was ich da programmiert hab kann mit einer Erklärung in Teilen auch als tutorial für blutige Anfänger herhalten, also vom Thema her: Typisierte Dateien als Minidatenbank. Wenn ihr nichts dagegen hättet, und sowas gebrauchen könnt, könnte ich ja vielleicht mal ein bisschen darüber schreiben, hab mich ja jetzt ne Weile damit rumgeschlagen. Gruss Jan |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:06 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