Bu siteye giriş yaparak Çerez kullanımını kabul etmiş oluyorsunuz. İşbu sitede; çerez olarak, sadece son giriş tarihiniz ve eğer üye olursanız oturum statünüz tutulacaktır. Bunlar dışında başka hiçbir bilgi tutulmamaktadır. Çerezler için detaylı bilgi için buraya tıklayınız.
ANLADIM

DUYURULAR

Yeni eklenen ve/veya güncellenen sayfaları görmek için buraya tıklayınız.

Güncel ödev ve test listesini görmek için buraya tıklayınız.

Sitede yapılan iyileştirmeAer ve hata düzeltmelerine ait tüm bilgilendirmeleri görmek içinburaya tıklayınız.

Baş
Udemy
Konular
Son
Konular
Dosyaokumaveyazma
Dosyaislemleri
VBAMakro
VBAMakroDosya işlemleri2

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ç

54261

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
0
0
0

Soru No:63. Aşağıdaki ifadelerden hangisi doğrudur?





Ö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



=YORUMLAR ve SORULAR=


DEVİR UYARISI

Herkese merhaba. Hosting maliyetlerinin aşırı artması yüzünden sitemi yakın zamanda(en geç Mayıs 2023) kapatmaya karar vermiştim. Ancak, siteyi yakından takip eden bir arkadaş siteyi devralmak istemiştir. Siteyi, Mayıs ayında kendisine devir etmeye karar verdim. Üyelik bilgilerini bana güvenerek girdiğiniz için, hepsini silmiş bulunuyorum, yani mail adreslerinizi kimseyle paylaşmamış olacağım. Bilginizi rica ederim.