ComboBox ze zmienną w nazwie - pętla

0

A czy dobrzy ludzie podpowiedzą czy można i jak kodem zmienić wartości ComboBox?
Mam 24 pola combo od 1 do 24 i chce użyć ich w pętli do generowania raportu.
w jednym bloku odpytywać po kolei ComboBox1 itd do ComboBox24

for k := 1 to 24 do                       
begin
  ComboBoxSKRYPT:='ComboBox' + IntToStr(k);    
  EditSKRYPT:='Edit'+ IntToStr(k);                                   
  Showmessage(ComboBoxSKRYPT.Name); // tu jest błąd ze ciągi nie posiadają właściwości lub metod
  Showmessage(EditSKRYPT);
end;
3

Opcje są dwie :)

Albo robisz tak:

for i := 0 to ComponentCount - 1 do                  
    if Components[i] is TCombobox then 

albo tak

for i := 1 to 24 do
  begin
    cbx := FindComponent('ComboBox' + IntToStr(i)) as TComboBox;

  end;

Dodam jeszcze mając na uwadze twoje ewentualne przygody z FastReport, że do obiektów bezpośrednio zaimplementowanych w raporcie również możesz się dostać z poziomu delphi poprzez:

var
t: TfrMemoView;
begin
t := TfrMemoView(frReport1.FindObject('Memo1'));
0

cbx - to moja zmienna?

0

tak musisz ją zadeklarować:

var
  cbx: TComboBox;
begin
for i := 1 to 24 do
  begin
    cbx := FindComponent('ComboBox' + IntToStr(i)) as TComboBox;
    if Assigned(cbx) then
      ShowMessage(cbx.name);
  end;
end;

oczywiście ten FindComponent szuka po nazwie czyli twoje Comboboxy muszą mieć nazwy Combobox1, Combobox2 .... Combobox24

2

do FastReport jak już muszę to odwołuję się dokładnie tak:

TfrxMemoView(frxReport1.FindObject('Memo1')).Memo.Text := Edit1.Text; // lub zmienna typu string
TfrxCheckBoxView(frxReport1.FindObject('CheckBox1')).Checked := CheckBox1.Checked; // lub zmienna typu boolean
TfrxBarCodeView(frxReport1.FindObject('BarCode1')).Text := '5900000000001'; // kod musi być prawidłowy
0

jak zwykle nie ma łatwo

screenshot-20210219124936.png

2

Dobra ustalmy jedną rzecz ... :) Po screenie wnioskuję, że to zakładka code z fastreport?
Prawdopodobnie gdzieś coś pomieszałeś z blokami begin / end; Wrzuć całą procedurę lub plik fr3

Druga sprawa:
Gdzie masz te comboboxy? Jaka to jest faktycznie klasa? Bo w FR (a przynajmniej w wersji, którą ja dysponuję) w raportach nie ma comboboxów

2

ShowMessage jest poza pętlą. Czyli wyświetlisz nazwę (czy tam text bo zmieniłeś zdanie) ostatniego ComboBoxa.

0

Na razie serdecznie dziękuje chętnym za pomoc, wrócę do tematu w poniedziałek.
Dziś mi już spuchła głowa od Pascalów i fastreportów :(

0

Dzień dobry poniedziałek
screenshot-20210222094306.png

RAPORT.zip

0

Dzień dobry
Czy uda się coś wyczarować z tymi Comboboxami?

0

Przecież dostałeś odpowiedź w drugim poście od @wolfik

cbx := FindComponent('ComboBox' + IntToStr(i)) as TComboBox;

Musisz tylko przerobić pod swój schemat nazw:

cbx := FindComponent('ComboBox1' + IntToStr(i) + '001') as TfrxComboBoxControl;

Możliwe, że wymagać to będzie poprawy bo nie wiem jak idzie dalej ta numeracja i nie korzystam z FastReport.

0

FindComponent jest bardzo wolny. Użyj i stwórz kontrolki comboBox dynamicznie. Jeśli kodu masz mało użyj w wątkach. Nawet jeśli umieścisz na formie owe 24 comboBox na sztywno kod będzie wykonywał się szybciej, aniżeli przez FindComponent w pętli. Jedyną drogą to tworzenie TComboBox jest dynamicznie ich tworzenie a później zastosowanie FindComponent

procedure ....UtworzCombo;
var
i : integer;
Kontrolka : TComboBox;
begin
 for i:= 1 to 24 do
   begin
   Kontrolka := TComboBox.Create(Self);
     try
      with Kontrolka do
       begin
       Kontrolka.Text:= Combobox1.Items[i-1];
       Kontrolka.Name:='ComboBox'+inttostr(i);
   end;
    except
      Kontrolka.Free;
   end;
 end;
end;
1
Mariusz Bruniewski napisał(a):

FindComponent jest bardzo wolny. Użyj i stwórz kontrolki comboBox dynamicznie. Jeśli kodu masz mało użyj w wątkach. Nawet jeśli umieścisz na formie owe 24 comboBox na sztywno kod będzie wykonywał się szybciej, aniżeli przez FindComponent w pętli. Jedyną drogą to tworzenie TComboBox jest dynamicznie ich tworzenie a później zastosowanie FindComponent

Ręce opadają... przecież w końcu i tak użyjesz Twoim zdaniem wolnego FindComponent. FindControl jest szybsze, bo szuka tylko kontrolek albo walnij sobie jakiś TStringsList na nim przez AddObject raz sobie zindeksuj potrzebne kontrolki ComboBox i później tylko tam szukaj.

A swoją drogą nie wiem w FreePacal stoi z RTTI czy jest wystarczająco szybkie, bo jeżeli tak to na pewno da się uzyskać kontrolkę znając jej nazwę.

1
Mariusz Bruniewski napisał(a):

FindComponent jest bardzo wolny. Użyj i stwórz kontrolki comboBox dynamicznie. Jeśli kodu masz mało użyj w wątkach. Nawet jeśli umieścisz na formie owe 24 comboBox na sztywno kod będzie wykonywał się szybciej, aniżeli przez FindComponent w pętli.

FindComponent nie jest bardzo wolny, o ile dany rodzic nie zarządza miliardami kontrolek. Tak, FindComponent jest wolniejszy od przeszukiwania własnej listy referencji. Jest wolniejszy o jakąś mikrosekundę, w typowym przypadku.


kAzek napisał(a):

A swoją drogą nie wiem w FreePacal stoi z RTTI czy jest wystarczająco szybkie, bo jeżeli tak to na pewno da się uzyskać kontrolkę znając jej nazwę.

RTTI nie jest potrzebne do pobrania referencji kontrolki na podstawie jej nazwy — każdy komponent w LCL (czyli klasy TComponent) posiada pole FComponents, pod postacią zwykłej listy obiektów, w której trzymane są referencje wszystkich osadzonych kontrolek. Znalezienie odpowiedniej to prosta iteracja po obiektach tej listy i porównanie ciągów nazw:

Function  TComponent.FindComponent(const AName: string): TComponent;

Var I : longint;
    C : TComponent;
begin
  Result:=Nil;
  If (AName='') or Not assigned(FComponents) then exit;
  For i:=0 to FComponents.Count-1 do
    Begin
      c:=TComponent(FComponents[I]);
      If (CompareText(C.Name,AName)=0) then
        Exit(C);
    End;
end;

Jest tych metod kilka — FindComponent, FindSubComponent, FindChildControl — można sobie wybrać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1