Dosya Okuma ve Yazma işlemleri
Giriş
İçine veri yazılan birçok dosya tipi bulunmaktadır, ancak biz VBA
konsepti içinde genellikle text(csv dahil) dosyalarıyla çalışacağız. SQL
kodlarını depoladığınız ".sql" uzantılı dosyaları da bu kapsamda
düşünebilirsiniz. Excel
dosyalarla çalışmayı zaten Workbook
ve Application
bölümlerinde görmüştük.
Text dosyaları bilgi depolayıp okumanın kolay
bir yolunu sunarlar. Özellikle settings(ayar) bilgileri veya aşamalı bir
sürecin durum bilgilerini(log) okumakta/yazmakta oldukça kullanışlıdırlar.
VBA'de iki tür okuma/yazma yöntemi bulunuyor. Öncelikle biz VB6'dan
miras gelen klasik okuma yazma yöntemine bakacağız.
UYARI:Buradan itibaren aşağıda göreceğiniz tüm dosya
okuma işlemlerinde, dosya okuma hep sağa ve aşağı yönlüdür. Döngüsel
işlemlerde "bir sağ kolona/karaktere veya bir alt satıra geç" tarzında
ilave bir kod ifadesi yoktur. Bu işlem otomatik olmaktadır.
Klasik Okuma/Yazma işlemleri
Dosya açma ve Kapama
Dosya Açma
Okuma işlemi için de de Yazma işlemi için de öncelikle dosyanın
açılması gerekir. Bunun için Open
fonksiyonu kullanılır. Aşağıdaki gibi bir syntax'a sahiptir.
Open dosyayolu For mod [Erişim tipi] [lock]
As Dosyano
- Dosyayolu:Dosyanın bulunduğu tam adres.
Ör:C:\deneme\deneme.txt
- Mod:Input ise okuma,
Output ise yazma, Append ise dosya sonuna ekleme
yapılır. 2 tane daha var ama bize bu üçü yeter. Output seçildiğinde
mevcut dosya varsa ezilip içeriği yeniden oluşturulur, olmayan bir
dosya girildiyse bu dosya yaratılır.
- Erişim tipi ve Lock tipi:Opsiyoneldirler. Dosya
açıkken, başkalarının ne yapabileceğini gösterir. Biz bunları
kullanmayacağız, o yüzden default değerleri devreye girecek.
Freefile
Dosyalar açıldığında onlara bir sıra numarası verilir. Bu numara
manuel belirtilebileceği gibi, çok sayıda okuma yazma yapılan bir prosedür
içinde o andaki müsait sıra numarasını veren Freefile
deyimi de kullanılabilir. Manuel giriş için sıra numarası # ile
kullanılır. #1 gibi.
Dosyayı Kapama
Dosyayı Close ifadesi ile kaparız, ancak parametre olarak dosya
adresi değil, numarasını alır.
Dosyayı kapatmazsak, tekrar aynı dosyayı açmaya çalıştığımızda
"Dosya zaten açık" hatası alırız.
Kod
Bu durumda, örnek bir dosya açma kodu şağıdaki gibi olacaktır.
adres = "C:\Users\Volkan\Desktop\denemeler\dosya1.txt"
Open adres For Input As #1 'veya 1 veya FreeFile
'çeşili işlemler
Close #1
Dosyadan veri okuma
Kolon kolon bilgi okumak
Aşağıdaki bilgileri içeren bir text dosyamız olsun. Kişinin adı, yaşı
ve baba adı bilgileri var.
volkan ,38 ,ismail
ayşe ,40 ,murat
serkan ,35 ,osman
Buradan ilk kaydın yaş bilgisini almak istiyoruz diyelim. Bunun için
Input deyimini kullanıp, istediğimiz
kolon sayısı kadar değişken belirleyip kolon bilgilerini bu değişkenlere
atıyoruz.
Sub teksatırdan_tekkolon_okuma()
adres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt
Open adres For Input As 1
Input #1, adı, yaş 'kolon sayısı kadar paremetre alır. # zorunlu
Debug.Print yaş '38 verir
'ikinci bi Debug.Print yaş yazsak bile yine 38 yazar. sadece tek satır okumasu var.
Close 1
End Sub
Bu kod tabiki sadece ilk satır için bilgi döndürür. Satırda ilerleme
yapamıyoruz. Özellikle her defasında üzerine yazma yapılan tek satırlık
bilgi içeren dosyalarda kullanışlıdır. Mesela ikinci kolonunda, bilginin
yazdırıldığı tarihi veya kişiyi gösteren bir dosyadan bu tarihi veya
kişiyi elde etmek
isteyebiliriz. Böylece bu dosyaya en son ne zaman bilgi yazıldığını veya
kimin tarafından yazıldığını elde edebiliriz.
Tek satırdan kısmi bilgi okuma
Input ifadesini Input(karakteradedi, dosyano)
şeklinde kullandığımızda belirli adette karakter okumuş oluruz.
Sub teksatır_kısmen_okuma()
adres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt"
Open adres For Input As 1
x = Input(6, 1) '1 nolu dosyadan 6 karakter oku
Debug.Print x 'volkan
End Sub
İlk satırın tamamını okuma
Yine yukarıdaki dosyamı elimizde bulunsun. Bu sefer ilk satırın
tamamını elde edeceğiz. Bunu Line Input
deyimi ile yapıyor ve içeriği ikinci parametredeki değişkene atıyoruz .
Sub teksatır_tamamını_okuma()
adres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt"
Open adres For Input As 1
Line Input #1, metin 'ilk satırı oku ve metin değişkeninde depola
Debug.Print metin 'volkan,38,ismail yazar
Close 1
End Sub
x adet satırı tek tek okuma
Bu işlem Line Input'un bir For Next döngüsü ile kullanımı ile yapılabilir.
Belli sayıda satır bilgisinin yeterli olduğu durumlarda kullanılır.
Sub x_adet_satır_oku()
adres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt"
Open adres For Input As 1
For i=1 to 2
Line Input #1, metin
Debug.Print metin
Next i
Close 1
End Sub
Dosyadaki tüm metni okuma
1.Yöntem:Dosyadaki karakter sayısı kadar okumak
Bunu
LOF ifadesi ile yapıyoruz. Bu, Length Of File'ın
kısaltılmışıdır, yani dosyadaki karakter sayısını verir. Input ile
birleştirerek de dosyadaki tüm karakter sayısını oku demiş oluruz.
"volkan naber" şeklinde 12 karakterli bir metni içeren bir dosyada;
LOF(1):12 döndürür
Input(LOF(1),1):1 nolu dosyayı tamamen okur:"volkan
naber"
Örnek bir kodumuz ise şöyledir. Bu kodda ayrıca
Seek ifadesini de kullandık. Bununla
dosyada belirli bir sıradaki karaktere konumlanıyoruz, ki bunu genelde
belirli bir sırayla ilerlediten sonra tekrar ilk karaktere dönmek için
kullanırız. Syntax: Seek dosyano, konum
Sub DosyaOkuTümü1()
adres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt"
Open adres For Input As 1
Debug.Print LOF(1) 'Length Of File Of File
içerik = Input(LOF(1), 1) '1 nolu dosyanın hepsini oku
Debug.Print içerik
Seek 1, 1 '1 nolu dosyanın 1.karakterine yan en başa git
içerik = Input(LOF(1) - 10, 1) '1 nolu dosyanın son 10 karekteri hariç oku
Debug.Print içSeek 1, 5 '1 nolu dosyanın 5.karakterine git
içerik = Input(10, 1) '1 nolu dosyanın 5.karakterinden sonraki ilk 10 karekterini okurini oku
Debug.Print içerik
Close 1
End Sub
Aynı mantıkla bir şekilde dosyanın ilk x karekterini okumak için içerik
değişkenine Input(x,1); son x karekteri hariç okuma yapmak
isterseniz içerik değişkenine Input(LOF(1)-x,1) şeklinde
atama yaparsınız.
Bu yöntemde dosya içindeki metnin kaç satırda yer aldığı önemli
değildir. Tüm metin tek bir değişkende depolanır.
2.Yöntem:Dosya sonuna kadar satır satır okumak
Yukarıda gördüğümüz belli sayıdaki satırları tek tek okumadan farklı
olarak tüm satırları tek tek okuyoruz. Satırların bittiğini
EOF(End Of File'ın kısaltması )özelliği
ile anlıyoruz.
Sub DosyaOkuTümü2()
tamadres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt"
Open tamadres For Input As 1
Line Input #1, satırmetni
içerik = satırmetni
Do Until EOF(1)
Line Input #1, satırmetni
içerik = içerik & vbNewLine && satırmetni
Loop
Debug.Print içerik
Close 1
End Sub
NOT: İçerik değişkenini oluşturuken kayıtlar arasınsa vbNewLine
koyarak
satırbaşı yapıyoruz. Ancak ilk başta değişkenin içi boş olacağı için
fazladan bir boş satır oluşmaması için en başta bir kezliğine döngüye
girmeden ilk satırın atamsını yapıyorum sonrasında döngü içinde vbNewLine ekliyorum.
Bu arada istenirse ilgili metinler vbNewLine denmeden satır satır değil
de ardışık bir şekilde de biraraya getirilebilir.
Tüm içeriği bir diziye aktarmak
Bunu da kendi içinde iki ayrı yöntemle yapabiliriz. İlk yöntemde
satır satır okur ve her satırı bir collectiona atarız. Özellikle her
satırın başına/sonuna başka bir metin eklemek gereken durumlarda bunu
kullanabiliriz. İkinci yöntemde ise tüm metni okuyup Enterları(vbCrLf veya vbNewLine) Split ederek
diziye atayabilirsiniz.
'1)Collectiona atama
Do Until EOF(1)
Line Input #1, metin
coll.Add metin
Loop
'2)Diziye atama
içerik=Input(LOF(1), 1)
dizi = Split(içerik, vbCrLf)
Bu iki yöntemle de yukardaki örneği yapalım.
Sub dosyaoku3()
adres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt"
Open adres For Input As 1
Debug.Print "------önce dizi yöntemi-----"
içerik = Input(LOF(1), 1)
dizi = Split(içerik, vbCrLf)
For Each satır In dizi
Debug.Print "Prefix:" + satır + " -Suffix"
Next satır
'veya
Debug.Print "------collection yöntemi-----"
Seek 1, 1
Dim coll As New Collection
Do Until EOF(1)
Line Input #1, metin
coll.Add metin
Loop
For Each satır In coll
Debug.Print "Prefix:" + satır + " -Suffix"
Next satır
Close 1
End Sub
Virgülle ayrılmış metinleri hücrelere yazdırmak
Virgülle ayrılmış tüm değerleri farklı kolonda olacak şekilde satır
satır Excele yazdırmak isteyebilirsiniz. Bunun için satır satır okuma
yapmamız gerekir ve her satırı Split ile bir diziye atayabilir, sonra da ilgili hücrelere bu
dizi elemanlarını döngüsel şekilde yazdırabiliriz.
Sub DosyaOkuTümü4()
tamadres = "C:\Users\volkan\Desktop\denemeler\dosya1.txt"
Open tamadres For Input As 1
i = i + 1
Do Until EOF(1)
Line Input #1, x
dizi = Split(x, ",")
For j = 0 To UBound(dizi)
Cells(i, j + 1) = dizi(j)
Next j
i = i + 1
Loop
Close 1
End Sub
Dosyaya veri yazma
Sıfırdan yazma
Dosyaya veri yazdırmak için dosyayı Output modunda açmamız
gerekir. Yazdırma eylemi için iki fonksiyonumuz var.
Write ve
Print. Write, yazdırılan ifadeyi " " içine alarak yazarken
Print böyle bir işlem yapmaz.
Her iki deyim de ardışık kullanımlarında satır satır yazdırır. Yani
birbirini takip eden metinler şeklinde yazılmaz. Örneğin;
ad="Volkan"
soyad="Yurtseven"
Print ad
Print soyad
'bu kodun çıktısı aşağıdaki gibidir
'Volkan
'Yurtseven
'VolkanYurtseven değil
Eğer yazdırılan metinlerin ardışık yazdırılması isteniyorsa aşağıda
anlattığım TextStream nesnesini kullanmanız gerekir.
Şimdi veri yazdırmaya ait küçük bir kod yazalım.
Sub DosyaYazTekSatır()
tamadres = "C:\Users\volkan\Desktop\denemeler\dosya2.txt
ff = FreeFile ' o an uygun olan dosya numarası verilir.
Open tamadres For Output As ff
Print #ff, "bu ilk satır"
Print #ff, "bu da ikinci satır"
Close ff 'kapatırken kaydeder, ayrı bir save işlemi yoktur
End Sub
NOT:Eğer dosya mevcut değilse otomatikman oluşturulur,
varsa ezilir ve üzerine yazılır.
Varolan dosyaya ekleme yapmak
Varolan bir dosyanın sonuna ekleme yapmak istiyorsak bu işi Append
deyimi ile yaparız. Eğer dosya mevcut değilse
Outputta olduğu gibi otomatikman oluşturulur.
Sub DosyaAppend()
tamadres = "C:\Users\volkan\Desktop\denemeler\dosya2.txt
ff = FreeFile ' o an uygun olan dosya numarası verilir.
Open tamadres For Append As ff
Print #ff, "bu üçüncü satır"
Close ff 'kapatırken kaydeder, ayrı bir save işlemi yoktur
End Sub
Excelden okuyup dosyaya yazma
İçiçie iki For Next ile satır ve sütunlarda dolaşırız, araya "," veya
istediğimiz başka bir ayraç ekleriz.
Aşağıdaki örnekte 10 satır 3 kolondan oluşan bir listeyi metin dosyasına
yazdırıyoruz.
Sub Exceldenyaz()
tamadres = "C:\Users\volkan\Desktop\denemeler\dosya3.txt
ff = FreeFile
Open tamadres For Output As ff
For i = 1 To 10
For j = 1 To 3
If j = 3 Then
satırmetin = satırmetin + Trim(Cells(i, j).Value)
Else
satırmetin = satırmetin + Trim(Cells(i, j).Value) + ","
End If
Next j
Print #ff, satırmetin
satırmetin = ""
Next i
Close ff
End Sub
Metin değişikliği yapmak
Bazen tek bir dosyada bazense birçok metin dosyasında aynı anda bir
metin değişikliği yapmak isteriz. Birçok dosyayı elde etmeyi
bir önceki
sayfada görmüştük. Bir döngü ile bu klasörleri/dosyaları elde ettikten
sonra yapmanız gereken iş 4 aşamadan oluşur:
- Önce dosyayı açmak
- Metni okumak
- Aradığımız metni bulup değiştirmek
- Dosyaya tekrar yazdırmak
Sub MetinDeğiştir()
Dim adres As String
Dim içerik As String
adres = "C:\deneme\deneme.txt"
Open adres For Input As 1
içerik = Input(LOF(1), 1)
Close 1
içerik = Replace(içerik, "abc123", "abc345")
Open adres For Output As 1
Print #1, içerik
Close 1
End Sub
Yapılan değişkliği illa dosyaya kaydetmek zorunda değilsiniz. Mesela
benim bazı SQL'leri tuttuğum metin dosyalarım var, içinde değişkenlerin
olduğu bölümler var. Bu dosyaları bir nevi şablon olarak tutuyorum, onların
üzerinde değişiklik yapmıyorum, onun yerine dosyayı okuyup bi değişkene
atıyorum ve onun üzerinde replace işlemi yapıp, SQL metni olarak işleme
sokuyorum. En aşağıdaki örnekler bölümünde bu işlemi görebilirsiniz.
UYARI/ÖNERİ:Yapılandırılmış tipteki(belli format, uzunluk ve kolonlardan oluşan) büyük metin dosyalarında büyük çaplı
değişiklikler yapılacaksa bu dosyaya ADO ile bağlanıp Update işlemi
yapılması daha hızlı sonuç verecektir. I/O yöntemi ile replace işlemi
küçük dosyalarda tercih edilmelidir.
TextStream nesnesi
Dosyalara yazma ve okumanın bir diğer yolu da
TextStream nesnesi
yoluyladır. Niye böyle bi yöntem daha var? Bu sınıf, aslında
web sayfalarında VBscript diliyle yazılmak üzere tasarlanmış bir sınıftı ama sonradan VBA içinde de kullanıma alındı. O yüzden
Scripting Runtime librarysi içindedir
ve references menüsünden eklenmesi gerekir.
Ben şahsen hem okunurluk hem de kullanım kolaylığı açısından
TextStream nesnesini kullanmayı tercih ediyorum, ancak her zaman olduğu
gibi başkalarının yazdığı kodları okumanız/kullanmanız gerekebileceği
için her yöntemi bilmekte fayda var. Aşağıda göreceğiniz
üzere TextStream'in bazı ek özellik ve metodları da onu ayrıcalıklı
kılmaktadır.
Erişim & Yaratım
Bir TextStream nesnesine erişmek için FSO'nun
CreateTextFile veya
OpenTextFile metodlarını kullanabileceğimiz gibi
File nesnesinin
OpenAsTextStream nesnesini de kullanabiliriz.
CreateTextFile
Syntax:
fso.CreateTextFile(dosyadı,Owerrite?,Unicode desteği?)
Aşağıdaki kod ile varolan bir dosyayı, eğer mevcutsa üzerine
yazdırarak(yani içini boşaltarak) Türkçe karakterleri de destekleyecek
şekilde açıyoruz.
'global fso nesnesnin var olduğunu düşünerek ilerliyoruz
Dim ts As TextStream
Set ts = fso.CreateTextFile("c:\deneme\deneme.txt", True, True)
Eğer ikinci parametreyi False olarak kullanmak yani dosya
mevcutsa onu ezmeyelim istiyorsak, aşağıdaki gibi dosyanın varlığını kontrol ederek
açmalıyız yoksa "dosya zaten mevcut" hatası alırız.
If Not fso.FileExists("C:\Users\Volkan\Desktop\denemeler\deneme1.txt") Then
Set ts = fso.CreateTextFile("C:\Users\Volkan\Desktop\denemeler\deneme1.txt", False, True)
ts.Write ("merhaba")
End If
OpenTextFile
Syntax:fso.OpenTextFile(dosyadı,I/O
tipi,MevcutdeğilseYaratılsınmı?,Format)
Set ts = fso.OpenTextFile("C:\deneme\deneme.txt",ForWriting,True,TristateFalse)
I/O tipi, ForWriting açıldığında içerik ezilir. Bu CreateTextFile'ın ikinci
parametresinin True olarak açılmasıyla aynı etkidedir.
ForReading ile okuma yaparsınız, yazmaya izin verilmez.
ForAppending ile en sona konumlanır ve oraya yazarsınız, böylece
mevcut içerik silinmemiş olur.
Üçüncü parametreyi, dosya mevcut değilse yaratmak istediğinizde True olarak kullanırız. Eğer burası
False ise ve aradığınız dosya yoksa
hata alırsınız. O yüzden ya burayı True yapmalısınız ya da dosyanın
mevcut olup olmadığını kontrol etmelisiniz. Mesela aşağıdaki kod ile,
dosya mevcut ise sonuna ekleme yapmak istiyoruz, mevcut değilse
yaratarak açıyoruz.
If Not fso.FileExists("C:\Users\Volkan\Desktop\denemeler\deneme2.txt") Then
Set ts = fso.OpenTextFile("C:\Users\Volkan\Desktop\denemeler\deneme2.txt", ForWriting, True, TristateFalse)
Else
Set ts = fso.OpenTextFile("C:\Users\Volkan\Desktop\denemeler\deneme2.txt", ForAppending, False, TristateFalse)
End If
Son parametre Unicode desteği ile olup olmayacağını verir.
OpenAsTextStream
Elinizde bir File nesnesi varsa bunun OpenAsTextStream
metodunu kullanarak da metin dosyalarını açabilirsiniz. Gerçi
File nesnesi için de yine bir FSO nesnesi gerekiyor. O yüzden her ikisini
de yaratmak gerekecek. Eğer File nesnesini başka birşey için
kullanmayacaksanız boşuna bu zahmete gerek yok, direkt FSO ve onun
metodları yeterli
olacaktır.
Syntax:File.OpenAsTextStream(I/O modu,Format)
İki parametre de opsiyonel olup default değerleri sırasıyla
ForReading ve TristateFalse'tur. Aşağıda bir örnek
bulunmakta.
Dim f As File, ts1 As TextStream, ts2 As TextStream
Set f = fso.GetFile("C:\Users\Volkan\Desktop\denemeler\deneme2.txt")
Set ts1 = f.OpenAsTextStream 'default değerlerle açıldı
x = ts1.ReadAll
ts1.Close
Set ts2 = f.OpenAsTextStream(ForAppending, TristateMixed)
y = ts2.Write("yeni")
ts2.Close
TextStream Üyeleri
Metin okuma şekilleri
ts.Read(5) 'Bulunulan yerden itibaren 5 karakter okur
ts.ReadLine 'Bulunulan satırı okur
ts.ReadAll 'Tüm dosya içeriğini okur
Üç yöntemde de bir değişkene atama işlemi yapılmalıdır.
Ör: içerik=ts.ReadLine
Yazma şekilleri
ts.Write(metin):Dosyaya metni yazar
ts.WriteLine(metin):Dosyaya metni yazar ve bir alt satıra geçer
ts.WriteBlankLines(5):Dosyaya 5 adet boş satır ekler
Line ile cursor'ın o anki satır
numarasını elde ederiz.
Close metodu ile TextStream nesnesini
kapatarız.
Dosyada okuma yaparken, belirli koşullar durumunda o satırı
SkipLine ile atlayarak bi sonraki satıra
geçebilriz. Aşağıdaki kod ile, sayısal bir ifadeyle başlayan herşeyi bir
collectiona atayıp en son da bunları yazdırıyoruz. Read ile bir karakter
okuduktan sonra kalanını ReadLine yaparken başına ilk okuduğumuz kısmı
eklediğimize dikkatinizi çekmek isterim. Örnek dosyamız aşağıdaki gibi
olsun
1-birinci satır
2-ikinci satır
falanfilan
3-üçüncü satır
falanfilan
4-dördüncü satır
Sub Satıratla()
Dim ts As TextStream
Dim col As New Collection
Set ts = fso.OpenTextFile("C:\Users\Volkan\Desktop\denemeler\deneme1.txt", ForReading, False, TristateMixed)
Do
kelime = ts.Read(1)
If IsNumeric(kelime) Then
col.Add kelime + ts.ReadLine
Else
ts.SkipLine
End If
Loop Until ts.AtEndOfStream
For Each Item In col
Debug.Print Item
Next Item
End Sub
Çıktı ise şöyle olacaktır:
1-birinci satır
2-ikinci satır
3-üçüncü satır
4-dördüncü satır
Hepsi bir arada bir örneğimi aşağıdaki gibi olabilir:
Sub çeşitli_üyeler()
Dim ts As TextStream
Const dosya As String = "C:\Users\Volkan\Desktop\denemeler\ts_üyeler.txt"
Set ts = fso.CreateTextFile(dosya, True, True)
ts.WriteLine ts.Line & "-" & Now
ts.Write ts.Line & "-": ts.WriteBlankLines (1) 'Dosyaya 1 adet boş satır ekler
ts.WriteLine ts.Line & "-" & Environ("username")
ts.WriteLine ts.Line & "-" & "selam"
ts.WriteLine ts.Line & "-" & "naber"
Debug.Print ts.Line
ts.Close
Set ts = fso.OpenTextFile(dosya, ForReading, False, TristateMixed)
x = ts.ReadLine ' Bulunulan satırı okur
ts.skipline 'ilgili satırı atlar
y = ts.Read(5) 'Bulunulan yerden itibaren 5 karakter okur, artık 3. satırdayız: 3-Vol
z = ts.ReadAll 'Cursordan itibaren tüm dosya içeriğini okur, baştan itibaren değil :kan4-selam5-naber
Debug.Print z
End Sub
Olay/Hata Logu tutan bir uygulama(Logger Prosedürü)
Hergün belli satlere schedule edilmiş(Application.Ontime
aracılığı ile) makrolarınızın olduğunu
düşünün. Bunlar içinde çeşitli aşamaları gün/saat başta olmak üzere
diğer önemli bilgilerle birlikte kayıt altına almak, nerde hata alınmış,
bunları görmek isteyebilirsiniz, hatta iyi bir programcı olarak görmek
istemelisiniz.
Keza, bölümünüz için raporlara ulaşım amacıyla hazırladığınız bir
arayüz(Kokpit Formu) olması
durumunda, kim ne zaman hangi rapora girmiş, en çok hangi rapor
kullanılıyor, Kokpiti en çok kim kullanıyor gibi soruların cevabını elde
etmek için bir log kaydı da tutmak isteyebilirsiniz.
İşte bu amaçlarla dosya yazma/okuma işlemlerini kullanabiliriz.
Otomasyon süreçlerinde Logger kullanımı
Diyelim ki aşağıdaki prosedür günün belirli saatlerinde çalışıyor.
Çalışmanın belirli aşamalarını(kritik önemde veya ana işlerin
öncesinde/sonrasında) kayıt altına alıyoruz. Ayrıca bir hata oluşursa yine bunu da
kayıt altına alalım.
Otomasyon süreçlerinde Log tutmanın bir alternatifi kendinize veya
ilgili kişilere mail attırmak
olacaktır. Ancak çalışan çok fazla iş varsa mail kalabalığında
boğulursunuz. O yüzden log sistemi daha güzel bir seçenektir.
Şimdi aşağıdaki örnekte Log dosyasmızda Tarih/Saat, Kullanıcı,
bilgisayar adı, rapor adı, log tipi, varsa hata kodu, açıklama kolonları
olmak üzere 7 kolon bilgi bulunmaktadır. Bunun ilk 3'ü Logger fonksiyonu
içinde dinamik olarak ele alınmakta, son 4 parametre ise Logger
fonksiyonuna KrediRaporu modülünden argüman olarak gönderilmektedir.
Diğer hususlar şöyledir.
- Rapor ismi toplamda 50 hane olacak şekilde ayarlanır. 50den kısa
olan rapor isimleri için başına 50ye tamalamanacak kadar boşluk
eklenir. Bunun amacı datayı Excele aktardığınızda aynı hizada görünemleri içindir. Bu
sizin dünyanızda daha yüksek bir sayıya ayarlanabilir.
- Bilgisayar ismi de yine aynı şekilde 10 haneye tamamlanmaktadır.
Bu da sizin dünyanızda daha yüksek ayarlanabilir.
- Hata yoksa hata kodu olarak 0 gönderilmektedir.
'*****Logger'ı çağıran prosedür*****
Sub KrediRaporu()
On Error GoTo hata
raporLoggerAd="KrediRaporu"
'çeşitli işler
Logger WorksheetFunction.Rept(" ", 50 - Len(raporLoggerAd)) & raporLoggerAd, "OK", 0, "Bölme işlemi başlayacak"
'çeşitli işler
Logger WorksheetFunction.Rept(" ", 50 - Len(raporLoggerAd)) & raporLoggerAd, "OK", 0, "Bölme işlemi bitti"
'çeşitli işler
Logger WorksheetFunction.Rept(" ", 50 - Len(raporLoggerAd)) & raporLoggerAd, "OK", 0, "Rapor başarıyla çalıştı"
Exit Sub
hata:
Logger WorksheetFunction.Rept(" ", 50 - Len(raporLoggerAd)) & raporLoggerAd, "Hata", Err.Number, Replace(Err.Description, vbNewLine, vbNullString)
End Sub
'*****Logger prosedürümüz*****
Sub Logger(rpr As String, logtip As String, hatano As Integer, açıklama As String)
On Error GoTo hata
Dim dosya As String
Dim dosyano As Variant
dosyano = FreeFile
dosya = gunlukklasor + "\GünlükRaporlarLog.txt"
Open dosya For Append As #dosyano
Print #dosyano, CStr(Now), Environ("UserName"), WorksheetFunction.Rept(" ", 10 - Len(Environ("computername"))) & Environ("computername"), rpr, logtip, hatano, açıklama
Close #dosyano
Exit Sub
hata:
Call mail_logger_hata(rpr, alicilar) 'Log prosedüründe bir şekilde hata önceden berlirlenmiş alınırsa alıcılara özel formatta mail atılır
End Sub
Kokpit uygulamalarında Logger kullanımı
Userform konusunda gördüğümüz
Kokpit uygulamalarında,
uygulamayı kullanan kişlerin aktivitelerini aşağıdakine benzer bir kod
ile kayıt altına alabiliriz.
'Form üzerindeki bir butona tıklanınca
Sub Btn_KrediRaporAc()
On Error Goto hata
'rapor açma kodları
Rapor="KrediRapor"
frekans="Günlük"
Call detayraporlogu(Rapor, frekans)
Exit Sub
hata:
On Error Goto -1
On Error Goto hata2
'burada hata kaydını tutan bir log kaydı(aşağıdaki log prosedürünü gölgede bırakmasın diye detayına girmedim)
Exit Sub
hata2:
'Diskte yer olmaması, veya kullanıcının ilgili diske yazma yetkisinin olmaması gibi bir sebeple hata olması durumunda
Call LogHata 'bu sefer maille size bilgilendirme yapılır
End Sub
'*****Logger prosedürümüz*****
Sub detayraporlogu(ByVal Rapor As String, ByVal frekans As String)
If Environ("UserName") = sizinuserınız Then Exit Sub 'kendimizi loglamıyoruz
i = FreeFile
Open adres & "Kokpitlog_detayrapor.txt" For Append As i
Print #1, Environ("UserName"), Date, Time, frekans, Rapor
Close #1
End Sub
Daha sonra bu text dosyasını bir Excel dosya içine aktarırı veya her
açıldığında refresh olan bir bağlantı kurararak gelen data üzerinde pivot
tablolarınızı oluşturabilirsiniz. Metin dosylarından bağlantı kurmak için
buraya
bakabilrisiniz.
Logger içinde hata
Bir sebeple logger fonksiyonu içinde de hata olursa bunu da başka bir hata
bloğuyla ele alabilirsiniz. Veya ana gönderici modülde On Error goto -1
deyip 2. bir hata bloğu açabilirsiniz. Yukarıdaki ilk örnekte Logger
fonksiyonu içinde hata bloğu ile yakaladık. İkinci örnekte ise ana
prosedürde On Error GoTo -1 yöntemini kullandık.
Çeşitli Örnekler
Settings işlemleri
Bir dosyadan bir database'in kullanıcı adı ve şifresini okuma, veya
bir dosyanın path'ini okuma gibi işlemler de bu sayfada
öğrendiklerimizle yapılabilir.
Diyelim ki jenerik bir Add-in yaptınız. Bu Add-indeki makrolardan bir
tanesi bir klasördeki bir Excel dosyasını açacak. İşte bu Excel dosyanın
yerinin sabit olmasının mümkün olmadığı, bunun hangi klasörde olacağını
kullanıcıya bırakmanız gereken durumlar olabilecektir.
SettingforAddin1.txt gibi bir dosya içine bu klasörün tam path'i
yazılabilir. Hatta buna birden fazla dosya için birden fazla klasör de
eklenebilir. İstenirse ";" ile ayırılır, istenirse satır satır yazılır,
hiç farketmez. Yukarıdaki yöntemlerden biriyle ilgili adresi elde etmek
oldukça kolaydır.
SQL
metinlerini değiştirme
Diyelim ki raporlama araçlarınız çok hantal ve katı. Siz de gerek
kendiniz gerek departmanınız için Excel içinden çalışan hızlı ve esnek
bir raporlama platformu oluşturdunuz. İlgili raporların SQL'ini bir
metin dosyası içine koydunuz. Kullanıcıya tarih ve müşteri listesi gibi
sorular sordurarak dosyadaki parametrik kısımlarla kullanıcının verdiği
cevapları replace ettirerek nihai SQL'inizi elde edersiniz. Böylece uzun
bir SQL'i VBA içine satır satır yazmaktan kurtulmuş olursunuz. VBA içine
de SQL kodu yazılabilir ama bu hem kodun uzun ve çirkin görünmesine
neden olur hem de çok zahmetli bir iştir, özellikle SQL onlarca hatta
yüzlerce satırdan oluşuyorsa.
Kodumuz şöyle olabilir:
Sub SQLDeğiştir()
tarih=InputBox("tarihi girin")
If tarih=vbNullString Then Exit Sub
adres="C:\SQLller\kredi.txt"
Open adres For Input As #1
içerik=Input(LOF(1),1)
Close #1
strSQL=Replace(içerik,"trh",tarih) 'SQLi elde ettik
'bundan sonra SQL'i çalıştıracak kodlar devreye girer
End Sub
TEST SORULARI
Son Sorumuz şuymuş:Bir metindeki tüm noktaları yoketmek istiyorsunuz. Hangi fonksiyonu kullanırdınız?
Soru:
A şıkkı:
B şıkkı:
C şıkkı:
D şıkkı:
Doğru Cevap
Etiketler
İlişkili konuyu seç
240739
Label
* Sorulara verilen yanlış cevaplardaki esprili yorumlarım için hoşgörünüze sığınıyorum.
* Test ve Ödevlerdeki bazı detaylar burada anlatılmamış olabilir. Bunları kendiniz araştırıp bulmalısınız.
* Birden çok konuya ait içeriği olan ödevler var. Algoritmik açıdan bakıldığında o an en uygun konuya adreslenmiştir.
Dikkat! Bir soruya cevap verdikten sonra geri dönemezsiniz.
4
2
0
0
Soru No:90.
adres="c:\deneme\abc.txt"
Open adres For Read As #1
Yukarıdaki kod çalıştığında ne olur?
ÖDEVLER
5
0
Ödev No:47.
İçeriği aşağıdaki gibi olan dosyadan 3.satırdaki kullanıcı adını ve 5.satırdaki şifreyi okuyun ve değişkenlere atayın
.
tarif adaslmds şm
aijfş şsş akşl dkşlsd
user:volkan
iqwşdifksdlşfşl
pass:abc345
Çözüme bakın(Başka türlü de çözülebilir tabi, bu benim çözümüm.)
Sub credentialsoku()
Dim ts As TextStream
Set ts = fso.OpenTextFile("C:\Users\Volkan\Desktop\denemeler\vegitarif.txt", ForReading, False, TristateMixed) 'buraya kendi dosya adresinizin geleceği aşikar
ts.skipline
ts.skipline
ts.Skip (5)
user = ts.ReadLine
ts.skipline
ts.Skip (5)
şifre = ts.ReadLine
End Sub