TCompanent uyuşmazlığı

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
sturen
Üye
Mesajlar: 11
Kayıt: 05 Haz 2014 08:27

TCompanent uyuşmazlığı

Mesaj gönderen sturen »

Mrb;

Form girişi için bir sürü edit ve memo bileşenim var.
Kod yazmakta üşengeç biri olduğumdan bunları tek tek kontrol etmek istemedim.
Bunun yerine array record oluşturup kontrol edilecek bileşen adını, tipini, kontrol şartını yazıyorum.
Daha sonrasında da For döngüsüne sokup şartları yerine getirip getirmediklerini denetliyorum. (Örn: Bu alan boş olamaz veya şu kadar karakter uzunlukta olmalı).
Kod satırı ve kontrolü kolaylaşıyor.

Bunu şöyle yapıyorum;

Var
obj:=Tedit;

diyerek bileşenimin Tedit sınıfından olduğunu belirtiyorum.

Arraydaki tanımlamaları mı döngüye sokuyorum

obj:=TEdit(findcompanent('ArraydaBelirtilenBileşenİsmi')); diyerek atamasını gerçekleştiriyorum.
obj.text ile özelliklerine ulaşıyorum.

Sıkıntım kontrol edeceğim bileşen TEdit değilde TMemo olduğunda baş gösteriyor.
Obj Tedit olarak tanımlandığından findCompanent uyuşmazlık hatası veriyor.
TMemo için yeni bir değişken tanımlamak çözüm olsa da alt satırlarda obj üzerinden yapılan tanımlamaları tekrar tekrar yapmak gerekecek. Buda çok kod ve kontrol demek. Üşengecim demiştim sanırım :)

Tek çözüm Objyi temsil edeceğimiz değişken tipinin hepsini kapsamasından geçiyor sanırım. Ama ben bulamadım.
Var mı yardımcı olacak?
ikra
Üye
Mesajlar: 901
Kayıt: 28 Nis 2005 01:26
Konum: Simdilik Topragin Üstü

Re: TCompanent uyuşmazlığı

Mesaj gönderen ikra »

Üsengeclik ile programcilik ak ile kara gibi birbirlerine zit.
Üsengecligini yenebilirsen eger isini görecek sey propinfo.
kıdemsiz üye
sturen
Üye
Mesajlar: 11
Kayıt: 05 Haz 2014 08:27

Re: TCompanent uyuşmazlığı

Mesaj gönderen sturen »

Teşekkürler bakıyorum hemen;

ikra yazdı:Üsengeclik ile programcilik ak ile kara gibi birbirlerine zit.
Üsengecligini yenebilirsen eger isini görecek sey propinfo.
xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: TCompanent uyuşmazlığı

Mesaj gönderen xxxjedixxx »

Merhaba,

İstediğinize uygun bir örneği paylaşıyorum. Umarım doğru anlamışımdır. Örnek kodu, formunuza Edit1, Edit2 ve Memo1 isimli nesneleri koyarak deneyebilirsiniz.

Kod: Tümünü seç

var Arr: array [0..2] of string;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Arr[0] := 'Edit1'; Arr[1] := 'Edit2'; Arr[2] := 'Memo1';
end;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
    Comp: TComponent;
begin
  for i := 0 to High(Arr) do
  begin
    Comp := FindComponent(Arr[i]);
    if (Comp is TEdit) and ((Comp as TEdit).Text = '') then
    begin
      ShowMessage((Comp as TEdit).Name + ' Boş');
      Break;
    end;

    if (Comp is TMemo) and ((Comp as TMemo).Text = '') then
    begin
      ShowMessage((Comp as TMemo).Name + ' Boş');
      Break;
    end;
  end;
end;
sturen
Üye
Mesajlar: 11
Kayıt: 05 Haz 2014 08:27

Re: TCompanent uyuşmazlığı

Mesaj gönderen sturen »

Öncelikle teşekkürler;

Sizin örneğiniz ile konuyu açmadan önce yazmış olduğum kodlar benzerlik gösteriyor.

Comp := FindComponent(Arr);

İle nesneyi tespit ediyoruz ve akabinde

if (Comp is TMemo) then begin
value:=(Comp is TMemo).text;
....
...
end;


if (Comp is TEdit) then begin
value:=(Comp is TEdit).text;
....
...
end;


komutlarıyla nesne tipine göre işlem yapıyoruz.
Benim uygulamamda if then blokları arasında ki tüm işlemlerim aynı.
Ben diyorum ki üşengeç olalım biraz daha takla atalım.
Bol bol if then bloğu kullanıp dallanmak ve tekrar tekrar kod yazmak yerine

value:=(Comp is TMemo).text;
örneğinde (Comp is TMemo) veya (Comp is TEdit) yerine öyle bir şey yazalım ki
array da belirtilen objeye bağlı olarak değeri çekelim.

Aşağıdaki gibi ama ben bir türlü çalıştıramadım.

var Arr: array [0..2] of string;

procedure TForm1.FormCreate(Sender: TObject);
begin
Arr[0] := 'Edit1'; Arr[1] := 'Edit2'; Arr[2] := 'Memo1';
end;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
Comp: TComponent;
begin
for i := 0 to High(Arr) do
begin
Comp := FindComponent(Arr);

showmessage(Comp.Text);

end;
end;


xxxjedixxx yazdı:Merhaba,

İstediğinize uygun bir örneği paylaşıyorum. Umarım doğru anlamışımdır. Örnek kodu, formunuza Edit1, Edit2 ve Memo1 isimli nesneleri koyarak deneyebilirsiniz.

Kod: Tümünü seç

var Arr: array [0..2] of string;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Arr[0] := 'Edit1'; Arr[1] := 'Edit2'; Arr[2] := 'Memo1';
end;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
    Comp: TComponent;
begin
  for i := 0 to High(Arr) do
  begin
    Comp := FindComponent(Arr[i]);
    if (Comp is TEdit) and ((Comp as TEdit).Text = '') then
    begin
      ShowMessage((Comp as TEdit).Name + ' Boş');
      Break;
    end;

    if (Comp is TMemo) and ((Comp as TMemo).Text = '') then
    begin
      ShowMessage((Comp as TMemo).Name + ' Boş');
      Break;
    end;
  end;
end;
ikra
Üye
Mesajlar: 901
Kayıt: 28 Nis 2005 01:26
Konum: Simdilik Topragin Üstü

Re: TCompanent uyuşmazlığı

Mesaj gönderen ikra »

findcomponent metodunu kullanmana gerek yok.
döngüye sokup Components ile bilesen ulasir, propinfo ile gerekli bilgiyi alip, o'na göre islem yaparsin.
Senin ilacin PropInfo.

aksi taktirde her farkli bilesen seti kullandiginda kodlari sil bastan yazmak zorunda kalacaksin.
bugün TEdit kullaniyorsun, yarin Raize bilesen seti hosuna gidecek TRzEdit olacak, öbür gün TCxEdit kullanacaksin.
Yada bir form icerisinde birden fazla bilesen setinin Editlerini kullanacaksin. o zaman If bloklarinin sayisi o kadar cogalacak ki, yarin bir sorun oldugunda isin icinden kendin dahi cikamayacaksin.
kıdemsiz üye
xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: TCompanent uyuşmazlığı

Mesaj gönderen xxxjedixxx »

Her nesnenin özellikleri kendine hastır. Her nesnede Text adında özellik olacak diye bir kural da yoktur. Edit ile Memo'nun Text özelliğinin olması zorunluluktan dolayı değildir. Memo1.Text yerine Memo1.Value'de olabilirdi. Hatta Text özelliği hiç konulmayabilirdi de. Zaten Text özelliği Memo1.Lines.Text ile aynı şeydir. Bu yüzden bazen birbirine benzer bir çok kod bloğunu yazmak zorunda kalırız.

Maksat Edit ve Memo için tek bir if bloğu ile yazmak ise;

Kod: Tümünü seç

var Arr, Msg: array [0..2] of string;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  Arr[0] := 'Edit1'; Arr[1] := 'Edit2'; Arr[2] := 'Memo1';
  Msg[0] := 'Edit1 boş'; Msg[1] := 'Edit2 boş '; Msg[2] := 'Memo1 boş';
end;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
    Comp: TComponent;
begin
  for i := 0 to High(Arr) do
  begin
    Comp := FindComponent(Arr[i]);
    if (Comp is TEdit) and ((Comp as TEdit).Text = '') or (Comp is TMemo) and ((Comp as TMemo).Text = '') then
    begin
      ShowMessage(Msg[i]);
      Break;
    end;
  end;
end;
sturen
Üye
Mesajlar: 11
Kayıt: 05 Haz 2014 08:27

Re: TCompanent uyuşmazlığı

Mesaj gönderen sturen »

Öncelikle ikra ve xxxjedixxx ikinize de ayrı ayrı teşekkürler;

Sevgili xxxjedixxx;

Her nesnenin text özelliği olmayacağını biliyorum zaten.
Ben sadece nesneyi bir şekilde seçip ki bu arrayda belirtilen nesne olsun istiyorum text özelliği varsa kullanmak istiyorum.
Zaten arrayda manuel tanımlama yapacağı için programcı buna dikkat edecektir.

Mesela benim tanımlamam aşağıdaki gibi;

type
TShopItem = record
Field : string;
Obj : string;
Typ : string;
Required : Boolean;
Len : Integer;

end;

const
Items : array[1..3] of TShopItem =
(
(Field : 'BARKOD'; Obj : 'YBarkod'; Typ: 'TEdit'; Required : true; Len : 15;),
(Field : 'URUNKODU'; Obj : 'YUrunkodu'; Typ: 'TEdit'; Required : true; Len : 0;),
(Field : 'ACIKLAMA'; Obj : 'YAciklama'; Typ: 'TMemo'; Required : false; Len : 10;)
) ;

Döngü içinde O nesne için yapılması gereken kuralları belirleyebiliyorum.
Kurallar arttırılabilir. Bir bileşen için tek tek veya birkaçı bir arada kullanılabilir.

En basit şekliyle;

for i := Low(Items) to High(Items) do begin

Comp := FindComponent(Items.Obj);

//Required true ise zorunlu alan;
if (Length(comp.Text)<=0 and (Items.Required)) then
showmessage('Bu haneye giriş yapmalısınız');

//Uzunluk Kontrolü İsteniyorsa
if (Length(comp.Text)<=Items.Len) then
showmessage('Yeterli uzunlukta veri girişi olmadı');
end;

ikra'nın PropInfo çözümünü de inceledim. Evet aslında aradığım şey o.
Çözemediğim iki nokta var.

1-) Components ile forumdaki tüm bileşenler değerlendiriliyor.
Oysa ben seçtiklerim üzerinde işlem yapmak istiyorum.
Belki formdaki tüm nesneler döngüye sokulup array'dakiyle eşleşiyorsa işleme alınabilir.
Çözümmüş gibi görünse de performans farkı yaratır. Nokta atış şansı arıyorum :)

2-) Anladığım kadarıyla PropInfo'da bileşenin özelliğine ulaşılıyor ve varsa şununla değiştir deniyor.
Bütün işi PropInfo üstelenmiş. Ben atama değil değeri alıp karşılaştırma yapmak kendi yargılarımı yazmak istiyorum.

Muhakkak bu istediklerim mümkündür. Ben bu tekniği PHP üzerinde kullanıyorum.
Sıkıntım Delphi'ye hakim olamamaktan geliyor. ikra biraz el atarsa çözüm olacak sanırım.

Tekrar teşekkürler;
sturen
Üye
Mesajlar: 11
Kayıt: 05 Haz 2014 08:27

Re: TCompanent uyuşmazlığı

Mesaj gönderen sturen »

Son mesajımda ikra 'ya durumu anlatırken kendi sorumu cevaplamışım aslında farkında değilim :)
Örnekleri incelerken hep SetStrProp komutuna denk gelmişim.
Birde GetStrProp yazayım bakalım ne olacak dedim. Sonuç başarılı.


//Objemizi yakalıyoruz
obj:=FindComponent(Items.Obj);

////////////////////////////////
Ek Bilgi

type
TItem = record
Field : string;
Obj : string;
Typ : string;
Required : Boolean;
Len : Integer;
end;

Type ksımında Obj değişkenini string yerine TComponent tanımlayabilsek
FindComponent komutuna ihtiyaç kalmayacak aslında.

PropInfo := GetPropInfo(Item[].Obj, 'Text', []); ile işi çözeceğiz.

TComponent olarak tanımladığımda arraya değer atamaya çalıştığımda hata veriyor .
Atama işlemini şu şekilde yapıyorum. Ben mi hata yapıyorum.
Items : array[1..3] of TItem =
(
(Field : 'BARKOD'; Obj : YBarkod; Typ: 'TEdit'; Required : true; Len : 15;),
(Field : 'URUNKODU'; Obj : YUrunadi; Typ: 'TMemo'; Required : true; Len : 0;),
(Field : 'URUNADI'; Obj : YStok; Typ: 'TEdit'; Required : false; Len : 0;)
) ;

///////////

//Objemizin Text Özelliğine Konumlanıyoruz
PropInfo := GetPropInfo(obj, 'Text', []);

//Objemizden Değeri alıyoruz
showmessage(GetStrProp(Obj, PropInfo));
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2381
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: TCompanent uyuşmazlığı

Mesaj gönderen freeman35 »

mesajlarında yazdığın kodlar "code" block larına alırsan daha okunaklı olacaktır.
"SetStrProp komutuna denk gelmişim.Birde GetStrProp yazayım bakalım ne olacak dedim." bu cümlenden anladığım copy+paste çı, yaptım oldu mantığında birisi olduğun. Amacın zorunlu konulmuş bir angarya dersten geçmekse, yada kendi işini görebileceğin, basit bir-iki şey yapmaksa sorun olmaz. Ama kendine "programcı" diyeceksen, sana tavsiyem, koyduğun noktanın, [ değilde ( olduğuna kadar kullandığın yada kullanılmış her karakterin ne olduğunu öğrenin, ve malesef ingilizce bilmek gerek. örnek:
//Objemizin Text Özelliğine Konumlanıyoruz
PropInfo := GetPropInfo(obj, 'Text', []);
gavur anlaşılması kolay olsun diye isim verirken açıklayıcı isim kullanır "get property information" kısaltılması, bunun "tercümesi" değil, "anlamı" programcılıkta "yaptığı iş" özelliğe ait bilgiyi 'AL' (SET ise ayarlamak, yerleştirmek, atamak anlamında kullanılır)
"konumlanmak" çok daha farklı bir anlam ve bu functionla en ufak alakası yok
Kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Cevapla