mein Projekt entwickelt sich praechtig.
Danke allen, die mir mit Rat zur Seite gestanden haben.
Ich habe jetzt mein DBGrid, das intensiv bearbeitet wird.
Dort wird mehrfach gefiltert, dort werden Spalten gerechnet und es
werden die Zeilen bunt markiert.
Alles, was schon onCreate gefiltert, berechnet und gezeichnet wird,
passt sofort. D.h. das Grid sieht aus, wie ich will.
Was hingegen zur "spaeteren" Laufzeit also auf Menu-Trigger veranlasst
wird, wird nicht sofort dargestellt. Ich klicke z.B. "Zeilen
ausblenden" oder "dieses fuer jenes berechnen". Ersteres soll im
Filter-Ereignis bearbeitet werden, letzteres im Calc Ereignis.
Alle Ereignisse arbeiten auch "zur späteren Laufzeit" wunschgemaess.
Allerdings SEHE ich das erst nach einigen Mausklicks.
Die Anzeige wird dann richtig, wenn ich mit dem Scrollbar einmal mein
DBGrid rauf- und runterscrolle. Danach erst stehen erst die Einträge in
den Spalten und danach erst sind (weitere) Zeilen ausgeblendet.
Und jetzt kommt die Kristallkugel ins Spiel: Ich weiss nicht, welchem
Event ich mit diesen Scroll-Mausklicks nachhelfe. Bzw. wie ich dieses
ausloesen kann.
Probiert habe ich bis jetzt: Form.Refresh, Autocalc auf true zu setzen,
das CalcEvent oder das FilterEvent explizit aufzurufen. Nix.
Mein DB Grid aktualisiert sich nach wie vor nur nachdem es gescrollt
wurde. Einmal aus dem Bildschirm raus und wieder rein - passt perfekt.
Wie erreiche ich den Effekt auch ohne Scrollen?
(bitte kein DisableControls, das muss aktiv bleiben)
Liebe Gruesse,
Nicole
vorab eine ernst gemeinte Bitte zur Wahl des Betreffs. Suche bitte eine
einigerma�en passende Kurzbeschreibung aus. Deine (zumindest fr�her) gerne
verwendeten Formulierung "f�r Experten" u.�. n�tzen weder Dir noch den
denjenigen die antworten wollen, aber "Kristallkugel" ist nicht besser.
Du stellt doch Fragen auf die Du eine Antwort erhoffst. Warum machst Du es
dann m�glichen Antwortenden nicht so leicht wie nur irgend m�glich?
"DbGrid, Ansicht aktualiseren" w�re z.B. ein Kandidat.
Weiter unten wirst Du lesen, dass es mit dem Grid aber nichts zu tun hat.
:-)
Nicole Wagner schrieb:
> Was hingegen zur "spaeteren" Laufzeit also auf Menu-Trigger veranlasst
> wird, wird nicht sofort dargestellt. Ich klicke z.B. "Zeilen
> ausblenden" oder "dieses fuer jenes berechnen". Ersteres soll im
> Filter-Ereignis bearbeitet werden, letzteres im Calc Ereignis.
Du meinst OnFilterRecord?
Ich vermute, Du schaltest DataSet.Filtered nicht mal auf False und wieder
auf True. Die Umschaltung braucht es aber.
Bzgl. OnCalcFields schaue Dir bitte nochmal die OH dazu an. Den Teil hatten
wir auch bereits.
---
OnCalcFields is triggered when:
A dataset is opened.
A dataset is put into dsEdit state.
A record is retrieved from a database
---
Das passiert in Deinem Szenario aber nicht. Abhilfe schafft u.a.
DataSet.Refresh. Wenn Du, wie ich vermute, TIBDataSet verwendest, dann
musst Du die Property RefrshSQL entsprechend f�llen. TIbDataSet kann Dir
dabei �ber das Eigenschaftsmen� (rechte Maustaste / Dataset Editor /
Generate SQL) helfen.
> (bitte kein DisableControls, das muss aktiv bleiben)
Ich wage zu unterstellen, dass Du nicht wei� worum es sich dabei handelt.
Warum soll das nicht empfohlen werden? Es w�rde eh nichts n�tzen.
Was hei�t, es soll so bleiben? Wenn diese Funktion zum Einsatz kommt, dann
sicherlich (fast) immer mit kurzfristig sp�ter erfolgter Wiederaktivierung.
DisableControls soll lediglich verhindern, dass w�hrend bestimmter Vorg�nge
die den Datensatzzeiger ver�ndern datenanzeigende Controls, wie z.B. das
DbGrid, nicht wild die Ansicht �ndern. Deshlab erfolgt die Verwendung
eigentlich immer nach folgendem Muster;
DataSet.DisableControls;
try
//Beispiel
DataSet.First;
while not DataSet.Eof do begin
//Was auch immer
DataSet.Next;
end;
finally
DataSet.EnableControls;
end;
So, wenn man nun aber anschlie�end auf dem gleichen Datensatz stehen m�chte
wie vorher verwendet man Bookmarks oder merkt sich den Wert des PKs und
versucht mit einem DataSet.Locate vor dem FINALLY dorthin zu navigieren.
Fazit:
a) DisableControls/EnableControls w�rde Dir im konkreten Fall also gar
nicht helfen, h�tte andererseits aber auch keine negativen Auswirkungen.
b) Du siehst, das ist wieder ein Fall in dem das Grid selbst gar keine
Rolle spielt. Dieses schlichte Db-Grid hat nichts mit den Zeilen zu tun die
angezeigt werden, nur mit der Art der Darstellung (Schrift, Farbe,
Hintergrund etc.).
Sollte es notwendig sein sich den aktuellen Datensatz zu merken und
anschlie�end dorthin zu navigieren betrachte ich diesen "Mehraufwand" an
Arbeit als so minimal, dass er keinerlei Entscheidungs�berlegung bedarf.
Gru�, Joe
--
> Was hingegen zur "spaeteren" Laufzeit also auf Menu-Trigger veranlasst
> wird, wird nicht sofort dargestellt. Ich klicke z.B. "Zeilen
> ausblenden" oder "dieses fuer jenes berechnen". Ersteres soll im
> Filter-Ereignis bearbeitet werden, letzteres im Calc Ereignis.
Was machst du denn nach so einer Menü-Aktion?
Es könnte helfen, einfach bei der zugrundeliegenden Query active:=false und
dann active:=true zu setzen.
Evtl. vorher den aktuellen Datensatz merken und anschließend wieder dorthin
positionieren, wie Joe schon geschrieben hat.
Gruß
Burkhard Schneider
Burkhard Schneider schrieb:
> Es könnte helfen, einfach bei der zugrundeliegenden Query active:=false und
> dann active:=true zu setzen.
Das entspräche vom Aufwand her einem TIBDataSet.Refresh, die Query wird
erneut ausgeführt. Das kann man sich für das Ändern des Filters aber
sparen.
Gruß, Joe
--
Danke fuer Deine Antwort.
> "DbGrid, Ansicht aktualiseren" w�re z.B. ein Kandidat.
>
> Weiter unten wirst Du lesen, dass es mit dem Grid aber nichts zu tun
> hat. :-)
Das hatte ich schon geahnt, deshalb habe ich dieses betreff genau nicht
gewaehlt, ;-)
>
> ---
> OnCalcFields is triggered when:
> A dataset is opened.
> A dataset is put into dsEdit state.
> A record is retrieved from a database
> ---
>
> Das passiert in Deinem Szenario aber nicht. Abhilfe schafft u.a.
> DataSet.Refresh. Wenn Du, wie ich vermute, TIBDataSet verwendest, dann
> musst Du die Property RefrshSQL entsprechend f�llen. TIbDataSet kann
> Dir dabei �ber das Eigenschaftsmen� (rechte Maustaste / Dataset
> Editor / Generate SQL) helfen.
>
ich haenge schon hier.
1)
Ich habe leider nicht TIBDate Set, sondern Dataset aus der Gruppe
"Zugriff."
2) Ein Refresh loest eine Exception aus:
"EIDClientError: Zeile kann nicht aktualisiert werden (keine
Aktualisierungs-Abfrage)".
Du schreibst aber etwas von RefreshSQL, das ich nicht gemacht habe.
Ich glaube naemlich nicht, dass ich das brauche fuer meinen speziellen
Zweck. Denn ich will nur die berechneten Felder aktualisieren, nicht
die via Query abgefragten.
Meine Aufgabe ist die:
Mein DBGrid ist gefuellt und listet mir viele Angaben, abgefragte und
berechnete. Calc hat getan, was es sollte und Filter und Draw auch.
Jetzt klicke ich auf ein Menue.
Dieser Click bewirkt, dass eine "nicht-Visuelle Query" (also gehoert
nicht zum Formular oder Thema...) von ein paar dutzend Unit verarbeitet
wird. Alles fuelle ich in ein Array.
Ich habe also 2 Mengen als Ergebnis:
Ein gefuelltes record-Array und mein DBGrid. Eine bestimmte Spalte
meines Records entspricht einer bestimmten Spalte meines DBGrids. Calc
wird wieder aktiv und traegt das Rechenergebnis aus dem Record in die
korrekte Spalte des DBGrids (erste Aktualisierung, die nur nach
Scrollen stattfindet).
Jetzt haben manche DBGrid-Zeilen ein Rechenergebnis und manche nicht.
Jene, die keines haben, will ich ausblenden. Das tut Filter.
(zweite Aktualisierung, die nur nach Scrollen stattfindet).
Wann ich Filter ein und ausschalten soll, weiss ich nicht so genau.
Wo ICH es gemacht habe, war es falsch, denn es hat seine Aufgabe des
Ausblendens nicht mehr erfuellt.
Nicole
PS: Wenn dieser Hinweis, die Sache nur verwirrt, bitte einfach
ignorieren:
Ich habe die Verarbeitung der "nicht-visuellen Unit" so gesteuert, dass
stets ein Array an Calc uebergeben wird. Calc verarbeitet das array von
Low bis High. Dieses Array hat grundsaetzlich die Laenge Null und in
Calc passiert nichts (bzw. nur eine Restaufgabe), weil Low to High Null
bleibt.
Mein Menue-Click tut im Grunde wenig anderes, als das Array zu fuellen,
das Calc zur Verarbeitung schickt.
Nicole Wagner schrieb:
>> "DbGrid, Ansicht aktualiseren" wäre z.B. ein Kandidat.
>>
>> Weiter unten wirst Du lesen, dass es mit dem Grid aber nichts zu tun
>> hat. :-)
>
> Das hatte ich schon geahnt, deshalb habe ich dieses betreff genau nicht
> gewaehlt, ;-)
Es wäre immer noch treffender und hilfreicher gewesen als der aktuelle
Betreff.
> 1)
> Ich habe leider nicht TIBDate Set, sondern Dataset aus der Gruppe
> "Zugriff."
Eine Komponente die Du aufs Form oder Datamodule ziehst mit Klassenname
"DataSet"? Ich denke, Du irrst.
Der Klassenname, den Dir der OI ja auch anzeigt, wird sicherlich mit T
beginnen.
>
> 2) Ein Refresh loest eine Exception aus:
> "EIDClientError: Zeile kann nicht aktualisiert werden (keine
> Aktualisierungs-Abfrage)".
Ich vermute, es handelt sich um einen EIBClientError (B statt D). Wenn ja,
dann tippe ich wieder auf TIBDataSet oder einen Verwandten davon.
"keine Aktualisierungs-Abfrage" klingt auch passend zu einer nicht
gesetzten RefreshSQL-Property der Komponente.
> Du schreibst aber etwas von RefreshSQL, das ich nicht gemacht habe.
> Ich glaube naemlich nicht, dass ich das brauche fuer meinen speziellen
> Zweck. Denn ich will nur die berechneten Felder aktualisieren, nicht
> die via Query abgefragten.
Du kannst glauben oder es einfach mal probieren. Was hälst Du davon? Es
geht schneller als ein neues Posting zu schreiben und hier abzusetzen _und_
Du lernst etwas dabei. Wenn ich Unrecht habe bleibt Dir der Lerneffekt. :-)
> Jetzt klicke ich auf ein Menue.
> Dieser Click bewirkt, dass eine "nicht-Visuelle Query" (also gehoert
> nicht zum Formular oder Thema...) von ein paar dutzend Unit verarbeitet
> wird. Alles fuelle ich in ein Array.
>
> Ich habe also 2 Mengen als Ergebnis:
Wenn ich Dich richtig verstehe wird dieses Array in einem (vielleicht sogar
etwas längerem) Aufwasch gefüllt. Genau jetzt wäre es ein passender Moment
Die Refresh-Methode Deines DataSets aufzurufen. Du siehst, bis Du klarer
beschreibst was Du hast bleibe ich dabei.
Dadurch, dass die Datenmenge neu abgefragt wird erübrigt sich
wahrscheinlich sogar der umschaltende Aufruf von
.Filtered:=False/Filtered:=True des DataSets. Probiere es einfach erst
einmal ohne diesen aus.
> stets ein Array an Calc uebergeben wird.
Was für ein CALC? Du meinst nicht das OnCalcFields-Event, sondern eine
eigene Methode/Funktion/Prozedur?
Gruß, Joe
--
> > 1)
> > Ich habe leider nicht TIBDate Set, sondern Dataset aus der Gruppe
> > "Zugriff."
>
> Eine Komponente die Du aufs Form oder Datamodule ziehst mit
> Klassenname "DataSet"? Ich denke, Du irrst.
>
> Der Klassenname, den Dir der OI ja auch anzeigt, wird sicherlich mit T
> beginnen.
Dann wissen wir beide, dass wir von TDataSet sprechen, ;-)
"das normale" halt.
Wenn man ein Anfaenger-Tutorial liest, steht dort: "Sie brauchen ein
Form und ziehen dorthin....TDataSet...."
(es mit IBDataSet zu ersetzen wuerde einen Giganto-Aufwand darstellen
schaetze ich)
> > 2) Ein Refresh loest eine Exception aus:
> > "EIDClientError: Zeile kann nicht aktualisiert werden (keine
> > Aktualisierungs-Abfrage)".
>
> Ich vermute, es handelt sich um einen EIBClientError (B statt D).
> Wenn ja, dann tippe ich wieder auf TIBDataSet oder einen Verwandten
> davon. "keine Aktualisierungs-Abfrage" klingt auch passend zu einer
> nicht gesetzten RefreshSQL-Property der Komponente.
Das finde ich auch.
Ich habe nur ein Problem. Ich finde so ein Property nicht im
Objekt-Inspektor. Und weiss auch nicht, wie ich es verarbeite.
Ein
Form.IBQuery.DataSource.DataSet.Refresh;
(meine Var-Namen habe ich mal weggelassen)
wird von der Syntax her akzeptiert, loest aber zur Laufzeit eine
Schutzverletzung aus.
Form.IBQuery.SQL.*
kennt kein Refresh
> Du kannst glauben oder es einfach mal probieren. Was hälst Du davon?
Theoretisch viel.
Praktisch siehe oben.
Das Property habe ich naemlich schon gestern nicht gefunden.
> Wenn ich Dich richtig verstehe wird dieses Array in einem (vielleicht
> sogar etwas längerem) Aufwasch gefüllt. Genau jetzt wäre es ein
> passender Moment Die Refresh-Methode Deines DataSets aufzurufen. Du
> siehst, bis Du klarer beschreibst was Du hast bleibe ich dabei.
ja klar.
In diese MenueClick-Methode hatte ich es auch geschrieben.
Aber wie gesagt, alle Refresh', die auf die Query zugreifen, loesen mir
eine Schutzverletzung aus.
(*sich am Kopf krazt* Warum eigentlich?)
Das Setzten von active true/false
hingegen blieb ohne den gewuenschten Erfolg.
> Dadurch, dass die Datenmenge neu abgefragt wird erübrigt sich
> wahrscheinlich sogar der umschaltende Aufruf von
> .Filtered:=False/Filtered:=True des DataSets. Probiere es einfach erst
> einmal ohne diesen aus.
Bitte nicht!
Das waere ganz schlimm.
Denn bevor die Zeilen gefiltert werden, muessen sie noch als
Lookup-Quelle fuers naechste DBGrid herhalten.
> > stets ein Array an Calc uebergeben wird.
>
> Was für ein CALC? Du meinst nicht das OnCalcFields-Event, sondern eine
> eigene Methode/Funktion/Prozedur?
ich meine mit "Calc" das OnCalcFieldsEvent.
Je mehr ich erahne, wozu es dient, desto nuetzlicher erscheint es mir
und desto mehr Aufgaben gebe ich dorthin.
Liebe Gruesse,
Nicole
Nicole Wagner schrieb:
>> Der Klassenname, den Dir der OI ja auch anzeigt, wird sicherlich mit T
>> beginnen.
>
> Dann wissen wir beide, dass wir von TDataSet sprechen, ;-)
Nein. Ich wei�, dass ich ganz sicher nicht davon spreche und vermute recht
stark, dass Du Dich irrst.
Vorab m�chte ich einige Vermutungen und Annahmen formulieren:
- Du verwendest Delphi 2010 (wobei die Unterschiede f�r das aktuelle
Problem wohl vernachl�ssigbar sind)
- Du arbeitest mit den Interbase-Komponenten wie TIBDatabase und TIBSQL.
- Du hast Deine Dataset-Komponente per Maus auf ein Formular oder
Datenmodul gezogen.
Bitte korrigiere mich in allen Punkten in denen ich falsch liege.
Ich habe z.B. noch nie ein Delphi gesehen welches in der Komponentenliste
ein schlichtes TDataset anbot, aber daf�r waren fast alle Komponenten wie
TxxxDataset, TxxxTable und �hnliche _Abk�mmlinge_ von TDataset. Das
bedeutet, dass es sich jeweils um TDatasets handelt (so wie auch Dein
Dataset ein TDataset sein wird) und sie damit alles k�nnen und anbieten was
eben TDataset im Programm hat. Dar�ber hinaus aber bieten sie nat�rlich
weitere M�glichkeiten.
Sollte ich also mit meinen Grundannahmen nicht vollst�ndig daneben liegen,
dann bitte ich Dich noch einmal, Deine Dataset-Komponente im Designmodus zu
markieren und Dir anzuschauen welchen Klassennamen der OI anzeigt. Ganz
oben steht der Name Deiner Komponente (MyQuery oder so) und rechts daneben
der Klassenname. Bitte, schau mal nach.
> "das normale" halt.
> Wenn man ein Anfaenger-Tutorial liest, steht dort: "Sie brauchen ein
> Form und ziehen dorthin....TDataSet...."
Ja, das ist dann irgendein TDataset-Nachfahre.
> Form.IBQuery.DataSource.DataSet.Refresh;
> (meine Var-Namen habe ich mal weggelassen)
> wird von der Syntax her akzeptiert, loest aber zur Laufzeit eine
> Schutzverletzung aus.
IBQuery: TIBQuery --> TIBCustomDataSet --> TWideDataSet --> TDataSet
Dein IBQuery ist ein Nachfahre von TDataSet, hat aber wirklich kein
RefreshSQL.
Mir kommt nur Dein Aufruf sehr seltsam vor. Worauf zeigt denn
IBQuery.DataSource.DataSet? Ich denke mal, es zeigt ins Leere. Das w�rde
dann auch die AV erkl�ren.
Das DataSet von dem Du redest, ist das nicht eben jene IBQuery selbst? Wenn
ja, welches Dataset willst Du �ber IBQuery.DataSource.DataSet ansprechen?
Anders gefragt:
Hat diese IBQuery �berhaupt eine Datasource zugeordnet oder gibt es nicht
eher eine Datasource der eben jene IBQuery zugeordnet wird?
IBQuery kennt �brigens auch ein Refresh.
Also, nicht weil ich rechthaberisch sein m�chte, sondern zur Verdeutlichung
wie vernebelnd Du oft beschreibst, weise ich nochmal darauf hin, dass Du
nicht einfach ein TDataset hast. Im Moment gehe ich von einer TIBQuery aus.
Aber eben weil Du immer von Dataset sprachst, vermutete ich, eben wegen des
angenommenen Einsatzes der Interbase-Komponenten, ein TIBDataset. Das gibt
es n�mlich. Es kennt RefreshSQL und tr�gt halt Dataset im Namen.
>> Dadurch, dass die Datenmenge neu abgefragt wird er�brigt sich
>> wahrscheinlich sogar der umschaltende Aufruf von
>> .Filtered:=False/Filtered:=True des DataSets. Probiere es einfach erst
>> einmal ohne diesen aus.
>
> Bitte nicht!
> Das waere ganz schlimm.
> Denn bevor die Zeilen gefiltert werden, muessen sie noch als
> Lookup-Quelle fuers naechste DBGrid herhalten.
Das h�rt sich alles verdammt chaotisch an, ich kann mir im Moment kein Bild
davon machen.
Aber an einem gewissen Punkt im Ablauf sollen sie gefiltert werden. Das
w�re der Moment des Umschaltens.
>>> stets ein Array an Calc uebergeben wird.
>>
>> Was f�r ein CALC? Du meinst nicht das OnCalcFields-Event, sondern eine
>> eigene Methode/Funktion/Prozedur?
>
> ich meine mit "Calc" das OnCalcFieldsEvent.
Wie �bergibst Du ein Array an OnCalcField()? Du meinst, Du greifst in der
Eventmethode auf eben jenes global oder als Bestandteil des Formulars
verf�gbare Array zu?
Gru�, Joe
--
danke fuer Deine Antwort.
Ich habe Deine Fragen beantwortet.
Doch bevor Du darauf eingehst, lies bitte das Posting zu Ende.
Denn moeglicherweise liegt das Problem woanders.
> - Du verwendest Delphi 2010 (wobei die Unterschiede für das aktuelle
> Problem wohl vernachlässigbar sind)
ja und ja
> - Du arbeitest mit den Interbase-Komponenten wie TIBDatabase und
> TIBSQL.
ja und jein.
Ich arbeite auch mit TIBQuery, weil TIBSQL manchen Schnittpunkt nicht
zur Verfuegung stellt, wie etwa zu TDBChart.
> - Du hast Deine Dataset-Komponente per Maus auf ein Formular oder
> Datenmodul gezogen.
> Ich habe z.B. noch nie ein Delphi gesehen welches in der
> Komponentenliste ein schlichtes TDataset anbot,
> Sollte ich also mit meinen Grundannahmen nicht vollständig daneben
> liegen, dann bitte ich Dich noch einmal, Deine Dataset-Komponente im
> Designmodus zu markieren und Dir anzuschauen welchen Klassennamen der
> OI anzeigt. Ganz oben steht der Name Deiner Komponente (MyQuery oder
> so) und rechts daneben der Klassenname. Bitte, schau mal nach.
Noch mal Nachsehen ist immer gut *erroet*:
Entschuldige meine Verwechslung. Ich lese das Dataset ununterbrochen in
der Programmierzeilenvervollstaendigung. Es ist mir das Wort so
vertraut, dass ich davon ueberzeugt war, es muesste da sein.
Doch habe habe gerade mein Formular angesehen: Ich habe gar kein
TDataset, nur ein TDataSource.
> > Form.IBQuery.DataSource.DataSet.Refresh;
> > (meine Var-Namen habe ich mal weggelassen)
> > wird von der Syntax her akzeptiert, loest aber zur Laufzeit eine
> > Schutzverletzung aus.
>
> IBQuery: TIBQuery --> TIBCustomDataSet --> TWideDataSet --> TDataSet
"Custom", damit bin ich sicher nicht hingekommen.
Ich habe es einmal in die "probieren"-Datei kopiert.
Zur Zeit irritiert mich jedoch "der 1ser", siehe unten.
> Dein IBQuery ist ein Nachfahre von TDataSet, hat aber wirklich kein
> RefreshSQL.
>
> Mir kommt nur Dein Aufruf sehr seltsam vor.
das wird er wohl auch sein.
Denn er fliegt mir nur um die Ohren.
> Das DataSet von dem Du redest, ist das nicht eben jene IBQuery
> selbst? Wenn ja, welches Dataset willst Du über
> IBQuery.DataSource.DataSet ansprechen?
>
> Anders gefragt:
> Hat diese IBQuery überhaupt eine Datasource zugeordnet oder gibt es
> nicht eher eine Datasource der eben jene IBQuery zugeordnet wird?
Genau, jetzt wird es mystisch, siehe dazu die Ausfuehrungen am Ende.
Denn es hat im OI KEINE Datasource zugeordnet.
Und die Auswahl, die im Property angeboten wird, zeigt nicht auf jene,
die ich brauchen wurde. Ein direktes Eingeben bewirkt die Fehlermeldung
"zirkulaere Referenz".
Das DBGrid wird aber gefuellt.
D.h. die Verbindung muss woanders ein.
als Kandidat ist denkbar:
Der Datasource ist ein Dataset zugeordnet, in dem der Name meiner
IBQuery-steht.
(dieses Dataset haette wieder ein Datasource, doch siehe unten, mir
wird hier schwindlig)
Allerdings auch ein "Update Object".
Ist das fuer mich brauchbar?
> IBQuery kennt übrigens auch ein Refresh.
das hat mir schon gestern ebenfalls eine Schutzverletzung ausgeloest.
> Also, nicht weil ich rechthaberisch sein möchte, sondern zur
> Verdeutlichung wie vernebelnd Du oft beschreibst,
Du hast ja recht.
Was Du liest, ist der Nebel in meinem Kopf. Dort fehlt das routinierte
Verstehen, wie all die Komponenten eigentlich aufgebaut sind und
miteinander arbeiten. Es ist meine allerste Anwendung mit diesen
Komponenten.
Klar fehlt bei einem ersten Versuch noch viel an Wissen.
Wenn man nicht wirklich versteht, was DataSet und DataSource genau
sind, verwechselt man sie natuerlich viel eher.
> > Bitte nicht!
> > Das waere ganz schlimm.
> > Denn bevor die Zeilen gefiltert werden, muessen sie noch als
> > Lookup-Quelle fuers naechste DBGrid herhalten.
>
> Das hört sich alles verdammt chaotisch an, ich kann mir im Moment
> kein Bild davon machen.
Es sieht recht schnuckelig aus.
Und wuerde es funktionieren, dann waere es das auch.
Ich habe ein PageControl: Ein Tab liest mir die aktuellen Tageskurse
ein und zeigt sie mir in einem DBGrid.
Ein anderes Tab listet mir mein Konto und die offenen Positionen in
einem anderen DBGrid.
Was interessiert bei den offenen Positionen? - die Buchgewinne.
Daher muss mein DBGrid des Kontos per Lookup aus dem ersten DBGrid die
eingelesenen Kurse holen und den momentanen Kontostand ausgeben.
> >> Was für ein CALC? Du meinst nicht das OnCalcFields-Event, sondern
> eine >> eigene Methode/Funktion/Prozedur?
> >
> > ich meine mit "Calc" das OnCalcFieldsEvent.
>
> Wie übergibst Du ein Array an OnCalcField()? Du meinst, Du greifst in
> der Eventmethode auf eben jenes global oder als Bestandteil des
> Formulars verfügbare Array zu?
ja
Doch jetzt zum angekuendigten Problem, das vielleicht ganz woanders
liegt.
Seit einigen Tagen irritiert mich ein Phaenomen in einer anderen Unit.
Vielleicht kommt das Uebel von dort her.
Die Unit ist zwar sehr lang, doch nicht komplex.
Sie enthaelt die meisten SQL-Queries.
Die Unit-Basis ist ein Modul, das enthaelt:
IBDatabase1, TBTransaction1 und IBSQL1.
Sonst nichts.
Seit einigen Tage stolpere ich ueber ein Phaenomen, das mir vorher
nicht auffiel.
In meinen Query-Methoden, die mir voellig gleich aufgebaut erscheinen,
werden 2 verschiedene Befehle vom Compiler akzeptiert:
Bitte achte auf den (fehlenden) "1" hinter dem Wort Transaction
(wobei '2 verschiedene' ein AUSSCHLUSS ist. D.h. es wird nur das eine
ODER das andere akzeptiert.)
eine Formulierung:
If Not IBTransaction1.InTransaction then
IBTransaction1.StartTransaction;
......
try
IBSQL1.ExecQuery;
IBSQL1.Transaction.Commit; //// !!!!!!!!!!!!!!
except
Showmessage('....');
IBTransaction1.Rollback;
end;
oder aber diese Formulierung:
If Not IBTransaction1.InTransaction then
IBTransaction1.StartTransaction;
......
try
IBSQL1.ExecQuery;
IBTransaction1.Commit; //// !!!!!!!!!!!!!!
except
Showmessage('....');
IBTransaction1.Rollback;
end;
Lasse ich den 1ser weg oder schreibe ihn dazu, sehe ich je die
Fehlermeldung
"unbekannte Var". Einmal so und einmal anders.
Die Deklaration springt mir hierhin fuer "IBTransaction1" in meine
eigene Unit:
TSQL_ = class(TDataModule)
IBDatabase1: TIBDatabase;
IBSQL1: TIBSQL;
IBTransaction1: TIBTransaction;
........
ODER aber hierher in die Delphi-Unit IBSQL fuer "IBTransaction":
TIBSQL = class(TComponent)
........
published
property Database: TIBDatabase read GetDatabase write SetDatabase;
property GoToFirstRecordOnExecute: Boolean read
FGoToFirstRecordOnExecute
write
FGoToFirstRecordOnExecute
default True;
property ParamCheck: Boolean read FParamCheck write FParamCheck
default true;
property SQL: TStrings read FSQL write SetSQL;
property Transaction: TIBTransaction read GetTransaction write
SetTransaction;
property OnSQLChanging: TNotifyEvent read FOnSQLChanging write
FOnSQLChanging;
end;
....
Liebe Gruesse,
Nicole
[active:=false und dann active:=true]
das hatte ich schon vorm Posten probiert.
Half nicht.
Nicole
Nicole Wagner schrieb:
>> - Du arbeitest mit den Interbase-Komponenten wie TIBDatabase und
>> TIBSQL.
>
> ja und jein.
> Ich arbeite auch mit TIBQuery, weil TIBSQL manchen Schnittpunkt nicht
> zur Verfuegung stellt, wie etwa zu TDBChart.
Es ging mir zuerst um die Sammlung selbst.
> Doch habe habe gerade mein Formular angesehen: Ich habe gar kein
> TDataset, nur ein TDataSource.
Klar, die Datasource benötigst Du für Deine visuellen Komponenten.
>> IBQuery: TIBQuery --> TIBCustomDataSet --> TWideDataSet --> TDataSet
>
> "Custom", damit bin ich sicher nicht hingekommen.
> Ich habe es einmal in die "probieren"-Datei kopiert.
Damit wollte ich nur die Herkunft verdeutlichen. Deine IBQuery ist eine
TINQuery und stammt von TIBCustomDatSet ab. Dieses stammt von TWideDataSet
ab usw.
T xxx Custom yyyy sind im Allgemeinen auch nicht zur direkten Verwendung
gedacht, sondern als Ausgangspunkt für eigene Ableitungen. Ein einfaches
Beispiel stellt TPanel dar, welches von TCustomPanel abstammt. TCustomPanel
bietet public nur
property ParentBackground stored FParentBackgroundSet;
constructor Create(AOwner: TComponent); override;
function GetControlsAlignment: TAlignment; override;
an, aber keine published Properties.
TPanel macht nun nichts neues oder eigens, außer dass verschiedene
Properties nun statt protected published deklariert sind.
So kann man eine eigene Komponenten von TCustomPanel ableiten, die aber
eben nicht so viel veröffentlicht wie TPanel, eben weil bestimmte
Properties nicht von außen gesetzt werden sollen. Dadurch bleibt die
Schnittstelle schlank. Mit TPanel wäre das nicht zu machen, da man im
Nachfahren die Sichtbarkeitstufe nicht wieder niedriger ansetzen kann. Man
kann nicht eine im Vorfahren als Public deklarierte Property im Nachfahren
auf Private oder Protected setzen.
> Zur Zeit irritiert mich jedoch "der 1ser", siehe unten.
Später, wenn ich es denn verstehe. :-)
> Genau, jetzt wird es mystisch, siehe dazu die Ausfuehrungen am Ende.
> Denn es hat im OI KEINE Datasource zugeordnet.
> Und die Auswahl, die im Property angeboten wird, zeigt nicht auf jene,
> die ich brauchen wurde. Ein direktes Eingeben bewirkt die Fehlermeldung
> "zirkulaere Referenz".
Die Eigenschaft Datasource Deiner IBQuery ist also leer? Was soll
IBQuery.DataSource.DataSet dann adressieren? Nix! Ist doch eigentlich
logisch, oder? Wenn nicht, sags einfach.
Es ist aber auch ein wenig verwirrend mit Datasource, das stimmt
allerdings.
Zur Eigenschaft Datasource, Deiner IBQuery (eingeführt wird sie vom
Vorfahren TDataset) sagt die D7-OH:
---
Die Eigenschaft DataSource gibt die Datenquelle einer anderen Datenmenge
an, die der aktuellen Datenmenge Werte bereitstellt.
Delphi-Syntax:
property DataSource: TDataSource;
...
Beschreibung
Mit DataSource können Sie auf die Datenquelle einer anderen Datenmenge
zugreifen, die der aktuellen Datenmenge Werte bereitstellt.
---
Auch wenn das nichts besagen will, diese Property habe ich selbst noch nie
benötigt und ich vermute, Du kommst bei Deinem Problem auch ohne aus. Lasse
sie bitte erst einmal unbeachtet.
Die übliche Verbindung zwischen TDateSource und eine TDataSet (oder halt
einem der Nachfahren) sieht so aus, dass man der Eigenschaft DataSet der
DataSource eben ein TDataSet oder einen Nachkommen davon zuweist.
DataSource := MyIBQuery; (oder MyDataSet oder MyIBDataSet oder MyIBTable)
>
> Das DBGrid wird aber gefuellt.
> D.h. die Verbindung muss woanders ein.
Ja, so wie ein paar Zeilen drüber beschrieben.
> als Kandidat ist denkbar:
> Der Datasource ist ein Dataset zugeordnet, in dem der Name meiner
> IBQuery-steht.
> (dieses Dataset haette wieder ein Datasource, doch siehe unten, mir
> wird hier schwindlig)
Genau das wäre nicht der fall.
DataSource.DataSet --- hier kommt Deine IBQuery hin.
IBQuery.DataSource bleibt leer.
> Allerdings auch ein "Update Object".
> Ist das fuer mich brauchbar?
Das ist wieder etwas ganz anderes und hat mit der aktuellen
Aufgabenstellung nichts zu tun.
Das Updateobjekt brauchst Du wenn Du mit IBQuery.Post auch Änderungen
schreiben möchtest.
Das Updateobjekt verweist auf eine Instanz von TUpdateSQL, welches über
eigene SQL-Properties verfügt, jeweils zum Löschen eines Datensatzes,
Einfügen eines neuen Dattensatzes und eben zum Ändern.
Stelle Dir eine Datenmenge vor, die sich aus einem etwas komplexeren
SQL-Statement mit JOINS ergibt. Die Datenmenge enthält also Felder aus
mehreren Tabellen. In TUpdateSQL.ModifySQL (IBQuery.UpdateObject.ModifySQL)
kann man nun eine Stamenet schreiben, bzw. sich generieren lassen, welches
nur Felder schreibt die auch in der betreffenden Tabelle existieren, nicht
aber irgendwelche per JOIN oder anderer SQL-Möglichkeiten hinzugefügten
Felder.
Wie gesagt, das brauchst Du im Moment nicht, langfristig aber bestimmt.
Ganz besonders wenn Du mit datensensitiven Edit-Controls arbeitest und
"darunter" eben nicht einfache Tabellen liegen.
>> IBQuery kennt übrigens auch ein Refresh.
>
> das hat mir schon gestern ebenfalls eine Schutzverletzung ausgeloest.
Ich gehe immer noch davon aus, dass Du es gar nicht aufgerufen hast.
| Form.IBQuery.DataSource.DataSet.Refresh
Wenn Form.IBQuery.DataSource schon leer (nil) war, siehe oben, dann bist Du
nie bis zu einem IBQuery vorgestoßen. Es hätte ja auch nur IBQuery.Refrsh
heißen müssen. Ich glaube auch, dass das Form davor eine Hinweis auf einen
ganz bösen Designfehler hinweist. Warum eigentlich Form? Ist das eine
simple Prozedur/Funktion, die nicht zum Formular gehört aber eben in der
Unit enthalten ist?
Ach ja, Du schriebst auch mal:
| Form.IBQuery.SQL.*
| kennt kein Refresh
Es war auch nie die Rede von einer Methode Refresh der Property SQL. Die
ist vom Typ TStrings und kennt sowas nicht.
> Klar fehlt bei einem ersten Versuch noch viel an Wissen.
> Wenn man nicht wirklich versteht, was DataSet und DataSource genau
> sind, verwechselt man sie natuerlich viel eher.
DataSet ist die Datenmenge, also einfach der Tabelleninhalt oder das
Ergebnis eines komplexeren SQL-Statements.
Ein Grid hat nun eine Eigenschaft DataSource (Quelle), an der ein DataSet
hängt. Über diese Verbindung holt sich das Grid die Daten.
> If Not IBTransaction1.InTransaction then
> IBTransaction1.StartTransaction;
> ......
>
> try
> IBSQL1.ExecQuery;
> IBSQL1.Transaction.Commit; //// !!!!!!!!!!!!!!
> except
> Showmessage('....');
> IBTransaction1.Rollback;
> end;
>
>
> oder aber diese Formulierung:
> If Not IBTransaction1.InTransaction then
> IBTransaction1.StartTransaction;
> ......
> try
> IBSQL1.ExecQuery;
> IBTransaction1.Commit; //// !!!!!!!!!!!!!!
> except
> Showmessage('....');
> IBTransaction1.Rollback;
> end;
Nun, mal rufst Du .Commit der IBTransaction1 auf, dabei handelt es sich
wohl um eine in Deinem Formular existierende Instanz von TIBTransaction.
Im anderen Fall rufst Du .Commit der Transaction auf die IBQuery zugewisen
ist. Dass kann die gleiche sein, aber Du kannst aus der Property
IBQuery.Transaction ja nicht IBQuery.Transaction1 machen.
Du siehst, dass der Unterschied nicht nur in der "1" besteht, sondern auch
in dem "IB" davor?
Das eigentliche Transaktionsobjekt kann dabei in beiden Fällen das Gleiche
sein; ich denke auch, dass es so ist.
Aber das hat alles nichts mit Deinen anderen Problem zu tun. Kein Phänomen.
Nimm nochmal das Beispiel TDataSource/TDataSet.
Du hast auf Deinem Formular ein MyDataSource: TDataSource und IBQuery:
TIBQuery.
Im OI wird nun MyDataSource.DataSet die IBQuery zugewiesen.
Innerhalb igendeiner Methode Deines Formulars könnte nun stehen:
var
LocalDataSet: TDataSet;
s: string;
begin
LocalDataSet := IBQuery;
S := LocalDataSet.FieldByName(xxx).AsString;
S := IBQuery.FieldByName(xxx).AsString;
S := MyDatasource.DataSet.FieldByName(xxx).AsString;
end;
S würde in allen drei Fällen der gleiche String zugewiesen.
In dem Falle würden LocalDataSet, IBQuery und MyDatasource.DataSet auf die
gleiche Datenmenge zeigen. ZEIGEN. Es sind lediglich Zeiger auf Objekte.
> "unbekannte Var". Einmal so und einmal anders.
unbekannter Bezeichner
Ja, das wirkt kleinlich. Aber gerade da Du aus Unkenntnis manchmal sehr
seltsame Umschreibungen und Begriffe wählst, bleibe bitte dort wo möglich
bei den passenden Formulierungen.
Gruß, Joe
--
> [Erklaerungen]
sorgsam gelesen
> Zur Eigenschaft Datasource, Deiner IBQuery (eingeführt wird sie vom
> Vorfahren TDataset) sagt die D7-OH:
>
> ---
> Die Eigenschaft DataSource gibt die Datenquelle einer anderen
> Datenmenge an, die der aktuellen Datenmenge Werte bereitstellt.
und das verstehst Du? (aber nur, weil Du denn Sinn schon vorher weisst)
Ich jedenfalls nicht.
DataSource uebersetze ich mit Datenquelle und das ist ein Hauptwort.
Wenn ich jetzt lese: Die Eigenschaft Datenquelle gibt die
Datenquelle...? haeh? Wovon ist da die Rede?
Sollte "Eigenschaft" vielleicht "property" sein?
Und was fuer eine "andere" Datenmenge? Was ist die aktuelle Datenmenge?
Daselbe wie "Eigenschaft" (Hauptwort oder Eigenschaft?) Datenquelle?
Ist Menge und Quelle jetzt dasselbe? Wenn nicht, was ist der
Unterschied?
Diese Kritik ist keineswegs gegen Dich gerichtet.
Sondern erklaert den Nebel in meinem Kopf. Ich lese dieses kryptische
Denglische Gestammel und lese es stundenlang und ich weiss danach nur
selten, was mir der Autor damit eigentlich sagen will. Moeglicherweise
ein Uebersetzungscomputer.
> > Delphi-Syntax:
>
> property DataSource: TDataSource;
>
> ...
unter "property" kann ich mir schon mehr vorstellen.
> Beschreibung
>
> Mit DataSource können Sie auf die Datenquelle einer anderen Datenmenge
> zugreifen, die der aktuellen Datenmenge Werte bereitstellt.
> ---
>
> Auch wenn das nichts besagen will, diese Property habe ich selbst
> noch nie benötigt und ich vermute, Du kommst bei Deinem Problem auch
> ohne aus. Lasse sie bitte erst einmal unbeachtet.
Ich bin mir da nicht so sicher.
Ich verknuepfe in meinem Formular Informationen aus verschiedenen
Tabellen miteinander und schreibe sie dann in eine andere Tabelle
meiner DB zurueck.
> Die übliche Verbindung zwischen TDateSource und eine TDataSet (oder
> halt einem der Nachfahren) sieht so aus, dass man der Eigenschaft
> DataSet der DataSource eben ein TDataSet oder einen Nachkommen davon
> zuweist.
>
> DataSource := MyIBQuery; (oder MyDataSet oder MyIBDataSet oder
> MyIBTable)
>
Was bedeutet TDataSource?
Ich uebersetze es mit Datenquelle und stelle mir jetzt die Quelle vor,
die nach starkem Regen manchmal aus der Wiese sprudelt.
Liege ich mit diesem Bild richtig?
> > Allerdings auch ein "Update Object".
> > Ist das fuer mich brauchbar?
>
> Das ist wieder etwas ganz anderes und hat mit der aktuellen
> Aufgabenstellung nichts zu tun.
es loest ohnehin eine Schutzverletzung aus.
> Das Updateobjekt brauchst Du wenn Du mit IBQuery.Post auch Änderungen
> schreiben möchtest.
>
> Das Updateobjekt verweist auf eine Instanz von TUpdateSQL, welches
> über eigene SQL-Properties verfügt, jeweils zum Löschen eines
> Datensatzes, Einfügen eines neuen Dattensatzes und eben zum Ändern.
Klar will ich das!
Ich habe es nur bis jetzt nicht implementiert.
Ich wollte das urspruenglich ueber meinen SQL-Werkzeugkasten machen.
Ist das via UpdateSQL probater?
> Stelle Dir eine Datenmenge vor, die sich aus einem etwas komplexeren
> SQL-Statement mit JOINS ergibt. Die Datenmenge enthält also Felder aus
> mehreren Tabellen. In TUpdateSQL.ModifySQL
> (IBQuery.UpdateObject.ModifySQL) kann man nun eine Stamenet
> schreiben, bzw. sich generieren lassen, welches nur Felder schreibt
> die auch in der betreffenden Tabelle existieren, nicht aber
> irgendwelche per JOIN oder anderer SQL-Möglichkeiten hinzugefügten
> Felder.
oh!
Wie interessant.
> Wie gesagt, das brauchst Du im Moment nicht, langfristig aber
> bestimmt. Ganz besonders wenn Du mit datensensitiven Edit-Controls
> arbeitest und "darunter" eben nicht einfache Tabellen liegen.
Ich brauche es schon heute, wenn ich meine Aufgabenliste ansehe, die
ich mir fuer diese Woche bereit gelegt habe.
Ich frage mich, ob ich das nicht schon vor 2 Wochen gebraucht haette.
Ich arbeite naemlich so:
Der Benutzer hat eine Checklistbox. Je nachdem, was er dort anklickt,
wird in verschiedene Tabellen geschrieben. Ich habe das bis jetzt
geloest, indem ich im OnClick-Event *.SQL.Active auf false gesetzt
habe, die *.SQL.text-Zuweisung neu geschrieben und danach die Query
wieder auf true.
Ist das de lege artis?
Apropos de lege artis:
Ein ganz schlechtes Gefuehl habe ich dabei, dass ich im Feldeditor die
IBQuery bearbeite, aufgrund der SQL-Formulierung Felder und Spalten
anlege und danach locker vom Hocker SQL.Text zur Laufzeit neu zuweise.
Sowas "macht man nicht". So grundsaetzlich.
> > Form.IBQuery.DataSource.DataSet.Refresh
>
> Wenn Form.IBQuery.DataSource schon leer (nil) war, siehe oben, dann
> bist Du nie bis zu einem IBQuery vorgestoßen. Es hätte ja auch nur
> IBQuery.Refrsh heißen müssen. Ich glaube auch, dass das Form davor
> eine Hinweis auf einen ganz bösen Designfehler hinweist. Warum
> eigentlich Form? Ist das eine simple Prozedur/Funktion, die nicht zum
> Formular gehört aber eben in der Unit enthalten ist?
Doch, sie gehoert zum Formular.
Ich habe das nie so ganz durchschaut, wann ich Form explizit angeben
muss und wann ich es nicht darf.
In 90 Prozent aller Faelle, wenn vom Compiler eine Syntax ohne Form
akzeptiert wurde, hatte ich in Wahrheit einen Pointer nach nil, der zur
Laufzeit eine Schutzverletzung ausloeste.
Das passierte etwa haeufig in Zusammenhang mit TChart. Ich habe mir
daher angewoehnt, im Zweifel Form explizit hinzuschreiben. Zudem ich
mit meine hunderte Variablennamen nicht merken kann und die
Programmierhilfe quasi verwenden muss.
Doch Methoden, die nicht zum Formular gehoeren: Wie loest man das? Legt
man dafuer eine eigene Klasse an? Wenn ja, wie bezeichnet man die
Klasse am besten, damit man die Methode wiederfindet?
> > Klar fehlt bei einem ersten Versuch noch viel an Wissen.
> > Wenn man nicht wirklich versteht, was DataSet und DataSource genau
> > sind, verwechselt man sie natuerlich viel eher.
>
> DataSet ist die Datenmenge, also einfach der Tabelleninhalt oder das
> Ergebnis eines komplexeren SQL-Statements.
ach so!!!!!!!!!!!!
Jetzt habe ich es verstanden.
> Ein Grid hat nun eine Eigenschaft DataSource (Quelle), an der ein
> DataSet hängt. Über diese Verbindung holt sich das Grid die Daten.
Das habe ich zum ersten mal auch verstanden, zumindest teilweise.
Dieser Teil ist mir unklar:
Wozu braucht das Grid eine DataSource?
Wenn DataSet eine Datenmenge ist, dann muesste doch das Grid nur ein
property DataSet haben?
Das Grid braucht doch nur die Datenmenge, die es darstellt und keine
Datenquelle?
Urspruenglich wollte ich meinem DBGrid eine Query zuweisen und dachte,
es wuerde darstellen, was das Query abfragt. Doch das ging nicht im OI.
und cit:
"Über diese Verbindung".... Ich dachte, "Query" waere die Verbindung
mit einer DB? Oder Transaction?
> Du siehst, dass der Unterschied nicht nur in der "1" besteht, sondern
> auch in dem "IB" davor?
noe, das ist mir auch beim dutzenden mal Lesen entgangen.
Das ist der Preis: Auch etwa mein Mann denkt sehr systematisch. Ihm
waere das auch aufgefallen.
Wort- und Silbenspiele gegen mich hasst er. Denn ich gewinne mit einen
Vorsprung zwischen dem Faktor 2 bis 10. Weil ich Buchstaben derart
radikal ausblende, dass ich sie NIE sehe. In meinem Kopf kommen nur
Woerter an.
Danke fuer den Hinweis!
> Das eigentliche Transaktionsobjekt kann dabei in beiden Fällen das
> Gleiche sein; ich denke auch, dass es so ist.
darum ist es mir auch lange nicht aufgefallen.
Weil meine Methoden gleichermassen funktionierten.
> Nimm nochmal das Beispiel TDataSource/TDataSet.
>
> Du hast auf Deinem Formular ein MyDataSource: TDataSource und IBQuery:
> TIBQuery.
> Im OI wird nun MyDataSource.DataSet die IBQuery zugewiesen.
>
> Innerhalb igendeiner Methode Deines Formulars könnte nun stehen:
>
> var
> LocalDataSet: TDataSet;
> s: string;
> begin
> LocalDataSet := IBQuery;
>
> S := LocalDataSet.FieldByName(xxx).AsString;
> S := IBQuery.FieldByName(xxx).AsString;
> S := MyDatasource.DataSet.FieldByName(xxx).AsString;
> end;
>
> S würde in allen drei Fällen der gleiche String zugewiesen.
> In dem Falle würden LocalDataSet, IBQuery und MyDatasource.DataSet
> auf die gleiche Datenmenge zeigen. ZEIGEN. Es sind lediglich Zeiger
> auf Objekte.
DARAN LIEGT ES!
Ich habe hier ratlos und endlos die Programmierhilfe meine Sachen
suchen lassen. Mir war voellig schleierhaft, wie und warum meine
ZEILEN-LANGEN Ausdruecke aufgebaut waren. Ich habe einen Weg gefunden,
dorthin zu kommen, der NOCH umstaendlicher ist. Von dort habe ich es
dann stets kopiert.
Bitte frage mich jetzt nicht wie, merken kann ich mir das nicht. Ich
weiss nur, dass ich manche lokale Vars nur deshalb fuehre, weil ich mit
den Zuweisungsmonstern nicht arbeiten kann.
Meine augenblickliche Idee waere, in Zukunft stets "IBQuery." zu
verwenden, weil es das kuerzeste ist.
> > "unbekannte Var". Einmal so und einmal anders.
>
> unbekannter Bezeichner
>
> Ja, das wirkt kleinlich. Aber gerade da Du aus Unkenntnis manchmal
> sehr seltsame Umschreibungen und Begriffe wählst, bleibe bitte dort
> wo möglich bei den passenden Formulierungen.
Von meiner Ueberzeugung bin ich ganz bei Dir.
Genaue Wortwahl fuehrt zu genauem und damit richtigerem und schnelleren
Denken.
Was ist der Unterschied von Bezeichner und Variable?
Ist Bezeichner ein Oberbegriff, unter den Var zu subsummieren ist?
D.h. Die Fehlermeldung in Delphi bedeutet, es koennte etwa auch eine
Methode sein, die dem Compiler nicht zuordernbar ist?
Nicole
Nicole Wagner schrieb:
>> Die Eigenschaft DataSource gibt die Datenquelle einer anderen
>> Datenmenge an, die der aktuellen Datenmenge Werte bereitstellt.
>
>
> DataSource uebersetze ich mit Datenquelle und das ist ein Hauptwort.
> Wenn ich jetzt lese: Die Eigenschaft Datenquelle gibt die
> Datenquelle...? haeh? Wovon ist da die Rede?
> Sollte "Eigenschaft" vielleicht "property" sein?
Ja natürlich.
>
> Und was fuer eine "andere" Datenmenge? Was ist die aktuelle Datenmenge?
Na, die IBQuery (oder IBDataset oder IBTable oder irgendein DataSet) deren
Eigenschaft DataSource wir gerade betrachten.
> Daselbe wie "Eigenschaft" (Hauptwort oder Eigenschaft?) Datenquelle?
> Ist Menge und Quelle jetzt dasselbe? Wenn nicht, was ist der
> Unterschied?
Datasource ist die Quelle, die Datenmenge irgendein TDataSet, bzw. ein
Nachkomme wie TIBQuery, TIBTable, TIBDataSet oder natürlich auch
TAdoDataSet und andere.
> Sondern erklaert den Nebel in meinem Kopf. Ich lese dieses kryptische
> Denglische Gestammel und lese es stundenlang und ich weiss danach nur
> selten, was mir der Autor damit eigentlich sagen will. Moeglicherweise
> ein Uebersetzungscomputer.
Das ist kein Denglish. Die Property heißt nun einmal DataSource und kann ja
nicht an dieser Stelle anders benannt werden. "Die Proptery DataSource
eines DataSets gibt die Datenquelle....".
>
> Ich bin mir da nicht so sicher.
> Ich verknuepfe in meinem Formular Informationen aus verschiedenen
> Tabellen miteinander und schreibe sie dann in eine andere Tabelle
> meiner DB zurueck.
Tu Dir und mir einen Gefallen und beachte diese Property vorläufig nicht.
Wenn hier jemand kommt und Dir _konkret_ zeigt wie Du sie für _genau_ Dein
aktuelles Problem einsetzen kannst, von mir aus. Bis dahin werde ich mich
nicht mehr um die Eigenschaft DataSource eines DataSets kümmern. Ich bin
mir zu sicher, dass Du Dich verzetteln wirst. So viel Zeit und Muße habe
ich nicht.
>> Die übliche Verbindung zwischen TDateSource und eine TDataSet (oder
>> halt einem der Nachfahren) sieht so aus, dass man der Eigenschaft
>> DataSet der DataSource eben ein TDataSet oder einen Nachkommen davon
>> zuweist.
>>
>> DataSource := MyIBQuery; (oder MyDataSet oder MyIBDataSet oder
>> MyIBTable)
>>
>
> Was bedeutet TDataSource?
> Ich uebersetze es mit Datenquelle und stelle mir jetzt die Quelle vor,
Hier kommen wir nun wieder zu der anders gelagerten Verbindung. Eine
DataSource der ein DataSet zugewiesen wird.
Ja, die Datenquelle für ein Control wie ein TDbGrid der TDbEdit etc.. Ich
habe früher bei dem Begriff Quelle auch eher an die Datenmenge gedacht,
d.h., ich habe mich verwirren lassen.
Stelle Dir es eher wie eine Verbindung oder Datenleitung vor. Du hast die
Datenmenge (TDataSet, TIBQuery, etc) und datensensitive Controls wie die
bereits genannten TDbGrid oder TDbEdit. Die Controls kommen über die
Dataquelle an die Datenmenge heran.
>>> Allerdings auch ein "Update Object".
>>> Ist das fuer mich brauchbar?
>>
>> Das ist wieder etwas ganz anderes und hat mit der aktuellen
>> Aufgabenstellung nichts zu tun.
>
> es loest ohnehin eine Schutzverletzung aus.
War denn der Property UpdateObject etwas zugewiesen? Wenn nicht, was sonst
außer einer AV soll da kommen?
> Klar will ich das!
> Ich habe es nur bis jetzt nicht implementiert.
>
> Ich wollte das urspruenglich ueber meinen SQL-Werkzeugkasten machen.
> Ist das via UpdateSQL probater?
Das kommt darauf an. :-)
Wenn Du direkt in Deiner Datenmenge mit IBQuery.FieldByName().As.. := ...
ändern und dann mit IBQuery.Post arbeiten möchtest, dann wirst Du
UpdateObject brauchen.
Willst Du stattdessen mit irgendeiner anderen IBQuery (SchreibQuery) und
'UPDATE TABLE Y SET Y=Z WHERE ID=N' (oder so) etwas direkt in die Tabelle
schreiben möchtest, dann geht es ohne UpdateObject. Deine ursprüngliche
IBQuery sieht diese Daten aber erst nach einem Refresh.
Was hälst Du davon, diesen Teil zu verschieben, bis der Rest klappt? Ja,
ich befürchte auch hier die Gefahr des Verzettelns.
> Der Benutzer hat eine Checklistbox. Je nachdem, was er dort anklickt,
> wird in verschiedene Tabellen geschrieben. Ich habe das bis jetzt
> geloest, indem ich im OnClick-Event *.SQL.Active auf false gesetzt
> habe, die *.SQL.text-Zuweisung neu geschrieben und danach die Query
> wieder auf true.
Warum hast Du das Statement neu zugewiesen? Oder meinst Du die Zuweisung
verschiedener schreibender Statements für die verschiedenen Tabellen?
> Ist das de lege artis?
Bei mehreren Tabellen ja.
> Ein ganz schlechtes Gefuehl habe ich dabei, dass ich im Feldeditor die
> IBQuery bearbeite, aufgrund der SQL-Formulierung Felder und Spalten
> anlege und danach locker vom Hocker SQL.Text zur Laufzeit neu zuweise.
> Sowas "macht man nicht". So grundsaetzlich.
Nun, es ist zumindest seltsam. Ich selbst schreibe niemals nie die Felder
in die DataSet-Komponente, d.h., ich lege diese persistenten Felder nicht
zur Designzeit an, nur zur Laufzeit. Enthält die Datenmenge nämlich
irgendwann ein weiteres Feld (egal ob durch Erweiterung der zugrunde
liegenden Tabelle oder durch Erweiterung der Abfrage), dann darf ich nicht
vergessen eben auch den Feldeditor zu verwenden um jenes Feld hinzuzufügen.
Mir fehlt es sonst in der Datenmenge. Trotzdem kannst Du natürlich so
verfahren.
Was spricht dagegen, anstatt die SQL-Statements neu zuzuweisen, für jeden
Zweck eine eigene Komponente zu nehmen? Oder sind es so viele, evtl.
dynamisch erzeugte Statements?
> Doch, sie gehoert zum Formular.
> Ich habe das nie so ganz durchschaut, wann ich Form explizit angeben
> muss und wann ich es nicht darf.
Das ist wirklich nicht so kompliziert. In einer Methode einer Klasse, und
ein Formular ist ja nur die Instanz einer Klasse, hast Du ein implizites
with Self, wobei Self auf eben diese Klasse verweist.
procedure TMyForm.TuWas;
begin
with Self do begin //das siehst Du nicht, musst es Dir denken
Caption := 'Ein Text'; //Durch das WITH SELF wird die Property Caption
//Deines Formulars angesprochen.
end; //das siehst Du nicht, musst es Dir denken
end;
procedure TMyForm.TuWas(Caption: string);
begin
with Self do begin //das siehst Du nicht, musst es Dir denken
//Mist, Du willst Caption an Caption zuweisen.
//Welches Caption ist denn nun gemeint?
//Durch Self wird nun klar, dass Du links der Zuweisung die Property
//Caption des Formulars meinst. Rechts davon ist es der Parameter.
Self.Caption := Caption;
end; //das siehst Du nicht, musst es Dir denken
end;
Solche Sachen können besonders gut auftreten wenn Du selbst mit with
arbeitest.
with MyObject do begin
Caption := //hier ist nun Caption des Objekts gemeint, auch wenn sich
//sich dieser Code in der Methode eines Formulars befindet.
end;
Du siehst, dass ich nirgends meine Formularvariable verwendet habe? Das tue
ich auch niemals. NIEMALS. Sehr viele Formulare benötigen gar keine
Variable, da niemand von außen darauf zugreift. Auf jeden Fall hat die
Variable für ein Objekt nichts im Code der Klasse dieses Objekts zu suchen.
Ich sage NIE. Nun mag besondere Beispiele geben, die mir in meiner
Schlichtheit nicht in den Sinn kommen, aber evtl. von anderen genannt
werden. Aber auch dann werde ich davon ausgehen, dass diese Fälle
ausreichend besonders sind, dass der eher unerfahrene Entwickler weiterhin
vom NIE ausgehen sollte.
Wenn irgendwann eine weitere Instanz der Klasse erzeugt wird, oder eine
andere Variabel dafür verwendet wird, dann zeigt die ursprüngliche Variable
entweder schlicht auf die erste Instanz oder einfach nur ins Leere.
Wenn ich mal in eine, Formular eine Funktion oder Prozedur deklarieren muss
die nicht Bestandteil des Formulars ist, aber darauf zugreifen muss, dann
bekommt diese Funktion einen passenden Parameter.
function GetValue(aForm: TMyForm): Integer;
begin
aForm....
end;
> In 90 Prozent aller Faelle, wenn vom Compiler eine Syntax ohne Form
> akzeptiert wurde, hatte ich in Wahrheit einen Pointer nach nil, der zur
> Laufzeit eine Schutzverletzung ausloeste.
Hast Du mal passende Beispiele, gerne auch in Form eines überschau- und
übersetzbaren Projekts (siehe Emailadresse, bitte nicht alles hier
reinposten), dann wird man anhand diese Codes sicherlich so manches
erklären können.
> Das passierte etwa haeufig in Zusammenhang mit TChart. Ich habe mir
> daher angewoehnt, im Zweifel Form explizit hinzuschreiben. Zudem ich
> mit meine hunderte Variablennamen nicht merken kann und die
> Programmierhilfe quasi verwenden muss.
Ok, da habe ich nur die mitgelieferte Version.
> Doch Methoden, die nicht zum Formular gehoeren: Wie loest man das? Legt
> man dafuer eine eigene Klasse an?
Wenn es nur eine kleine Hilfsfunktion ist, kommt sie einfach in die
Firmularunit. Spo benötigt man als Fallback-Funktion für Sortieraufgaben
eine einfache Funktion und eben keine Methode.
Schlichte Funktionen bleiben bei mir auch meist einfache Funktionen, werden
halt in einer Unit ausgelagert.
> Wenn ja, wie bezeichnet man die
> Klasse am besten, damit man die Methode wiederfindet?
Das ist ein ganz anderes Thema. Ich kann nur sagen, dass man sich durchaus
Zeit zur Namensfindung nehmen sollte. Eben um solche Unterstrichsuffixe wie
Du sie gerne verwendest zu vermeiden.
Aber ich werde nur sehr langsam schlau und nehme mir auch heute noch zu
selten genug Zeit dafür. Oder ich bin einfach zu phantasielos.
> Bitte frage mich jetzt nicht wie, merken kann ich mir das nicht. Ich
> weiss nur, dass ich manche lokale Vars nur deshalb fuehre, weil ich mit
> den Zuweisungsmonstern nicht arbeiten kann.
Das ist oft auch besser, als zur Vermeidung fröhlich mit WITH zu arbeiten,
vielleicht sogar noch geschachtelten WITHs. Nicht, dass ich sie gar nicht
verwende, aber eher sparsam udn ganz bestimmt nicht über vile Zeilen. Wenn
ich Anfang und Ende des Blockes nicht mehr gleichzeitig sehen kann, dann
ist sowas auf jeden Fall zu vermeiden. Eigentlich schon früher. Dann sind
kurze Variablennamen sehr hilfreich. Geschachtelte WITHs kommen mir nicht
in meinen Code, die schafft mein Hirn nicht ausreichend gut.
Wo ich gerne WITH verwende ist bei manchen modalen Dialogen.
fcuntion TMyForm.GetDialogValue: TModalResult;
begin
with TMyDialogForm.Create(Application) do begin
try
Result := ShowModal;
finally
Free; //Das Free des erzeugten Formulars
end;
end;
end;
Dieses TMyDialogForm kommt ganz sicher ohne jegliche Formularvariable aus,
die automatisch erzeugte wird sowieso, wenn ich es nicht vergesse, gleich
beseitigt.
> Meine augenblickliche Idee waere, in Zukunft stets "IBQuery." zu
> verwenden, weil es das kuerzeste ist.
Warum gibst Du dem Kind nicht gleich einen passenden Namen? Ebenso hoffe
ich, dass IBTransaction1 nur der Name aus einem Testcode ist.
> Was ist der Unterschied von Bezeichner und Variable?
> Ist Bezeichner ein Oberbegriff, unter den Var zu subsummieren ist?
> D.h. Die Fehlermeldung in Delphi bedeutet, es koennte etwa auch eine
> Methode sein, die dem Compiler nicht zuordernbar ist?
Ja.
Gruß, Joe
--
> Das ist kein Denglish. Die Property heißt nun einmal DataSource und
> kann ja nicht an dieser Stelle anders benannt werden. "Die Proptery
> DataSource eines DataSets gibt die Datenquelle....".
Denglish ist fuer mich, wenn jemand mit seltsamen Vokalbeln herumlallt,
etwa "schoppen geht" (hat der eine Ente zum Fuettern?). Und dann, wenn
jemand termini technici eindeutscht. Etwa "Eigenschaft" statt
"property" sagt. Fuer mich ist das nur ein Vokabel zusaetzlich.
Wobei ein Usenet-Beitrag sicher etwas anderes ist, als eine
Hilfefunktion.
Wie ungluecklich die Uebersetzung per se und dann noch mit dem Wort
"Eigenschaft" ist, wird klar, wenn man sich vorstellt, man will nach
dem Wort suchen, nachdem man etwa "property read" gefunden hat.
> > Ich bin mir da nicht so sicher.
> > Ich verknuepfe in meinem Formular Informationen aus verschiedenen
> > Tabellen miteinander und schreibe sie dann in eine andere Tabelle
> > meiner DB zurueck.
>
> Tu Dir und mir einen Gefallen und beachte diese Property vorläufig
> nicht. Wenn hier jemand kommt und Dir konkret zeigt wie Du sie für
> genau Dein aktuelles Problem einsetzen kannst, von mir aus. Bis dahin
> werde ich mich nicht mehr um die Eigenschaft DataSource eines
> DataSets kümmern. Ich bin mir zu sicher, dass Du Dich verzetteln
> wirst. So viel Zeit und Muße habe ich nicht.
Danke, dass Du Dir die Zeit nimmst, die Du Dir nimmst!
> >> Die übliche Verbindung zwischen TDateSource und eine TDataSet (oder
> >> halt einem der Nachfahren)
... dieser Satz hat mich gerade 2 Stunden beschaeftigt.
Ich habe wieder einen mir verstaendlichen Teil in der Hilfe gefunden.
Und einige Links, die nicht ins Leere zeigten, sondern auf Romane.
sieht so aus, dass man der Eigenschaft
> >> DataSet der DataSource eben ein TDataSet oder einen Nachkommen
> davon >> zuweist.
> >>
> >> DataSource := MyIBQuery; (oder MyDataSet oder MyIBDataSet oder
> >> MyIBTable)
> >>
> >
> > Was bedeutet TDataSource?
> > Ich uebersetze es mit Datenquelle und stelle mir jetzt die Quelle
> > vor,
>
> Hier kommen wir nun wieder zu der anders gelagerten Verbindung. Eine
> DataSource der ein DataSet zugewiesen wird.
>
> Ja, die Datenquelle für ein Control wie ein TDbGrid der TDbEdit etc..
> Ich habe früher bei dem Begriff Quelle auch eher an die Datenmenge
> gedacht, d.h., ich habe mich verwirren lassen.
>
> Stelle Dir es eher wie eine Verbindung oder Datenleitung vor. Du hast
> die Datenmenge (TDataSet, TIBQuery, etc) und datensensitive Controls
> wie die bereits genannten TDbGrid oder TDbEdit. Die Controls kommen
> über die Dataquelle an die Datenmenge heran.
Ich probiere mit den neuen Woertern einmal, ob der Nebel im Kopf sich
lichtet.
Angenommen, ich habe Wasser, das sich in einem Berg sammelt.
Es fliesst aus dem Felsen ueber ein kleines Rohr in ein Becken.
Aus dem Becken kann Wasser geschoepft werden.
Dann waere:
TDataBase: Das Wasser im Berg
TConnection: die Oeffnung im Felsen
TDataSource: das kleine Rohr? Und nicht das Becken?
TDataSet / TIBQuery:
Wasserschoepfen im Primaerbecken inkl. Wasserteilmenge und
Schoepfvorgang
Die Controls sind die Nutzniesser der Einrichtungen?
Und was ist die Gesamtheit des Beckens?
> > Klar will ich das!
> > Ich habe es nur bis jetzt nicht implementiert.
> >
> > Ich wollte das urspruenglich ueber meinen SQL-Werkzeugkasten machen.
> > Ist das via UpdateSQL probater?
>
> Das kommt darauf an. :-)
>
> Wenn Du direkt in Deiner Datenmenge mit IBQuery.FieldByName().As.. :=
> ... ändern und dann mit IBQuery.Post arbeiten möchtest, dann wirst Du
> UpdateObject brauchen.
>
> Willst Du stattdessen mit irgendeiner anderen IBQuery (SchreibQuery)
> und 'UPDATE TABLE Y SET Y=Z WHERE ID=N' (oder so) etwas direkt in die
> Tabelle schreiben möchtest, dann geht es ohne UpdateObject. Deine
> ursprüngliche IBQuery sieht diese Daten aber erst nach einem Refresh.
>
> Was hälst Du davon, diesen Teil zu verschieben, bis der Rest klappt?
> Ja, ich befürchte auch hier die Gefahr des Verzettelns.
ja und nein.
Ich meinem DBGrid-testen komme ich auf viel hundert Klicks pro Tag.
Und neu Starten der Anwendung, weil sich meine DBGrids wieder mal
ungewollt geleert haben. So gehen die Stunden auch dahin.
Ich weiss nur noch immer nicht, was ich "Refresh" muss.
> > Der Benutzer hat eine Checklistbox. Je nachdem, was er dort
> > anklickt, wird in verschiedene Tabellen geschrieben. Ich habe das
> > bis jetzt geloest, indem ich im OnClick-Event *.SQL.Active auf
> > false gesetzt habe, die *.SQL.text-Zuweisung neu geschrieben und
> > danach die Query wieder auf true.
>
> Warum hast Du das Statement neu zugewiesen? Oder meinst Du die
> Zuweisung verschiedener schreibender Statements für die verschiedenen
> Tabellen?
>
> > Ist das de lege artis?
>
> Bei mehreren Tabellen ja.
ja, es sind mehrere Tabelle.
Der Benutzer kann seine Geschaefte verschiedenen Konten zuweisen.
> > Ein ganz schlechtes Gefuehl habe ich dabei, dass ich im Feldeditor
> > die IBQuery bearbeite, aufgrund der SQL-Formulierung Felder und
> > Spalten anlege und danach locker vom Hocker SQL.Text zur Laufzeit
> > neu zuweise. Sowas "macht man nicht". So grundsaetzlich.
>
> Nun, es ist zumindest seltsam. Ich selbst schreibe niemals nie die
> Felder in die DataSet-Komponente, d.h., ich lege diese persistenten
> Felder nicht zur Designzeit an, nur zur Laufzeit. Enthält die
> Datenmenge nämlich irgendwann ein weiteres Feld (egal ob durch
> Erweiterung der zugrunde liegenden Tabelle oder durch Erweiterung der
> Abfrage), dann darf ich nicht vergessen eben auch den Feldeditor zu
> verwenden um jenes Feld hinzuzufügen. Mir fehlt es sonst in der
> Datenmenge. Trotzdem kannst Du natürlich so verfahren.
> Was spricht dagegen, anstatt die SQL-Statements neu zuzuweisen, für
> jeden Zweck eine eigene Komponente zu nehmen? Oder sind es so viele,
> evtl. dynamisch erzeugte Statements?
Ich habe Mischformen davon.
Wenn ich etwa nur das Konto austausche, dann sind alle Tabellen gleich
aufgebaut und ich brauche nur einen einzigen Buchstaben aendern.
also etwas so:
procedure sql_Abfrage(Buchstabe: string);
SQL.Text:='select ... from Konto_' + Buchstabe + ';';
Wenn die Aufgabe ganz verschieden ist, dann flog mir die Sache ohnehin
um die Ohren mit dem Feldeditor.
Unter dem Strich habe ich zur Zeit drei eigene Komponenten. Also
ueberschaubar.
Mit denen hakt es aber auf jeden Fall. Ich kann leider nicht mal die
Frage formulieren, wo es hakt. Rufe ich sie einzeln nach Programmstart
auf, dann klappt alles wunderbar. Klicke ich schnell zwischen ihnen hin
und her, dann warte ich bis zu einer Minute. Auch hier denke ich, dass
es etwas mit dem Refresh-Thema haben muss. Eine Pruefung der
OnCalc-Events ergab ein Mitverschulden, doch es kann es nicht alleine
sein.
> > Doch, sie gehoert zum Formular.
> > Ich habe das nie so ganz durchschaut, wann ich Form explizit angeben
> > muss und wann ich es nicht darf.
>
> Das ist wirklich nicht so kompliziert. In einer Methode einer Klasse,
> und ein Formular ist ja nur die Instanz einer Klasse, hast Du ein
> implizites with Self, wobei Self auf eben diese Klasse verweist.
>
> procedure TMyForm.TuWas;
> begin
> with Self do begin //das siehst Du nicht, musst es Dir denken
>
> Caption := 'Ein Text'; //Durch das WITH SELF wird die Property
> Caption //Deines Formulars angesprochen.
>
> end; //das siehst Du nicht, musst es Dir denken
> end;
>
> procedure TMyForm.TuWas(Caption: string);
> begin
> with Self do begin //das siehst Du nicht, musst es Dir denken
>
> //Mist, Du willst Caption an Caption zuweisen.
> //Welches Caption ist denn nun gemeint?
>
> //Durch Self wird nun klar, dass Du links der Zuweisung die
> Property //Caption des Formulars meinst. Rechts davon ist es der
> Parameter. Self.Caption := Caption;
>
> end; //das siehst Du nicht, musst es Dir denken
> end;
Wenn Self auf das Formular zeigt und ich mir das Wort dazudenken
kann,... kann ich dann nicht auch den Formularnamen explizit anweisen?
also:
procedure TMyForm.TuWas;
MyForm.Caption := 'Ein Text';
?
> Solche Sachen können besonders gut auftreten wenn Du selbst mit with
> arbeitest.
>
> with MyObject do begin
> Caption := //hier ist nun Caption des Objekts gemeint, auch wenn
> sich //sich dieser Code in der Methode eines Formulars
> befindet. end;
Marian sagte
"with verheisst Unheil".
Da sich diese Prophezeiung bewahrheitet hat (man hat ja auch bei
Var-Namen seine Lieblingsausdruecke und Gleichheiten bringen VIEL
Unheil) vermeide ich with, solange ich die Zeile noch irgendwie
handlich tippen kann.
With habe ich nur noch bei Owner-Draw Teilen, wo man den Codeteil
bequem unter jedes "With Formularnamen" kopieren kann.
> Du siehst, dass ich nirgends meine Formularvariable verwendet habe?
> Das tue ich auch niemals. NIEMALS.
interessant
> Sehr viele Formulare benötigen gar
> keine Variable, da niemand von außen darauf zugreift. Auf jeden Fall
> hat die Variable für ein Objekt nichts im Code der Klasse dieses
> Objekts zu suchen.
ui, das habe ich nicht vestanden.
Was ist "die Variable fuer ein Objekt"?
> > In 90 Prozent aller Faelle, wenn vom Compiler eine Syntax ohne Form
> > akzeptiert wurde, hatte ich in Wahrheit einen Pointer nach nil, der
> > zur Laufzeit eine Schutzverletzung ausloeste.
>
> Hast Du mal passende Beispiele, gerne auch in Form eines überschau-
> und übersetzbaren Projekts (siehe Emailadresse, bitte nicht alles hier
> reinposten), dann wird man anhand diese Codes sicherlich so manches
> erklären können.
es wird mir sicher wieder unterkommen.
Ich hatte es damals an der mir heute nicht mehr gelaeufigen Stelle
sogar kommentiert, dass ich die E gesehen hatte aus diesem Grund.
> > Das passierte etwa haeufig in Zusammenhang mit TChart. Ich habe mir
> > daher angewoehnt, im Zweifel Form explizit hinzuschreiben. Zudem ich
> > mit meine hunderte Variablennamen nicht merken kann und die
> > Programmierhilfe quasi verwenden muss.
>
> Ok, da habe ich nur die mitgelieferte Version.
Probiere einmal Pro.
Ich bin von der schlichtweg begeistert.
Sie hat nur eine Nag-Screen als Demo und ist uneingeschraenkt
funktionsfaehig.
> > Doch Methoden, die nicht zum Formular gehoeren: Wie loest man das?
> > Legt man dafuer eine eigene Klasse an?
>
> Wenn es nur eine kleine Hilfsfunktion ist, kommt sie einfach in die
> Firmularunit. Spo benötigt man als Fallback-Funktion für
> Sortieraufgaben eine einfache Funktion und eben keine Methode.
huch?
Ich habe mein Leben lang gedacht, Methode waere der Oberbegriff von
Funktionen und Prozeduren?
> Schlichte Funktionen bleiben bei mir auch meist einfache Funktionen,
> werden halt in einer Unit ausgelagert.
>
> > Wenn ja, wie bezeichnet man die
> > Klasse am besten, damit man die Methode wiederfindet?
>
> Das ist ein ganz anderes Thema. Ich kann nur sagen, dass man sich
> durchaus Zeit zur Namensfindung nehmen sollte. Eben um solche
> Unterstrichsuffixe wie Du sie gerne verwendest zu vermeiden.
>
> Aber ich werde nur sehr langsam schlau und nehme mir auch heute noch
> zu selten genug Zeit dafür. Oder ich bin einfach zu phantasielos.
Ich habe mir Bibliotheken angelegt.
Etwa eine namens Zeit.
Dort sammelt sich im Laufe der Jahre der Schrott.
Wie ich vor 5 Jahren ein Datum formatiert habe, das mache ich heute
nicht mehr. Ebenso wie ich verschiedene Formatumwandlungen nicht mehr
brauchem weil ich das Format wahrscheinlich(!) nicht mehr verwende.
Wenn ich aber etwas loesche, ist es notorisch jenes, das ich noch
gebraucht haette.
Keine Unterstrichsuffixe?
Ohne die bin ich verloren. Ich kann nur mit Woertern.
Ich ueberlege zur Zeit, ob ich Unix nicht links liegen lasse mit all
den Kuerzeln.
> > Bitte frage mich jetzt nicht wie, merken kann ich mir das nicht. Ich
> > weiss nur, dass ich manche lokale Vars nur deshalb fuehre, weil ich
> > mit den Zuweisungsmonstern nicht arbeiten kann.
>
> Das ist oft auch besser, als zur Vermeidung fröhlich mit WITH zu
> arbeiten, vielleicht sogar noch geschachtelten WITHs. Nicht, dass ich
> sie gar nicht verwende, aber eher sparsam udn ganz bestimmt nicht
> über vile Zeilen. Wenn ich Anfang und Ende des Blockes nicht mehr
> gleichzeitig sehen kann, dann ist sowas auf jeden Fall zu vermeiden.
ich vermeide es auch, wo geht.
Doch je laenger ein Block, desto mehr erspart das with
Zu Blockanfang und Ende habe ich einen Trick:
D 2010 hat recht gute Autofunktionen:
Schreibe ich ein begin und die Eingabetaste, dann schreibt mir Delphi
ein end; genau drunter.
D.h. ich habe meine begin-end-Block formatiert, bevor ich die erste
Zeile schreibe. Und bevor ich die Zeile schreibe, kopiere ich die
Befehlszeile als Kommentar hinter das end.
Also for i:=0 to 100 do
begin
end; // zu for i:=0 to 100
Dann erst beginne ich meinen Code zu tippen.
Natuerlich nur fuer laengere und ineinandergeschachtelte Schleifen.
Etwa fuer Boolean-bedingte while-Schleifen, die ineinanderzahnen, ist
mir das nach einiger Zeit eine Arbeitsersparnis beim Wiederbearbeiten,
zu sehen, welches end welche Schleife begrenzt.
> Eigentlich schon früher. Dann sind kurze Variablennamen sehr
> hilfreich. Geschachtelte WITHs kommen mir nicht in meinen Code, die
> schafft mein Hirn nicht ausreichend gut.
und das Ueberwachungsfenster im Compiler noch weniger
Leider habe ich geschachtelte withs als Fremdcode. Grauslich ist das,
mit denen zu arbeiten.
> Wo ich gerne WITH verwende ist bei manchen modalen Dialogen.
>
> fcuntion TMyForm.GetDialogValue: TModalResult;
> begin
> with TMyDialogForm.Create(Application) do begin
> try
> Result := ShowModal;
> finally
> Free; //Das Free des erzeugten Formulars
> end;
> end;
> end;
>
> Dieses TMyDialogForm kommt ganz sicher ohne jegliche Formularvariable
> aus, die automatisch erzeugte wird sowieso, wenn ich es nicht
> vergesse, gleich beseitigt.
Was ist denn DAS?
Das sieht viel griffiger aus als meine Dialoge mit der Message Box.
* kopier *
Abgesehen davon, dass ich modale Dialoge vermeide. Zu oft kam ich an
ein Fenster nicht mehr ran und musste das Programm abschiessen. Nicht
in einenen Anwendungen. Ich vermeide modal ja wo geht, ;-)
> > Meine augenblickliche Idee waere, in Zukunft stets "IBQuery." zu
> > verwenden, weil es das kuerzeste ist.
>
> Warum gibst Du dem Kind nicht gleich einen passenden Namen? Ebenso
> hoffe ich, dass IBTransaction1 nur der Name aus einem Testcode ist.
Meine Queries heissen alle so, wie ihre DBGrid-PageContolTab-Eltern.
Meine Transaction hingegen heisst wirklich nur 1.
Diese Transaction1 ist in irgendeinem Zusammenhang als "default"
gelistet (weiss nicht mehr wo, im OI?). Sobald ich eine andere
Transaction verwenden wollte, fand ich den Eintrag nicht mehr in der
DB. Bzw. sprang dieser default-Eintrag im OI hin und her und es
passierten seltsame Dinge.
Ich ging dann den Weg des geringsten Widerstandes und verwendete stets
nur die eine Transaction1, die funktionierte.
Liebe Gruesse,
Nicole
Nicole Wagner schrieb:
>> Das ist kein Denglish. Die Property heißt nun einmal DataSource und
>> kann ja nicht an dieser Stelle anders benannt werden. "Die Proptery
>> DataSource eines DataSets gibt die Datenquelle....".
>
>
> Denglish ist fuer mich, wenn jemand mit seltsamen Vokalbeln herumlallt,
> etwa "schoppen geht" (hat der eine Ente zum Fuettern?). Und dann, wenn
> jemand termini technici eindeutscht. Etwa "Eigenschaft" statt
> "property" sagt. Fuer mich ist das nur ein Vokabel zusaetzlich.
Ach so, Du stößt Dich an der deutschen Bezeichnung Eigenschaft. Nun, die
finde ich aber vorrangig so in der deutschen Literatur verwendet. Ich
schreibe in deutschem Fließtext auch Prozedur und nicht Procedere. Das
halte ich für durchaus angemessen und habe diesbzüglich an dem betreffenden
Text nichts auszusetzen.
> Wie ungluecklich die Uebersetzung per se und dann noch mit dem Wort
> "Eigenschaft" ist, wird klar, wenn man sich vorstellt, man will nach
> dem Wort suchen, nachdem man etwa "property read" gefunden hat.
In einem deutschen Hilfstext hätte ich durchaus "Eigenschaft" gewählt, in
Code eben "property".
War Dir der deutsche Begriff dafür wirklich so unbekannt?
>> Stelle Dir es eher wie eine Verbindung oder Datenleitung vor. Du hast
>> die Datenmenge (TDataSet, TIBQuery, etc) und datensensitive Controls
>> wie die bereits genannten TDbGrid oder TDbEdit. Die Controls kommen
>> über die Dataquelle an die Datenmenge heran.
>
>
> Ich probiere mit den neuen Woertern einmal, ob der Nebel im Kopf sich
> lichtet.
>
> Angenommen, ich habe Wasser, das sich in einem Berg sammelt.
> Es fliesst aus dem Felsen ueber ein kleines Rohr in ein Becken.
> Aus dem Becken kann Wasser geschoepft werden.
> Dann waere:
>
> TDataBase: Das Wasser im Berg
> TConnection: die Oeffnung im Felsen
> TDataSource: das kleine Rohr? Und nicht das Becken?
> TDataSet / TIBQuery:
> Wasserschoepfen im Primaerbecken inkl. Wasserteilmenge und
> Schoepfvorgang
>
> Die Controls sind die Nutzniesser der Einrichtungen?
> Und was ist die Gesamtheit des Beckens?
Ich glaube wirklich nicht, dass Dir solche Abbildungen weiterhelfen werden.
Zum Einen werden die Ähnlichkeiten an verschiedenen Stellen zu schwammig
werden, zum Anderen bist Du schon viel zu lange im Metier um es so
anzufangen. So kannst Du es Kindern klarmachen. Das ist nicht böse gemeint,
aber Du solltest Dir die Beispiele auf etwas höherem Niveau suchen.
Und wenn Du es schon versuchen willst, dann nimm doch Deine IB-Komponenten.
Da gibt es kein TConnection, sondern nur TIBDatabase.
Diese selbst enthält aber doch gar keine Daten. Diese liegen in Deine
Firebird-Datenbank; diese Datei ist Dein Berg. Die einzelnen Tabellen wäre
verschiedene Wasseransammlungen. Aber schon hier hört es auf sinnvoll zu
bleiben.
Du hast Deine Datenbankdatei mit vielen Tabellen und darin enthaltenen
Daten. Deine TIBDatabase-Komponente stellt nun lediglich eine
Schnittstelle/Verbindung zu diesen Daten dar. Diese Verbindung wird von
TDataset-Nachfahren wie TIBQuery genutzt, eine bestimmte Datenmenge
abzufragen und Dir zur Verfügung zu stellen.
Im Code kannst Du direkt auf die Eigenschaften des Datasets, wie z.B. die
einzelnen Felder und deren Inhalte zugreifen. FieldByName() liefert Dir ja
schließlich nur einen Zeige auf eine Instanz von TField, deren Eigenschaft
AsXXX Du zum lesen oder schreiben verwendest.
Visuelle Komponenten, wie Dein TDbGrid oder ein TDbEdit bekommen eine
TDataSource zugewiesen, die man auch als Verteiler bezeichnen kann. Dieser
Verteiler, dem ja ein DataSet zugewiesen wird, kann nun von vielen
visuellen Komponenten genutzt werden.
Warum man nicht direkt das DataSet an die visuellen Komponenten zuweist?
Als Grund kenne ich selbst nur das Ziel der Entkoppelung.
So kann man nur durch Zuweisung eines eine neuen DataSets an die Datasource
direkt alle visuellen Komponenten auf eine andere Datenmenge umschalten.
Außerdem geht man vielfach auch so vor, die Dataset-Komponenten auf einem
Datenmodul zu sammeln, die Datasource aber auf dem jeweiligen Formular.
Diese Entkoppelung nutzt TDataSource auf der UI-Ebene und TDataSet in der
Datenzugriffsebene.
> Ich meinem DBGrid-testen komme ich auf viel hundert Klicks pro Tag.
> Und neu Starten der Anwendung, weil sich meine DBGrids wieder mal
> ungewollt geleert haben. So gehen die Stunden auch dahin.
>
> Ich weiss nur noch immer nicht, was ich "Refresh" muss.
Die IBQuery-Instanz in der Deine Daten liegen
Wenn die Probleme so groß sind und Du so viel Zeit darin investieren musst,
dann kannst Du auf jeden Fall auch eine kleine Testanwendung bauen, so dass
Du gerade die Problematik ausprobieren kannst.
Dafür brauchst Du auch keine großen Datenstrukturen, immerhin versuchst Du
Dich in den Basics. Wenn Du da eine kleine Anwendung, die auch woanders
kompilierbar ist, d.h. ohne Verwendung irgendwelchen Codes aus Deinen
Toolunits (ja, es geht ohne) samt einer kleine Test-Datenbank bereitstellen
kannst, dann schaue ich da auch mal rein.
> Wenn Self auf das Formular zeigt und ich mir das Wort dazudenken
> kann,... kann ich dann nicht auch den Formularnamen explizit anweisen?
>
> also:
>
> procedure TMyForm.TuWas;
> MyForm.Caption := 'Ein Text';
>
> ?
Ja, das könntest Du, aber Du solltest es auf gar keinen Fall tun.
Im einfachsten Testprojekt wäre das automatische Codeerzeugung
TForm1.TuWas;
begin
Form1.Caption := ...
end;
Ok, Form1 zeigt auf die einzige Instanz von TForm1 und alles ist schön.
Diese Formular zeigt z.B. Detaildaten zu einem Kunden an und Du kommst
irgendwann auf die Idee, nicht nur die Daten des gerade im Grid
fokussierten Kunden anzuzeigen, sondern mehrere Fenster gleichzeitig
darzustellen. Was machst Du dann?
Wenn Du die einzelnen Formulare von außen ansprechen musst, dann hälst Du
irgendwo Zeiger auf Instanzen von TForm1 z.B. in einem dynamischen Array.
FormArray[x] := TForm.Create(Application);
FormArray[x].ShowData(Pk-Wert_eines_bestimmten_Kundenrecords);
Oder es reicht
with TForm1.Create(Application) do begin
ShowData(Pk-Wert_eines_bestimmten_Kundenrecords);
end;
Durch Action := caFree im OnFormClose-Event des Formulars musst Du Dich
nicht weiter darum kümmern. Wenn es geschlossen wird, wird es zerstört.
Aber da ist ja immer noch
TForm1.TuWas;
begin
Form1.Caption := ...
end;
Worauf zeigt denn nun Form1? Ja, vielleicht auf das irgendwann mal erzeugte
und noch immer nicht zerstörte Formular, aber eben nicht unbedingt auf sich
selbst, weil die Instanz deren Code gerade ausgeführt entweder gar keine
Zeiger hat der auf es zeigt, oder es ist FormArray[x].
Nun sage nicht, Du weißt, dass Du das Formular nur einmal brauchst. Ich
glaube Dir, auch wenn eine solche Aussage zu den berühmten letzten Worten
gehört. Du benötigst diese Verwendung nicht, wirklich nicht. Sie macht auch
nichts einfacher. Nichts. Ginge es nur um guten Stil und würde die
Verwendung etwas vereinfachen, dann könnte man auch auf den guten Stil
pfeifen. Aber zu so etwas will ich gar nicht raten. Guter Stil ist nicht
einfach eine Frage überkommener Gepflogenheiten, er macht Code auch
wartbarer und sicherer.
Fazit: Du sparst Dir die Verwendung der Variablen.
>> Du siehst, dass ich nirgends meine Formularvariable verwendet habe?
>> Das tue ich auch niemals. NIEMALS.
>
> interessant
D.h. ich verwende diese Formularvariable nicht im Code der Formularklasse,
evtl. habe ich nicht einmal eine.
>> Sehr viele Formulare benötigen gar
>> keine Variable, da niemand von außen darauf zugreift. Auf jeden Fall
>> hat die Variable für ein Objekt nichts im Code der Klasse dieses
>> Objekts zu suchen.
>
> ui, das habe ich nicht vestanden.
> Was ist "die Variable fuer ein Objekt"?
Du hast eine Klasse TMyClass, Dein TMyForm ist nichts anderes. Diese Klasse
ist aber mehr nur eine Vorlage (Klassenmethode etc. lasse ich bewusst außen
vor), da lebt noch nichts.
Das geschieht erst mit dem Constructor Create(), dessen Rückgabewert einer
Variablen vom Typ dieser Klasse zugewiesen werden kann. Kann, nicht muss.
Mit dieser Erzeugung hast Du nun ein Objekt, eine Instanz der Klasse.
Natürlich kannst Du mehrere Instanzen erzeugen.
var
MyObject: TMyClass;
...
MyObject := TMyClass.Create;
TMyClass.Create;
Du hast nun 2 Instanzen von TMyClass, wobei Du nur auf die erste über
MyObject zugreifen kannst, auf die andere Instanz fehlt Dir der Zeiger.
Das muss aber nicht schlimm sein, wenn diese Instanz ihre Aufgabe auch so
erfüllen kann.
>>> Das passierte etwa haeufig in Zusammenhang mit TChart. Ich habe mir
>>> daher angewoehnt, im Zweifel Form explizit hinzuschreiben. Zudem ich
>>> mit meine hunderte Variablennamen nicht merken kann und die
>>> Programmierhilfe quasi verwenden muss.
>>
>> Ok, da habe ich nur die mitgelieferte Version.
>
> Probiere einmal Pro.
> Ich bin von der schlichtweg begeistert.
> Sie hat nur eine Nag-Screen als Demo und ist uneingeschraenkt
> funktionsfaehig.
Wenn ich sie brauche, werde ich sie verwenden, vorher nicht. :-)
>>> Doch Methoden, die nicht zum Formular gehoeren: Wie loest man das?
>>> Legt man dafuer eine eigene Klasse an?
>>
>> Wenn es nur eine kleine Hilfsfunktion ist, kommt sie einfach in die
>> Firmularunit. Spo benötigt man als Fallback-Funktion für
>> Sortieraufgaben eine einfache Funktion und eben keine Methode.
>
> huch?
> Ich habe mein Leben lang gedacht, Methode waere der Oberbegriff von
> Funktionen und Prozeduren?
Ich "übersetze" es mir mit: "Methoden sind die Prozeduren und Funktionen
einer Klasse.".
> Keine Unterstrichsuffixe?
> Ohne die bin ich verloren. Ich kann nur mit Woertern.
> Ich ueberlege zur Zeit, ob ich Unix nicht links liegen lasse mit all
> den Kuerzeln.
Was hat das Eine mit dem Anderen zu tun? Auch ohne Unterstrichsuffixe kann
man sprechende Namen wählen. Besser sogar. IMHO.
> ich vermeide es auch, wo geht.
> Doch je laenger ein Block, desto mehr erspart das with
> Zu Blockanfang und Ende habe ich einen Trick:
> D 2010 hat recht gute Autofunktionen:
> Schreibe ich ein begin und die Eingabetaste, dann schreibt mir Delphi
> ein end; genau drunter.
> D.h. ich habe meine begin-end-Block formatiert, bevor ich die erste
> Zeile schreibe. Und bevor ich die Zeile schreibe, kopiere ich die
> Befehlszeile als Kommentar hinter das end.
>
> Also for i:=0 to 100 do
> begin
> end; // zu for i:=0 to 100
>
> Dann erst beginne ich meinen Code zu tippen.
Klar macht man das so oder sollte es zumindest. Aber was hat das mit WITH
zu tun? Das Risiko, in einem With-Block versehentlich die falsche
Eigenschaft oder Methode zu verwenden steigt halt mit der Anzahl der
Zeilen.
> Meine Transaction hingegen heisst wirklich nur 1.
> Diese Transaction1 ist in irgendeinem Zusammenhang als "default"
> gelistet (weiss nicht mehr wo, im OI?). Sobald ich eine andere
> Transaction verwenden wollte, fand ich den Eintrag nicht mehr in der
> DB. Bzw. sprang dieser default-Eintrag im OI hin und her und es
> passierten seltsame Dinge.
Nicole! Du hast eine TIBTransaction auf Dein Formular/Datenmodul gezogen
und die IDE hat halt standardgemäß den Namen ohne führendes T, aber mit
abschließender Nummerierung vergeben. Hier eben die 1. Das IST der Default.
Benenne sie einfach um.
Gruß, Joe
--
Die DB ist nicht mein Problem.
Das habe ich alles selbst modelliert und lange vorbereitet, WIE ich es
mache. SQL ist eine schlanke, gerade Sache.
Meine SQL Abfragen sind durch das "Verbot" der Redundanz beim
Informationsspeichern vielleicht mit den joins etwas kompliziert, aber
sie erscheinen mir (also subjektiv) keinesweg verworren, wie manche
Komponenten-Properties.
...
[Erklaerungen aufmerksam gelesen]
> Warum man nicht direkt das DataSet an die visuellen Komponenten
> zuweist? Als Grund kenne ich selbst nur das Ziel der Entkoppelung.
>
> So kann man nur durch Zuweisung eines eine neuen DataSets an die
> Datasource direkt alle visuellen Komponenten auf eine andere
> Datenmenge umschalten.
Das klingt aber interessant!
> Außerdem geht man vielfach auch so vor, die Dataset-Komponenten auf
> einem Datenmodul zu sammeln, die Datasource aber auf dem jeweiligen
> Formular.
Ich wuenschte, ich haette das auch getan.
Mein Formular ist recht unuebersichtlich geworden.
> Diese Entkoppelung nutzt TDataSource auf der UI-Ebene und TDataSet in
> der Datenzugriffsebene.
Der Satz war mir zu hoch.
Die Abkuerzung UI ist mir nicht gelaeufig.
> > Ich meinem DBGrid-testen komme ich auf viel hundert Klicks pro Tag.
> > Und neu Starten der Anwendung, weil sich meine DBGrids wieder mal
> > ungewollt geleert haben. So gehen die Stunden auch dahin.
> >
> > Ich weiss nur noch immer nicht, was ich "Refresh" muss.
>
> Die IBQuery-Instanz in der Deine Daten liegen
> Wenn die Probleme so groß sind und Du so viel Zeit darin investieren
> musst, dann kannst Du auf jeden Fall auch eine kleine Testanwendung
> bauen, so dass Du gerade die Problematik ausprobieren kannst.
>
> Dafür brauchst Du auch keine großen Datenstrukturen, immerhin
> versuchst Du Dich in den Basics. Wenn Du da eine kleine Anwendung,
> die auch woanders kompilierbar ist, d.h. ohne Verwendung
> irgendwelchen Codes aus Deinen Toolunits (ja, es geht ohne) samt
> einer kleine Test-Datenbank bereitstellen kannst, dann schaue ich da
> auch mal rein.
ich fuerchte, das geht nicht.
Es ist alles derart komplex vernetzt. Hinter jedem Funktionsteil
haengen miteinander verbundene Units. Alleine die Liste der Units ist
einige Din A4 Seiten lang. Und alles ist auch noch vernetzt und greift
weitere fremd-DBs auf meiner HD und einige Dateien zu.
Doch ganz lieben Danke fuer Dein Angebot!
* Sitze vor dem Schirm und lache laut *
> Du benötigst diese Verwendung nicht, wirklich
> nicht. Sie macht auch nichts einfacher. Nichts. Ginge es nur um guten
> Stil und würde die Verwendung etwas vereinfachen, dann könnte man
> auch auf den guten Stil pfeifen. Aber zu so etwas will ich gar nicht
> raten. Guter Stil ist nicht einfach eine Frage überkommener
> Gepflogenheiten, er macht Code auch wartbarer und sicherer.
>
> Fazit: Du sparst Dir die Verwendung der Variablen.
Jetzt weiss ich, warum mir meine Formulare noch nie um die Ohren
geflogen sind: Ich habe sie bis jetzt wirklich nur einmal verwendet.
Ich muss nach der Kommentarzeile suchen, wo "es nicht ging mit TChart".
Diese Probleme waren es, warum ich dazu ueberging, es immer explizit
anzufuehren.
Doch ich kenne die Regel: Was schief gehen kann, geht auch eines Tages
schief. Und wie bei mir kein Pfannengriff in den Gehbereich der Kueche
ragt, so versuche ich, robusten Code zu schreiben.
> >> Du siehst, dass ich nirgends meine Formularvariable verwendet habe?
> >> Das tue ich auch niemals. NIEMALS.
> >
> > interessant
>
> D.h. ich verwende diese Formularvariable nicht im Code der
> Formularklasse, evtl. habe ich nicht einmal eine.
Auch den Satz habe ich nicht verstanden.
Formularvariable ist:
Var Form1: TForm1; ?
und Code der Formularklasse waere:
Procedure TForm1.Tu_was;
begin
end;
?
Und was hast Du nicht mal?
Und wie ist das mit "self."?
"Muss" man das auch weglassen oder wuerde das kein Problem verursachen
koennen?
> >> Sehr viele Formulare benötigen gar
> >> keine Variable, da niemand von außen darauf zugreift. Auf jeden
> Fall >> hat die Variable für ein Objekt nichts im Code der Klasse
> dieses >> Objekts zu suchen.
> >
> > ui, das habe ich nicht vestanden.
> > Was ist "die Variable fuer ein Objekt"?
>
> Du hast eine Klasse TMyClass, Dein TMyForm ist nichts anderes. Diese
> Klasse ist aber mehr nur eine Vorlage (Klassenmethode etc. lasse ich
> bewusst außen vor), da lebt noch nichts.
>
> Das geschieht erst mit dem Constructor Create(), dessen Rückgabewert
> einer Variablen vom Typ dieser Klasse zugewiesen werden kann. Kann,
> nicht muss.
>
> Mit dieser Erzeugung hast Du nun ein Objekt, eine Instanz der Klasse.
> Natürlich kannst Du mehrere Instanzen erzeugen.
>
> var
> MyObject: TMyClass;
>
> ...
> MyObject := TMyClass.Create;
>
> TMyClass.Create;
>
> Du hast nun 2 Instanzen von TMyClass, wobei Du nur auf die erste über
> MyObject zugreifen kannst, auf die andere Instanz fehlt Dir der
> Zeiger. Das muss aber nicht schlimm sein, wenn diese Instanz ihre
> Aufgabe auch so erfüllen kann.
* Hirn rattert *
> >>> Das passierte etwa haeufig in Zusammenhang mit TChart. Ich habe
> mir >>> daher angewoehnt, im Zweifel Form explizit hinzuschreiben.
> Zudem ich >>> mit meine hunderte Variablennamen nicht merken kann und
> die >>> Programmierhilfe quasi verwenden muss.
> >>
> >> Ok, da habe ich nur die mitgelieferte Version.
> >
> > Probiere einmal Pro.
> > Ich bin von der schlichtweg begeistert.
> > Sie hat nur eine Nag-Screen als Demo und ist uneingeschraenkt
> > funktionsfaehig.
>
> Wenn ich sie brauche, werde ich sie verwenden, vorher nicht. :-)
All die tollen Dinge die es gibt, stehlen einem die Zeit zum Leben,
wenn man sie alle probieren wollte.
> >>> Doch Methoden, die nicht zum Formular gehoeren: Wie loest man das?
> >>> Legt man dafuer eine eigene Klasse an?
> >>
> >> Wenn es nur eine kleine Hilfsfunktion ist, kommt sie einfach in die
> >> Firmularunit. Spo benötigt man als Fallback-Funktion für
> >> Sortieraufgaben eine einfache Funktion und eben keine Methode.
> >
> > huch?
> > Ich habe mein Leben lang gedacht, Methode waere der Oberbegriff von
> > Funktionen und Prozeduren?
>
> Ich "übersetze" es mir mit: "Methoden sind die Prozeduren und
> Funktionen einer Klasse.".
ah, das ist genauer gesagt.
> > Keine Unterstrichsuffixe?
> > Ohne die bin ich verloren. Ich kann nur mit Woertern.
> > Ich ueberlege zur Zeit, ob ich Unix nicht links liegen lasse mit all
> > den Kuerzeln.
>
> Was hat das Eine mit dem Anderen zu tun? Auch ohne Unterstrichsuffixe
> kann man sprechende Namen wählen. Besser sogar. IMHO.
Dann brauchst Du eine Alternative schaetze ich, wie CamelCase?
Ich moechte meine Klassen / Methoden so benannt haben, dass ich im
Source Code in Stammelsprache lesen kann, was sie tun.
z.B.
myArrayClass.Lies_Array_in_DB(myArray);
myDBClass.tbKalender_read(datum, 'Feiertagsname');
Wenn der Code mal nicht laeuft, muss ich oft in jahralte Units
hineinsehen. Wenn ich die Schnittstellen nicht schnell finde, sitze ich
daran viel laenger als noetig.
In obigem Beispiel setze ich dann etwa den Breakpoint auf
"Lies_Array_in_DB" um festzustellen, wo die falsche Zahl herkommt.
Denn genau in solchen Zeile werden meine Objekte geschleust und dort
kann ich sie vergleichen und pruefen.
Wie machst Du das, wenn Du den Weg einer Zahl durch 50.000 Zeilen
finden musst?
Wie verwaltest Du die Informationen, was ein Codeteil tut?
Auch Kommentare werden mit der Masse lang zu lesen. Ich habe
mittlerweile in einer Unit schon stehen, wo ich zu lesen anfangen soll.
> > Meine Transaction hingegen heisst wirklich nur 1.
> > Diese Transaction1 ist in irgendeinem Zusammenhang als "default"
> > gelistet (weiss nicht mehr wo, im OI?). Sobald ich eine andere
> > Transaction verwenden wollte, fand ich den Eintrag nicht mehr in der
> > DB. Bzw. sprang dieser default-Eintrag im OI hin und her und es
> > passierten seltsame Dinge.
>
> Nicole! Du hast eine TIBTransaction auf Dein Formular/Datenmodul
> gezogen und die IDE hat halt standardgemäß den Namen ohne führendes
> T, aber mit abschließender Nummerierung vergeben. Hier eben die 1.
> Das IST der Default.
>
> Benenne sie einfach um.
Auf den Namen kommt es nicht an, sondern, dass es mir nicht gelungen
ist, mehr als eine Transaction zum Kooperieren mit meiner DB zu bringen.
Liebe Gruesse,
Nicole
also zumindest fuer mein Formular brauche ich keine Berg-Bilder mehr.
Als ich nach meinem Refresh (noch vergeblich) suchte, fand ich DAS:
http://docwiki.embarcadero.com/RADStudio/de/Datenbankarchitektur
Nicole
Nicole Wagner schrieb:
>> Außerdem geht man vielfach auch so vor, die Dataset-Komponenten auf
>> einem Datenmodul zu sammeln, die Datasource aber auf dem jeweiligen
>> Formular.
>
> Ich wuenschte, ich haette das auch getan.
> Mein Formular ist recht unuebersichtlich geworden.
Dieses noch umzubauen ist nun wirklich ein recht schmerzarmer Prozess.
>> Diese Entkoppelung nutzt TDataSource auf der UI-Ebene und TDataSet in
>> der Datenzugriffsebene.
>
> Der Satz war mir zu hoch.
> Die Abkuerzung UI ist mir nicht gelaeufig.
User-Interface. Benutzerschnittstelle. Hier sind es die Formulare, Buttons,
Edits etc.
>> Dafür brauchst Du auch keine großen Datenstrukturen, immerhin
>> versuchst Du Dich in den Basics. Wenn Du da eine kleine Anwendung,
>> die auch woanders kompilierbar ist, d.h. ohne Verwendung
>> irgendwelchen Codes aus Deinen Toolunits (ja, es geht ohne) samt
>> einer kleine Test-Datenbank bereitstellen kannst, dann schaue ich da
>> auch mal rein.
>
> ich fuerchte, das geht nicht.
> Es ist alles derart komplex vernetzt. Hinter jedem Funktionsteil
> haengen miteinander verbundene Units. Alleine die Liste der Units ist
> einige Din A4 Seiten lang. Und alles ist auch noch vernetzt und greift
> weitere fremd-DBs auf meiner HD und einige Dateien zu.
Es geht um Deine Refresh-Problem. Ich bin bereit zu wetten, dass der
Aufwand vertretbar ist. Gerade durch die Verschlankung machst Du es Dir
selbst leichter, die Zusammenhänge überhaupt zu verstehen. Wenn Du es im
Testprogramm hinbekommen hast. Vergiss Deine originale Datenbank und baue
Dir eine kleine, die gerade so viel beinhaltet (also wenige Tabellen,
wenige Daten) um dein Problem nachzustellen. In einer separaten Anwendung
verwendest Du ebenfalls gerade so viel, dass Du das Problem mit dem Refresh
nachstellen kannst. Wenn Du es in dieser Anwendung hinbekommst, ist die
Übertragung in Deine Hauptanwendung nicht mehr das große Problem.
Wie gesagt, geht nicht darum, Deine Hauptanwendung auf ein Minimum
zusammenzustreichen. Eher kannst Du schon Deine Originaltabelle nehmen.
Es geht auch nicht darum, ob Du die Anwendung jemand anderem zum anschauen
gibst. Das Ziel ist es, nur das eigentliche Problem vor Augen zu haben. So
lässt sich das Problem,. wenn man es schon nicht jemand anderem zeigen
kann, so doch immerhin besser beschreiben. Bedenke, dass Dich die Antworten
auf Deine bisherigen Beschreibungen nicht weitergebracht haben.
Du meinst, das kostet Zeit? Klar. Aber wie lange kämpfst Du schon damit
herum?
>> Fazit: Du sparst Dir die Verwendung der Variablen.
>
>
> Jetzt weiss ich, warum mir meine Formulare noch nie um die Ohren
> geflogen sind: Ich habe sie bis jetzt wirklich nur einmal verwendet.
>
> Ich muss nach der Kommentarzeile suchen, wo "es nicht ging mit TChart".
> Diese Probleme waren es, warum ich dazu ueberging, es immer explizit
> anzufuehren.
Aber das eigentliche Problem war wahrscheinlich ein ganz anderes, bzw. auch
anders sauber zu lösen. Such mal, zeig mal.
>> D.h. ich verwende diese Formularvariable nicht im Code der
>> Formularklasse, evtl. habe ich nicht einmal eine.
>
> Auch den Satz habe ich nicht verstanden.
> Formularvariable ist:
> Var Form1: TForm1; ?
Ja.
> und Code der Formularklasse waere:
> Procedure TForm1.Tu_was;
> begin
> end;
> ?
Auch ja.
> Und was hast Du nicht mal?
Zu meinem TForm1 gibt es evtl. keine Variable die darauf zeigt. Diese
Variablen sind ja im Grunde nur Zeiger, anders als z.B. eine
Integervariable.
Du erinnerst Du an meinen modalen Dialog?
with TMyDialog.Create(Application) do begin usw.?
In der Unit des Dialogs, der Unit mit der Klasse TMyDialog hat Delphi ja
automatisch eine Variable in Form von "MyDialog: TMyDialog" angelegt. Im
konkreten Fall brauche ich sie gar nicht, auf jeden fall findet sie
innerhalb der Formularunit keine Verwendung. Doch, es gibt schon Fälle,
aber selbst dann wird da noch umgebaut und die Variable ist im
Implementation-Teil, nicht im Interface. Aber das ist Stoff für eine
spätere Lektion.
> Und wie ist das mit "self."?
> "Muss" man das auch weglassen oder wuerde das kein Problem verursachen
> koennen?
Das kann man gerne verwenden.
Wenn Du x Instanzen von TForm1 hast udn verwendest darin Self, dann zeigt
diese Self ja jedes Mal nur auf die eine eigene Instanz.
>>> ui, das habe ich nicht vestanden.
>>> Was ist "die Variable fuer ein Objekt"?
Das ist wie mit dem Formular. Aber Variable trifft es nicht so richtig, es
ist ja eigentlich ein Zeiger.
Du hast irgendwo stehen:
y: TIrgendEineKlasseWelcheNatuerlichAuchEineFormularklasseSeinKann
Dann meinte ich mit Objektvariable eben jenes y.
>> var
>> MyObject: TMyClass;
>>
>> ...
>> MyObject := TMyClass.Create;
>>
>> TMyClass.Create;
>>
>> Du hast nun 2 Instanzen von TMyClass, wobei Du nur auf die erste über
>> MyObject zugreifen kannst, auf die andere Instanz fehlt Dir der
>> Zeiger. Das muss aber nicht schlimm sein, wenn diese Instanz ihre
>> Aufgabe auch so erfüllen kann.
>
> * Hirn rattert *
Lege doch mal einen Breakpoint ins Create einer Deiner Klassen und teste
es. Du wirst 2 mal daran vorbeikommen.
> Dann brauchst Du eine Alternative schaetze ich, wie CamelCase?
Ja. Ich meinte auch wirklich Suffixe, also _ am Ende. So wie Du sie
verwendest um sprechende Bezeichner zu haben ist es ja vollkommen in
Ordnung. Ich persönlich setze sie nur eher selten ein, da mir eben
CamelCase lieber ist.
> Wie machst Du das, wenn Du den Weg einer Zahl durch 50.000 Zeilen
> finden musst?
> Wie verwaltest Du die Informationen, was ein Codeteil tut?
>
> Auch Kommentare werden mit der Masse lang zu lesen. Ich habe
> mittlerweile in einer Unit schon stehen, wo ich zu lesen anfangen soll.
Ich bin sogar der Meinung, dass man wirklich zu viel kommentieren kann.
Sprechende Bezeichner und die Vermeidung supertoller, cleverer
Codekonstruktionen könne da auch schön helfen.
Code sollte möglichst schön langweilig sein, einfach und schlicht.
Bei LsNr := LsNr +1 brauche ich nicht den Kommentar, dass dort eine
Lieferscheinnummer inkrementiert wird. Für ganz fremde vielleicht noch der
Hinweis, dass es sich um eine Lieferscheinummer handelt bei der
Deklaration.
Allerdings muss ich gestehen, dass ich oft genug zu wenig dokumentiere.
>> Benenne sie einfach um.
>
> Auf den Namen kommt es nicht an, sondern, dass es mir nicht gelungen
> ist, mehr als eine Transaction zum Kooperieren mit meiner DB zu bringen.
Brauchst Du mehrere?
Gruß, Joe
--
> Es geht um Deine Refresh-Problem. Ich bin bereit zu wetten, dass der
> Aufwand vertretbar ist. Gerade durch die Verschlankung machst Du es
> Dir selbst leichter, die Zusammenhänge überhaupt zu verstehen. Wenn
> Du es im Testprogramm hinbekommen hast. Vergiss Deine originale
> Datenbank und baue Dir eine kleine, die gerade so viel beinhaltet
> (also wenige Tabellen, wenige Daten) um dein Problem nachzustellen.
> In einer separaten Anwendung verwendest Du ebenfalls gerade so viel,
> dass Du das Problem mit dem Refresh nachstellen kannst. Wenn Du es in
> dieser Anwendung hinbekommst, ist die Übertragung in Deine
> Hauptanwendung nicht mehr das große Problem.
Ich finde jetzt das Link nicht, doch gestern habe ich gelesen, dass
Refresh fuer IBQuery-Komponenten zumeist nicht implementiert ist. Man
soll stattdessen die Query schalten.
Das Link war auf jeden Fall ein Klick von diesem Ausgangspunkt:
http://docwiki.embarcadero.com/RADStudio/de/Nachkommen_der_Klasse_TDataS
et_verwenden
Fuer heute werde ich mir alle Schaltungen in eine ActionList schreiben
und sie einmal haendisch klicken. Denn zuweilen sind meine DBGrids leer
und dann warte ich manchmal ungleich laenger als es in IBExperts dauern
wuerde, bis sie sich wieder fuellen.
Ich vermute den Fehler gerade in der Vernetzung. Etwa, dass irgendetwas
mein onCalc-Event in eine zu lange Schleife draengt. Ich ueberlege,
statt der Lookup-Zuordnungen im DBGrid Suchen-mit-DisableControls. In
der Hilfe habe ich dazu eine Idee gefunden. Ob sie gut ist, wird sich
weisen.
> Du meinst, das kostet Zeit? Klar. Aber wie lange kämpfst Du schon
> damit herum?
Viel, viel, viel zu lange!
Jeden Tag bin ich mir boese dafuer.
Trotzdem vermute ich den Fisch in der Interaktion der DBGrids.
Ich werde heute einmal alle Schaltungen auf Klick laufen lassen.
Ich fuerchte, drei Tage ueber der Erstellung eines vereinfachten Modell
zu sitzen und nachher nicht auch nicht klueger zu sein.
> > Und was hast Du nicht mal?
>
> Zu meinem TForm1 gibt es evtl. keine Variable die darauf zeigt. Diese
> Variablen sind ja im Grunde nur Zeiger, anders als z.B. eine
> Integervariable.
Wo mein Formular seine Var in alle Units zerstreut, ist etwa der
Progress Bar.
Da habe ich in einer voellig anderen nicht-visuellen Unit ploetzlich
einen StepIt-Aufruf. Das will mir gar nicht gefallen.
> Du erinnerst Du an meinen modalen Dialog?
teilweise, zudem weiss ich, wo ich ihn gesichert habe ;-)
> with TMyDialog.Create(Application) do begin usw.?
>
> In der Unit des Dialogs, der Unit mit der Klasse TMyDialog hat Delphi
> ja automatisch eine Variable in Form von "MyDialog: TMyDialog"
> angelegt. Im konkreten Fall brauche ich sie gar nicht, auf jeden fall
> findet sie innerhalb der Formularunit keine Verwendung. Doch, es gibt
> schon Fälle, aber selbst dann wird da noch umgebaut und die Variable
> ist im Implementation-Teil, nicht im Interface. Aber das ist Stoff
> für eine spätere Lektion.
Grundsatzfrage:
Laesst Du Deine Forms automatisch erstellen?
Ich habe das alles abgedreht, weil ich mich noch weniger heraussah, was
jetzt "da" war und was nicht.
> > Und wie ist das mit "self."?
> > "Muss" man das auch weglassen oder wuerde das kein Problem
> > verursachen koennen?
>
> Das kann man gerne verwenden.
>
> Wenn Du x Instanzen von TForm1 hast udn verwendest darin Self, dann
> zeigt diese Self ja jedes Mal nur auf die eine eigene Instanz.
Dann werde ich mal "self" probieren, sobald ich meinen
TChart-nil-Zugriff wieder finde.
> Ich bin sogar der Meinung, dass man wirklich zu viel kommentieren
> kann. Sprechende Bezeichner und die Vermeidung supertoller, cleverer
> Codekonstruktionen könne da auch schön helfen.
> Code sollte möglichst schön langweilig sein, einfach und schlicht.
Genau: "Wenn Du viele Moeglichkeiten zur Wahl hast, waehle die
einfachste."
(Das ist fuer mich persoenlich mehr Thema, als Du vermutlich ahnst. Die
Boerse wahrscheinlichkeitstheoretisch durchzurechnen, ist alles andere
als einfach. Und die Idee ist so bestechend, dass "jeder" es will: Denn
im Simpeli-Denken Vieler ist so ein Programm eine Geldmaschine.
Beginnen sie mal mit dem Projekt, dann zeigt ihnen das bald, dass die
Sache eben so einfach nicht ist. Was tun sie? Sie verwirren ihre Idee
bis zum Exzess und behaupten anschliessend, sie waere nicht
programmierbar.
Was ich anders mache? - Ich gehe nicht davon aus, dass es eine
Boersenberechnung ieS geben kann. Vielmehr muss man die
Wahrscheinlichkeiten davon mathematisch verwalten. Riskmanagement
nennen es die Insider.)
> Bei LsNr := LsNr +1 brauche ich nicht den Kommentar, dass dort eine
> Lieferscheinnummer inkrementiert wird. Für ganz fremde vielleicht
> noch der Hinweis, dass es sich um eine Lieferscheinummer handelt bei
> der Deklaration.
>
> Allerdings muss ich gestehen, dass ich oft genug zu wenig
> dokumentiere.
;-)
> >> Benenne sie einfach um.
> >
> > Auf den Namen kommt es nicht an, sondern, dass es mir nicht gelungen
> > ist, mehr als eine Transaction zum Kooperieren mit meiner DB zu
> > bringen.
>
> Brauchst Du mehrere?
Das weiss ich nicht!
Die Interaktion meiner IBQeries liegt im Argen.
Aber nachdem, was ich gestern ueber Transaktionen gelesen habe, sollte
meine Loesung woanders sein.
Liebe Gruesse,
Nicole
Nicole Wagner schrieb:
> Ich finde jetzt das Link nicht, doch gestern habe ich gelesen, dass
> Refresh fuer IBQuery-Komponenten zumeist nicht implementiert ist. Man
> soll stattdessen die Query schalten.
Zumeist nicht implementiert? Entweder ist es das oder eben nicht. Klar,
wenn es nicht implementiert ist, musst Du Dir anders helfen.
"Query schalten"?
Du meinst schließen und wieder öffnen? Klar, damit wird ja alles neu
gelesen. Erwähnte ich die Möglichkeit nicht in einem meiner Postings? Ich
weiß es nicht mehr.
> Ich vermute den Fehler gerade in der Vernetzung. Etwa, dass irgendetwas
> mein onCalc-Event in eine zu lange Schleife draengt. Ich ueberlege,
> statt der Lookup-Zuordnungen im DBGrid Suchen-mit-DisableControls. In
> der Hilfe habe ich dazu eine Idee gefunden. Ob sie gut ist, wird sich
> weisen.
Ich habe das Gefühl, Du suchst nach Strohhalmen.
>> Du meinst, das kostet Zeit? Klar. Aber wie lange kämpfst Du schon
>> damit herum?
>
> Viel, viel, viel zu lange!
> Jeden Tag bin ich mir boese dafuer.
>
> Trotzdem vermute ich den Fisch in der Interaktion der DBGrids.
> Ich werde heute einmal alle Schaltungen auf Klick laufen lassen.
Noch ein Strohhalm. :-)
> Ich fuerchte, drei Tage ueber der Erstellung eines vereinfachten Modell
> zu sitzen und nachher nicht auch nicht klueger zu sein.
Erstens dauert das keine 3 Tage. Du willst ja nur das prinzipielle Handling
nachstellen. Auch die Inhalte von OnCalcFields() und Konsorten können da
einfacher sein, ebenso die Abfragen selbst. Hol Dir auch nicht alles mit
Copy/Paste aus dem alten Code. Genau das wäre kontraproduktiv.
Zweitens, auch wenn Du nicht klüger sein solltest, Du wirst das Problem
deutlich und klarer beschreiben können, das macht es anderen leichter, oder
gar erst möglich, Dir zu helfen.
Drittens stehen sogar die Chancen recht gut, dass Du von alleine darauf
kommst. Gerade dadurch, dass man nicht im alten Code rumwühlt, sondern neu
herangeht wird oft vieles klarer.
Viertens sind Dir doch genügend Basics noch gar nicht klar; diese
Unklarheiten könntest Du so schon reduzieren.
Kennst Du es nicht von schlichten Matheaufgaben her, dass man ewig nach
einem Fehler sucht und den nicht findet? Schreibt man die Rechnung komplett
neu (nicht einfach nur ab), kommt man manchmal auch von alleine darauf.
Dein Aufnehmen von Strohhalmen und herumbasteln kann natürlich auch zum
Erfolg führen, mit Glück sogar schnell. Meist ist es jedoch ganz anders und
dauert wesentlich länger. Der vermeintlich aufwändigere Weg stellt sich
längerfristig im Mittel oft als der schnellere Weg.
Ich weiß das deshalb, weil ich natürlich auch zu oft in diese Falle laufe.
"Das probiere ich noch aus...."
Es gibt ja Leute, die behaupten, jeden Fehler nur ein mal zu machen. Leider
darf ich das von mir nicht in allen Fällen behaupten.
> Wo mein Formular seine Var in alle Units zerstreut, ist etwa der
> Progress Bar.
> Da habe ich in einer voellig anderen nicht-visuellen Unit ploetzlich
> einen StepIt-Aufruf. Das will mir gar nicht gefallen.
Dein Formular verstreut Variablen in verschiedene Units? Was bedeutet das?
> Grundsatzfrage:
> Laesst Du Deine Forms automatisch erstellen?
> Ich habe das alles abgedreht, weil ich mich noch weniger heraussah, was
> jetzt "da" war und was nicht.
Nein, außer dem MainForm eigentlich niemals. Evtl. lass ich ein
Datenformular vorher noch automatisch erzeugen, alle anderen auch nur bei
Bedarf.
Aber ich mache das nicht, weil ich dann nicht wüsste was da ist und was
nicht. Festgeschrieben steht es in der DPR und aufpassen müsste ich dann
nur im FormCreate der anderen Formulare, dass ich da nicht auf noch nicht
existente Formulare zugreife. Na ja, blöd udn steif wäre es trotzdem.
Ich mache es deshalb nicht, weil ich die Dinger erst erzeuge wenn ich sie
brauche und wenn die Verwendung auch ein klares Ende hat, werden sie dann
auch gleich entsorgt.
Also entweder durch ein
...Create..
try
//
finally
...Free;
end;
oder ein Action := caFree im FormClose des Formulars.
> Dann werde ich mal "self" probieren, sobald ich meinen
> TChart-nil-Zugriff wieder finde.
Zeig lieber mal die Stelle.
Gruß, Joe
--
> Nicole Wagner wrote:
> > Ich vermute den Fehler gerade in der Vernetzung. Etwa, dass
> > irgendetwas mein onCalc-Event in eine zu lange Schleife draengt
>
> Versuche doch mal http://www.gurock.com/smartinspect/ damit kannst du
> schön beobachten welche function aufgerufen wird in welcher
> Reihenfolge und wie lang sie läuft.
>
> Gruß aus den Bergen
> Günter
Danke fuer das Link!
Wenn es kann, was ich mir erhoffe, brauche ich es wie einen Bissen Brot.
Nicole
> "Query schalten"?
> Du meinst schließen und wieder öffnen?
IBQUery.Active:=false;
...
IBQUery.Active:=true;
> Klar, damit wird ja alles neu
> gelesen.
eben nicht!
Es fehlen mir Zahlen in meinen berechneten Feldern.
Ich weiss nicht, wie ich meine Events OnCalcFields und OnFilterRecords
(hiessen die so?) aufrufen kann.
Ein direkter Aufruf der Methoden tut einfach nichts.
Auch Filtered zu schalten tut nichts oder nicht das Gewuenschte.
Diese Events haben nur funktioniert, als ich die Maschine es machen
liess, bzw. als ich sie mit dem Scrollen ausloeste.
Apropos: Weisst Du, ob es eine Moeglichkeit gibt, "Disable Controls" zu
schalten und trotzdem zu scrollen?
Mit anderen Worten: Ich brauechte einen Zustand, der den Inhalt meines
DBGrids kennt und mir als Text anzeigt, aber nicht neu berechnet. Kann
man Controls teilweise abschalten?
> > Ich vermute den Fehler gerade in der Vernetzung. Etwa, dass
> > irgendetwas mein onCalc-Event in eine zu lange Schleife draengt.
> > Ich ueberlege, statt der Lookup-Zuordnungen im DBGrid
> > Suchen-mit-DisableControls. In der Hilfe habe ich dazu eine Idee
> > gefunden. Ob sie gut ist, wird sich weisen.
>
> Ich habe das Gefühl, Du suchst nach Strohhalmen.
Spock lag mit seinen Gefuehlen stets richtig, wenn er sie zuliess.
:-)
> >> Du meinst, das kostet Zeit? Klar. Aber wie lange kämpfst Du schon
> >> damit herum?
> >
> > Viel, viel, viel zu lange!
> > Jeden Tag bin ich mir boese dafuer.
> >
> > Trotzdem vermute ich den Fisch in der Interaktion der DBGrids.
> > Ich werde heute einmal alle Schaltungen auf Klick laufen lassen.
>
> Noch ein Strohhalm. :-)
Schilf, nicht Stroh.
Hat sich nett gebogen: Die Zugriffsverzoegerung zwischen meinen
PageControl-Tabs-Wechsel ist weg. Ich kann jetzt "normal" hin- und
herschalten, ohne dazwischen eine Minute Wartezeit.
Dass mein Calc und Filter nicht mehr arbeitet, steht leider auf einem
anderen Blatt und haengt damit zusammen. Doch wenigstens weiss ich
jetzt, dass ich dort meine Problemquelle habe.
> > Ich fuerchte, drei Tage ueber der Erstellung eines vereinfachten
> > Modell zu sitzen und nachher nicht auch nicht klueger zu sein.
>
> Erstens dauert das keine 3 Tage. Du willst ja nur das prinzipielle
> Handling nachstellen.
Ich kann recht gut abschaetzen, wie lange das dauert.
Denn ich fuerchte, ich habe immer wieder mal "ganz von vorne
angefangen".
> Auch die Inhalte von OnCalcFields() und
> Konsorten können da einfacher sein, ebenso die Abfragen selbst. Hol
> Dir auch nicht alles mit Copy/Paste aus dem alten Code. Genau das
> wäre kontraproduktiv.
Meine OnCalcField Procedure hatte ich zwischenzeitlich schon gekuerzst
auf:
begin
exit;
end;
[....]
Deine Argumente sind gut und auch richtig.
Doch ob man neu aufsetzt bei einer Schwierigkeit oder nicht, ist immer
im Einzelfall zu beurteilen.
Oft schon habe ich mich fuer "neu" entschieden.
Diesmal hoffe ich, dass es anders schneller geht.
Die Hoffnung stirbt bekanntlich zuletzt ;-)
> Dein Aufnehmen von Strohhalmen und herumbasteln kann natürlich auch
> zum Erfolg führen, mit Glück sogar schnell. Meist ist es jedoch ganz
> anders und dauert wesentlich länger. Der vermeintlich aufwändigere
> Weg stellt sich längerfristig im Mittel oft als der schnellere Weg.
>
> Ich weiß das deshalb, weil ich natürlich auch zu oft in diese Falle
> laufe. "Das probiere ich noch aus...."
> Es gibt ja Leute, die behaupten, jeden Fehler nur ein mal zu machen.
> Leider darf ich das von mir nicht in allen Fällen behaupten.
ach, ich mache meine Fehler immer wieder.
Die Leute, die von sich anders denken, haben oft nur ein schlechtes
Gedaechtnis oder Illusionen.
Zuweilen habe ich mir auch Fehlerkontrollschemata gemacht, wie bei
Flugzeugabstuerzen. Dabei kam ich drauf, dass auch ich mir ziemliche
Illusionen mache. Erst das Kontrollschema zeigte mir, wie fehler- und
illsuionsbehaftet ich wirklich bin.
Spannend ist es, sich Dinge schriftlich zu notieren, "bei denen man
sich ganz sicher ist". Hat man sich geirrt, denkt man sich "ich habe es
ja gleich gewusst" - in der eigenen Handschrift steht aber was Anderes.
Wer sich davor gefeilt fuehlt, teste sich selbst - schriftlich ;-)
> > Wo mein Formular seine Var in alle Units zerstreut, ist etwa der
> > Progress Bar.
> > Da habe ich in einer voellig anderen nicht-visuellen Unit ploetzlich
> > einen StepIt-Aufruf. Das will mir gar nicht gefallen.
>
> Dein Formular verstreut Variablen in verschiedene Units? Was bedeutet
> das?
ich fabuliere mal ein Beispiel:
Unit Dos-Konsolen-Rechnung;
....
Prozedure Nicht-Visuelle-Array-Iteration(DB-Info);
....
for i:=Low(DB-Info) to high(DB-Info) do
begin
MathematischeKomplexanweisung (DB[i]);
If i = 50 then
===> Form1.ProgressBar1.StepIt(5);
end;
Das ist doch keine elegante Kapselung.
> > Grundsatzfrage:
> > Laesst Du Deine Forms automatisch erstellen?
> > Ich habe das alles abgedreht, weil ich mich noch weniger heraussah,
> > was jetzt "da" war und was nicht.
>
> Nein, außer dem MainForm eigentlich niemals.
ich nicht mal das. Denn oft brauche ich das gar nicht.
> Ich mache es deshalb nicht, weil ich die Dinger erst erzeuge wenn ich
> sie brauche und wenn die Verwendung auch ein klares Ende hat, werden
> sie dann auch gleich entsorgt.
mache ich auch.
> > Dann werde ich mal "self" probieren, sobald ich meinen
> > TChart-nil-Zugriff wieder finde.
>
> Zeig lieber mal die Stelle.
Habe keine Zeit zum Suchen. Erst muss mein DBGrid tun, was es soll.
Leider muckt jetzt die Fremd-DB und verbindet sich nicht, wie sie soll.
Das werde ich mir heute vornehmen. *Haare rauf*
Doch Thema self:
Ich habe gestern schon mal probiert, statt
"FormName."
zu schreiben
"self."
Und schon hatte es einen Nachteil:
"Refactor"-Variablen-umbenennen funktionierte nicht mehr.
Erst als ich voll zitierte, inkl. "FormName." wurde meine Methode
wieder korrekt in alle Zusammenhaengen umbenannt.
Liebe Gruesse,
Nicole
> Apropos: Weisst Du, ob es eine Moeglichkeit gibt, "Disable Controls" zu
> schalten und trotzdem zu scrollen?
> Mit anderen Worten: Ich brauechte einen Zustand, der den Inhalt meines
> DBGrids kennt und mir als Text anzeigt, aber nicht neu berechnet. Kann
> man Controls teilweise abschalten?
>
Langsam beschleicht mich der Gedanke, dass du besser ein "normales"
StringGrid genommen hättest anstatt eines DBGrids. Editierst Du die Daten
eigentlich in dem DBGrid?
Ansonsten wäre ein StringGrid vielleicht die bessere Lösung: Einfach in
einer While not Query.eof - Schleife den Inhalt der Query samt den
berechneten Werten ins StringGrid packen. Wenn dann irgendetwas neu
berechnet wird, kannst du es direkt in die entsprechenden Zellen Schreiben.
Nur so ne Idee...
Gruß
Burkhard Schneider
... die Idee ist nicht von der Hand zu weisen.
Ich habe sie schon die laengste Zeit im Hinterkopf.
StringGrid kenne ich gut und kann damit auch "alles" machen, was es
kann.
Leider von dieserm Wissen her: Ich brauche eher DBGrid.
Nicole
Nicole Wagner schrieb:
> IBQUery.Active:=false;
> ...
> IBQUery.Active:=true;
>
>
>
>> Klar, damit wird ja alles neu
>> gelesen.
>
> eben nicht!
Wenn die IB-Komponenten nicht seltsam gestrickt sind, dann sollte das
.Close/.Open entsprechen. Dann möchte ich darauf wetten, dass die Daten
jener Query neu gelesen werden. Setze mal einen Haltepunkt auf das
IBQUery.Active:=true und ändere parallel mit IBExpert mal einen Wert in der
Tabelle, der zu einem anderen Ergebnis führen müsste. Dann gehe in Deiner
Anwendung weiter; die Änderung wird auch in der Datenmenge sein.
Oder ist es nicht so, dass Du das Neueinlesen nur aufgrund eines
Anzeigeproblems nicht siehst?
> Es fehlen mir Zahlen in meinen berechneten Feldern.
> Ich weiss nicht, wie ich meine Events OnCalcFields und OnFilterRecords
> (hiessen die so?) aufrufen kann.
Du rufst die nicht auf, das sind Ereignisse. Die _werden_ aufgerufen.
> Ein direkter Aufruf der Methoden tut einfach nichts.
Dafür sind die auch nicht gedacht.
> Apropos: Weisst Du, ob es eine Moeglichkeit gibt, "Disable Controls" zu
> schalten und trotzdem zu scrollen?
> Mit anderen Worten: Ich brauechte einen Zustand, der den Inhalt meines
> DBGrids kennt und mir als Text anzeigt, aber nicht neu berechnet. Kann
> man Controls teilweise abschalten?
Nochmal: Das Grid hat keinen Inhalt, es stellt den Inhalt einer Datenmenge
dar. Bitte bedenke das.
Wenn Du den Inhalt Deiner Datenmenge separat kontrollieren möchtest,
schreibe ihn doch mit einer einfachen Routine auf die Platte.
http://www.galinke.de/downloads/SaveDataSetToFile.pas
> Schilf, nicht Stroh.
> Hat sich nett gebogen: Die Zugriffsverzoegerung zwischen meinen
> PageControl-Tabs-Wechsel ist weg. Ich kann jetzt "normal" hin- und
> herschalten, ohne dazwischen eine Minute Wartezeit.
>
> Dass mein Calc und Filter nicht mehr arbeitet, steht leider auf einem
> anderen Blatt und haengt damit zusammen. Doch wenigstens weiss ich
> jetzt, dass ich dort meine Problemquelle habe.
"Der Motor meines Wagens ist jetzt endlich ganz leise. Er startet nicht
mehr." SCNR.
>> Erstens dauert das keine 3 Tage. Du willst ja nur das prinzipielle
>> Handling nachstellen.
>
> Ich kann recht gut abschaetzen, wie lange das dauert.
> Denn ich fuerchte, ich habe immer wieder mal "ganz von vorne
> angefangen".
Ich meinte ganz und gar nicht, dass Du das halbe Programm neu schreiben
sollst. Es geht nur um eine Beispielanwendung.
> Oft schon habe ich mich fuer "neu" entschieden.
Eben, darum geht es im Moment ja nicht.
>> Dein Formular verstreut Variablen in verschiedene Units? Was bedeutet
>> das?
>
> ich fabuliere mal ein Beispiel:
>
> Unit Dos-Konsolen-Rechnung;
> ....
> Prozedure Nicht-Visuelle-Array-Iteration(DB-Info);
> ....
> for i:=Low(DB-Info) to high(DB-Info) do
> begin
> MathematischeKomplexanweisung (DB[i]);
> If i = 50 then
> ===> Form1.ProgressBar1.StepIt(5);
> end;
Nicht Dein Formular verstreut Variablen, Du nutzt eine Variable die auf
dein Formular zeigt recht wild überall.
Das Beispiel sieht schlimm aus.
Einigermaßen elegant wäre ein Datenmodul welches die Berechnung ausführt
und ein Event OnProgress(Step: Integer) anbietet. Form1 hängt sich an das
Event und handhabt Progressbar. Wie der Fortschritt nämlich dargestellt
wird, das geht die Berechnusgroutine nichts an.
Einfacher geht es, indem der Routine eine Parameter ProgressForm:
TMyProgressForm mitgegeben wird. Nun kann man innerhalb der Routine
ProgressForm:ProgressBar... aufrufen oder, etwas sauberer, eine
public-Methode DoProgress(Step: Integer).
TMyProgressForm.DoProgress() versorgt dann den Balken. Ich mag dabei nicht,
dass Deine Werkzeugunit nun ein spezielles Formular, bzw. dessen Klasse,
kennen muss.
Das wäre die ersten einfachen Lösungen.
> Doch Thema self:
> Ich habe gestern schon mal probiert, statt
> "FormName."
> zu schreiben
> "self."
>
> Und schon hatte es einen Nachteil:
> "Refactor"-Variablen-umbenennen funktionierte nicht mehr.
> Erst als ich voll zitierte, inkl. "FormName." wurde meine Methode
> wieder korrekt in alle Zusammenhaengen umbenannt.
Das wäre für mich niemals ein Grund, FormName statt Self zu verwenden. Wenn
es mir wichtig wäre würde ich halt schauen, ob ich auf das Self selbst
verzichten könnte.
Nochmal zur Sicherheit, es handelt sich um eine Methode von FormName, in
der Du das brauchst? Zeige die Methode doch mal.
Gruß, Joe
--
Benötigst du ein berechnetes Feld, erstellst du dir einfach eines. Dazu
klickst du doppelt auf die entsprechende Query (bzw. Dataset), worauf
der Feld-Editor erscheint. Auf diesen klickst du nun mit der rechten
Maustaste und wählst den Eintrag "Neues Feld" (geht auch mit Strg-N). Im
Feld-Dialog gibst du einen Namen für das Feld ein, das den berechneten
Wert enthalten soll.
Ich habe mir angewöhnt, für Nachschlagefelder das Präfix N_ zu
verwenden, entsprechend für berechnete Felder B_ und für Datenfelder D_.
So heißt dann dein neues Feld beispielsweise B_Emailadresse.
Gehen wir einmal davon aus, du verwaltest in deiner Datenbank eine
Tabelle ADRESSEN, die eine Spalte "Emailadresse" und den Primärschlüssel
"Idx_Emailadressen" enthält. In einer anderen Tabelle PROVIDER gibt es
die Spalte "Emailprovider" mit dem Primärschlüssel "Idx_Emailprovider".
Zusammen ergibt sich dann die Emailadresse, deren "Berechnung" in dem
gerade erzeugten Feld abgelegt werden soll, und die dann vielleicht so
aussieht: mein...@online.de. Berechnet werden soll also - als Beispiel
- eine vollständige Emailadresse aus den beiden Tabellen, in der eine
Spalte "Email" heißt und eine andere in derselben Tabelle "Provider"
genannt wurde, aber keine Providernamen enthält, sondern lediglich einen
Index-Wert (Integerwert). Dieser Indexwert korrespondiert mit dem
Primärschlüssel der Tabelle PROVIDER - ein eindeutiger Schlüssel, der
immer nur auf einen Provider zeigt. Um nun im neu erzeugten Feld
B_Emailadresse die Kombination aus der Spalte "Emailadresse" (Tabelle
Adressen) und der Spalte "Emailprovider" (Tabelle PROVIDER) ablegen zu
können, benötigen wir eine Procedure, die du ganz einfach erzeugst:
Du klickst das neu erzeugte Feld "B_Emailadresse" an und wählst
daraufhin im Objektinspektor unter dem Reiter Ereignisse das Ereignis
OnGetText. In das leere Feld daneben klickst du doppelt rein und
erzeugst damit eine Procedure, die z.B. heißt:
"Dataset_AdressenB_EmailadresseGettText(Sender: TObject; var Text:
string; DisplayText: Boolean);
In diese Procedure schreibst du nun deinen Code, der die beiden
Feldinhalte in einem neuen Feld zusammenführt und vergißt dabei auch
nicht das trennende @-Zeichen:
VAR
Email, Provider : STRING
Index_Provider : LONGINT;
BEGIN
Index_Provider :=
Dataset_Adresse.FieldByName('Provider').AsInteger;
IF NOT Dataset_Provider.Locate('Idx_Provider',Index_Provider,[])
THEN
BEGIN
ShowMessage('Eintrag nicht gefunden');
CLOSE; //Fehler aufgetaucht, Programm beenden
EXIT;
END;
Email := Dataset_Adresse.FieldByName('Emailadresse').AsString;
Provider := Dataset_Provider.FieldByName('Provider').AsString;
Text := Email + '@' + Provider;
DisplayText := TRUE;
END;
Du nimmst also aus der aktuellen Emailadresse den Index für den Provider
und ermittelst diesen. Dann lokalisierst du ihn in der Tabelle PROVIDER
und übergibst den gefundenen Eintrag in das neue Feld.
Damit wird dann jedesmal, wenn irgend eine Komponente diese Spalte
abruft, in das Feld "B_Emailadresse" der berechnete Wert eingetragen. In
deinem DBGrid-Spalteneditor löscht du nun das Feld "Emailadresse" und
fügst stattdessen das neu erzeugte Feld "B_Emailadresse" ein. Und auf
wundersame Weise wird dir in deinem DB_Grid der berechnete Wert angezeigt.
Alle anderen Herangehensweisen wären mehr oder weniger Unfug ... wenn du
das jetzt nicht begreifst, dann weiß ich auch nicht mehr ...
[]
danke fuer die genauen Anweisungen!
Werde sie mir dann mal ausdrucken sie Punkt fuer Punkt durchgehen.
Es ist alles soo komplex.
Ich ziehe bei einem Thema an und finde 10 unbekannte neue Teile der
Komponenten. 10 weitere finde ich nicht (selbst).
Meine DBGrids und auch deren berechneten Felder funktionieren im Grunde
schon recht ordentlich. Alle einzeln.
Die Interaktion der Komponenten will noch nicht.
Meine Anwendung sieht aus wie ein zusammengenagelter Formel 1 Bolide.
"fahren" wuerde er. Leider von Fussgaengern ueberholt.
Nicole
> >> Klar, damit wird ja alles neu
> >> gelesen.
> >
> > eben nicht!
>
> Wenn die IB-Komponenten nicht seltsam gestrickt sind, dann sollte das
> .Close/.Open entsprechen.
in der Hilfe habe ich gelesen, dass dem so waere.
Probiert habe ich es nicht.
> Dann möchte ich darauf wetten, dass die
> Daten jener Query neu gelesen werden. Setze mal einen Haltepunkt auf
> das IBQUery.Active:=true und ändere parallel mit IBExpert mal einen
> Wert in der Tabelle, der zu einem anderen Ergebnis führen müsste.
> Dann gehe in Deiner Anwendung weiter; die Änderung wird auch in der
> Datenmenge sein.
ui, darueber muss ich nachdenken.
Ich schreibe im Grunde gar nichts in mein DBGrid.
Die DB Aenderungen sind so komplex, dass ich mir ein Panel mit normalen
Edits (also TEdit, nicht TDBEDit) gemacht habe, das alle Aenderungen
auflistet. Ein Button prueft erst mal alle Eingabe auf Stimmigkeit und
schickt dann alle Felder an die DB direkt via IBSQL einer anderen Unit.
(dass das eine andere Unit tut, ist ein ganz anderes Thema, das mit dem
Zusammenspiel der DBGrids nichts zu tun hat. Das andere Thema macht
zwar auch Probleme, doch ist zur Zeit auf ToDo)
IBQuery.Active schalte ich zur Zeit, um eine bessere Kontrolle zu
haben, auf Menue-Click.
Auch im OI habe ich "active" abgedreht.
Mir faellt im Augenblick kein Breakpoint ein.
> Oder ist es nicht so, dass Du das Neueinlesen nur aufgrund eines
> Anzeigeproblems nicht siehst?
glaube ich nicht.
Aber ich werde es noch mal extra pruefen.
> > Es fehlen mir Zahlen in meinen berechneten Feldern.
> > Ich weiss nicht, wie ich meine Events OnCalcFields und
> > OnFilterRecords (hiessen die so?) aufrufen kann.
>
> Du rufst die nicht auf, das sind Ereignisse. Die werden aufgerufen.
>
> > Ein direkter Aufruf der Methoden tut einfach nichts.
> Dafür sind die auch nicht gedacht.
ist mir schon klar, aber ich braeuchte es.
Vor allem Abschalten-Koennen wuerde ich es gerne.
So ala
OnCalcEvent.Trigger.Disable;
> http://www.galinke.de/downloads/SaveDataSetToFile.pas
>
DANKE!
Mit diesem Thema habe ich mich schon vor Wochen herumgeschlagen, mit
SaveToFile und LoadFromFile. Da ist aber nichts dabei herausgekommen.
Jetzt habe ich es als nicht-dringend auf die ToDo Liste gesetzt.
> > Schilf, nicht Stroh.
> > Hat sich nett gebogen: Die Zugriffsverzoegerung zwischen meinen
> > PageControl-Tabs-Wechsel ist weg. Ich kann jetzt "normal" hin- und
> > herschalten, ohne dazwischen eine Minute Wartezeit.
> >
> > Dass mein Calc und Filter nicht mehr arbeitet, steht leider auf
> > einem anderen Blatt und haengt damit zusammen. Doch wenigstens
> > weiss ich jetzt, dass ich dort meine Problemquelle habe.
>
> "Der Motor meines Wagens ist jetzt endlich ganz leise. Er startet
> nicht mehr." SCNR.
haha
Sie arbeiten mittlerweile wieder zuviel. brrrrrrrruuummm roar
Wann was und wovon ausgeloest wird, das habe ich noch immer nicht raus.
Die Listung ist der Hilfe ist recht oberflaechlich.
Jedenfalls finde ich zu meiner Ueberraschung dieses:
Wenn ich die Query zu einem DBGrid aktiv setze, wird das andere
DBGrid/Query in voller Menge durchgearbeitet. Es wird aktiv geschaltet
und alle Events rattern ab.
Ja, ich habe Lookup Felder. Doch wo die Nachschlage-Query auf activ
geschaltet wird, ahne ich bis jetzt noch nicht. Denn ich habe sie im OI
auf false gesetzt und schalte sie nur manuell.
> >> Dein Formular verstreut Variablen in verschiedene Units? Was
> bedeutet >> das?
> >
> > ich fabuliere mal ein Beispiel:
> >
> > Unit Dos-Konsolen-Rechnung;
> > ....
> > Prozedure Nicht-Visuelle-Array-Iteration(DB-Info);
> > ....
> > for i:=Low(DB-Info) to high(DB-Info) do
> > begin
> > MathematischeKomplexanweisung (DB[i]);
> > If i = 50 then
> > ===> Form1.ProgressBar1.StepIt(5);
> > end;
>
> Nicht Dein Formular verstreut Variablen, Du nutzt eine Variable die
> auf dein Formular zeigt recht wild überall.
>
> Das Beispiel sieht schlimm aus.
eben
> Einigermaßen elegant wäre ein Datenmodul welches die Berechnung
> ausführt und ein Event OnProgress(Step: Integer) anbietet.
meine Fantasie reicht da im Augenblick nicht.
Dann spukt ja das Modul viel zu tief in meine Unit
Dos-Konsolen-Rechnung? Denn nur die weiss, wie und wovon berechnet wird.
Im Grunde will ich meine Dos-Unit sauber halten.
> Form1
> hängt sich an das Event und handhabt Progressbar. Wie der Fortschritt
> nämlich dargestellt wird, das geht die Berechnusgroutine nichts an.
eben!
> Einfacher geht es, indem der Routine eine Parameter ProgressForm:
> TMyProgressForm mitgegeben wird. Nun kann man innerhalb der Routine
> ProgressForm:ProgressBar... aufrufen oder, etwas sauberer, eine
> public-Methode DoProgress(Step: Integer).
> TMyProgressForm.DoProgress() versorgt dann den Balken. Ich mag dabei
> nicht, dass Deine Werkzeugunit nun ein spezielles Formular, bzw.
> dessen Klasse, kennen muss.
mag ich auch nicht. Gar nicht.
Macht es aber extrem viel Unterschied, ob sie ein anderes Formular oder
eine anderes Modul kennen muss?
> Das wäre die ersten einfachen Lösungen.
Sie sind besser als meine.
Aber so richtig perfekt wird es noch nicht.
> > Doch Thema self:
> > Ich habe gestern schon mal probiert, statt
> > "FormName."
> > zu schreiben
> > "self."
> >
> > Und schon hatte es einen Nachteil:
> > "Refactor"-Variablen-umbenennen funktionierte nicht mehr.
> > Erst als ich voll zitierte, inkl. "FormName." wurde meine Methode
> > wieder korrekt in alle Zusammenhaengen umbenannt.
>
> Das wäre für mich niemals ein Grund, FormName statt Self zu
> verwenden. Wenn es mir wichtig wäre würde ich halt schauen, ob ich
> auf das Self selbst verzichten könnte.
>
> Nochmal zur Sicherheit, es handelt sich um eine Methode von FormName,
> in der Du das brauchst? Zeige die Methode doch mal.
ui, die ist schon lange wieder im Speichergewirr verschwunden.
Es war dieser Aufbau:
.... // Deklaration
Var Form1: TForm1;
Procedure TForm1.MyUmzubenennende;
begin
end;
Procedure TForm1.TuWas;
begin
Form1.MyUmzubenennende; // pfui, ich weiss
end;
Fuer mich ist Refactor sehr wichtig. Oft erarbeite ich mir eine
Struktur und am Ende bemerke ich, dass im Laufe der Zeit die Namen
Flickwerk wurden. Bevor Delphi Refactor konnte, habe ich mich lange
gequaelt, bevor ich umbenannte. Und das war stets die Quelle von viel
Aerger.
Heute kann ich in Sekunden umbenennen und effizienter arbeiten, weil
ich bei konsquenter Benennung schneller mutmassen kann, was ich mir am
Vortag bei einer Sache gedacht haben koennte. ;-)
Nicole