AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Gelöst: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen
Thema durchsuchen
Ansicht
Themen-Optionen

Gelöst: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

Ein Thema von Perlsau · begonnen am 29. Jul 2012 · letzter Beitrag vom 29. Jul 2012
Antwort Antwort
Seite 1 von 2  1 2      
Perlsau
(Gast)

n/a Beiträge
 
#1

Gelöst: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 10:34
Moin allerseits, heute hab ich ein eher kniffliges Problem, dessen Lösung mir partout nicht einfallen will:

Ich bastle mir gerade eine eigene Terminverwaltung mit einem StringGrid (TjvStringGrid). Via OnDrawCell manipuliere ich gewisse Zellen hinsichtlich Hintergrund- und Schriftfarbe. So sollen u.a. auch die Tage, die nicht zum aktuellen Monat gehören (ein paar in Row 1 und ein paar in der letzten Zeile) anders gefärbt werden als die zum Monat gehörenden Tage. Die Schriftfarbe dieser Zellen ist auf rot eingestellt, wie man am angehängten Screenshot sehen kann. Zu meiner Verwirrung werden die ersten Tage des nächsten Monats im Gegensatz zu den letzten Tagen des vorherigen Monats nicht rot dargestellt.

Hier einmal die OnDrawCell-Procedure:
Delphi-Quellcode:
procedure TFormTermin.StrGrid_MonatDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
VAR
   p : Integer;
   Aus : String;

begin
     // Farbliche Markierung der Zellen mit einem Termineintrag
     Aus := StrGrid_Monat.Cells[ACol,ARow]; // Zelle auslesen
     p := POS(CHR(10),Aus); // nach Zeilenumbruch suchen
     IF p > 0 THEN // wenn Zeilenumbruch gefunden dann
        BEGIN
             IF (ACol > 0) AND (ARow > 0) THEN // wenn Spalte > 0 AND Zeile > 0 dann
             BEGIN
                  StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridEinColorFont; // Schriftfarbe setzen
                  StrGrid_Monat.Canvas.Brush.Color := Konst.Benutzer.TermStrGridEinColor; // Hintergrundfarbe setzen
                  StrGrid_Monat.Canvas.FillRect(Rect); // zeichnen
             END;
        END ELSE // wenn kein Zeilenumbruch gefunden
        BEGIN
             IF (ACol > 0) AND (ARow > 0) THEN
             BEGIN
                  StrGrid_Monat.Canvas.Font.Color := Benutzer.TermStrGridColorFont;
                  StrGrid_Monat.Canvas.Brush.Color := Konst.Benutzer.TermStrGridColor;
                  StrGrid_Monat.Canvas.FillRect(Rect);
             END;
        END;

     // Aus enthält noch immer den Zellen-Inhalt
     IF Aus <> 'THEN // wenn Aus nicht leer ist
     BEGIN
          IF TryStrToInt(Aus,p) THEN // wenn Aus eine Zahl enthält
             IF ((ARow = 1) AND (ACol > 0) AND (p > 7)) OR // wenn Zeile 1 AND Spalte > 0 AND Tag > 7 oder
                ((ARow = StrGrid_Monat.ColCount -1) AND (ACol > 0) AND (p < 7)) THEN // wenn letzte Zeile AND Spalte > 0 AND Tag < 7
                StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridOtherColor;
     END;

     IF ARow > 0 THEN
        StrGridAusrichtung(StrGrid_Monat, Rect, ACol, ARow, taLeftJustify, TRUE) ELSE
        StrGridAusrichtung(StrGrid_Monat, Rect, ACol, ARow, taCenter, False);

     IF ACol = 0 THEN StrGridAusrichtung(StrGrid_Monat, Rect, ACol, ARow, taRightJustify, FALSE);
Soweit ich das beurteilen kann, ist mein Algorithmus, der die ersten Tage des nächsten Monats ermitteln soll, stimmig. Aber er funktioniert nicht. Also stimmt was nicht. Nur was? Sicher wieder irgend so ein dummer Fehler, den ich vor läuter Bäumen nicht sehe ...
Miniaturansicht angehängter Grafiken
terminverwaltung.jpg  

Geändert von Perlsau (29. Jul 2012 um 11:26 Uhr) Grund: Gelöst
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.323 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 11:04
Hallo,

ich kenne jetzt deine Konstanten (besser Records) nicht, aber müsste das hier nicht so heissen:

Delphi-Quellcode:
     IF p > 0 THEN// wenn Zeilenumbruch gefunden dann
         BEGIN
              IF (ACol > 0) AND (ARow > 0) THEN// wenn Spalte > 0 AND Zeile > 0 dann
              BEGIN
                   StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridEinColorFont; // Schriftfarbe setzen
                   StrGrid_Monat.Canvas.Brush.Color := Konst.Benutzer.TermStrGridEinColor; // Hintergrundfarbe setzen
                   StrGrid_Monat.Canvas.FillRect(Rect); // zeichnen
              END;
         END ELSE// wenn kein Zeilenumbruch gefunden
         BEGIN
              IF (ACol > 0) AND (ARow > 0) THEN
              BEGIN
                   StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridColorFont; //<== Konst. hinzugefügt
                   StrGrid_Monat.Canvas.Brush.Color := Konst.Benutzer.TermStrGridColor;
                   StrGrid_Monat.Canvas.FillRect(Rect);
              END;
         END;
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#3

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 11:08
Hallo,

ich kenne jetzt deine Konstanten (besser Records) nicht, aber müsste das hier nicht so heissen:

StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridColorFont; //<== Konst. hinzugefügt
Ja, richtig, den hatte ich wohl übersehen. Ist aber erstmal nur ein "Schönheitsfehler", weil es im ganzen Programm sonst keinen Record gibt, der "Benutzer" heißt.

Das ist aber auch nicht mein Problem ...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 11:10
Auf den ersten Blick sieht es so aus als ob es tatsächlich funktionieren müsste, somit könnte der Fehler bei der erfolglosen Umwandlung des Zellinhaltes in eine Zahl zu finden sein.

Abgesehen davon bin ich aber kein Freund davon von einer Dateninterpretation (Feldinhalt des Stringgrids) die Darstellung zu interpretieren. Besser wäre es hier einen Adapter zu schreiben der mit den Termindaten gefüllt wird (oder den Zugriff auf diese Objekte kennt) und der sich auch um die Befüllung des Stringgrids und das Event OnDrawCell kümmert. Dann kann man beim Zeichnen direkt auf die Terminobjekte und dessen Daten zurückgreifen und von den echten Daten die Darstellungsart ableiten.

Eine zukünftige Erweiterung wie z.B. spezielle Termine besonders einfärben ist dann ein Klacks.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.323 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 11:17
wo soll denn die Farbe ausgegeben werden?

Ist das dieser Block?
Delphi-Quellcode:
     // Aus enthält noch immer den Zellen-Inhalt
      IF Aus <> 'THEN// wenn Aus nicht leer ist
      BEGIN
           IF TryStrToInt(Aus,p) THEN// wenn Aus eine Zahl enthält
              IF ((ARow = 1) AND (ACol > 0) AND (p > 7)) OR// wenn Zeile 1 AND Spalte > 0 AND Tag > 7 oder
                 ((ARow = StrGrid_Monat.ColCount -1) AND (ACol > 0) AND (p < 7)) THEN// wenn letzte Zeile AND Spalte > 0 AND Tag < 7
                 StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridOtherColor;
      END;
Wenn ja, warum steht da
((ARow = StrGrid_Monat.ColCount -1) müsste es nicht
((ARow = StrGrid_Monat.RowCount -1) heissen?
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<

Geändert von Helmi (29. Jul 2012 um 11:19 Uhr)
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#6

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 11:20
Auf den ersten Blick sieht es so aus als ob es tatsächlich funktionieren müsste, somit könnte der Fehler bei der erfolglosen Umwandlung des Zellinhaltes in eine Zahl zu finden sein.
Glaube ich nicht. Wenn er die letzten Tage des vorigen Monats findet, dann sollte er auch die ersten Tage des letzten Monats finden. Bei den Tagen des aktuellen Monats steht ja das komplette Datum drin, da liefert TryStrToInt ein FALSE zurück. Und an der vorangestellten 0 bei den ersten Tagen des nächsten Monats kanns auch nicht liegen, die machen bei StrToInt keine Schwierigkeiten.

Abgesehen davon bin ich aber kein Freund davon von einer Dateninterpretation (Feldinhalt des Stringgrids) die Darstellung zu interpretieren. Besser wäre es hier einen Adapter zu schreiben der mit den Termindaten gefüllt wird (oder den Zugriff auf diese Objekte kennt) und der sich auch um die Befüllung des Stringgrids und das Event OnDrawCell kümmert. Dann kann man beim Zeichnen direkt auf die Terminobjekte und dessen Daten zurückgreifen und von den echten Daten die Darstellungsart ableiten. Eine zukünftige Erweiterung wie z.B. spezielle Termine besonders einfärben ist dann ein Klacks.
Keine Ahnung, was du dir unter einem Adapter vorstellst. Ich entwickle zum ersten Mal eine Terminverwaltung mit einem selbstgebastelten Kalender und habe noch etliche Schwierigkeiten damit, für alle anfallenden Problemstellungen Lösungen zu finden. Das ist sozusagen mein Prototyp. Wenn ich das Prinzip erstmal richtig kapiert habe, geht's an die Optimierung.

Beim Befüllen des Stringgrids wird erstmal das Stringgrid mit den reinen Monatsdaten gefüllt. Danach wird mittels SELECT die Datenmenge in der Datenbank nach Datum gefiltert (eben nur Termine mit dem Datum des aktuellen Monats).
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#7

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 11:25
((ARow = StrGrid_Monat.ColCount -1) müsste es nicht
((ARow = StrGrid_Monat.RowCount -1) heissen?
Hi Helmi, du hast den Fehler entdeckt! 100 Punkte!!!

Ich wußte doch, daß es etwas einfaches sein muß, das ich nur mal wieder nicht sehe

Jetzt funktioniert es so, wie ich es wollte.

Geändert von Perlsau (29. Jul 2012 um 11:27 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Gelöst: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 12:35
Ist sichergestellt, daß diese Methode erst dann aufgerufen wird, wenn das Grid schon auch Daten hat?

Mit Sys- bzw. DateUtils tust du dir leichter.

Ungetestet:

Delphi-Quellcode:
function ExtractDate(const S: string): string;
var
  L: integer;
begin
  L := Pos(sLineBreak, S);
  if L > 0 then
    Dec(L)
  else
    L:= Length(S);
  Result := Copy(S, 1, L);
end;

function CheckDate(const S: string): boolean;
var
  ADate: TDateTime;
  AYear, AMonth, ADay: Word;
begin
  Result := false;
  if SysUtils.TryStrToDate(ExtractDate(S), ADate) then
  begin
    SysUtils.DecodeDate(ADate, AYear, AMonth, ADay);
    Result := DateUtils.IsValidDate(AYear, AMonth, ADay);
  end;
end;

procedure TForm1.StrGrid_MonatDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  Ausrichtung: TAlignment;
  AusrichtungFlag: boolean;
begin
  if CheckDate(StrGrid_Monat.Cells[ACol, ARow]) then
  begin
    if Pos(sLineBreak, StrGrid_Monat.Cells[ACol, ARow]) > 0 then
    begin
      StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridEinColorFont;
      StrGrid_Monat.Canvas.Brush.Color := Konst.Benutzer.TermStrGridEinColor;
    end
    else
    begin
      StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridColorFont;
      StrGrid_Monat.Canvas.Brush.Color := Konst.Benutzer.TermStrGridColor;
    end;
  end
  else
  begin
    StrGrid_Monat.Canvas.Font.Color := Konst.Benutzer.TermStrGridOtherColor;
    StrGrid_Monat.Canvas.Brush.Color := Konst.Benutzer.TermStrGridColor;
  end;
  StrGrid_Monat.Canvas.FillRect(Rect);
  if ACol = 0 then
  begin
    Ausrichtung := taRightJustify;
    AusrichtungFlag := false;
  end
  else
    if ARow > 0 then
    begin
      Ausrichtung := taLeftJustify;
      AusrichtungFlag := true;
    end
    else
    begin
      Ausrichtung := taCenter;
      AusrichtungFlag := false;
    end;
  StrGridAusrichtung(StrGrid_Monat, Rect, ACol, ARow, Ausrichtung, AusrichtungFlag);
end;

Geändert von Bjoerk (29. Jul 2012 um 13:08 Uhr) Grund: ExtractDate erforderlich
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.736 Beiträge
 
Delphi 6 Enterprise
 
#9

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 17:07
Abgesehen davon bin ich aber kein Freund davon von einer Dateninterpretation (Feldinhalt des Stringgrids) die Darstellung zu interpretieren. Besser wäre es hier einen Adapter zu schreiben der mit den Termindaten gefüllt wird (oder den Zugriff auf diese Objekte kennt) und der sich auch um die Befüllung des Stringgrids und das Event OnDrawCell kümmert. Dann kann man beim Zeichnen direkt auf die Terminobjekte und dessen Daten zurückgreifen und von den echten Daten die Darstellungsart ableiten. Eine zukünftige Erweiterung wie z.B. spezielle Termine besonders einfärben ist dann ein Klacks.
Keine Ahnung, was du dir unter einem Adapter vorstellst. Ich entwickle zum ersten Mal eine Terminverwaltung mit einem selbstgebastelten Kalender und habe noch etliche Schwierigkeiten damit, für alle anfallenden Problemstellungen Lösungen zu finden. Das ist sozusagen mein Prototyp. Wenn ich das Prinzip erstmal richtig kapiert habe, geht's an die Optimierung.
Er meint glaub ich damit, dass du eine Struktur schaffen sollst, in der die Daten gespeichert werden. Das Grid soll nur zur Darstellung dienen. So sollst du dann quasi im OnDraw nicht schauen, was steht in der Grid-Zelle, sondern was steht in der Datenstruktur was für ein Wert in dieser Zelle steht, bzw. noch besser, was sagt mir die Datenstruktur, wie ich diese Zelle färben soll. Das geht dann denk ich in Richtung MVC.
Ralph
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#10

AW: Algorithmus zum Ermitteln bestimmter StringGrid-Zellen

  Alt 29. Jul 2012, 19:31
Er meint glaub ich damit, dass du eine Struktur schaffen sollst, in der die Daten gespeichert werden. Das Grid soll nur zur Darstellung dienen. So sollst du dann quasi im OnDraw nicht schauen, was steht in der Grid-Zelle, sondern was steht in der Datenstruktur was für ein Wert in dieser Zelle steht, bzw. noch besser, was sagt mir die Datenstruktur, wie ich diese Zelle färben soll. Das geht dann denk ich in Richtung MVC.
Ich habe bereits eine Struktur zur Speicherung der Daten: eine Firebird-Datenbank. In dieser ist aber nicht vermerkt, an welchem Wochentag ein bestimmter Termin ist oder in welcher Spalte im StringGrid er steht. Ich möchte ja das Stringgrid je nach aktuellem Status so oder so aussehen lassen. Daher lese ich auch am Stringgrid aus, wie es sich derzeit befindet ... Natürlich könnte ich das auch aus den Daten in der DB ausrechnen. Da ich aber sowieso auf das OnDrawCell-Ereignis reagieren muß und dort auf bestimmte Spalten und Zeilen abfragen muß, ob und wie sie (hinsichtlich aktuellem Monat und Jahr bzw. hinsichtlich ihres Inhalts) manipuliert werden sollen. Ich will ja nicht nur Zellen manipulieren, in denen ein oder mehrere Termine stehen, sondern auch Zellen, in denen keine stehen. Wieso also sollte ich diese Manipulation einmal in einem extra "Adapter" machen und dann nochmal in OnDrawZell? Ich finde das so einfacher ...

Und was ist MVC?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz