Arşiv Kapalı Excel Dosyasından Veri Alma (ADO)

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Arkadaşlar merhaba,
Excel kullanımı sırasında zaman zaman kullandığımız excel dışındaki dosyalara başvurmamız gerekebiliyor. VBA ile bu duruma çeşitli çözümler üretebiliyoruz elbette, fakat çözümler içerisinde çok pratik ve hızlı olan ama genelde dikkate alınmayan ADO yöntemini elimden geldiğince anlatmaya çalışacağım.

Öncelikle ADO'nun tanımı ile başlamakta fayda görüyorum;
ActiveX Data Object olarak adlandırdığımız VERİ NESNESİ'dir. Peki nedir bu veri nesnesi? Veri kaynağı ile kullandığımız arayüz arasında iletişimi kuran ve veri akışını sağlayan nesne olarak tanımlayabiliriz.

ADO nesnesini, vbe references penceresinden kullanıma açabiliyoruz;
References.jpg


ADO'yu kullanırken en sade hali ile 2 (iki) temel nesneye başvururuz.
Bunlardan bir tanesi "ADODB.Connection" nesnesidir.
Bir diğeri ise "ADODB.Recordset" nesnesidir.

Connection nesnesi adı üstünde veri kaynağımız ile bağlantı kurmamızı, iletişime geçmemizi sağlayan nesnedir.
Bir çok özellik, yordam içeriyor olmasına rağmen temelde işimize yarayacak özellik "ConnectionString" olacak.
Yine yordamlar içerisinde Open, Close yordamlarını sık sık kullanıyor olacağız.

Öncelikle connection nesnesinin değişken olarak tanımlama yöntemleri ile başlayalım. Bu yöntemler early binding ve late binding olarak ikiye ayrılır.

EarlyBindingLateBinding.jpg

ekran görüntüsünde de anlaşılacağı gibi early binding yönteminde dim tanımlaması yaparken nesnemizi oluşturmuş oluyoruz. Late binding yönteminde ise nesnemiz daha sonraki SATIR içinde set ile tanımlanmaktadır.

Late binding yönteminde ayrıca değişkenimiz önce object olarak tanımlanıp daha sonra CreateObject() ile de tanımlanabilir. Örnek;
Dim conn as Object
Set conn = CreateObject("ADODB.Connection")

aynı şeyler Recordset nesnemizi tanımlamak için de geçerli olacaktır.

(Bu süreçten sonra connection nesnemizden con olarak bahsedeceğim.)
nesnemizi tanımladıktan sonra sıra bağlantımızı açma ve kapamaya geldi. veritabanı ile bağlantı kurabilmek için kullanacağımız yöntem
con.open şeklinde olacaktır. Bağlantıyı gerçekleştirip yapmamız gereken işlemleri yaptıktan sonra ise con.close ile bağlantıyı kapatmamız gerekiyor.

con.open yönteminde ConnectionString parametresi ile veritabanı sağlayıcımızı, veri yolumuzu, güvenlik gibi bilgilerimizi tanımlamış olmamız gerekiyor. Bu tanımlamalarda herhangi bir hata yapmamız nesnemizin veri kaynağımıza bağlanamaması ile sonuçlanacaktır.

ConnectionString özelliğini önceden tanımlayabileceğimiz gibi bağlantı sırasında da tanımlayabiliyoruz.
Örnek olarak;
'bağlantı dizesini önceden tanımlama yöntemi
con.ConnectionString = "Bağlantı dizemiz"
con.open


'bağlantı dizesini bağlanırken tanımlama yöntemi
con.open "Bağlantı dizemiz"

Peki oldukça uzun olan bağlantı dizemizi ezberlememiz mi gerekiyor? Hayır. bunun için sitesinden bize uygun olan bağlantı dizesini bulup kopyalayabiliriz. Kopyaladığımız bağlantı içindeki veri yolunu kendi veritabanımıza göre düzenlememiz gerekir.

Önemli Not: anlatım sırasında örnekler, dosyalar paylaşacağım. Paylaştığım örneklerden kendi sistemime uygun bağlantı dizeleri gerçekleştireceğim. İnternette bulduğum örnek verisetleri üzerinde işlemler yapacağım.

Kaynaklar:
Verisetleri için başvurduğum
Kaynağım içerisinden örnek olarak kullandığım verisetleri; FoodSales, WorkOrders, Orders, InsurancePolicy olacaktır. Benimle birlikte bu örnekleri gerçekleştirmek isteyenlerin bu tabloları sisteminde hazır bulundurmalarında fayda vardır.

İlk konumu burada tamamlıyorum. Konunun devamını vakit buldukça "AYNI BAŞLIK" altında devam ettireceğim. Yaptığımız bu başlangıcın üzerine kata kata gideceğiz diye umuyorum.

Konuyu tamamlamadan önce veritabanımıza ilk erişimimizi yapalım ve öyle kapatalım.

İlk olarak FoodSales veritabanına erişelim. Benim FoodSales veritabamınım konumu "D:\VBA\ADO" şeklinde olduğu için ben bağlantı dizelerimde bu yolu kullanacağım.

Veritabanına bağlantı kodu;

CSS:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
 

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
ADO nesnemiz kapalı excel dosyamızı veritabanı olarak kullanacağı için bir takım kurallara riayet etmemiz gerekiyor. Bu konuda en çok dikkat etmeniz gereken konu ise veritabanı normalizasyonu olacaktır.
En temelde iki farklı amaca hizmet eder; ilk olarak veri tekrarının önüne geçmek, ikinci olarak ise veri tutarlılığına zorlamak.

Her sayfa ADO için bir tablo niteliği taşımaktadır. Sayfa içerisindeki her bir SATIR recordset (kayıtseti), her bir sütun ise field (alan) olarak tanımlanmaktadır.
Verilerimizin normalizasyon kuralına uyması için her bir alanın bir veri türüne ayrılmış olması elzemdir. Yanlış ve Doğru kullanım için örnek verecek olursak;
YanlışAlanKullanımı.jpg
Her bir alan (sütun) bir veri türüne ayrılmış durumdadır. Bu veri türleri metin, sayı, para birimi, tarih gibi türler içerir. Üstteki resimde görüldüğü gibi 2. 3. ve 4. kayıt setlerinde OrderDate alanı veri normalizasyonu kuralımıza uymamaktadır. Tarih için ayrılmış alanımıza metin veri türünde değerler girilmiştir ve veritabanı işlemlerimizde hatalı sonuçlar almamıza yol açacaktır.
Doğru kullanım için;
DoğruAlanKullanımı.jpg
2. paylaştığım resimde ise verilerimiz doğru alanlara doğru şekilde girilmiştir.
Her bir alanın bir veri türüne ayrılması veri tutarlılığına zorlama amacına hizmet eder.

Ayrıca veritabanı yönetiminde tablolarımız primary key (birincil anahtar), foreign key (ikincil anahtar) ve unique key (benzersiz anahtar) anahtar alanlar içerebilir. Kullandığımız bir çok tabloda bu anahtarlara ihtiyacımız olacaktır.

Primary Key = Her kayıt için bir kimlik numarası niteliğinde benzersiz (birden fazla kayıt setinde tekrar etmeyen) değerler alabilir. Genel olarak 1 den başlayarak devam eden ardışık sayı değerleri alabildiği gibi benzersiz metin değerleri de alabilmektedir.

Primary Key için her bir vatandaşın sahip olduğu T.C. Kimlik Numaraları örnek olarak verilebilir.

Foreign Key = Kullanıldığı tabloda birden fazla kullanıma izin verebilen anahtardır. Bir başka tablo içindeki Primary Keyi referans alır. İlişkisel veritabanlarında tablolar arası ilişki kurmak için kullanılır.

Foreign Key için örnek olarak;
Elimizde SatisTemsilcisi adında bir tablo ve bir de Satislar adında bir tablo olsun. Herhangi bir satış temsilcisinin birincil anahtarı, temsilcimiz bir çok satış yapacağı için satış tablosundan birden fazla geçebilir. Satış tablosundaki her bir kaydı satış temsilcimiz ile ilişkilendirmiş oluyoruz.

Veritabanı normalizasyonu konusuna çok küçük de olsa bir giriş yaptık ve bundan sonraki konumuzda artık veritabanından veri getirmeyi öğrenmiş olacağız.
 

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Şimdiye kadar anlatılanlar arasından anlaşılmayan konular olmuştur, bunu aşmak için biraz zamana ve sabıra ihtiyacımız var. Konular ilerledikçe bu problemi çözmüş olacağız.

Şimdiye kadar bağlantı oluşturmayı ve veritabanı normalizasyonu konularına değildik, bundan sonrası için ise SQL (Structured Query Language) Türkçesi ile (Yapılsal Sorgulama Dili) diline ihtiyacımız olacak.

Haydaaa VBA ile başa çıkamıyoruz nerden çıktı şimdi bu SQL dili? Demediğinizi varsayarak küçük bir giriş yapıyorum;
Sql sorgularında temel bir kaç sorgu türü vardır bunlar seçme sorguları, ekleme sorguları, silme sorguları ve güncelleme sorgularıdır.

Seçme sorguları SELECT ile, ekleme sorguları INSERT INTO ile, silme sorguları DELETE ile ve son olarak güncelleme sorguları UPDATE ile ifade edilir.

Son olarak veriler ile çalışmaya başlamadan önce değinmemiz gereken bir konu daha mevcut. Bu konuya kısaca bir değindikten sonra bir sonraki gönderide artık verilerle çalışmaya başlıyor olacağız. Ayrıca konunun girizgahı biraz sıkmış olabilir, uzun sürmüş olabilir ama konuyu sağlam temellere oturtmak açısından bu biraz gerekli bir durum malesef.

Recordset nesnemizden bahsetmiştik. Recordset nesnemiz de con nesnemiz gibi Open, Close yordamları ile çalıştırılır genelde. con nesnemizde nasıl connectionstring parametresine ihtiyaç duymuşsak rs (bundan sonrası için recordsetten rs olarak bahsedeceğim) nesnemizde de query yani sorgu parametresine ihtiyaç duyarız. İhtiyacımıza göre hazırlamış olduğumuz sorgumuzu rs.open yordamında kullanarak kayıtsetimize ne yapmaya çalıştığımızı anlatmış oluyoruz bir nevi.
con nesnesinden farklı olarak rs nesnemizde cursortype ve locktype parametrelerine de ihtiyaç duyuyoruz. Kısaca değinecek olursak.

CursorType:
adOpenForwardOnly=
Varsayılan olarak kullanılan cursordur. Yalnızca ileriye dönük işlem yapabilirsiniz. Bir kayıt kümesinde yalnızca ileriye dönük bir işlem yapma ihtiyacımız olduğunda performans açısında daha kullanışlı bir cursortype dır.

adOpenKeyset= Kayıtlar üzerinde ileri ve geri hareket edebilen cursordur fakat diğer kullanıcıların yaptığı değişiklikleri görmemizi sağlar, aynı zamanda yerel bir kopya üzerinde işlem yaptığımız için veriler üzerinde değişiklik yapamayız.

adOpenDynamic= Kayıtseti üzerinde herhangi bir değişiklik yapıldığında (yapılan değişikliği hangi kullanıcının yaptığından bağımsız olarak) yapılan değişikliğe anında erişim gerektiren durumlarda kullanılır. Birden çok kullanıcının vertabanına aynı anda işlem yapması gerektiği durumlarda kullanılır.

adOpenStatic= Veritabanı üzerindeki kayıtların statik bir kopyasını oluşturur ve daha önceki

LockType:
adLockReadOnly=
Veri üzerinde sadece okuma yapmaya izin verir.

adLockPessimistic= Güncelleme gerçekleştikten sonra kayıt kilitlenir.

adLockOptimistic= Sadece güncelleme sırasında kayıt kilitlenir.

Evet böylece anlaşılmayan, soyut kalan teknik terimlerden kurtulmuş oluyoruz. Bir sonraki anlatımlarımızda veriler üzerinde çalışmaya başlayacağız.
 

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Artık ilk verimizi çekmenin zamanı geldi.
Şimdiye kadar öğrendiklerimize istinaden verileri görüntülemek istediğimiz excel dosyasında kullanacağımız kod yapısı aşağı yukarı aşağıdaki şekilde görünecektir.


CSS:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

genel yapımız bu şekilde görünecek.

Şimdi SQL ifadelerine kısa bir göz attıktan sonra ilk sorgumuzu çalıştıralım. Örnek olarak veritabanımızdaki FoodSales tablosunda bulunan bütün kayıtları getirme ile başlayalım. (Bütün alanları ve bütün kayıtları getirme ile başlayalım)

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.


query değişkenine atayacağımız seçme sorgusu;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Şimdi gelin bu sorguyu uygulayıp aktif çalışma sayfamıza verileri getirelim.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Bu kodu uyguladığımızda görebiliyoruz ki veritabanı olarak kullandığımız excelin açık olmasına gerek kalmadan bize gereken verileri alabiliyoruz.

Aktif çalışma sayfamızda A2 hücresinden itibaren sola ve aşağıya doğru bütün verilerimizi getirebildik.
 

Adnan

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
1,513
Çözümler
267
Aldığı beğeni
1,523
Excel Versiyonu
Office 365 TR
Ellerinize sağlık. Oldukça güzel hazırlanmış emek verilmiş doyurucu bilgi içeren bir yazı. Teşekkürler
 

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
SELECT Sorgularında elbette tek yapabildiğimiz bütün kayıtları getirmek değil. Bu sorgu ile kendi belirlediğimiz kriterlere göre kayıtları filtreleyerek getirebiliyoruz.

Bu kriter belirlemeyi sorgu içerisinde WHERE ile gerçekleştiriyoruz. Bunun için WHERE tek başına yeterli olmadığı için WHERE deyimi ile birlikte "<", ">", "=", "IS NULL", "IS NOT NULL" gibi mantıksal operatörlere de ihtiyacımız var.

Şimdi gelin bir önceki örnekte yazmış olduğumuz
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Sorgusuna WHERE şartı ekleyelim.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Yukarıda gördüğünüz mantıkta WHERE şartımızı kuralım. Bunun için Region alanını ve = operatörünü kullanalım.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Region alanı "West" e eşit olanları filtreleyerek kayıt setimizin içine alacağız.

Bu bilgiler ışığında daha önce yazmış olduğumuz kod içerisinde sadece query değişkeni üzerinde değişiklik yapmamız yeterlidir.


Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Bir önceki kodun aksine kalabalık görünümü azaltmak için yorum satırlarını kaldırdım. Artık kodlarımızın hangisinin ne işe yaradığını biliyoruz. Ve bu paylaştığım kodu içeren çalışma kitabı ile Veritabanını dosya olarak paylaşacağım.
 

Ekli dosyalar

  • FoodSales.zip
    98.7 KB · Gösterim: 66

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Bir önceki mesajımda paylaştığım dosyada Module1 üzerinde düzenleme yapıyoruz, sonuç almayı userform üzerindeki listbox üzerinde yapıyoruz.

Module1 üzerinde hazırlayacağımız kodların listesi userform üzerindeki combobox listesinde çıkacaktır. Bu combobox listesinden hazırladığımız kodları seçip sonuçlarını görüntüleyebiliriz.

Evet WHERE şartına devam edebilriz. Bir önceki derste bahsetmeyi unuttuğum bir konu var, hemen onunla başlayalım. WHERE şartında metin araması yaparken metnimizi ' (tek tırnak) işaretleri arasına yazmak durumundayız. Rakamsal değerler için buna ihtiyacımız yok.

Evet şartımızı göz önünde bulundurarak sorgumuzu yazdık ve sorgumuz bize doğru sonuçları getirdi. Peki bizim her zaman tek bir şartımız mı olacak? Birden fazla şartımız olması durumunda ne yapacağız? Bunun için WHERE şartı içinde AND operatörü ya da OR operatörünü kullanıyoruz.

Önemli Not: Yazdığım sorguları burada numaralandırıyorum. Paylaşacağım dosyadaki kodları da sorgularla aynı numara yapacağım, ve böylece hangi sorguyu nerede arayacağınızı bileceksiniz.

Şimdi FoodSales veritabanımızdan Region'u West olan ve Category'si Cookies olan verilerimizi getirelim. Bunun için Sorgumuz aşağıdaki gibi olacaktır.
No:1:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Evet iki şartımızın arasına AND operatörü koyarak elimizdeki tek kiriteri ikiye çıkarmış oluyoruz.


Şimdiki şartımızda ise Region'u yine West seçelim fakat diğer şartımıza da Quantity'nin 100 üzerinde olması olsun. Fakat verimizi getirmesi için ilk şarttan ya da ikinci şarttan herhangi birini yerine getiriyor olması yeterli olsun.

No:2:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Daha önce hep = operatörü ile iş yapıyor iken şimdi büyüktür operatörünü görüyoruz. Bu operatör tek başına kullanıldığı gibi aynı zamanda ">=" ve "<=" şeklinde de kullanılabilir. Anlamları ise "Büyük Eşittir", "Küçük Eşittir"i temsil etmektedir.

Son olarak LIKE operatöründen den bahsederek konuya şimdilik son verelim. Metinsel ifadelerde şimdiye kadar hep = operatörünü kullandık fakat metinsel ifadelerde şartımız bazen metnin tamamı olduğu gibi bazen de metnin bir kısmı olabiliyor. Bunu gerçekleştirebilmek için LIKE operatörü ve yanında metinsel operatörleri kullanıyoruz.

Metinsel operatörler için temelde "%" ve "_" operatörleri kullanılır. Söz konusu operatörler ile ilgili bir kaç örnek sunmak gerekirse;
No:3:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
% işareti kendisinden sonra gelen herhangi bir değeri filtremize dahil eder. Yani yukarıdaki sorgumuz Category alanındaki değerin C ile başlamasına dikkat edecek ve geri kalan değerlerin ne olduğuna dikkat etmeyecek.

No:4:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Yukarıdaki sorgumuz ise Product alanında kelime içerisinde herhangi bir yerde geçen "an" metinlerine dikkat edecek ve sadece söz konusu kayıtları getirecek.

No:5:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
"_" operatörü de "%" operatörü gibi harfin ne olduğuna bakmıyor fakat tek fark olarak tek bir karakter için bunu gerçekleştiriyor.
yani yukarıdaki sorgumuz 1. ve 2. harfinin karakterin ne olduğu önemli değil şartı , 3. ve 4. harfi "an "olsun şartı ve yine kelimenin geri kalanı ne kadar uzun olursa olsun, hangi karakter olursa olsun şartı getirir.

Anlatımlarla ilgili yaptığım çalışmayı dosya olarak paylaşıyorum. "%" ve "_" ile ilgili örnekleri deneme yanılma yolu ile dilediğiniz kadar çoğaltabilirsiniz. Zira en iyi öğrenme yolu (bana göre) deneme yanılma yoludur.
 

Ekli dosyalar

  • FoodSales.zip
    101 KB · Gösterim: 26

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Şimdiye kadar SELECT ve WHERE sorgu ifadelerine göz attık. Biraz da kendi denemelerinizle konuyu biraz daha pekiştirdiğinizi düşünüyorum. Herhangi bir deneme için kurmuş olduğunuz sorgu ifadeleri çalışmadığında "ben yapamıyorum", "sorgu ifadesi kuramıyorum" gibi ümitsizliğe kapılmayın. Günlerce üzerinde çalışmış olmama rağmen ben de bir çok defa hatalar yaptım ve hala yapıyorum, fakat öğrenmek için yine de vazgeçmedim. Siz de vazgeçmeyin.

EĞER hatalar ile karşılaşıyorsanız ve sormak istediğiniz sorular var ise özel mesaj yolu ile ya da talep olursa "kapalı excel dosyasından veri alma ado soru" adında bir başlık açarak soru sorabilirsiniz.

Şimdi gelelim yeni konularımıza. Excelde bulunan =TOPLA(), =EĞER() işlevleri gibi SQL sorgu dilinde de bir takım fonksiyonlara yer verilmiştir. Bunlardan bazıları SUM, AVG, IIF, ISNULL, CONCAT, MONTH, YEAR gibi excel fonksiyonlarına benzeyen ifadelerdir. Kullanmak istediğimiz formülü uygulamak istediğimiz alanın başına yazarak kullanırız.
No:6
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu sorgumuz bize sattığımız toplam miktarı vermektedir.

Peki Sattığım ürünlerin tamamını değil de sadece bir kısmını toplamak istersem ne yapmalıyım? Örnek bir sorgu ile konuyu netleştirelim;
no:7
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Belli bir kısım veriyi toplamak için daha önce öğrendiğimiz WHERE ifadesinden yardım alıyoruz. Sorgumuz önce Product alanında Carror değeri olan kayıt setlerini bizim için filtreledi ve filtrelediği değerlerin Qunatity değerlerini topladı. Böylece dilediğimiz alandaki rakamları toplamış olduk.

Yine TOPLAMA işlemimizde Bir ifade için filtre yapabilmenin yanında birden fazla ifade için de filtre yapabiliriz.


no:8
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu sorgumuzda Carrot ve Bran ürünlerinin toplamını aldırabiliyoruz. Bu sorgudan sonra akıllara bir soru gelmiş olabilir. Nedir o soru? Benim aynı alan içinde onlarca kriterim varsa bunlar için tek tek;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
sorgusundaki gibi arka arkaya OR kullanmam mı gerekir? Bu sorunun cevabı tabiki hayır olacaktır. Bu tür durumlar için IN ifadesine başvuruyoruz.

no:9
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Koşul ifademizden sonra alan adımızı kullanıyoruz. Ardından IN ifadesini kullandıktan sonra parantezi içinde aralarında virgül olacak şekilde değerlerimizi yazıyoruz.
9. ve 8. sorguları çalıştırdığımızda aralarında herhangi bir fark göremeyeceksiniz.

Son iki sorgumuzda Carrot ve Bran ürünlerinin toplamını tek bir veri içerisinde gördük. Her iki ürünün de toplamlarını farklı verisetleri içerisinde görmek istersek yeni bir sorgu ifadesine göz atmamız gerekecek. Yeni sorgu ifademiz GROUP BY bkz;

no10:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
SUM() AVG() gibi formülleri tek bir alan seçerek kullandığımızda formüllerimiz sorunsuz çalışacaktır. Fakat SUM() işlemini yaptığımız alan dışında farklı alanlar seçtiğimizde SUM() ifadesi bize "toplam alayım ama hangi kritere göre toplam alayım" diyerek biraz bozulabilir. Dolayısıyla biz kullandığımız SUM() fonksiyonuna hangi kritere göre TOPLAMA yapacağını GROUP BY ifadesi ile söylüyoruz. Söz konusu ifade kendinden sonra gelen alan ad(lar)ına göre verilerimizi gruplayacaktır.

GROUP BY ifademizle bir alana göre gruplandırma uygulayabileceğimiz gibi birden fazla alana göre de gruplandırma uygulayabiliriz. Bkz;
no:11
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

10 no lu sorgumuzdan farklı olarak alan seçimimize Region alanını da dahil ederek toplam aldırdık. Fonksiyon kullandığımız bir sorguda Fonksiyon içermeyen bütün alanları GROUP BY içine dahil etmek ZORUNDAYIZ.

Yanlış kullanıma bir örnek;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu ifademiz bize herhangi bir veri döndürmeyecektir. Hatta rs ifademiz açılmayacaktır.

GROUP BY ifadesindeki sıralamanın yaptığımız sorguda ne gibi değişikliklere yol açacak hadi bir de ona göz atalım;
no:12
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bir önceki ifademizde önce Region sonra Product alanlarını gruplandırma yapmıştık. Şimdi ise Önce Product sonra Region alanını gruplandırma yaptık. Bu sorgumuzda neye yol açtı?
İlk sorgumuz önce region değerlerini aldı ve regionlara göre product toplamlarını aldı, ikinci sorgumuz ise önce product alanlarını aldı ve product alanlarına göre region toplamlarını aldı. Bu ayrım hangisine göre sıralama yapacağımızı değiştirdi.

Sıralama demişken bu gönderimizde ORDER BY ifadesine değinmeden geçmeyelim. ORDER BY ifadesi sorgularımızda verilerimizi küçükten büyüğe, büyükten küçüğe sıralama yapacağı gibi A dan Z ye, Z den A ya sıralama yapabilmektedir.

no:13
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

ORDER BY kullanırken ASC ve DESC ifadeleri karşımıza çıkar. ASC ifadesi küçükten büyüğe (A dan Z ye) DESC büyükten küçüğe (Z den A ya) sıralama yapar. fonksiyon ve GROUP BY kullandığımız ifadelerde ORDER BY kullanmasak da default olarak ASC olarak sıralayacaktır.

Kişisel Not: ADO bize performans sunmanın yanında veriler üzerinde kolaylıkla çalışmamızda da yardımcı oluyor. Şimdiye kadar paylaştığım dosyaların içindeki kodlara bakacak olursanız, birbirinin aynı kodlar içerisinde sadece sorgu ifadelerini değiştirerek bir çok farklı veriyi listeleme şansı elde ettik. Kişisel kanaatime göre ADO yu kullanmaktan ve öğrenmekten geri kalmayın. Elbette her projenin içine ADO yu sokuşturmak zorunda değiliz ama bir çok veri takibinde işimize fazlasıyla yarayabileceği aşikardır. Bu konuyu da burada bitiriyorum. Yeni sorgu ifadeleri ile yeni derslerde görüşmek üzere.

Son Not: Daha önce FoodSales verilerini içeren dosyayı paylaştığım için bu seferki mesajımda sadece Çalışma Sayfası dosyasını paylaşıyorum. Daha önce FoodSales verilerini içeren dosyayı indirmemiş olanlar önceki mesajımdaki zip dosyasına göz atabilirler.
 

Ekli dosyalar

  • Çalışma Dosyası.xlsm
    38.9 KB · Gösterim: 24
Son düzenleme:

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Şimdiye kadar epey ilerlememize rağmen biraz geriye dönüp; veri, veritabanı ve ilişkisel veritabanı gibi terimler üzerinde biraz durmak istiyorum. Çünkü ne kadar güzel bir kodlama yaparsak yapalım, ne kadar güzel sorgular yazarsak yazalım yaptığımız işin en başında kullanacağımız veritabanını doğru tasarlamazsak mutlaka bir yerlerde bu hatamız karşımıza ciddi sorunlar olarak çıkacaktır.

Konu başlığının "kapalı excel dosyasından veri alma" olduğuna bakmayın. Bu yöntemle SQL Server, Access, Azure DB vb. veritabanlarından veri alabiliyoruz. Hatta txt uzantılı text dosyalarını bile okuyabiliyoruz.

Veri Nedir?
bize veriyi aşağıdaki gibi açıklamaktadır.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Açıklamadan da anlaşılacağı gibi veri tek başına herhangi bir şey ifade etmemektedir.
Daha anlaşılır olması açısından "10.03.2021" tarihi tek başına herhangi bir anlam ifade etmiyor. Fakat biz bu verimizi farklı bir veri ile eşleştirirsek biraz daha anlam kazanacaktır. Bu tarihi aşağıdaki gibi bir yapıya çevirirsek biraz daha anlam kazanmaya başlayacaktır;

Kullanıcı AdıKayıt Tarihi
aeGNoR10.03.2021
Yukarı da da görüldüğü gibi 10.03.2021 tarihi kullanıcı kayıt tarihi olarak anlam kazanmış durumdadır. Bu verileri diğer kullanıcıların da kayıt tarihleri ile doldurmaya başladığımızda işte bu verilerimizin tamamı veritabanı yapısına dönüşmektedir.

Veritabanı nedir?
açıklaması ile başlayalım.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Buradaki temel konumuz veritabanı tablolarında bulunan verilerin birbirleri ile ilişkisinin olmasıdır. Örnek verecek olursak bugün ülke genelindeki yaşanan depremlerin verisi ile telefonumuzdaki kişilerin e-posta bilgileri birbirleri ile ilişkili veriler değildir. Dolayısı ile veritabanımızdaki verilerin birbirleri ile ilişki içinde olması elzem bir konudur.

Burada yaşanabilecek problemlerden bir tanesine örnek verecek olursak;
(Log tutmayan bir veritabanı sisteminde) Bir poliklinik veritabanı tasarlıyoruz diyelim, bu veritabanında "tblHasta" adını verdiğimiz bir tablo olsun. Biz bu tabloda bulunan alanlara en başında "Oluşturma Tarihi" "Oluşturan Kişi" ve "Değiştirme Tarihi" "Değiştiren Kişi" gibi alanlar açmadığımızı varsayalım. Binlerce hasta kaydı bu veritabanına işlendikten sonra hastaların ilk kayıt tarihi ve kaydeden kişi, üzerinde değişiklik yapılma tarihi ve değişiklik yapan kişi bilgilerine erişme ihtiyacı doğarsa karşımıza ciddi bir sorun çıkmış demektir. Bundan sonraki süreç için veritabanımıza bu alanları ekleyebiliriz belki fakat daha önceki kayıtlarda bu bilgilere asla erişemeyiz.

Yukarıda verdiğim örnekte de görüleceği gibi bir veritabanı tasarımında ihtiyacımız olabilecek "her bilgi" mutlaka en ince ayrıntısına kadar düşünülmeli ve veritabanı yapımız (veritabanı şemamız) buna göre şekillenmelidir.

Veri modelleme?
tanımına göz atalım.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Oldukça uzun bir tanıma sahip olan veri modelleme bir kaç farklı konuya ayrılmaktadır. Burada sık kullanılan ilişkisel-veritabanı anlatılacaktır.

İlişkisel veritabanı?
her zamanki gibi tanımına bakalım. Bu tanımı burada paylaşmaya lüzum görmüyorum. wiki bağlantısından görebilirsiniz.

Daha önce bahsettiğimiz gibi ilişkisel veritabanlarında veriler tablo şeklinde tutulurlar. Hemen bir örnekle anlatımı somutlaştıralım;
Bir kütüphane veritabanında "tblKitap" adında bir tablomuz var bu tabloda kitabın ISBN kodu, Adı, Yayın Tarihi vb. bilgileri tutuyoruz. Kütüphane envanterinde kayıtlı kitapların okuyuculara belirli bir süreliğine emanet verildiği sürenin sonunda geri alındığını biliyoruz. Biz bu bilgiyi "tblKitap" tablosunda tutmaya çalışırsak son emanete veriliş tarihini ve son emanetten alınış tarihini görebiliriz. Halbuki daha önceki emanete verilme ve alınma tarihlerine de ihtiyaç duyabiliriz. Bunun için "tblEmanet" tablosu oluşturup "tblKitap" tablosu ile ilişkilendirmemiz gerekecektir. (Buradaki örnek konuya özel olduğu için aslında ihtiyaç duyulan bir çok tabloyu dikkate almayacağız)

Screenshot_1.jpg
Yukarıdaki resimde de anlaşılacağı üzere "tblKitap" tablosundaki "ISBN" birincil anahtarımız "tblEmanet" tablosundaki "ISBN" ikincil anahtarımız ile ilişkilendirilmiştir. Böylece kütüphanemizde bulunan kitapları her emanete verdiğimizde yeni kayıt açılacak ve eskiye dönük emanet kayıtlarına erişebilmiş olacağız.
Bu örnekte olması gereken fakat anlatımı sade tutmak için oluşturmadığım bir çok tablo düşünülebilir. Bkz: "tblÜye", "tblPersonel", "tblKutuphane", "tblYayinci", "tblYazar", "tblTur" vb.


Bütün bu anlatımların sonunda anlaşılacağı üzere, daha sonra ihtiyacımız olacak bütün verileri tutmamızın önemli bir mesele olmasının yanında tutacağımız verilerin hangi koşullarda ve nasıl tutulacağı da bir o kadar önemli bir meseledir.

Bu konu benim anlatımımla (ya da bir başkasının) bizzat anlaşılabilecek meseleler olmayabilir. Çeşitli veritabanları tasarlayarak (bkz: "kütüphane", "hastahane", "stok", "muhasebe", "pazarlama", "satış" vb. ) ve tasarlanan bu veritabanları üzerinde kodlamalarla çalışmalar yürüterek anlaşılabilecektir.

Yine kişisel not: İyi bir anlatıcı olmadığımın farkındayım, dolayısıyla anlatımım konusunda eleştirilerinize her daim açığım. Buradaki maksadımızın sizlerin daha iyi anlaması olduğunu unutmayın.
 

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Sorgulara verdiğimiz kısa bir aradan sonra tekrar devam ediyoruz.

SQL Sorgularında bulunan bütün fonksiyonları anlatmak oldukça uzun süreceği için üzerinde bir kaç tanesi ile çalışmak istiyorum sadece.
Şimdiye kadar SUM üzerinde çalıştık. Bundan sonrası için bir kaç farklı sorgu paylaşıp, paylaştığım sorgular altında sorgularımızın ne işe yaradıkları hakkında kısa kısa bilgiler vereceğim.

no:14
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
COUNT fonksiyonu ile ilk adımımızı atalım. COUNT fonksiyonu kelime anlamı itibariyle de (saymak,miktar) anlamına geliyor zaten. Yukarıda yazdığımız kod ise bize FoodSales tablosundaki verilerin sayısını vermektedir. Parantez içinde * kullanabileceğimiz gibi herhangi bir alan adını da yazsaydık sonuç bizim için değişmeyecekti.

no:15
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
SUM fonksiyonunda kullandığımıza benzer şekilde, COUNT fonksiyonumuza da WHERE koşulları ekleyerek sadece belirli değerleri içeren kayıtları saydırabiliriz. Bu sorgumuzda Region değeri West olan kayıtlarımızın sayılarını bulmaya çalıştık.

Şimdiye kadar SUM sorgumuzda pek çok koşul ifadesine yer verdiğimiz için bundan sonra öğreneceğimiz COUNT sorgusunda hepsine tek tek değinmeyeceğim. Benzer şekilde sorgu kurulduğu için. Sadece günlük hayatta işimize yaraya bileceğini düşündüğüm bir kaç şeklini paylaşacağım sizlerle.

no:16
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

SUM konusunu anlatırken değinmediğim bir konu burada gözünüze çarpmış olabilir. SUM konusunu anlatırken ORDER BY ile sıraladığımız bütün sorgularda sıralama ölçütümüz hep fonksiyon kullanılmayan alanlardı. Şimdi ise fonksiyon uyguladığımız alan üzerinde ORDER BY uyguluyoruz. Herhangi bir şekilde SUM() AVG() COUNT() gibi fonksiyonları kullandığımız alanlara göre sıralama yapacaksak aynı fonksiyonu ORDER BY ifadesinden sonra da kullanmamız gerekir. Yazmış olduğumuz bu sorgu tam olarak "hangi üründen kaç defa 100 adetin üzerinde satış yaptık?" sorusunun cevabıdır.

no17:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
16. sorguda gördüğümüz ORDER BY içerisinde fonksiyon kullanmak zorunluluğunu öğrendikten sonra öğrenmemiz gereken konulardan biri ise sıralamanın sadece tek bir alana göre değil, birden çok alana göre de yapılabildiğidir. Sorgumuz birden fazla alana göre sıralama yapacak fakat önce hangi alanı dikkate alarak sıralama yapacak? Buradaki ayrım ise ORDER BY dan sonra kullanılan alan isimlerinin sıralamasında önemli bir hal alıyor. Hangi alanı diğer(ler)inden önce sıralamasını istiyorsanız o alanı diğer(ler)ine göre ORDER BY ifadesine daha yakın tutmalısınız. Ayrıca sıralama yapacağınız her alan için ASC ve DESC ifadelerini kullanmanız istediğiniz veri setine daha doğru şekilde ulaşmanıza yardımcı olacaktır.

18. sorgu ile birlikte TOPLAMA, sayma gibi fonksiyonların dışına çıkarak biraz daha farklı sorgular üzerinde çalışalım.
no18:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu sorgumuzda HESAPLANMIŞ ALAN kullandık. Nedir bu hesaplanmış alan? Veritabanımızda bulunan tabloda Region ve City değerlerini tek bir alanda gösteren bir alanımız olmamasına rağmen, böyle bir şeye ihtiyacımız olduğunda iki alanı birleştirerek kullandık. İki alanı birleştirmek için kullanacağımız ifade ise + ifadesidir.
NOT: + ifadesi string değer içeren alanları birleştirmek için kullanılırken sayısal değer içeren iki farklı alanda kullanıldığında TOPLAMA işlemi yapacaktır.

Hadi gelin biraz daha karmaşık hesaplanmış alan sorgusu yapalım.
no19:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu sorgumuz ile birlikte biraz daha karmaşık olan sorgulara geçmişiz gibi görünüyor. Yazılışı biraz daha karmaşık gibi görünebilir fakat bu gözünüzü korkutmasın. Sorgumuzu parça parça ele alırsak aslında ne kadar da basit bir sorgu yazdığımız ortaya çıkacaktır.
Peki başlıyoruz, bu sorgumuzda biz ne yaptık?
1. alanda Product alanımızı seçtik
2. alanda TotalPrice alanımızı seçtik
3. alanda TotalPrice alanımızı seçtik fakat tek bir farkla, seçtiğimiz bu alanın 0.08 değeri ile çarpımını sonuç olarak getirmesini istedik. (Her ürüne %8 kdv uyguladık diyebiliriz.)
4. alanda ise gerçek TotalPrice değerimizi aldık, bu değeri yine TotalPrice'ın 0.08 ile çırpımı ile topladık. (Sonuç olarak TotalPrice değerimizin üzerinde %8 daha ekleyerek sonuç elde ettik.)

4. alan olarak kullandığımız hesaplanmış alandaki () parantezleri neye göre koyduğumuzu, koymanın zorunlu olup olmadığını merak edebilirsiniz. Hemen cevaplandıralım. Öncelikle bu parantezleri koymamız zorunlu değildir. Kendinden önceki "," den itibaren kendinden sonraki "," e kadar olan (ya da son seçilen alan ise FROM ifadesine kadar) sorgu alanı bizim için tek bir alanı ifade etmektedir. Yani biz seçimini yaptığımız son alanı TotalPrice + TotalPrice * 0.08 şeklinde de yazabilirdik.
Parantezleri neye göre koydumuza gelince açıkçası bu konu üzerinde çok kafa yormadım. Neye göre koyulur ve nasıl bir kuralı vardır bilmiyorum. Benim kendi mantığıma kullandığım ve şimdiye kadar hata almadığım yöntem "her bir alanı parantez içine alıp parantez içine alınan alanlar arasında herhangi bir işlem var ise onları da ayrıca dış parantez içine almak."
Konu hakkında daha detaylı bilgisi olan arkadaşlar fikir beyan edebilirler, mesajımı düzenleyerek isimlerini ve açıklamalarını ekleyebilirim.

Bu bize neyi gösteriyor? Elimizde satış ile ilgili bir tablo var ve bu tabloda kdv'ler ile ilgili herhangi bir veri tutulmamış ise yine de bu tür alanları hesaplanmış olarak kendimiz sorgular aracılığı ile üretebiliyoruz.
 

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Şimdiye kadar WHERE deyimi ile koşullarımızı sorgumuza anlattık. Peki bütün koşullarımızı sadece WHERE ile mi anlatıyoruz? Hayır, bütün koşullarımızı sorgumuza sadece WHERE ile anlatmıyoruz. Bunu yapmanın bir yöntemi de HAVING kullanımıdır. Görüldüğü üzere HAVING adında yeni bir deyim ile karşı karşıyayız. Peki WHERE ile hemen hemen her koşulumuzu veritabanına anlatabiliyorken şimdi ne gerek vardı HAVING kullanmaya diyeceksiniz. Aslında gerek var.

WHERE SUM() COUNT() gibi gruplandırma işlemlerinden önceki değerleri seçmek için kullanılır.
HAVING ise gruplanmış değerler üzerinden koşullar üreterek bu koşulların sonuçlarını getirir.

Bir örnek ile konuyu biraz daha anlaşılır hale getirelim.
no:20
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu sorgumuzda SUM fonksiyonu ile toplam alıyoruz. Toplam almadaki şartımız ise TotalPrice değeri 150 üzerinde olanları almasıdır.
Ayrıca bu sorgumuz ile birlikte tarih fonksiyonu olan MONTH() fonksiyonunu da görmüş oluyoruz. MONTH(TarihAlani) şeklide kullanılan fonksiyon bize tarih değeri içerisindeki ay sayısını döndürür. Aynı mantıkla YEAR() ve DAY() fonksiyonlarını da kullanabiliyoruz.

no:21
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu sorgumuzda da anlaşılacağı gibi ilk önce 20 sorgumuzda yaptığımız 150 üzeri kayıtları aylara göre gruplayarak topladık. Daha sonra ise HAVING ile toplamları 2000 üzeri olan kayıtları getirmesini istedik.

Hatalı kullanım:
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Aynı sorguda HAVING ile bu işlemi yapmak yerine yukarıdaki hatalı kullanımda bulunan WHERE koşulu gibi yapsaydık kayıtsetimiz bize veri getirmeyecekti. Çünkü henüz veriler üzerinde TOPLAMA yapıp gruplandırmamış olacaktı.

iki kriter belirleme deyimi arasındaki farkı küçük bir örnek ile anlatmış olduk. Bu dersimizi biraz kısa tutuyoruz fakat yeni öğrendiğimiz konuyu etkili bir örnek üzerinde anlattığımı düşünüyorum. Herhangi bir şekilde kafanıza takılan konular olursa sormaktan çekinmeyin.

Düzeltme: Yapılan çalışmalara ilişkin kodları içeren excel dosyasını ekledim. Bu mesajdan sonra farklı bir veritabanı oluşturup o veritabanı üzerinden devam edeceğiz.
 

Ekli dosyalar

  • Çalışma Dosyası.xlsm
    43.8 KB · Gösterim: 22
Son düzenleme:

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Bugüne kadar örnek FoodSales dosyası üzerinde çalıştık. Bundan sonrası için hem örnek olması açısından hem, hemde kullanabileceğiniz küçük bir uygulama yapma açısından yeni bir veritabanı ile çalışacağız. "Çalışma Dosyası.xlsm" dosyamızın yanındaki "FoodSales.xlsx" ile vedalaştıktan sonra "Rehber.accdb" dosyası oluşturalım.

Farkına vardığınız gibi konumuz "kapalı excel dosyasından veri alma" olmasına rağmen, biz "Rehber.accdb" dosyası oluşturduk.
ADO ister excel olsun, ister access olsun, ister MSSQL olsun bunların hepsini veritabanı olarak görür. Yani ado çalışma yaptığımız dosyanın türüne bakmaz sadece veri transferine odaklanır.

ADO ile kabaca kod yapımızın nasıl olduğunu tekrar paylaşarak hatırlatmakta fayda görüyorum.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Şimdiye kadar SELECT sorguları üzerinde durduk artık bu çerçeveden çıkmanın zamandı geldi. (İlerleyen zamanlarda SELECT sorgularına tekrar döneceğiz)
Şimdi elimizde tertemiz hiç bir tablo barındırmayan "Rehber.accdb" dosyası mevcut, bu dosyamıza yeni tablolar açmanın zamanı geldi. Bunu hem dosyayı açıp manuel olarak gerçekleştirebiliyoruz hem de kullandığımız uygulama üzerinden kod ile gerçekleştirebiliyoruz.
Konumuz SQL SORGULARINA odaklı olduğu için biz kolaya kaçıp tablomuzu elle açmak yerine kodla açmayı deneyeceğiz.

NOT: SELECT sorguarı rs değişkenimizde bize veriler sundu ve biz de bu veriler üzerinde çalıştık. (Daha spesifik çalışma örneklerini ilerleyen zamanlarda anlatacağım) fakat bazı sorgular herhangi bir veri döndürmeden bazı olayları gerçekleştirdikten sonra kapanırlar.

Şimdi göreceğimiz sorgu deyimi CREATE TABLE deyimi.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Genel kullanımı üstte gördüğünüz şekildedir. CREATE TABLE deyimini kullandıktan sonra tablo adı belirlenir. Daha sonra oluşturulacak alanlar Parantez içerisinde veri türlerini de içerir şekilde yazılır. Görüldüğü üzere bazı karmaşık kullanım şekilleri hariç basit bir yapısı vardır.

Biz Rehber.accdb adında bir veritabanı oluşturduk ve rehberimizdeki bilgileri tutmak istiyoruz.
Öncelikle Kisiler adında bir tabloya ihtiyacımız var. Bu tablo için nelere ihtiyacımız olduğunu göz atalım.
Hemen hemen her tablo (bazı istisnalar hariç) her kaydı ayrı ayrı tanımlayan benzersiz bir kimlik değeri içermek zorundadır. Biz buna kisiID diyelim ve veritipi olarak LONG seçelim. (Access veritabanına geçtik, access bize her alan için bir veri tipi sunar bu veri tiplerinin neler olduğuna kısaca göz atmak için bkz: ), Adi alanımız olsun bunu Text olarak tanımlayalım. Soyadi Text olsun, Cinsiyet Text olsun, GSM1 Text, GSM2 Text, Faks Text, EPosta1 Text, EPosta2 Text olsun. (Bu tablo normalizasyon kurallarına uymuyor, uymak için uğraşırsak örneklerimiz hem karmaşıklaşır hem de sıkıcı bir şekilde çok uzar)

Şimdi sorgumuz içinde yukarıda bahsettiğimiz alanları kullanalım.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
ID rakam olacağı için sayısal veritipi seçerek buna long dedik, soyadı metinsel ifade içereceği için varchar dedik. (varchar metisel ifadeler için kullanılır parantez içindeki rakam en fazla kaç karakter değer alabileceğini ifade eder) daha sonraki ifadeler için de benzer şekilde belirlemeler yaptık.

Şimdi kodumuzu oluşturup sorgumuzu çalıştıralım.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Kodumuzu çalıştırdıktan sonra access dosyamızda Kisiler tablosunun oluştuğunu görebiliriz.

Şimdi buradaki önemli hususlardan birisi yukarıda da bahsettiğim gibi SELECT sorguları defalarca çalıştırılsa dahi çalışabilecek sorgulardır, fakat CREATE TABLE sorgusunu en fazla bir kere çalıştırabiliriz. Bunun sebebi kodu bir kere çalıştırdıktan sonra tablomuz veribanında oluşacaktır, 2. ve diğer çalıştırmalarda aynı tablodan bir tane daha açamayacağı için kod çalışırken hata üretecektir. (Bu tür hataların önüne geçmek için hem kod tarafında hem sorgu tarafından bir takım yöntemler var fakat şimdi onlara değinmeyeceğim. İlerleyen zamanlarda vakit bulursak konumuz çok uzamazsa değinebiliriz.)

NOT: Sorguyu en basit haliyle paylaştım, tablomuzda bulunması gereken Primary Key, Foreign Key gibi alanları Null değer alabilip alamayacağı ile ilgili kısımları da tanımlamak istersek kısaca bir örnek;

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
bu tablomuz Primary Key alanı tanımı yapar. Ayrıca KisiID alanının Primary Key değerini tanımlama için (KisiID int NOT NULL PRIMARY KEY, ...) şeklinde de yazabilirdik. Farkına varacağınız gibi alanların NULL değer alıp almayacağını ayarladık, dikkat ederseniz NOT NULL olmayan değer için NULL yazma ihtiyacı duymadık çünkü NULL ya da NOT NULL ayarı default olarak NULL gelir.

CREATE TABLE konusuna da olduk. Bundan sonrası için öğreneceğimiz sorgu ifadesi ise INSERT INTO ile tabloya veri ekleme olacak.
 

Ekli dosyalar

  • Rehber.zip
    51.1 KB · Gösterim: 25
Son düzenleme:

Akuma

Yeni Üye
Kullanıcı Bilgileri
Katılım
9 Mar 2021
Mesajlar
64
Aldığı beğeni
60
Excel Versiyonu
Office 2010 TR
@aeGNoR hocam çok başarılı bir çalışma gerçekleştirmişsiniz.
Artık ADO kullanma vakti gelmiştir.
Elinize yüreğinize sağlık.
Saygılarımla
 

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Tablomuzu oluşturduk, şimdi tablomuza veri girişi yapma zamanı. Veri girişinde INSERT INTO ifadesini kullanıyoruz. Bu ifade veritabanındaki tablomuza bir adet Recordset yani kayıtseti ekleyebiliyor.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Örnek üzerinde de görüldüğü gibi INSERT INTO çok basit bir mantıkla işlemektedir. INSERT INTO ifadesini kullandıktan sonra kayıt eklemek istediğimiz tablonun adını yazıyoruz. Daha sonra veri eklemek istediğimiz alanları parantez içerisinde yazıyoruz. Veri girilecek alanlar belirlendikten sonra VALUES deyimi ile yine parantez içinde girilecek değerler belirlenecek.

Örneğimizi Rehber veritabanımızı kullanarak biraz somutlaştıralım.

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Yukarıda bahsettiğimiz mantıkla Rehber veritabanımıza veri girişi yapmış olduk. Şimdi aklımıza şöyle bir soru takılabilir; ben kayıt yaparken her defasında kaçıncı kişiyi kaydettiğimi bilmek zorunda mıyım? kisiID yi bizim yerimize kendisi her kayıt için 1 (bir) arttırsa olmaz mı? Evet olur çok da güzel olur. Fakat bu konuya değinebilmek için tablomuzu ilk oluştururken bilerek bir hata yaptım. Nedir o hata? KisiID alanını LONG olarak oluşturdum. Veritabanımızın bizim yerimize sayılar atayabilmesi için alanımızı AutoNumber olarak tanımlamalıydık. Telaş yapmaya gerek yok, veritabanını ve çalışma excel dosyamızı bu mesaj ile paylaşacağım. Paylaştığım dosyalarda kisiID autonumber olarak ayarlanmış olacaktır.

Şimdi tekrar dönelim INSERT INTO konumuza. Yukarıdaki örnekte görüldüğü gibi Kisiler tablosundan sonraki parantez içinde 9 adet alan seçildi ve yine VALUES ile değerleri girerken de 9 adet alana seçim sırasıyla değer girdik.
Peki 8 Alan seçip 9 değer yazmış olsaydım ne olacaktı? Hata verecekti.
Aynı mantıkla 9 alan seçip 8 değer yazmış olsaydım da hata verecekti.
Buradan şunu çıkarıyoruz seçilen alan ile girilen değerlerin sayısı aynı olmak zorundadır.

kisiID alanımız AutoNumber olsaydı;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
görüldüğü gibi seçilen alanlardan ve girilen değerlerden kisiID kısmını kaldıracaktık ve işin o kısmını veritabanı bizim için halledecekti.

Burada akıllarda yine bir soru belirebilir. Kayıtseti kendini oluşturan alanların tamamı ile bir bütündü, ama biz yeni değer girerken alanlardan bir tanesini seçmedik bu nasıl mümkün olabilir? Veritabanımız bizim seçmediğimiz her alan için kendi içinde default bir değer verebilir. Yani ben kişi ekleme kaydımı
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
şeklinde yapmış olsaydım GSM, EPosta gibi alanlara seçtiğimiz default değerleri girecekti (Default değerler belirlenmemişse Null (boş) olarak değer girecekti).
Burada sadece benzersiz değerler ile ilgili problem söz konusu olabilir. Yani bizim Kisiler tablomuzda TCKimlik adında bir alanımız olsaydı ve her kayıt için benzersiz olma şartı olsaydı INSERT INTO sorgumuza bu alanı eklemek zorundaydık.
 

Ekli dosyalar

  • Rehber.zip
    42.7 KB · Gösterim: 23

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Bir önceki dosyada paylaştığım veri ekleme örneği textboxlara bağlı değildi, gelin şimdi bu textboxlardan veri alarak yeni kayıt ekleyelim. Bunu yapmanın çok fazla yolu olmasına rağmen ben query değişkenini oluşturmayı bir fonksiyona bağlamayı tercih ediyorum. Şimdi bir örnekle bunu netleştirelim.

Userform üzerindeki textbox ve commandbutton nesnelerini adlandırdım. Şöyle ki txtEkleAdi, txtEkleSoyadi, cmdKaydet vb. Bunu örnek dosya eklediğimde daha net göreceksiniz.

Userform üzerindeki bütün kodlarımızı siliyoruz tamamını yeniden revize edeceğiz. Declarations kısmında bulunan;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Değişkenlerimiz sabit kalıyor.

Şimdi listbox nesnemizi doldurmak için initialize olayına yazdığımız kodları ayrıca;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Üstteki RefreshListBox prosedürüne çevirdik. Böylece listbox içindeki verilerimizi her yenilememiz gerektiğinde call RefrshListBox yaparak yenileyebileceğiz.

Formu açarken listbox'ı doldurmak için Initialize olayında call ile refreshlistbox prosedürünü aşağıdaki gibi çağırıyoruz;

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Şimdi veri query değişkenimizi inşa edecek fonksiyonu yazmaya geldi sıra(Fonksiyon yazmayı, fonksiyon üzerinde değişken kullanmayı bildiğinizi varsayıyorum);

Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Query değişkenimizi yapılandıracak fonksiyonu da bu şekilde yazmış olduk. Query değişkenini oluşturmak için oluşturduğumuz fonksiyonu ekle butonu içerisinde kullanacağız böylece ekle butonumuz içerisindeki kodlarımızı karmaşıklaştırmamış alacağız.
Artık Kaydet butonu ile verilerimizi ekleyebilecek duruma geldik sayılır. Kaydet butonu içindeki kodlarımızı da ayarladıktan sonra artık veri kaydedebilir duruma geleceğiz.
Kaydet butonumuzun kodları ise aşağıdaki gibi olacaktır;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu kodlarla con nesnemizi açıyoruz ve oluşturduğumuz fonksiyon ile query değişkenimizi yapılandırıyoruz belirlediğimiz parametreler ile. Daha sonra rs nesnemizi open yaparak kaydın gerçekleşmesini sağlıyoruz. (Bu tür kayıtlarda hata denetimleri yapılmak ZORUNDADIR fakat şimdilik konumuz tam olarak bu olmadığı için buna değinmiyorum.)
Ayrıca rs nesnemiz ile kaydı gerçekleştirdikten sonra listbox yenilemek için tekrar kod yazmak yerine daha önce yazdığımız RefreshListBox prosedürümüzü call komutu ile çağırıyoruz ve eklemiş olduğumuz kaydı listbox üzerinde anlık olarak görmüş oluyoruz.

INSERT INTO sorgusunun form üzerindeki nesneler ile ilişkilendirilerek nasıl kullanılabileceği hakkında bir örnek gerçekleştirmiş olduk.
Bugünlük bu kadar yeterli, daha sonraki derslerimizde görüşmek üzere.
 

Ekli dosyalar

  • Rehber.zip
    40.5 KB · Gösterim: 44

aeGNoR

Destek Ekibi
Kullanıcı Bilgileri
Katılım
10 Mar 2021
Mesajlar
772
Çözümler
98
Aldığı beğeni
866
Excel Versiyonu
Office 2021 TR
Konuyu Başlatan
Merhaba arkadaşlar,
Çok uzun bir aradan sonra rehber uygulamamıza güncelle ve sil butonlarını da ekleyelim. Farklı bir gelişme olmazsa bu anlatımla rehber uygulaması yapmayı sonlandırmak istiyorum. ADO'nun farklı özelliklerini daha farklı örneklerle anlatmayı planlıyorum.
UPDATE
Güncelle sorgumuz kabaca;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Şeklinde bir yapı bulunur. Bu yapıda önemli olan güncelleme yapılırken değişiklik yapacağımız sütunları SET etmeliyiz. Ayrıca çok önemli olarak güncelleme sorgumuza WHERE şartını mutlaka eklemeliyiz.
Örnek olarak;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu sorgudan Kisiler tablosunda bulunan Faks alanı üzerinde değişiklik yapılacağını anlıyoruz. Fakat bir problemimiz var ki, hangi kayıt setindeki Faks alanını değiştireceğimizi söylemedik. Bu çalıştırılan sorgu bize ciddi bir sıkıntı olarak geri dönecektir. Tablomuzda bulunan bütün kayıtsetlerinde bulunan faks alanlarına aynı numarayı yazacaktır. Dolayısıyla UPDATE Sorgumuzda WHERE şartı ciddi öneme sahitir.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Doğru olan örnek kod yukarıdaki gibi olacaktır.
Not:Belli bir grup kayıt seti üzerinde değişiklik yapmayı düşünmüyorsak, tek bir kayıt seti üzerinde değişiklik yapmayı düşünüyorsak genelde ID kolonlarını WHERE şartına referans olarak gösteririz.
Not2:Bir grup kayıt üzerinde değişiklik yapmak istiyorsak WHERE şartımızı hangi gruba göre değişiklik yapacaksan ona göre kurmalıyız. Örneğin Rehber veritabanımızdaki kişileri gruplandırmak isteyip Grup diye bir alan eklemiş olsaydık şartımızı buradan yapmış olacaktık.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bir grup kayıtseti üzerinde yapılacak olan değişikliğin örneği.

DELETE
DELETE
sorgularında ilk olarak anlamamız gereken şey WHERE şartına mutlaka ihtiyacımız olacak. Diyelim ki tablonuzda binlerce kayıt girdiniz ve şöyle bir silme sorgusu çalıştırdınız;
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Geçmiş olsun dileklerimizi size iletelim, çünkü herhangi bir yedeğiniz yoksa tablonuzdaki BÜTÜN KAYITLAR SİLİNDİ :)
UPDATE sorgularındaki gibi WHERE şartımız olmazsa olmaz bir gereklilik olarak karşımızda duruyor.
Doğru sorgu yapısı ise aşağıdaki gibi olmalıdır.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.

Silme sorgularının doğrusunu öğrendikten sonra genel kullanıma bir örnek verelim.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu örnekte 1 ID numaralı kişiyi silmiş oluyoruz.

Diyelim ki birden çok kayıtsetini silmek istiyoruz. Where şartımızı daha geniş kapsamlı tutarak silme işlemi yapabiliriz.
Kod:
Değerli Misafirimiz İçeriği Görebilmek İçin Üyemiz İseniz Giriş Yap'ın Ya da Üye Ol'un.
Bu örnekte ise Adi alanındaki 'Mustafa' değerine sahip bütün kayıtlarımız silinmiş olacaktır.

Bu son mesajımla; ayırabildiğim kısıtlı zaman içerisinde en azından temel konuları bitirmeye çalıştım diyelim. Biliyorum konuyu geçiştirmişim gibi duruyor ama son zamanlarda oldukça yoğun bir gündeme sahibim. Dolayısıyla ŞİMDİLİK bu anlatımı burada sonlandırıyorum. Umarım en kısa zamanda tekrar vakit bulabilir ve sizinle burada güzel işlere imza atabiliriz.
 

Konuyu okuyanlar

Üst