Lazarus (Pascal): Отсортировать таблицу StringGrid1 учеников, оставить только тех, у кого средний балл больше 4.5
Здраствуйте, есть проблема в коде:
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.
Вместо того чтобы оставить тех кто подходит под условие - убирает все ячейки (схлопывает их, нулевая высота)
Как можно исправить?
Здравствуйте.
Вам нужно сделать 3 процедуры - заполнение массива студентов, очистку StringGrid и заполнение StringGrid данными. У процедуры заполнения StringGrid должен быть параметр указывающий на то, что выводить всех студентов или с баллом больше 4.5. В процедуре заполнения проходить по всем элементам массива и выводить в зависимости от значения параметра.
PS. Смогу сделать вечером, только напишите если будет актуально(если не напишите - делать не буду).
в целом актуально, очень помогли бы!
сделал, куда выложить?
скачать можно отсюда: https: // transfiles .ru/ g62yj
уберите пробелы из ссылки
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. Спасибо большое, чуть позднее посмотрю, могу я в случае появления вопросов задать их вам?
Ты пытаешься фильтровать отдельные переменные, а массив stud пустой. Поэтому программа работает верно)))
может ты просто не правильно убираешь их вместо фильтрации попробуй добавить проверку в цикл
а какую проверку тогда добавить?
может ты просто не правильно удаляешь строки попробуй сначала собрать подходящих в новый массив а потом обновить grid
может ты просто не обновляешь таблицу после фильтрации попробуй вызвать refresh или redraw после сортировки
может ты просто не обновляешь таблицу после фильтрации попробуй вызвать refresh или redraw после сортировки
а как именно?
Терминатор 84?
Да