FindComponent не работает в процедуре

Я разрабатываю программу, которая вычисляет средние значения некоторых данных в разных TStringGrid, и я подумал использовать процедуру. Он называется calcola.

procedure calcola(numero:ShortInt; StringGrid:TStringGrid; pbarprog:ShortInt);
var i,j,cont,num:shortint;
    avg,temp,numfl:double;
    a:string;
    Edit1:TEdit;
begin
if StringGrid.Colcount>1 then

 //other code

       avg:=temp/cont;
       TLabel(FindComponent('Label'+IntToStr(num))).Caption:=FloatToStrF(avg, ffGeneral, 1, 1);
       Edit1.Text:=FloatToStr(StrToFloat(TLabel(FindComponent('Label'+IntToStr(num))).Caption)*10);
       TProgressBar(FindComponent('ProgressBar'+IntToStr(i+pbarprog))).Position:=StrToInt(Edit1.Text);

       //other code

     end;
   end;
end; 

В этой процедуре Lazarus сообщает мне "Идентификатор FindComponent не найден". Затем я вырезал/вставил тот же код в procedure TForm1.Button1Click(Sender: TObject);, и у меня не было ошибок.

Мне нужно использовать FindComponent() внутри calcola, как я могу это сделать?


person Alberto Miola    schedule 10.08.2013    source источник
comment
FindComponent — это метод TComponent, а не функция.   -  person TLama    schedule 10.08.2013
comment
Так что я должен?   -  person Alberto Miola    schedule 10.08.2013
comment
Прежде всего, я бы рассмотрел код. Это крайне небезопасно.   -  person TLama    schedule 10.08.2013
comment
Хорошо, но я думаю, что ему нужен ответ на его вопрос перед просмотром кода.   -  person Alberto Rossi    schedule 10.08.2013
comment
@Альберто, точно. Следовательно, это комментарий, а не ответ :-) Есть много способов ответить на этот вопрос с помощью кода (например, передать объект формы в качестве параметра в процедуру и вызвать FindComponent, например, PassedForm.FindComponent). Но этот код требует почти полного редизайна. А если бы это произошло, то не было бы такого вопроса.   -  person TLama    schedule 10.08.2013
comment
О, хорошо :) так что я могу сделать что-то вроде 'TForm1.FindComponent();' ?   -  person Alberto Miola    schedule 10.08.2013
comment
Либо вы можете получить доступ к глобальной переменной Form1 (в вашем случае вы бы назвали ее как Form1.FindComponent в своей процедуре). Или вы можете добавить еще один параметр в свою процедуру, где вы должны передать объект формы и вызвать этот метод для этого параметра. Но лучше как-то подумать о редизайне.   -  person TLama    schedule 10.08.2013
comment
@tlama: просто превратите свой комментарий в ответ. Использование ссылки на экземпляр формы устраняет непосредственную проблему, а с добавленным предупреждением или советом это довольно надежный ответ, за который можно проголосовать.   -  person Wouter van Nifterick    schedule 10.08.2013
comment
Прекратите смешивать код пользовательского интерфейса и математический код в одну нечестивую и непристойную херню. Прекратите использовать FindComponent. В этом нет необходимости, и это плохая практика. Не делай этого.   -  person David Heffernan    schedule 10.08.2013
comment
Прекратите использовать FindComponent ---› Вопрос о FindComponent. Хороший ;)   -  person Alberto Rossi    schedule 14.08.2013


Ответы (1)


Затем я вырезал/вставил тот же код в процедуру TForm1.Button1Click(Sender: TObject); а у меня ошибок не было.

Причина, по которой компилятор перестал жаловаться, когда вы сделали это изменение, заключается в том, что, когда calcola объявлен как метод TForm1, компилятор может разрешить идентификатор FindComponent, выполняя поиск в обратном направлении через объявленные методы TForm1 и общедоступные методы объектов, от которых он происходит ( TForm ... TObject), пока не найдет объект с таким именем. FindComponent объявлен в TComponent.

Причина, по которой компилятор пожаловался на вашу исходную версию, заключалась в том, что calcola была объявлена ​​(я полагаю) в глобальной области вашей программы как автономная процедура, и для них компилятор ищет только ранее объявленные автономные процедуры/функции, а не те, которые объявляются как методы объектов.

Если по какой-либо причине ваша процедура вычисления обязательно должна быть автономной процедурой, то лучше всего настроить ее параметры, чтобы вы могли передать ей конкретный экземпляр TForm1 в качестве параметра, как вы это сделали со StringGrid.

person MartynA    schedule 10.08.2013