Top.Mail.Ru
Ответы

Lazarus (Pascal): Отсортировать таблицу StringGrid1 учеников, оставить только тех, у кого средний балл больше 4.5

Здраствуйте, есть проблема в коде:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
 unit Unit1; 
 
{$mode objfpc}{$H+} 
 
interface 
 
uses 
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, StdCtrls; 
 
type 
 
  { TForm1 } 
 
  TForm1 = class(TForm) 
    Button1: TButton; 
    Button2: TButton; 
    StringGrid1: TStringGrid; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
  private 
  public 
  end; 
 
var 
  Form1: TForm1; 
 
const 
  N_MAX = 3; 
  INDEX_COL = 0; 
  TITLE_ROW = 0; 
  SEARCH_COLOR = clYellow; 
 
type 
  t_student = record 
    name : string[25]; 
    inf : 0..5; 
    phys : 0..5; 
    math : 0..5; 
    sr_ball : real; 
  end; 
 
  var 
  stud : array[1..N_MAX] of t_student; 
 
implementation 
 
{$R *.lfm}  
{ TForm1 } 
 
procedure TForm1.Button1Click(Sender: TObject); 
var 
  stud1, stud2, stud3 : t_student; 
  i: Byte; 
  
begin 
   stud1.name := 'Бабурин'; 
   stud1.inf := 4; 
   stud1.phys := 4; 
   stud1.math := 5; 
   stud1.sr_ball := (stud1.inf + stud1.math + stud1.phys)/3; 
 
   with stud2 do begin 
     name := 'Васильев'; 
     inf := 5; 
     phys := 5; 
     math := 5; 
     sr_ball := (inf + math + phys)/3; 
   end; 
 
   with stud3 do begin 
     name := 'Дьяконова'; 
     inf := 2; 
     phys := 3; 
     math := 3; 
     sr_ball := (inf + math + phys)/3; 
   end; 
   i := 1; 
   StringGrid1.Cells[1,i] := stud1.name; 
   StringGrid1.Cells[2,i] := IntToStr(stud1.inf); 
   StringGrid1.Cells[3,i] := IntToStr(stud1.phys); 
   StringGrid1.Cells[4,i] := IntToStr(stud1.math); 
   StringGrid1.Cells[5,i] := FloatToStrF(stud1.sr_ball,ffFixed,1,2); 
   i := 2; 
   with stud2 do begin 
   StringGrid1.Cells[1,i] := name; 
   StringGrid1.Cells[2,i] := IntToStr(inf); 
   StringGrid1.Cells[3,i] := IntToStr(phys); 
   StringGrid1.Cells[4,i] := IntToStr(math); 
   StringGrid1.Cells[5,i] := FloatToStrF(sr_ball,ffFixed,1,2); 
   end; 
   i := 3; 
   with stud3 do begin 
   StringGrid1.Cells[1,i] := name; 
   StringGrid1.Cells[2,i] := IntToStr(inf); 
   StringGrid1.Cells[3,i] := IntToStr(phys); 
   StringGrid1.Cells[4,i] := IntToStr(math); 
   StringGrid1.Cells[5,i] := FloatToStrF(sr_ball,ffFixed,1,2); 
   end;  
end; 
 
procedure TForm1.Button2Click(Sender: TObject); 
var i: Byte; 
begin 
  for i := 1 to N_MAX do 
   begin 
        if stud[i].sr_ball >= 4.5 then 
            begin 
               StringGrid1.RowHeights[i] := 30; 
            end 
        else 
            StringGrid1.RowHeights[i] := 0; 
   end; 
end; 
 
procedure TForm1.FormCreate(Sender: TObject); 
var 
  i: 0..N_MAX; 
begin 
   for i := 1 to N_MAX do begin 
     StringGrid1.Cells[INDEX_COL, i] := IntToStr(i); 
   end; 
 
   StringGrid1.Cells[0, TITLE_ROW] := 'N'; 
   StringGrid1.Cells[1, TITLE_ROW] := 'Фамилия'; 
   StringGrid1.Cells[2, TITLE_ROW] := 'Информатика'; 
   StringGrid1.Cells[3, TITLE_ROW] := 'Физика'; 
   StringGrid1.Cells[4, TITLE_ROW] := 'Математика'; 
   StringGrid1.Cells[5, TITLE_ROW] := 'Ср. балл'; 
   StringGrid1.ColWidths[1] := 110; 
   StringGrid1.ColWidths[2] := 110; 
   StringGrid1.ColWidths[3] := 60; 
   StringGrid1.ColWidths[4] := 110; 
   StringGrid1.ColWidths[5] := 110; 
  
end; 
end. 
       


Вместо того чтобы оставить тех кто подходит под условие - убирает все ячейки (схлопывает их, нулевая высота)

Как можно исправить?

Дополнен
По дате
По рейтингу
Аватар пользователя
Мастер
11мес

Здравствуйте.
Вам нужно сделать 3 процедуры - заполнение массива студентов, очистку StringGrid и заполнение StringGrid данными. У процедуры заполнения StringGrid должен быть параметр указывающий на то, что выводить всех студентов или с баллом больше 4.5. В процедуре заполнения проходить по всем элементам массива и выводить в зависимости от значения параметра.
PS. Смогу сделать вечером, только напишите если будет актуально(если не напишите - делать не буду).

Аватар пользователя
Ученик
11мес

в целом актуально, очень помогли бы!

Аватар пользователя
Мастер
11мес

сделал, куда выложить?

Аватар пользователя
Мастер
11мес

скачать можно отсюда: https: // transfiles .ru/ g62yj
уберите пробелы из ссылки

Аватар пользователя
Профи
11мес
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
 unit Unit1; 
 
{$mode objfpc}{$H+} 
 
interface 
 
uses 
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, StdCtrls; 
 
type 
  TStudent = {$IFDEF CPUX86}packed{$ENDIF}record 
    name: string; 
    inf: byte; 
    phys: byte; 
    math: byte; 
    avg: real; 
  end; 
 
  TStudents = specialize TArray<TStudent>; 
 
  { TForm1 } 
 
  TForm1 = class(TForm) 
    Button1: TButton; 
    Button2: TButton; 
    StringGrid1: TStringGrid; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
  private 
    FStudents: TStudents; 
  protected 
    procedure AddStudentToGrid(AStudent: TStudent); 
  public 
    procedure AddStudent(const AName: string; AInf, APhys, AMath: byte); 
    procedure ClearGrid; 
    procedure FilterAvg(AValue: Real = 0); 
  end; 
 
var 
  Form1: TForm1; 
 
implementation 
 
{$R *.lfm} 
 
{ TForm1 } 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  StringGrid1.ColCount := 6; 
  StringGrid1.RowCount := 2; 
  StringGrid1.Rows[0].AddStrings( 
    ['N', 'Фамилия', 'Информатика', 'Физика', 'Математика', 'Ср. балл']); 
  StringGrid1.ColWidths[0] := 30; 
  StringGrid1.ColWidths[1] := 110; 
  StringGrid1.ColWidths[2] := 110; 
  StringGrid1.ColWidths[3] := 60; 
  StringGrid1.ColWidths[4] := 110; 
  StringGrid1.ColWidths[5] := 110; 
end; 
 
procedure TForm1.AddStudentToGrid(AStudent: TStudent); 
begin 
  with AStudent do 
    StringGrid1.Rows[StringGrid1.RowCount - 1].AddStrings( 
      [ 
        (StringGrid1.RowCount - 1).ToString, 
        name, 
        inf.ToString, 
        phys.ToString, 
        math.ToString, 
        FormatFloat('0.0', avg) 
      ] 
    ); 
  StringGrid1.RowCount := StringGrid1.RowCount + 1; 
end; 
 
procedure TForm1.AddStudent(const AName: string; AInf, APhys, AMath: byte); 
begin 
  if not AName.IsEmpty then 
  begin 
    SetLength(FStudents, Length(FStudents) + 1); 
    with FStudents[High(FStudents)] do 
    begin 
      name := AName; 
      inf := AInf; 
      phys := APhys; 
      math := AMath; 
      avg := (AInf + APhys + AMath) / 3; 
    end; 
    AddStudentToGrid(FStudents[High(FStudents)]); 
  end; 
end; 
 
procedure TForm1.ClearGrid; 
var 
  i: integer; 
begin 
  for i := 1 to StringGrid1.RowCount - 1 do 
    StringGrid1.Rows[i].Clear; 
  StringGrid1.RowCount := 2; 
end; 
 
procedure TForm1.FilterAvg(AValue: Real); 
var 
  i: integer; 
begin 
  ClearGrid; 
  for i := 0 to High(FStudents) do 
    if FStudents[i].avg >= AValue then 
      AddStudentToGrid(FStudents[i]); 
end; 
 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  SetLength(FStudents, 0); 
  ClearGrid; 
  AddStudent('Бабурин', 4, 4, 5); 
  AddStudent('Васильев', 5, 5, 5); 
  AddStudent('Дьяконова', 2, 3, 3); 
end; 
 
procedure TForm1.Button2Click(Sender: TObject); 
begin 
  FilterAvg(4.5); 
end; 
 
end. 
Аватар пользователя
Ученик
11мес

Спасибо большое, чуть позднее посмотрю, могу я в случае появления вопросов задать их вам?

Аватар пользователя
Гений
11мес

Ты пытаешься фильтровать отдельные переменные, а массив stud пустой. Поэтому программа работает верно)))

Аватар пользователя
Ученик
11мес

может ты просто не правильно убираешь их вместо фильтрации попробуй добавить проверку в цикл

Аватар пользователя
Ученик
11мес

а какую проверку тогда добавить?

Аватар пользователя
Ученик
11мес

может ты просто не правильно удаляешь строки попробуй сначала собрать подходящих в новый массив а потом обновить grid

Аватар пользователя
Ученик
11мес

может ты просто не обновляешь таблицу после фильтрации попробуй вызвать refresh или redraw после сортировки

Аватар пользователя
Ученик
11мес

может ты просто не обновляешь таблицу после фильтрации попробуй вызвать refresh или redraw после сортировки

Аватар пользователя
Ученик
11мес

а как именно?

Аватар пользователя
Просветленный
11мес

Терминатор 84?

Аватар пользователя
Ученик
11мес

Да



Видео по теме