Stringgrid: ´Fontfarbe ändern, nach dem es befüllt wurde

    Stringgrid: ´Fontfarbe ändern, nach dem es befüllt wurde

    Guten Tag,
    ich weiß zu dem Thema Stringgrid und Zellen färben kann man Bücher füllen. Dennoch finde ich nur Ergebnisse, die das Färben von Zellen (in meinem Fall die Fontfarbe) nur im OnDrawCell ermöglicht. Ich möchte aber das Färben ermöglichen, nach dem es bereits befüllt ist.
    Der Grund ist folgender: Ich habe eine Tabelle, da wird Pro User seine Anzahl eines bestimmten Produktes angezeigt. Das Programm soll nun erstmal den höchsten Wert ermitteln und die Font-Color dann ändern.

    Meine Funktion zum ermitteln des höchsten Wertes in einer Spalte:

    Delphi-Code

    1. function TF_UsersStatistic.CheckFirstOne(sg: TStringGrid; Col: Integer ): Integer;
    2. var I, Max, Row: Integer;
    3. begin
    4. Row := 0;
    5. Max := StrtoInt(sg.Cells[Col, 1]);
    6. for I := 1 to sg.RowCount do
    7. if StrtoInt(sg.Cells[Col, I])> Max then
    8. begin
    9. Max := StrtoINt(Sg.Cells[Col,I]);
    10. Row := I;
    11. end;
    12. result := Row;
    13. end;


    Dann müsste ja sinngemäß so etwas folgen:

    Delphi-Code

    1. for I := 1 to sg.ColCount do
    2. sg[I,CheckFirstOne(Stringgrid, I)].Font.Color := cl_Red]


    Aber solch eine Funktion bietet ja die TStringgrid nicht an.

    Wie könnte ich das umsetzen?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Asura“ ()

    Berechne den Maximalwert doch einfach, bevor du das Grid füllst. Die Daten müßen ja irgendwo herkommen. Dann sparst du dir auch das andauernde StrToInt
    Glückauf

    Herr, wirf Hirn vom Himmel

    Ein Leben ohne Möpse ist möglich, aber sinnlos ( Loriot )
    Der beste Platz für Politiker ist das Wahlplakat. Dort ist er tragbar, geräuschlos und leicht zu entfernen ( Loriot )

    Es gibt Leute, die fühlen sich überall gedemütigt, wo sie nicht frech sein dürfen ( Otto Weiss )
    Dann müsste ich das über SQL machen:

    Delphi-Code

    1. procedure TF_UsersStatistic.LoadUserStatistic(Query: TADOQuery; Username: String);
    2. begin
    3. with Query do
    4. begin
    5. SQL.Clear;
    6. SQL.Add('SELECT DISTINCTROW usr_users.usr_ID, usr_users.usr_Username, bev_beverages.bev_ID, bev_beverages.bev_name, Sum(odt_details.odt_Count) AS [Anzahl]');
    7. SQL.Add('FROM bev_beverages INNER JOIN ((usr_users INNER JOIN ord_orders ON usr_users.[usr_ID] = ord_orders.[ord_usr_ID]) INNER JOIN odt_details ON ord_orders.[ord_id] = odt_details.[odt_ord_ID]) ON bev_beverages.[bev_ID] = odt_details.[odt_bev_ID]');
    8. SQL.Add('WHERE usr_Username = :Username');
    9. SQl.Add('GROUP BY usr_users.usr_ID, usr_users.usr_Username, bev_beverages.bev_ID, bev_beverages.bev_name');
    10. SQL.Add('ORDER BY usr_users.usr_Username, bev_beverages.bev_name') ;
    11. Parameters.ParamByName('Username').Value := Username ;
    12. Open;
    13. First;
    14. end;
    15. end;


    Delphi-Code

    1. try
    2. for Z := 1 to sg.RowCount do
    3. begin
    4. LoadUserstatistic(Query, sg.Cells[0,Z]);
    5. while not Query.Eof do
    6. begin
    7. for Y := 1 to sg.ColCount do
    8. begin
    9. if Query.FieldByName('bev_name').ASString = sg.Cells[Y,0] then
    10. begin
    11. sg.Cells[Y,Z] := Query.FieldByName('Anzahl').AsString;
    12. end
    13. end;
    14. Query.Next;
    15. end;
    16. Query.Close
    17. end;
    18. except
    19. // Fehlermeldung abfangen wegen leeren Zellen
    20. end;


    Daher kriege ich meine Daten. Muss ich dann schlichtweg mir den maximalen Wert anzeigen lassen, von den beverages nach der Summe von Count?
    Mach dir einen Record oder ein Object, in dem du die Daten einer Zeile hälts. Lies jede zeile ein und speichere die Daten aller Zeilen in einer Liste von Records ober Objecten. Dann kannst du in der Objectliste die Spalten durchsuchen.
    Ein Stringgrid i eine Klasse zum Anzeigen von Daten, nicht zum Speichern. ( Trennung Oberfläche und Logik )
    Glückauf

    Herr, wirf Hirn vom Himmel

    Ein Leben ohne Möpse ist möglich, aber sinnlos ( Loriot )
    Der beste Platz für Politiker ist das Wahlplakat. Dort ist er tragbar, geräuschlos und leicht zu entfernen ( Loriot )

    Es gibt Leute, die fühlen sich überall gedemütigt, wo sie nicht frech sein dürfen ( Otto Weiss )
    Ich habe es nun erstmal anders versucht: Mit TStringlists.
    Er soll ja anhand von mehreren Datensätzen bei jedem Getränk den höchsten Wert notieren.
    Das klappt auch insoweit: Am Ende existiert eine Bestlist (TStringlist) in der nach dem Index 0 bis n der höchste Wert notiert ist.
    Beispiel:
    Im Stringgrid würde unter sg.Cells[1,0] = Getränk 1 und im Index 0 von Bestlist steht dann der Maximalwert von Getränk 1. So auch bei sg.Cells[2,0] = Getränk 2 und im Index 1 vn Bestlist steht dann sein Maximalwert usw.
    Nun wollte ich natürlich bevor das OnDrawCell Ereignis ausgeführt wird diese Liste erstellen, damit ich in diesem Ereignis damit arbeiten kann. Hier besteht aber nun der Fehler.
    Ich dachte eig. dass das Ereignis erst ausgelöst wird, wenn eine Zeile befüllt wird bzw. wenn auf diese Stringgrid zugegriffen wird.
    Deswegen dachte ich mir: Im FormShow Ereignis wo die Prozedur dann aufgerufen wird, die dafür zuständig ist, dass das Stringgrid gefüllt wird, packe ich die Prozedur, die für die Erstellung der Bestlist zuständig ist, vorher damit diese als erstes ausgeführt wird. Die Bestlist ist hier als Private Variabel deklariert.
    Wenn ich aber nun testweise Bestlist.Text im OnDrawCell Ereignis anzeigen lasse, wird mir kein Inhalt angezeigt. Auch noch im OnCreate, wenn ich hier die Bestlist bereits erstelle.
    Ich vermute, dass das OnDrawCell also bereits dort ausgeführt wird.

    Ich kann auch gerne mal die Unit hochladen. Weil wenn ich nun alle Prozeduren hier reinstelle verliert man bestimmt schnell die Übersicht, da es schon über 4 Prozeduren läuft und verschachtelt ist.
    Dateien