Delphi ile "Login olmak" (Kullanıcı giriş denetimi)
- 20 Mayıs 2010 Perşembe
- Uğur Parlayan
Yazılara uzun bir süre ara verdikten sonra aşağıdaki gibi bir örnekle geri
dönmek sanırım hepimiz için güzel bir başlangıç olacak...
Yazdığımız programlarda kullanıcının programa girişini kontrol altına almak,
yetkileri ve arabirimi kullanıcıya göre giriş esnasında şekillendirmek
herzaman bizler için bir sıkıntı olmuştur. Bu yazıda bu sorunu nasıl
aşabileceğimize dair hazırladığım özel bir bileşeni tanıtacağım;
TupLoginDialog...
TupLogindialog Ne İşe Yarar
Bu bileşen, programcının tercihine bağlı kalarak açılış anında veya bir
butonun tetiklemesiyle devreye girip kullanıcıdan kullanıcı adı ve şifresini
bir forma girmesini, girdiği bilgileri kullanarak o kullanıcının
veritabanından kontrol edilmesini, varsa programa girmesine izin vermesini,
yoksa kullanıcıyı uyarmasını, belli bir miktar hatalı girişten sonra programı
kapatmasını sağlayan nevişahsına münhasır özel bir bileşenimizdir.
Tasarım anında görsel olmayan bir nesne olarak kullanılır. Sizden, ana
formunuza bu bileşeni eklediğinizde aşağıdaki alanları doldurmanızı ister.
Temel parametreleri girdiğinizde çalıştırılmaya hazırdır. Ayrıca sonuca göre 2
farklı olay da tetikleyebilmektedir. 1. Olayda, kullanıcı adı ve şifresi
doğrulanan bir kullanıcı veritabanında bulunduysa OnGirisKabulEdildi olayını
tetikler. Eğer belirttiğiniz miktarda hatalı bir giriş denemesi yapıldıysa
limit dolduğunda OnHataLimiti olayını tetikler. Bu olaylar size giriş
düğmesine basıldığında programınızda kullanıcı ile ilgili diğer işlemleri
yapmanıza, belli miktarda hatalı giriş yapıldığında ise programınızı
kapatmadan önce yapmanız gereken diğer işlemleri gerçekleştirmenize veya
ilgili kullanıcının hesabını kilitlemenize olanak verir.
TupLoginDialog Bileşeninin Kaynak Kodu
Aşağıda, size bu bileşenin kaynak kodunu veriyorum. Bu bileşen ile ilgili
teknik detayları ayrı ayrı da anlatabilirdim fakat konu bütünlüğünün
bozulmaması için gereken açıklamaları kodun içine serpiştirdim, neyi neden ve
nerede yaptığımı böylece daha iyi anlatabileceğimi düşünüyorum...
{******************************************************************************}
{* *}
{* Programlayan: Uğur Parlayan (ugurparlayan@gmail.com) *}
{* Tarih: 17.05.2010 *}
{* *}
{* Kullanım: Ayrım gözetmeksizn külliyatıyla ÜCRETSİZDİR *}
{* Yazarın gönlü olsun diye kaynak belirtirseniz sevinirim... *}
{* *}
{* Uygulamanıza Kullanıcı adı ve şifre ile giriş yapılabilmesine imkân verir *}
{* *}
{* URL: http://www.kavramca.com/index.php?k=40 *}
{* *}
{******************************************************************************}
unit upLoginDialog;
interface
uses
SysUtils, Classes, StdCtrls, Mask, DBCtrls, DB, ExtCtrls, Controls, Buttons,
Variants, Messages, Windows, Forms, Dialogs, ADODB, Grids, DBGrids, Graphics,
AppEvnts;
const
WM_AFTER_SHOW = WM_USER + 300;
WM_AFTER_CREATE = WM_USER + 301;
type
TupLoginDialog = class(TCommonDialog)
private
FUygulamaOlayi : TApplicationEvents;
{Pencerenin iç nesneleri}
FPencere : TForm;
FCMB_Kullanici : TComboBox;
FEdit_Sifre : TEdit;
FBTN_Giris : TButton;
FBTN_Kapat : TButton;
FLBL_Kullanici : TLabel;
FLBL_Sifre : TLabel;
FBTN_Hatirlatici : TButton;
{Diğer zımbırtılar}
FConnection : TAdoConnection;
FGirisKabulEdildi : TNotifyEvent; {Girişte tetiklenen olay.}
FHataLimiti : TNotifyEvent;
FOtomatikBaslat : Boolean; {Program çalışınca devreye girecek mi}
FGirebilir : Boolean; {Giriş izni verildi mi}
FKullaniciListele : Boolean;
FKullanici_Tablosu : string;
FHatirlatmaGoster : Boolean;
FAlan_Soru : string;
FAlan_Cevap : string;
FAlan_Key : string;
FAlan_Kullanici : string;
FAlan_Sifre : string;
FAlan_Pasif : string;
FAlan_SonTarih : string;
FAlan_Yetkiler : string;
FAlan_Hesap : string;
FMetin_Baslik : string;
FMetin_Kullanici : string;
FMetin_Sifre : string;
FMetin_Login : string;
FMetin_Kapat : string;
FMetin_Hatirlat : string;
FValue_Kullanci : string;
FValue_Sifre : string;
FValue_Hesap : string;
FValue_Key : string;
FValue_Yetkiler : string;
FValue_Pasif : Boolean;
FHataSayaciKullan : Boolean;
FHataSayaci : Integer;
function GetSQL : string;
function GetBilesenDurumu: string;
function GetValue_Kullanci: string;
function GetValue_Sifre: string;
procedure SetConnection(const Value: TAdoConnection);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
{Ana programa sistem mesajı gönderir...}
procedure OnMsg(var Msg:tagMsg;var Handled:Boolean);
procedure Klik_Tus(Sender: TObject; var Key: Char);
procedure Klik_Giris(Sender: TObject);
procedure Klik_Kapat(Sender: TObject);
procedure Klik_Hatirlat(Sender: TObject);
procedure Sifirla;{Pencere açılmadan önce sonuçları sıfırlar...}
procedure Sonuclar;
procedure Olustur;{Penceremizi oluşturur...}
property OnClose;
property OnShow;
protected
procedure DoGirisKabulEdildi; virtual;
procedure DoHataLimiti; virtual;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure Calistir;{Dialog penceresini istenilen esnada gösterir}
published
property Connection : TAdoConnection read FConnection
write SetConnection;
{SQL cümlemizi parametrelere göre üretir.}
property SQL : string read GetSQL;
{Bileşen için gereken kritik değişkenler hakkında dış ortama bilgi verir.}
property BilesenDurumu : string read GetBilesenDurumu;
{Kaç kere hata yapılabileceğini bu değişken karar verir}
property HataSayaci : Integer read FHataSayaci
write FHataSayaci
Default 10;
{Eğer istersek kullanıcının hatalarını saymayabiliriz...}
property HataSayaciKullan : Boolean read FHataSayaciKullan
write FHataSayaciKullan
Default False;
{Şifresini unutan kullanıcıya soru sorabiliriz}
property HatirlatmaGoster : Boolean read FHatirlatmaGoster
write FHatirlatmaGoster
Default False;
{Ana form çalışır çalışmaz devreye girmesini sağlayabiliriz.}
property OtomatikBaslat : Boolean read FOtomatikBaslat
write FOtomatikBaslat
Default False;
{Kullanıcı adlarını eğer istersek listeleyebiliriz, ŞART DEĞİL !!!}
property Kullanici_Listele : Boolean read FKullaniciListele
write FKullaniciListele
Default False;
{Temel Parametre: Kullanıcıların veritabanındaki tablo adı}
property Kullanici_Tablosu : string read FKullanici_Tablosu
write FKullanici_Tablosu;
{Temel Parametre: USERNAME alanı}
property Alan_Kullanici : string read FAlan_Kullanici
write FAlan_Kullanici;
{Temel Parametre: PASSWORD alanı}
property Alan_Sifre : string read FAlan_Sifre
write FAlan_Sifre;
{Şart değil: Sorunun tutulduğu tablo alanı}
property Alan_Soru : string read FAlan_Soru
write FAlan_Soru;
{Şart değil: Cevabın tutlduğu tablo alanı}
property Alan_Cevap : string read FAlan_Cevap
write FAlan_Cevap;
{Temel Parametre: Her kullanıcı için bir referans numarası vardır}
{Bu alan işte o referansı kullanmanızı sağlar (PRIMARY KEY)}
property Alan_Key : string read FAlan_Key
write FAlan_Key;
{Şart değil: Pasifleştirilmiş kullanıcıları sonuçlardan dışlar...}
property Alan_Pasif : string read FAlan_Pasif
write FAlan_Pasif;
{Şart değil: Eğer kullanıcının belli bir tarihten sonra giriş }
{yapmasını istemiyorsanız bunu kullanabilirsiniz...}
property Alan_SonTarih : string read FAlan_SonTarih
write FAlan_SonTarih;
{Şart değil: Giriş yaptıktan sonra yetkileri denetlemenizi sağlar}
property Alan_Yetkiler : string read FAlan_Yetkiler
write FAlan_Yetkiler;
{Şart değil: ACCOUNT alanı...}
property Alan_Hesap : string read FAlan_Hesap
write FAlan_Hesap;
{Görsel: Pencerenin başlığı}
property Metin_Baslik : string read FMetin_Baslik
write FMetin_Baslik;
{Görsel: Giriş düğmesinin başlığı}
property Metin_Login : string read FMetin_Login
write FMetin_Login;
{Görsel: Kapat düğmesinin başlığı}
property Metin_Kapat : string read FMetin_Kapat
write FMetin_Kapat;
{Görsel: Kullanıcı adı text alanının başlığı}
property Metin_Kullanici : string read FMetin_Kullanici
write FMetin_Kullanici;
{Görsel: Şifre text alanının başlığı}
property Metin_Sifre : string read FMetin_Sifre
write FMetin_Sifre;
{Görsel: "Şifremi Unuttum" düğmesinin başlığı}
property Metin_Hatirlat : string read FMetin_Hatirlat
write FMetin_Hatirlat;
{SONUÇ: Kullanıcı adı}
property Value_Kullanici : string read GetValue_Kullanci
write FValue_Kullanci;
{SONUÇ: Şifresi}
property Value_Sifre : string read GetValue_Sifre
write FValue_Sifre;
{SONUÇ: PRIMARY KEY}
property Value_Key : string read FValue_Key;
{SONUÇ: Bu kullanıcının yetkileri}
property Value_Yetkiler : string read FValue_Yetkiler;
{SONUÇ: ACCOUNT adı...}
property Value_Hesap : string read FValue_Hesap;
{SONUÇ: Aktif / Pasif kullanıcı olup olmadığı...}
property Value_Pasif : Boolean read FValue_Pasif;
{SONUÇ: Kullanıcının mevcut olup olmadığının kararı...}
property Girebilir : Boolean read FGirebilir
Default False;
{OLAY: Giriş düğmesi olayı}
property GirisKabulEdildi : TNotifyEvent read FGirisKabulEdildi
write FGirisKabulEdildi;
{OlAY: Hata sayacı olayı}
property HataLimiti : TNotifyEvent read FHataLimiti
write FHataLimiti;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('UgurPack2007', [TupLoginDialog]);
end;
{ TupLoginDialog }
constructor TupLoginDialog.Create(AOwner: TComponent);
begin
inherited;
{ Varsayılanları ayarlıyoruz... }
if (FMetin_Baslik = '') then FMetin_Baslik := 'Kullanıcı Girişi';
if (FMetin_Kapat = '') then FMetin_Kapat := 'Kapat';
if (FMetin_Login = '') then FMetin_Login := 'Giriş';
if (FMetin_Kullanici = '') then FMetin_Kullanici := 'Kullanıcı Adı :';
if (FMetin_Sifre = '') then FMetin_Sifre := 'Şifre :';
if (FMetin_Hatirlat = '') then FMetin_Hatirlat := 'Şifremi Unuttum';
FHataSayaci := 10; {Kullansak da kullanmasak da bu varsayılan miktardır...}
{ Uygulama olayı tanımlıyoruz, Başlangıçta devreye girebilsin diye... }
FUygulamaOlayi := TApplicationEvents.Create(Self);
FUygulamaOlayi.OnMessage := OnMsg;
PostMessage(TForm(Owner).Handle, WM_AFTER_CREATE, 0, 0);
end;
destructor TupLoginDialog.Destroy;
begin
FUygulamaOlayi.Destroy;
inherited;
end;
procedure TupLoginDialog.DoGirisKabulEdildi;
begin
{ Giriş düğmesine bsama olayını burada atama yapıyoruz }
if Assigned(FGirisKabulEdildi) then FGirisKabulEdildi(SELF);
end;
procedure TupLoginDialog.DoHataLimiti;
begin
{ Hata miktarının tetiklenmesi olayını burada atama yapıyoruz }
if Assigned(FHataLimiti) then FHataLimiti(SELF);
end;
procedure TupLoginDialog.FormClose(Sender: TObject; var Action: TCloseAction);
begin
{ Form kapatıldığında onu yoketmeyip sadece gizliyoruz. }
Action := caHide;
{ caFREE kullansaydık nesneyi yoketmiş olurduk ki bu da hata üretir... }
if (FGirebilir = False) then begin
MessageBox(TForm(Owner).Handle, 'Program Kapatılacaktır.',
PWideChar(Application.Title), MB_OK + MB_ICONERROR);
PostMessage(TForm(Owner).Handle, WM_CLOSE, 0, 0);
{ Şifreyi giremediyse ana programı da kapat...}
end;
end;
procedure TupLoginDialog.FormShow(Sender: TObject);
var
FADS: TAdoDataSet;
SQL: String;
I: Integer;
Sonuc: String;
Ek: String;
begin
{ Formu çalıştırdığımızda bu kısım devreye giriyor }
{ Nesnelerimiz mevcutsa önce imleci kullanıcı adı text alanına }
{ konumlandırıyor, sonra da eğer kullanıcı listesi göstereceksek değerleri }
{ okuyup ilgili bileşene yazıyor... }
if Assigned(FPencere) and Assigned(FCMB_Kullanici) then begin
FCMB_Kullanici.SetFocus;
if (FAlan_Kullanici>'')
and (FKullanici_Tablosu>'')
and (FKullaniciListele = True)
then begin
SQL := '';
SQL := FORMAT('SELECT DISTINCT [%s] FROM dbo.[%s]',
[FAlan_Kullanici, FKullanici_Tablosu]);
if (FAlan_Pasif>'') or (FAlan_SonTarih>'') then begin
SQL := FORMAT('%s WHERE', [SQL]);
if (FAlan_Pasif > '') then SQL := FORMAT('%s ISNULL([%s],0) =
0', [SQL, Alan_Pasif]);
if (FAlan_Pasif>'') and (FAlan_SonTarih>'') then SQL :=
FORMAT('%s AND',[SQL]);
if (FAlan_SonTarih>'') then SQL := FORMAT('%s ISNULL([%s],0) <=
GETDATE()', [SQL, Alan_SonTarih]);
end;
if (SQL > '') then begin
FADS := TADODataSet.Create(Application);
with FADS do begin
Close;
Connection := FConnection;
CommandType := cmdText;
CommandText := SQL;
Open;
First;
end;
if (FADS.IsEmpty = False) then begin
for I := 0 to FADS.RecordCount - 1 do begin
Sonuc := Sonuc +
FORMAT('"%s",',[FADS.FieldByName(FAlan_Kullanici).AsString]);
FADS.Next;
end;
with FCMB_Kullanici.Items do begin
QuoteChar := '"';
Delimiter := ',';
DelimitedText := Sonuc;
end;
end;
FADS.Close;
FADS.Destroy;
end;
end else begin
FCMB_Kullanici.Style := csSimple;
end;
end;
end;
function TupLoginDialog.GetSQL: string;
var
SQL_Cumlesi: String;
begin
{ Kullanıcı adı, şifre, tablo, varsa pasif ve varsa son tarihle birlikte }
{ bu bilgilerini kullanarak bir SQL cümlesi üretiyor}
SQL_Cumlesi := '';
SQL_Cumlesi := FORMAT('SELECT TOP 1 [%s]',[FAlan_Key]);
if (FAlan_Hesap>'') then SQL_Cumlesi := FORMAT('%s, [%s]',[SQL_Cumlesi,
FAlan_Hesap]);
if (FAlan_Yetkiler>'') then SQL_Cumlesi := FORMAT('%s, [%s]',[SQL_Cumlesi,
FAlan_Yetkiler]);
SQL_Cumlesi := FORMAT('%s FROM dbo.[%s] WHERE [%s]=''%s'' AND [%s]=''%s''',
[ SQL_Cumlesi
, FKullanici_Tablosu
, Alan_Kullanici
, GetValue_Kullanci
, Alan_Sifre
, GetValue_Sifre
]);
if (Alan_Pasif > '') then SQL_Cumlesi := FORMAT('%s AND ISNULL([%s],0) =
0', [SQL_Cumlesi, Alan_Pasif]);
if (FAlan_SonTarih>'') then SQL_Cumlesi := FORMAT('%s AND ISNULL([%s],0) <=
GETDATE()', [SQL_Cumlesi, Alan_SonTarih]);
Result := SQL_Cumlesi;
end;
function TupLoginDialog.GetBilesenDurumu: string;
var
Sonuc: String;
begin
{ Bu bileşen için gerekli olan kritik değişkenler hakkında dış ortama bilgi
verir. }
Sonuc := '';
if NOT Assigned(FConnection) then Sonuc := Sonuc + 'Bağlantı nesnesi eksik.
';
if Assigned(FConnection) then begin
if (FConnection.Connected = False) then Sonuc := Sonuc + 'Bağlantı
nesnesi KAPALI ! ';
end;
if (FAlan_Key = '') then Sonuc := Sonuc + 'Anahtar alan
belirtilmemiş. ';
if (FAlan_Kullanici = '') then Sonuc := Sonuc + 'Kullanıcı adı alanı
belirtilmemiş. ';
if (FAlan_Sifre = '') then Sonuc := Sonuc + 'Şifre alanı
belirtilmemiş. ';
if (FKullanici_Tablosu = '') then Sonuc := Sonuc + 'Kullanıcı tablosu
belirtilmemiş. ';
if (Sonuc = '') then Sonuc := 'Temel parametreler mükemmel';
Result := Sonuc;
end;
function TupLoginDialog.GetValue_Kullanci: string;
begin
{ girişten sonra dış ortama kullanıcı adını veriyor... }
if Assigned(FCMB_Kullanici)
then Result := FCMB_Kullanici.Text
else Result := FValue_Kullanci;
end;
function TupLoginDialog.GetValue_Sifre: string;
begin
{ girişten sonra dış ortama şifreyi veriyor... }
{ Tabii ki dış ortamdan kastım sadece "ana form"... }
if (Assigned(FEdit_Sifre) = True)
then Result := FEdit_Sifre.Text
else Result := FValue_Sifre;
end;
procedure TupLoginDialog.Calistir;
begin
{ Siz, ana formda "Kullanıcı Girişi" diye bir butondan bunu çağırırsanız }
{ önce oluşturulmamışsa giriş formunu üretir, sonra sonuçları sıfırlar }
{ en sonunda da giriş formunu gösterir... }
if NOT Assigned(FPencere)
then Olustur;
Sifirla;
FPencere.ShowModal;
end;
procedure TupLoginDialog.Klik_Kapat(Sender: TObject);
begin
{ Kapat düğmesine bastığımızda bu işlem gerçekleşir... }
Fpencere.Close;
end;
procedure TupLoginDialog.Klik_Giris(Sender: TObject);
begin
{ Giriş düğmesine bastığımızda burası devreye girer; Kısaca şu işleri yapar }
{ Kullanıcının kullanıcı adı ve parametresini veritabanından sorgular }
{ Sonuçta bu kişi girebiliyorsa ana forma geçiş yapar}
{ giremiyorsa uygun bir dille uyarır... }
{ Hatta hata sayacı da burada sayılır ve kontrol edilir...}
Sonuclar;
if (FGirebilir = True) then Begin
GirisKabulEdildi(SELF);
FPencere.Close;
End else Begin
if (FHataSayaciKullan = True) then Begin
FHataSayaci := FHataSayaci - 1;
if (FHataSayaci <= 0) then begin
FGirebilir := False;
if Assigned(FHataLimiti) then HataLimiti(SELF);
FPencere.Close;
//Exit;
end else begin
MessageBox(TForm(Owner).Handle,PWideChar('Hatalı giriş yaptınız.
'+IntToSTR(FHataSayaci)+' defa daha hatalı giriş yaparsanız program
kapanacaktır. '#13#10'Lütfen sistem yöneticinize
danışınız...'),'HATA',MB_OK+MB_ICONERROR);
end;
End else Begin
MessageBox(TForm(Owner).Handle,'Kullanıcı adı ve/ya Şifreniz yok
ve/ya yanlış.'#13#10'Lütfen sistem yöneticinize
danışınız...','HATA',MB_OK+MB_ICONERROR);
end;
end;
end;
procedure TupLoginDialog.Klik_Hatirlat(Sender: TObject);
var
Soru : String;
Cevap: String;
Yanit: String;
Sifre: String;
FADS : TAdoDataSet;
begin
{ Eğer kullanıcımız, sevgili şifresini unuttuysa ona bir soru sormamız }
{ gerekir. Verdiği cevap ile veritabanındaki yanıt aynı ise ona şifresini }
{ gösteririz, yanlış bir yanıt verdiyse hata mesajı üretiriz...}
{ Tüm bunları yapabilmek için kullanıcı adının yazılmış olması gerekir... }
if (FHatirlatmaGoster = True) and (FAlan_Soru > '') and (FAlan_Cevap > '')
then begin
if (FCMB_Kullanici.Text > '') then begin
FADS := TADODataSet.Create(Application);
with FADS do begin
Close;
Connection := FConnection;
CommandType := cmdText;
CommandText := FORMAT('SELECT TOP 1 * FROM dbo.[%s] WHERE [%s]
= ''%s''', [FKullanici_Tablosu, FAlan_Kullanici, FCMB_Kullanici.Text]);
Open;
Soru := FieldByName(FAlan_Soru).AsString;
Cevap:= FieldByName(FAlan_Cevap).AsString;
Sifre:= FieldByName(FAlan_Sifre).AsString;
Close;
end;
FADS.Free;
Yanit := InputBox('Lütfen soruyu cevaplayın', Soru, '');
if lowercase(Yanit) = lowercase(Cevap) then ShowMessage(Sifre)
else MessageBox(TForm(Owner).Handle,'Yanlış
yanıt.','HATA',MB_OK+MB_ICONWARNING);
end else begin
MessageBox(TForm(Owner).Handle,'Lütfen Kullanıcı Adınızı
yazınız.','HATA',MB_OK+MB_ICONWARNING);
end;
end;
end;
procedure TupLoginDialog.Olustur;
const
sbt_Aralik = 4; { Penceredeki düğmeler arasındaki boşluk (Pixel
cinsinden...)}
sbt_Padding = 10;
sbt_ButonGenislik = 75;
sbt_ButonYukseklik = 25;
begin
{Dialog penceresini tüm unsurlarıyla birlikte üretir.}
if NOT Assigned (FPencere) then
FPencere := TForm.Create(Application.Owner);
with FPencere do begin
Position := poMainFormCenter;
KeyPreview := True;
Caption := Metin_Baslik;
ShowHint := True;
Width := 350;
Height := 130;
BorderStyle := bsDialog;
FormStyle := fsStayOnTop;
OnClose := FormClose;
OnShow := FormShow;
//OnPaint := PencereBoyutlandir;
//OnKeyDown := FormKeyDown; {Özel bir tuşa basılırsa...}
{ OnResize := PencereBoyutlandir; Bunu kullanmıyoruz, }
{ Çünkü nesne henüz "üretim" aşamasında olduğu için OnResize }
{ olayı anında devreye giriyor ve hata üretiyor. Bunu önlemek için }
{ bu kısma bir değer atamıyoruz. Belki OnPaint olayına tanımlanabilir. }
{ Show; Bunu özellikle çalıştırmadık... }
end;
if NOT Assigned (FLBL_Kullanici) then
FLBL_Kullanici := TLabel.Create(FPencere);
with FLBL_Kullanici do begin
Parent := FPencere;
Left := sbt_Padding;
Top := sbt_Padding + sbt_Aralik;
Height := 17;
Caption := Metin_Kullanici;
AutoSize := True; {Kendi genişliğini kendisi ayarlasın...}
Show;
end;
if NOT Assigned (FCMB_Kullanici) then
FCMB_Kullanici := TComboBox.Create(FPencere);
with FCMB_Kullanici do begin
Parent := FPencere;
Height := 20;
Top := sbt_Padding;
Left := FLBL_Kullanici.Left + FLBL_Kullanici.Width +
sbt_Aralik;
Width := FPencere.ClientWidth
- Left
- sbt_Padding;
if (FValue_Kullanci>'') then Text := FValue_Kullanci
else Text := '';
OnKeyPress := Klik_Tus;
Anchors := [akLeft,akTop,akRight]; { Pencere boyu değiştiğinde
uyum sağlasın }
Text := FValue_Kullanci;
Show;
end;
if NOT Assigned (FLBL_Sifre) then
FLBL_Sifre := TLabel.Create(FPencere);
with FLBL_Sifre do begin
Parent := FPencere;
Left := sbt_Padding;
Top := FCMB_Kullanici.Top +
FCMB_Kullanici.Height+sbt_Aralik+2;
Height := 17;
Caption := Metin_Sifre;
AutoSize := True; {Kendi genişliğini kendisi ayarlasın...}
Show;
end;
if NOT Assigned (FEdit_Sifre) then
FEdit_Sifre := TEdit.Create(FPencere);
with FEdit_Sifre do begin
Parent := FPencere;
Height := 20;
{şifremizi yazarken tepemizdekiler ne yazdığımız görmesin...}
PasswordChar := '?';
Top := FCMB_Kullanici.Top + FCMB_Kullanici.Height +
sbt_Aralik;
Left := FLBL_Kullanici.Left + FLBL_Kullanici.Width +
sbt_Aralik;
Width := FPencere.ClientWidth
- Left
- sbt_Padding;
if (FValue_Kullanci > '') then Text := FValue_Kullanci
else Text := '';
OnKeyPress := Klik_Tus;
Anchors := [akLeft,akTop,akRight]; { Pencere boyu değiştiğinde
uyum sağlasın }
Text := FValue_Sifre;
Show;
end;
if NOT Assigned (FBTN_Giris) then
FBTN_Giris := TButton.Create(FPencere);
with FBTN_Giris do begin
Caption := FMetin_Login;
Anchors := [akRight,akTop];
Parent := FPencere;
Width :=
TForm(Owner).Canvas.TextWidth(FMetin_Login)+(sbt_Padding*2); // 40
Height := sbt_ButonYukseklik;
Top := FEdit_Sifre.Top + FEdit_Sifre.Height + sbt_Aralik +
sbt_Padding;
Left := FPencere.ClientWidth - sbt_Padding - width;
OnClick := Klik_Giris;
Show;
end;
if NOT Assigned (FBTN_Kapat) then
FBTN_Kapat := TButton.Create(FPencere);
with FBTN_Kapat do begin
Caption := FMetin_Kapat;
Anchors := [akRight,akTop];
Parent := FPencere;
Width :=
TForm(Owner).Canvas.TextWidth(FMetin_Kapat)+(sbt_Padding*2);
Height := sbt_ButonYukseklik;
Top := FEdit_Sifre.Top + FEdit_Sifre.Height + sbt_Aralik +
sbt_Padding;
Left := FBTN_Giris.Left - sbt_Aralik - width;
OnClick := Klik_Kapat;
Show;
end;
if NOT Assigned(FBTN_Hatirlatici) then
FBTN_Hatirlatici:= TButton.Create(FPencere);
with FBTN_Hatirlatici do begin
Caption := FMetin_Hatirlat;
Anchors := [akLeft,akTop];
Parent := FPencere;
Width :=
TForm(Owner).Canvas.TextWidth(FMetin_Hatirlat)+sbt_Padding;
Height := sbt_ButonYukseklik;
Top := FEdit_Sifre.Top + FEdit_Sifre.Height + sbt_Aralik +
sbt_Padding;
Left := sbt_Padding;
OnClick := Klik_Hatirlat;
if (FHatirlatmaGoster = True) then Show else Hide;
end;
end;
procedure TupLoginDialog.OnMsg(var Msg: tagMsg; var Handled: Boolean);
begin
{ Ana forma burası aracılığıyla mesaj gönderiyoruz... }
case Msg.message of
WM_AFTER_SHOW:
begin
if (GetBilesenDurumu = 'Temel parametreler mükemmel') then begin
if not Assigned(FPencere) then Olustur;
Calistir;
end else begin
MessageBox(TForm(Owner).Handle,'Parametreler eksik veya yanlış
olabilir. Lütfen kontrol ediniz..','HATA',MB_OK+MB_ICONSTOP);
end;
end;
WM_AFTER_CREATE:
begin
if NOT (csDesigning in ComponentState) then
if (FOtomatikBaslat = True)
then PostMessage(TForm(Owner).Handle, WM_AFTER_SHOW, 0, 0);
end;
end;
end;
procedure TupLoginDialog.SetConnection(const Value: TAdoConnection);
begin
{ Malesef ADO (dbGO) bileşenlerini destekleyebiliyoruz. }
FConnection := Value;
end;
procedure TupLoginDialog.Sifirla;
begin
{ Anladınız siz bunu... }
FValue_Key := '';
FValue_Hesap := '';
FValue_Yetkiler:= '';
FValue_Kullanci:= '';
FValue_Sifre := '';
FValue_Pasif := FALSE;
end;
procedure TupLoginDialog.Sonuclar;
var
FADS: TAdoDataSet;
begin
{ Eğer temel parametrelerimizde herhangi bir pürüz yoksa sonuç alabiliriz...}
try
if (GetBilesenDurumu = 'Temel parametreler mükemmel') then begin
if NOT (csDesigning in ComponentState) then begin
FADS := TADODataSet.Create(Application);
with FADS do begin
Close;
Connection := FConnection;
CommandType := cmdText;
CommandText := GetSQL;
Open;
FGirebilir := NOT FADS.IsEmpty;
{ Sorgu sonucu BOŞ DEĞİL ve Sadece 1 KAYIT VAR İSE ! }
if (FGirebilir = True) AND (FADS.RecordCount = 1) then begin
if (FAlan_Key > '')
then FValue_Key := FieldByName(FAlan_Key).AsString;
if (FAlan_Hesap > '')
then FValue_Hesap := FieldByName(FAlan_Hesap).AsString;
if (FAlan_Yetkiler > '')
then FValue_Yetkiler:= FieldByName(FAlan_Yetkiler).AsString;
if (FAlan_Pasif > '' )
then FValue_Pasif := FieldByName(FAlan_Pasif).AsBoolean
end else begin
Sifirla;
end;
Close;
end;
FADS.Free;
end;
end;
except
// Hata verdirtmiyoruz...
end;
end;
procedure TupLoginDialog.Klik_Tus(Sender: TObject; var Key: Char);
begin
{ Klavyeden ESC'ye basıldığında KAPAT düğmesine basar}
{ ENDER'e basıldığında ise sonraki nesneye geçer... }
if (Key = #27) then Klik_Kapat(Sender) else
if (Key = #13) then begin
if (Sender = FCMB_Kullanici) then begin
if FCMB_Kullanici.Text>'' then begin
FEdit_Sifre.SetFocus
end;
end else
if (Sender = FEdit_Sifre) then begin
if (FEdit_Sifre.Text>'') then begin
FBTN_Giris.SetFocus;
FBTN_Giris.Click;
end;
end;
end;
end;
end.
T-SQL ile Dakikayı Metne Çevirmek
- 23 Kasım 2009 Pazartesi
- Uğur Parlayan
Bazı işleri veritabanına yaptırmak uygulamalara zaman kazandırabiliyor... Veriler üzerinde süre hesaplamak da bunların arasında sayılabilir, çünkü uygulama üzerinde süre hesaplamaktansa veritabanı tablosunu çekerken sürenin hesaplanmış olarak gelmesi hem hız, hem de performans açısından daha kârlıdır. Bununla birlikte bu tür işlere giriştiğinizde sunucunuzun da güçlü olması sıkıntılarınızı azaltabilir...
Aşağıda tanıtacağım kod, dakika (tamsayı) cinsinden verilen bir süreyi "Yıl + Ay + Gün + Saat + Dakika" cinsinden yazabilmenizi sağlıyor. Bir nevi dakikayı okunabilir bir metne çeviriyor. Kıytırık bir iş gibi gözükebilir fakat bu tür küçük şeylerle uğraşmak büyük sistemlerde kodların okunabilirliğini ve hataların çabuk giderilmesini sağlaması açısından gayet faydalıdır.
Şu an kullanmakta olduğumuz takvim konusundaki bilgiyi vikipedi'den edinebilirsiniz. Gevelemeden koda geçelim;
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
/********************************************************************************\
|* Dakika cinsinden süreyi metne çevirir. Küllim beleş ve paylaşıma açıktır... *|
|* Uğur PARLAYAN © 23.11.2009 Pazartesi *|
\********************************************************************************/
ALTER FUNCTION [dbo].[FN_STR_SureYaz] ( @Parametre INT )
RETURNS VARCHAR(MAX)
AS BEGIN
DECLARE @Sonuc VARCHAR(MAX)
, @ToplamDakika INT
, @ArtanDakika INT
, @ToplamSaat INT
, @ArtanSaat INT
, @ToplamGun INT
, @ArtanGun INT
, @ToplamAy INT
, @ArtanAy INT
, @ToplamYil INT
SELECT @ToplamDakika = ISNULL(@Parametre, 0) /* Tutarlılık için küçük bir önlem :) */
, @ArtanDakika = @ToplamDakika % 60
, @ToplamSaat =(@ToplamDakika - @ArtanDakika) / 60
, @ArtanSaat = @ToplamSaat % 24
, @ToplamGun =(@ToplamSaat - @ArtanSaat) / 24
, @ArtanGun = @ToplamGun % 30.436875
, @ToplamAy =(@ToplamGun - @ArtanGun) / 30.436875
, @ArtanAy = @ToplamAy % 12
, @ToplamYil =(@ToplamAy - @ArtanAy) / 12
SELECT
@Sonuc = CASE WHEN @Parametre<=0 THEN 'yok'
ELSE CASE WHEN @ToplamYil > 0 THEN CAST(@ToplamYil AS VARCHAR)+' yıl ' ELSE '' END
+ CASE WHEN @ArtanAy > 0 THEN CAST(@ArtanAy AS VARCHAR)+' ay ' ELSE '' END
+ CASE WHEN @ArtanGun > 0 THEN CAST(@ArtanGun AS VARCHAR)+' gün ' ELSE '' END
+ CASE WHEN @ArtanSaat > 0 THEN CAST(@ArtanSaat AS VARCHAR)+' saat ' ELSE '' END
+ CASE WHEN @ArtanDakika>0 THEN CAST(@ArtanDakika AS VARCHAR)+' dk' ELSE '' END
END
RETURN (RTRIM(@Sonuc))
END
Şimdi bir de bu fonksiyonun nasıl kullanıldığına dair kısa ve öz bir kaç örnek verelim...
/* Mesela 1 Ocak 1753'den şimdiye kadar olan süreyi yazdıralım */
SELECT dbo.FN_STR_SureYaz(DATEDIFF(minute,'17530101',GETDATE())) as [Geçen Süre]
/* Veya belli iki tarih arasındaki süreyi yazdıralım */
SELECT dbo.FN_STR_SureYaz(DATEDIFF(minute,'20090101','20091010')) as [Geçen Süre]
Geçen Süre
---------------------------------
256 yıl 7 ay 22 gün 14 saat 12 dk
(1 row(s) affected)
Geçen Süre
---------------------------------
9 ay 7 gün
(1 row(s) affected)
T-SQL ile Metinleri Parçalarına Ayrıştırmak
- 01 Eylül 2009 Salı
- Uğur Parlayan
Pascal ile metinleri en küçük parçasına ayrıştırmak başlıklı yazımda Parse işlemine yönelik bir teknikten bahsetmiştim. İlgili yazıya şuradan ulaşabilirsiniz. Aynı konuyu SQL'de nasıl yaparız sorusunu bazı arkadaşlar sormaya başlamış olabilir. Bu konudaki merakı gidermek adına doğrudan bir Kullanıcı Tanımlı Fonksiyon (UDF) tanımlayıp kaynak kodunu aşağıda veriyoruz. Gerekli açıklamaları kod içerisinden takip edebilirsiniz.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
/*********************************************************/
/* */
/* Bu fonksiyon, verilen bir metni kelimelerine ayrış- */
/* tırır ve sonucu bir tablo olarak kullanıcıya sunar. */
/* */
/* Uğur PARLAYAN */
/* */
/*********************************************************/
ALTER FUNCTION [dbo].[FN_TBL_KelimeListesi] (
@Parametre VARCHAR(MAX)
, @Ayraclar VARCHAR(100)
)
RETURNS @Sonuc TABLE (
[Sıra] INT IDENTITY(1,1)
, [Boy] INT DEFAULT((0))
, [Ayrac] VARCHAR(1) DEFAULT('')
, [Kelime] VARCHAR(MAX) DEFAULT('')
) AS BEGIN
DECLARE @Basamak INT
, @Boy INT
, @Ayrac VARCHAR(1)
, @Kelime VARCHAR(MAX)
, @Paragraf VARCHAR(MAX)
SELECT @Basamak = 1
, @Ayraclar = ISNULL(@Ayraclar, '%[ ,.:; '
+ CHAR(10)+CHAR(13)
+ '!?"()<&>={}\/*+`_-]%')
, @Paragraf = ISNULL(@Parametre, '')
WHILE @Basamak <> 0 BEGIN
/* En soldan başlayıp ilk ayracımızın hangi basamakta olduğunu buluyoruz */
/* Ardından bu haltı hangi ayraç yemiş onu buluyoruz */
SELECT @Basamak = PATINDEX(@Ayraclar, @Paragraf)
, @Ayrac = SUBSTRING(@Paragraf, @Basamak, 1)
/* Kelimeyi Soldan ayraca kadar alıyoruz */
IF (@Basamak <> 0) SELECT @Kelime = RTRIM(LTRIM(LEFT(@Paragraf, @Basamak - 1)))
ELSE SELECT @Kelime = RTRIM(LTRIM(@Paragraf))
/* Kelimenin boyunu posunu ölçüyoruz */
SET @Boy = LEN(@Kelime)
IF (@Boy > 0) BEGIN
/* Kelimemizi ve boyunu posunu tablomuza yazıyoruz */
INSERT INTO
@Sonuc ( Kelime
, Boy
, Ayrac
)
VALUES ( @Kelime
, @Boy
, @Ayrac
)
END
/* Aldığımız kelimeyi paragraftan siliyoruz */
SELECT @Paragraf = RIGHT(@Paragraf,LEN(@Paragraf) - @Basamak)
/* Paragrafta kelime kalmadıysa döngüden kaçıyoruz */
IF LEN(@Paragraf) = 0 BREAK
END
RETURN
END
Bu kodu kullanabilmek için ise şöyle bir SQL cümlesi kullanmamız yeterli;
SELECT *
FROM dbo.FN_TBL_KelimeListesi('Test,amaçlı!deneysel&veriler.', NULL)
Yukarıdaki sorgumuz ise şöyle bir sonuç tablosu üretecektir;
Sıra Boy Ayrac Kelime
----------- ----------- ----- ----------------------
1 4 , Test
2 6 ! amaçlı
3 8 & deneysel
4 7 . veriler
HatırlatmaBu sayfa test aşamasında olup deneysel veriler içermektedir.
Cıvıltılar- Herkes aynı fikirdeyse, hiç kimse yeterince düşünmüyor demektir
- Beleş malın ömrü kısa olur
- Bütün mucitler tembel olsaydı cilalıtaş devrine yeni girmiştik...
- Çaresizlik insana icat yaptırır...
- Yüzyılın Soykırımı
- Sparkfun elektronik 7 Ocak 2010'da 1000 kişiye 100$ değerinde hediye dağıtacakmış...
- Muharrem Ankara'da işbaşı yaptı, kendisine başarılı ve müreffeh bir iş hayatı diliyoruz :)
- Erhan'a da huzurlu ve mutlu bir ömür diliyoruz.
- MikroPascal'ın LCD kütüphanesinde ne tür bir sorun olabilir AÇAPAAAA! Nerede bu kodlar, nerede bu kaynak kodlar !!!
Sayfa Seç1 2 3 4 5 Toplam 5 sayfa var. Siz 1. sayfadasınız ve 13 kayıt içinden 1 ile 3 arasını görmektesiniz
Yazı MiktarıBu sayfada kaç adet yazı görmek istiyorsunuz? Aşağıdakilerden birini seçiniz 1
2
3
5
10
15
20
30
50
75
100
200
300
|