Erişim
Workbooklar bir koleksiyon üyesi oldukları için onlara koleksiyonun
Item
özelliği ve bu özelliğin index numarası ile ulaşabiliriz. Item özelliği
koleksiyonların default özelliği olduğu için tüm diğer koleksiyonlarda
olduğu gibi bunda da yazılmadan es geçilebilir. Yani Workbooks.Items(1) ile
Workbooks(1) tamamen özdeştir.
Koleksiyonlarda indexler 1'den başlar, ilk açılan dosyanın indexi 1'dir.
Workbooklara index numarasıyla olduğu gibi dosya adı ile de, Workbooks("Bütçe2016.xlsx")
gibi, ulaşabiliriz. Dosya ismini Window nesnesi ile de kullanabiliriz.
Windows("Bütçe2016.xlsx") gibi.
Mevcut bir Workbook'u Açma
Diskte kayıtlı olan bir dosyayı Open metodu ile açarız. Hemen makro
kaydedici ile bir dosya açıyorum ve koduma bakıyorum.
Sub Macro3()
Workbooks.Open Filename:="C:\Users\Volkan\Desktop\deneme.xlsx
End Sub
NOT:Bunu yazarken Filename ifadesini kullanmadan veya parantez içinde
şöyle de yazabilirdim: Workbooks.Open
("C:\Users\Volkan\Desktop\a.xlsx"). Parametre yazımının detayları
için buraya bakınız.
Open metodunun birçok parametresi var ama ben burada sadece önemli
olduğunu düşündüğüm 2 parametreden bahsetmek istiyorum. Bunlardan ilki ReadOnly parametresi.
Şimdi diyelim ki, kullanıcılar için UserForm kullanarak bir arayüz veya bir
Add-in oluşturdunuz. Oradaki bir buton da bir dosyayı açacak, ama dosyada
ara ara güncellemeler yapmanız gerekiyor, hatta dosyayı schedule programına
aldınız ve gece belirli bir saatte açılıp refresh olacak ve kaydedilecek. Bunun için dosyanın kimsede açık olmaması lazım. O yüzden kullanıcılar bu
butona tıkladıklarında bunun Readonly açılmasını sağlamak akıllıca olurdu.
İşte bu parametre ile bunu yapabiliyoruz, tabi buna True değerini atayarak.
Peki, diyeceksiniz ki, "Bizim bölümdeki bazı kullanıcılar çok cin veya
umarsız, onlara hazırladığım arayüzü/add-ini değil de doğrudan dosyanın
bulunduğu klasörden dosyayı açabilirler". Bunun da çözümü var, Dosyanın Workbook_Open event modülüne dosyanın Readonly açılıp açılmadığını kontrol
eden bir kod yazarsınız. (Bu detayları yeri geldikçe göreceğiz).
Kodlar şöyle olacaktır:
'dosyayı açmaya yarayan kod
Sub dosyaac()
Workbooks.Open "C:\Users\Volkan\Desktop\deneme.xlsx", ReadOnly:=True
End Sub
'----------------------
'bu dosyanın Workbook_Open modülü
Sub Workbook_Open()
'ilk başta açan kullanıcının sizin dışında bir kullanıcı olup olmadığı kontrolü yapaım
If Environ$("computername") = "bilgisayar adınız" then Exit Sub 'veya username ile de kontrol edilebilir
If Me.Readonly=False Then
MsgBox "Lütfen Add-in üzerinden giriş yapınız"
Me.Close SaveChanges:=False
End If
End Sub
İkinci önemli parametre de Updatelinks'tir.
Bu parametre ile, dosya açıldığında içinde başka workbooklara link varsa
bunların güncellenip güncellenmeyeceğini belirtmiş oluruz. Eğer bu parametre
belirtilmediyse Excel bize sorar. DisplayAlerts=False kullanımının
baskılayamadığı tek uyarı şekli budur, o yüzden bunu kendi içinde
halletmemiz gerekir. 0, güncelleme yapılmasın; 3,
yapılsın demektir.
Linklerle ilgili bir başka önemli metod da LinkSources metodu olup,
bir dosyanın başka bir dosyadan(veya MS uygulamasından) link alıp
almadığını gösterir. Bu metodun dönüş değeri dizidir. Tüm linkleri bir dizi
içinde ayrı elemanlar olarak depolar. Eğer link yoksa dizi boştur ve IsEmpty
ile yakalanabilir.
linkler = ActiveWorkbook.LinkSources(xlExcelLinks)
If Not IsEmpty(linkler) Then
For i = 1 To UBound(aLinks)
MsgBox "Link " & i & ":" & Chr(13) & linkler(i)
Next i
Else
MsgBox "Dosya başka dosyalara link içermemektedir."
End If
Auto_open makrosu
Workbook_Open event handlerına benzer bir de Auto_open
prosedürü vardır. Bu, daha
çok eskiden
kullanılırdı, ancak Excel 2000'den sonra Workbook_Open event makrosu devreye
girdiği için buna pek gerek kalmadı, eski makroları destek adına yaşamaya
devam ediyor. O yüzden olur da elinizde sizden önce
birilerinin yazdığı bir Auto_open kodu varsa ve bunu değiştirmek
istemiyorsanız aşağıdaki bilgi önemli olacaktır.
Biz henüz eventlere(olaylara) gelmedik, neden bundan bahsediyorum.
İşte, VBA içinden çalışan bir Open metodu Auto_open makrosunu tetiklemez,
bu makro sadece dosya manuel olarak yani Excel içinden veya Windows
Explorerdan açıldığında tetiklenir. Bunun için ayrıca dosyayı açtıktan sonra
bir de şu kodu eklemek lazım.
Workbooks.Open "C:\Users\Volkan\Desktop\deneme.xlsx"
ActiveWorkbook.RunAutoMacros xlAutoOpen
Bu arada Workbook_Open makrosunda dosyanın nasıl açıldığı önemli
değildir. Manuel de açılmış olsa, kod ile de açılmış olsa tetiklenir.
Dosya Kapatma
Close metodu ile dosyalar kapatılır.
Bu metodun en önemli parametresi kapatırken kaydedip kaydetmemeye yarayan
Savechanges parametresidir.
Aşağıdaki kod ile, aktif dosyayı kaydederek kapatıyoruz.
Sub kapama()
Activeworkbook.Close savechanges:=True
End Sub
Open metodunda olduğu gibi, eğer bir Auto_close makrosu varsa, bu makro Workbook.Close
metodu ile tetiklenmez, dosya X işaretine basılarak kapatıldığında
tetiklenir. Bunun için Open metodunda olduğu gibi şu kod eklenmelidir,
ancak bu sefer close işleminden önce eklenmelidr.
ActiveWorkbook.RunAutoMacros xlAutoClose
ActiveWorkbook.Close Savechanges:=False
Aşağıdaki örnekte, açık olan tüm dosyaları kapatan ama kapatmadan önce
kaydetip kaydedilmeyeceklerini soran bir kod bulunuyor. Tabi Personal.xlsb
gibi gizli dosyalarda bu işlemi atlıyoruz, yoksa tüm Excel kapanır. Ayrıca
henüz kaydedilmemiş dosyalar için ayrı bir işlem uyguluyoruz.
Sub tümdosyaları_kapat()
Dim wb As Workbook
cevap = MsgBox("Kapatırken save edeyim mi", vbYesNoCancel)
If cevap = vbYes Then
A = True
ElseIf cevap = vbNo Then
A = False
Else
Exit Sub
End If
For Each wb In Application.Workbooks
Workbooks(wb.Name).Activate
If Windows(wb.Name).Visible = True Then
If InStr(ActiveWorkbook.Name, ".") = 0 Then 'henüz kaydedilmemiş bir dosyaysa
wb.SaveAs Filename:=Application.DefaultFilePath & "\" & wb.Name & ".xlsx", _
FileFormat:=Application.DefaultSaveFormat, CreateBackup:=False
ActiveWindow.Close
Else
wb.Close savechanges:=A
End If
End If
Next wb
End Sub
Yeni Dosya Yaratma
Yeni bir dosya yaratacağımız zaman Add
metodunu kullanırız. Bağımsız bir satırda kullanacağımız gibi aynı anda bir
değişkene de atayabiliriz.
Sub yenidosya()
Dim wb as Workbook
Set wb=Workbooks.Add
End Sub
Dosya Kaydetme
Basit kaydetme işlemi Save metodu ile,
farklı kaydetme işlemi ise SaveAs metodu ile
yapılır. Save metodu parametre almaz, dosyayı sadece kaydeder. SaveAs
metodunun birkaç parametresi vardır.
Tüm syntax şöyle: SaveAs(FileName, FileFormat,
Password, WriteResPassword, ReadOnlyRecommended,
CreateBackup, AccessMode, ConflictResolution, AddToMru,
TextCodepage, TextVisualLayout, Local)
FileName ile dosyaya ne isim vereceğimizi belirtiriz, bu isim klasör
ismini de içerebilir, klasör belirtilmezse Default kaydetme klasörüne
kaydedilir.
FileFormat ile dosya formatının ne olacağına karar veririz.
Belli başlı dosya formatları şöyle olup, tüm listeye
buradan ulaşabilirsiniz. Parantez içindeki değerler enumaration
sabitleridir, kodlarınızda parantez içi de dışı da kullanılabilir.
İsim(Değer) | Açıklama ve uzantı |
xlExcel12(50) | 2007 sonrasında binary format, xlsb |
xlWorkbookDefault(51) | 2007 sonrasında gelen klasik format, xlsx |
xlOpenXMLWorkbookMacroEnabled(52) | 2007 sonrasında gelen makrolu format, xlsm |
xlExcel8(56) | 2007 sonrasında eski klasik format, xls |
xlWorkbookNormal(-4143) | 2007 öncesinde klasik format, xls |
Dosya kaydetme işlemlerinde Excel versiyon kontrolünü de yapmak, zorunlu
olmasa da, hataları ele alması açısından akıllıca bir yol olacaktır.
(Versiyon numaralarına
buradan ulaşabilirsiniz.)
Aşağıda örnek bir kod bulunmaktadır.
Sub versiyonkontrol()
Dim wb As Workbook
Dim uzantı As String
Dim frmt As Integer
Set wb = ActiveWorkbook
If Val(Application.Version) < 12 Then
'2007 öncesini kullanıyorsunuzudur
uzantı = ".xls": frmt = -4143
Else
'2007 sonrasını kullanıyorsunuzudur
cevap = MsgBox("Eski formatta mı kaydetmek istiyorsunuz?", vbYesNo)
If cevap = vbYes Then
uzantı = ".xls": frmt = 56 'belki bu dosyayı 2003 kullanan bir alıcıya göndereceksinizidr
Else
uzantı = ".xlsx": frmt = 51
End If
End If
wb.SaveAs Filename:="Yenidosya" & uzantı, FileFormat:=frmt
End Sub
Bir kaydetme metodu daha
vardır, bu metod dosyanın o anda bulunan halini
(kendi üzerinde kayıt işlemi yapmadan) başka bir yere kaydetmeye
yarayan SaveCopyAs metodudur. Mevcut dosya
üzerinde kayıt işlemi yapmadan, ama bu halini de saklaması adına güzel bir
metoddur. Yani özetle, SaveAs açık dosyayı o andaki değişiklikleriyle
kaydederken, SaveCopyAs, açık dosyayı aynen bırakır, buna herhangi bir
kaydetme işlemi uygulamaz, ancak son değişklikleri
içeren halini farklı bir isimde kaydeder. Bu da SaveCopyAs'i yedekleme
amacına hizmet etmesi için harika bir metod yapar.
Mesela aşağıdaki kod Ribbonunuzda kısayol tuşu olarak bile atayabileceğiniz
güzel bir koddur.(FileDialog işlemlerini ayrıca göreceğiz)
Sub anlık_yedekal()
'kodun sağlıklı çalışması için References içinde Microsoft Scripting Runtime kütüphanesi eklenmiş olmalı
'eğer bu kütühane ekli değilse ve şuan eklemeyi tam bilmiyorsanız aşağıdaki satırı diğer iki set cümlesinin altına ekleyin
'Set fso = CreateObject("Scripting.FileSystemObject")
Dim adres As String
Dim isim As String
Dim fd As FileDialog
Dim wb As Workbook
Dim fso As New FileSystemObject
Set wb = ActiveWorkbook
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
fd.ButtonName = "Seçin"
fd.Title = "Kayıt yeri seçin"
fd.InitialFileName = wb.path
If fd.Show = -1 Then
adres = fd.SelectedItems(1)
isim = InputBox("Dosya ismi ne olsun", Default:=fso.GetBaseName(wb.Name) & ".... yapmadan önceki yedek")
wb.SaveCopyAs (adres + "\" + isim + "." + fso.GetExtensionName(wb.Name))
End If
End Sub
Network üzerinde kaydetme işlemi
Network üzerinde bir yere kayıt yaparken bazen bir bug(hata) nedeniyle
kaydetme işlemi ekranda takılı kalmaktadır. Bunun ne zaman olacağı asla
kestirilememekte(%3-5 ihtimal diyebilirim) ve Microsoft da malesef bu soruna
bir çözüm bulabilmiş değildir. Eğer schedule edilmiş bir iş sırasında
başınıza bu gelirse sonrasında çalışması gereken tüm makrolar durmaktadır,
bu da gününüzün iyi geçmemesi için yeterli bi gerekçe olabilir.
Bununla beraber bu konuda bir çözüm bulunmaktadır. Sırayla şu adımlar
uygulanmalıdır.
- Dosya önce yerel makinaya kaydedilir
- Sonra bu dosya kapatılır
- Sonra dosya kapalıyken yerel diskten networkteki klasöre kopyalanır
- Yerel diskteki dosya silinir
Bunun kod örneği aşağıdaki gibidir.
Sub çağıran()
'.....
'.....
hedef=ActiveWorkbook.FullName
saveas_islemi(hedef)
End Sub
Sub saveas_islemi(ByVal hdf As String)
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:="C:\geçici\geçici.xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled 'burda dosya isminin ne olduğu önemli dğeil bile
Kaynak = ActiveWorkbook.FullName
ActiveWorkbook.Close 'filecopy yapmadan önce dosyayı kapatmak lazım yoksa izin vermiyor
FileCopy Kaynak, hdf
Kill Kaynak
Application.DisplayAlerts = True
End Sub
NOT:Eğer bu işlemin Workbook_Open prosedürü içinde yapılması gerekirse
ikinci bi geçici dosya daha yaratmak gerekecektir.
Workbook kaydedilmiş mi kontrolü
Dosya üzerinde, son açıldığından beri bir değişiklik yapılıp yapılmadığını
görmek için Saved özelliği kullanılır. True
dönerse, son açılışından beri bir değişiklik yapılmadığını gösterir.
Bu property, özellikle Excel'i kapatırken işe yarar. Şöyle ki, diyelim ki
belli bir saatte Excel'i kapatmak istiyorsunuz, kapatırken de o anda tüm
açık dosyaları sanki kayıtlıymış gibi göstermeniz gereken durumlar olabilir. Olayı daha somutlaştırmak adına yine kendi işimden örnek vermek istiyorum.
Normalde işimi yaptığımı PC'm dışında Application.Ontime örneklerinde bahsettiğim bir de laptop'ım var, orda da scheduled makrolar çalışıyor. Bunların dışında bir üçüncü bilgisayar daha var ki, bu da bir televizyona bağlı. Televizyonda 10 dk'da bir refresh olan birkaç rapor var, oradan tüm departman anlık olarak bu rapor sonuçlarını görüyor.
Bu bilgisayarı her akşam 21:00'de kapanacak, her sabah 08:30'da da açılacak şekilde ayarladım. Kapama işlemini makroyla, sabah açma işlemini Windows Task Scheduler'a yaptırıyorum. Sabah açılır açılmaz, 21:00'de kapatacak makroyu schedule ediyorum. Schedule etme işinin detaylarını bu sayfada detaylıca göreceğiz.
Bu projeyi
Hayalet Protokol bölümünde detaylıca ele alacağım. Şimdi sadece bizi ilgilendiren kısmının kodlarını inceleyelim.
Ön bir bilgi daha:Task Scheduler Exceli açar açmaz, XLSTART klasöründeki schedule.xlsb dosyası da açılıyor. Bunun Workbook_Open eventinde da birkaç dosyayı açan bir kod var. Açılan ilk dosya "Kredi raporu", aşağıdaki kodlar da bu kredi raporuna aittir.
'Öncelikle Workbook_Open makrosuna bakalım
Private Sub Workbook_Open()
'Öncül kodlar(tanımlamalar vs)
If Environ$("computername") = "A12345" Then 'TV bilgisayarıysa diye bakıyor. Çünkü bu dosyayı düm departmandakiler açabilir. Sadece TVye bağlı bilgisayrda otomatik refresfh devreye girmeli
'kodlar
Application.OnTime Now + TimeValue("00:10:00"), Procedure:="TVRefresh"
'kodlar
End If
Logger "Giris", 0, "Giris yapildi ve 21:00e 'kapat' schedule ediliyor"
Application.OnTime TimeValue("21:00:00"), Procedure:="kapat" '10 dk sonrasına tekrar refreshliyorum
'Diğer kodlar
End Sub
'-------------------------------------------------------------------------
'şimdi de Workbook_BeforeClose'a bakalım
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error GoTo hata 'kapatma tuşuna basıp tüm bunlar yapıldıktan sonra hiç iptal edilecek schedule işşemi kalmıyor ama en son "şu dosyaları save edeyim mi" diye bi dialog çıkarıyor ya, buna cancel dediğimde Excelde kalmış oluyoruz, sonra ikinci bi kapat dediğinde iptal edecek bi schedule olmadığı için hata oluyor, o yüzden hata kontrolü koydum
If Hour(Now) < 21 Then
Application.OnTime TimeValue("21:00:00"), Procedure:="kapat", Schedule:=False '21den önce kapatılırsa kapat'ın schedulını iptal ediyoruz
Logger "Kapanis", 0, "21den once BeforeClose'a girildi ve SCH iptal edildi"
Else
Logger "Kapanis", 0, "21de BeforeClose'a girildi ve kapanıyor"
End If
Exit Sub
hata:
If Err.Number = 1004 Then Resume Next
End Sub
'---------------------------------------------------------------------------
'son olarak da kapat makrosuna bakalım, bizim esas ilgilendiğimiz kısım burası
Sub kapat()
On Error GoTo hata
If Environ$("computername") = "A12345" Then
'.....
For Each wb In Workbooks
wb.Saved = True 'işte Saved özelliğini burada kullanıyorum,
Next wb
Logger "OtoKapanma", 0, "kapat makrosu ile TV'de kapaniyor"
Application.Quit 'Burası ile de Excel kapatılıyor
Else
Logger "OtoKapanma", 0, "kapat makrosu ile kapaniyor"
Windows("Anlık Kredi Raporu.xlsm").Close savechanges:=False
End If
Exit Sub
hata:
Logger "Hata", Err.Number, "Kapat makrosunda hata:" & Err.Description
End Sub
Neden böyle yapıyoruz, bunu açıklayayım.
- Kapat makrosu içine direkt Application.Quit dersem, Excel bana "şu şu dosyaları kaydedeyim mi" diye sorar ve ekran öylece kalır. Bu istediğim birşey değil.
- Neden Workbook.Close deyip Savechanges özelliğine False atamıyorum? Çünkü böyle dersem kodun çalıştığı kredi dosyası kapanırsa(ki ilk o kapanacaktır çünkü ilk açılan dosya o) kalan dosyalar için kapatma işlemi uygulanmaz.
- Tüm dosyaları kaydedip neden kapatmıyorum? Çünkü dosyalar readonly açılıyor, kaydedilemez; gerçi readonly açılmasa bile kaydetme işlemini TV bilgisayarında yaptırmazdım.
- O yüzden dosyaların Saved özelliğine True atayıp, onları sanki kaydedilmiş gibi gösteriyorum ve böylece Excel'in bana soru sormamasını sağlıyorum.
Açık dosyalar arasında dolaşma
Tüm açık dosyalarda dolaşmak ve onlarda işlem yapmak için aşağıdaki basit
kodu kullanabilrisiniz.
Sub wbisimleri()
Dim i As Integer
For i = 1 To Workbooks.Count
'buraya diğer kodlar yazılır
Next i
End Sub
Bazen Personal.xlsb gibi dosyaları hariç tutarak işlem yapmak isteriz.
Örneğin, açık olan tüm dosyalarınızı kapatmak isterseniz yukardaki kodu alıp
araya Workbooks(i).Close dersek, bu kodu yerleştirdiğimiz Personal.xlsb de
kapandıktan sonra hiç açık dosya kalmayacağı için Excel de kapanmış olur. O
yüzden gizli dosyalar hariç bakalım demeliyiz. Ancak Workbook nesnesinin
Visible diye bir özelliği yok, bunun yerine Window nesnesinin bu özelliğini
kullanacağız. Bu durumda kodumuz aşağıdaki gibi olur.
Dim wb As Workbook
For Each wb In Workbooks
If Windows(wb.Name).Visible = True Then
'diğer kodlar buraya
End If
Next wb
Açık dosyalar arasında Window nesnesnin metodları aracılığı ile de
dolaşabiliriz. Window nesnesi birçok açıdan Workbook'a benzese de, bir
workbook içnde birden fazla window olduğu durumlarda biraz farklılaşma
yaşanabilir. Pencereler arasında dolaşma
ActiveWindow.ActivateNext ve
ActiveWindow.ActivatePrevious metodları aracılığı ile olur, ilki bir
sonraki pencereyi(workbooku) aktive ederken ikincisi bir öncekini aktive eder. İki dosya
arasında git gel yaptığınız durumlarda oldukça kullanışlıdır. Ancak birden fazla dosyanın açık olduğu durumlarda
karışıklığa neden olacağı için kullanmanızı tavsiye etmem.
ActiveWorkbook & ThisWorkbook & Me
Çoğu zaman birbiri yerine kullanılabilecek olan bu terimler arasında
küçük farklar bulunmaktadır. ActiveWorkbook, o anda aktif olan dosya iken
ThisWorkbook, kodun çalıştığı dosyadır.
Mesela, bizim ana kod dosyamız olan Personal.xlsb dosyası gizli bir dosya
olduğu için genelde activeworkbook o
olmayacaktır, ancak eğer ondaki bir kod çalışıyorsa ThisWorkbook o olacaktır.
Sayfa gibi bir nesnenin önünde Workbook ifadesi belirtilmediyse Excel
bunun ActiveWorkbookun bir sayfası olduğunu düşünür. Bunun bir istisnası
vardır: Eğer bir Workbook modülüne(ThisWorkbook) girildiyse ve burada bir
Workbook adı belirtilmeden bir nesne mesela bir sayfa adı kullanılıyorsa, bu
durumda bu nesne Activeworkbooka ait değil kodun çalıştığı workbooka ait
olarak algılanır.
Başka bir örnek ise şöyle olabilir: Diyelim ki Kredi Format.xlsm diye bir
dosyanız var, gece belli bir saatte çalışacak şekilde programlanmış olsun.
Bu dosya ilgili saatte açıldığında, Workbook_Open makrosu devreye girsin ve
bazı kodları çalıştırsın. Kodların bir bölümünde PersonelBilgileri.xlsx diye
bir dosyayı açıp bundan sicil kodlarının yanına personelin ismini getirsin ve eğer kredi dosyasında personelbilgi dosyasında olmayan bir sicil varsa
bunu bu dosyaya eklesin. Bu durumda kredi dosyasından copy yapılıp personel
dosyasına paste işlemi yapılacağı için son açık görünen dosya yani
activeworkbook, personelsicil dosyası olacaktır. O yüzden paste işleminden
hemen sonra Activeworkbook.Close denirse, personelsicil dosyası kapatılmaya çalışılır.
Thisworkbook.Close denirse, aktif dosya personel dosyası olduğu halde kredi
dosyası kapatılmaya çalışılır, zaten o kapanırsa kod da durur, ve personel
dosyası açık bir şekilde bekler.
Bu örneği biraz da aşama aşama görelim, yazım tekrarı olmaması adına
ThisWorkbook'un kod boyunca hep Kredi dosyası olacağını söyleyelim ve sadece
Activeworkbook'un değişimini izleyelim:
- Kredi dosyası açılır açılmaz Workbook_Open devreye girdi -->
Activeworkbook=Kredi
- Personel dosyası açıldı-->Activeworkbook=Personel
- Personelden krediye lookup yapılacak, kredi aktive edilir-->
Activeworkbook=Kredi
- #N/A gelenler Personel dosyasına eklenecek, personel aktive edildi
ve yeni siciller yapıştırıldı --> Activeworkbook=Personel.
- Önce personel dosyasını kapatmak için Activeworkbook.Close
Savechanges:=True denir
- Akabinde ThisWorkbook.Close Savechanges:=True denir ve kredi dosyası
da kapanır
Bir de Me ifadesi vardır. Eğer kodumuz
ThisWorkbook modülü içindeyse bu ifade, ThisWorkbook anlamında kullanılabilir. (Ancak
Me'nin başka anlama geleceği durumlar da olabilir. Eğer, kodumuz bir sayfa
modülü içindeyse mesela Sheet1 modülünüdeyse, Me=Sheet1'dir. Onun dışında
Me'nin en çok kullanıldığı yer sanırım UserFormlardır. Bu durumda da Me, formun kendisi
olmaktadır. Bunu formlar bölümünde göreceğiz.)
Dosya ismi ve adresi/klasörü
Dosyanın ismine Name özelliği ile
ulaşırız. İsimden kastımız uzantı dahil isimdir. Ör:"Krediler.xlsx".
Worksheet'in Name özelliğinden farklı olarak bu özellik Readonly'dir(Nesne model tanımınıda "Sets" yok, sadece
"Returns" vardır), yani dosya adı dosya
açıkken değiştirilemez. Ancak SaveAs veya SaveCopyAs
ile dosyaları farklı
isimde kaydetme imkanımız olabilir.
Name özelliği dosyanın sadece adı ve uzantısını verirken,
Fullname
özelliği tüm path'i de verir. Ör: "C:\Users\Volkan\Desktop\deneme.xlsx"
Bazen de dosya adını uzantısı olmadan almak isteriz, mesela uzantısız
ismi alıp bu ismin sonuna bir ek ekleyip sonra tekrar uzantıyı eklemek
isteyebilirsiniz. Bunun için birkaç yöntem var. Hepsini de göstermeye
çalışacağım, başka yöntemler de bulunabilir tabiki, VBA'de bir sonucu
elde etmenin binbir türlü şekli var sonuçta.
1.yöntem: FileSystemObject objesinin
GetBaseName özelliğini kullanmak. Bu kanımca
en ideal yöntemdir, zira her versiyon ve uzantıda işe yarar. Bunu yukarda
anlık_yedek al makrosunda kullanmıştık.
CreateObject("Scripting.FileSystemObject").GetBaseName(ActiveWorkbook.name)
2.yöntem: Uzantının ne olduğunu biliyorsak, bunu "" yani sıfır uzunluklu
metinle replace ederiz.
isim = Replace(ActiveWorkbook.Name, ".xlsx", "")
3.yöntem: Dosya isminde nokta işareti olmadığından eminsek,
noktanın yerini bulup oraya kadar olan ismi almaktır.(Dosya isminde nokta
varsa bu yöntem işe yaramaz)
isim=Left(ThisWorkbook.Name, (InStrRev(ThisWorkbook.Name, ".", -1, vbTextCompare) - 1))
4.yöntem: Uzantı kadar karakteri hariç tutup soldan yeterli sayıda
karakter seçmek. Bu örnekte bir de versiyon kontrolü yapılabilir.
Dim i As Integer
If Application.Version = 12 Then 'Excel 2007 ve sonrasıysa
If ActiveWorkbook.FileFormat=56 then 'xls uzantılıysa
i=4
Else
i=5
End If
Else
i = 4
End If
uzantısızisim= Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - i)
Ve isterseniz bütün bunları bir fonksiyona da atayabilirsiniz.
Function uzantısızisim() As String
Dim i As Integer
If Application.Version >= 12 Then
If ActiveWorkbook.FileFormat=56 then
i=4
Else
i=5
End If
Else
i = 4
End If
uzantısızisim= Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - i)
End Function
Dosyanın bulunduğu klasör ismine Path özelliği, uzantısına da yine
isminde olduğu gibi birkaç yolla ulaşılabilir, ben örnek olarak sadece FileSystemObject objesinin GetExtensionName özelliğini söyleyeyim,
diğer yolları siz düşünün.
FileSystemObject nesnesine ayrıca bakacağımız için burada daha fazla
detaya girmiyorum.
Workbook Protection
Excel'in Review menüsünden konulup kaldırılan şifre işlemleri elebetteki
VBA ile de yapılabilmektedir.
Mesela genel kullanıma açık olan bir dosyanızda otomatik refresh
işlemleri olduğunu düşünelim. Dosya gece çalışıp içindeki sorgular refresh
edilecek ve bazı copy paste işlemleri olacak diyelim. Dosya genel kullanıma
açık olduğu ve kimsenin gizli sayfalardaki veriye ulaşmasını istemediğiniz
için dosyayı korumaya almış olabilirsiniz. Ancak gece dosya otomatik
açıldığında işlemlerin öncesinde korumayı kaldırmalı, işler bitince tekrar
korumayı aktive etmelisiniz. İşte kodumuz:
Private Sub Workbook_Open()
ThisWorkbook.UnProtect (1234)
'işlemler yapılır
ThisWorkbook.Protect (1234)
ThisWorkbook.Close Savechanges:=True
End Sub
Bir dosyada koruma olup olmadığını görmek için de
ProtectStructure özelliği kullanılır.
Aşağıdaki örnekte belirli bir grup dosyada toplu connection şifre
değişikliği gerçekleşecek ancak öncesinde her dosya için protection kontrolü
yapılıyor.
'Belirli dosyaları files isminde bir collectiona atadım ve bu collection içinde dolanarak çeşitli işlemler yapacağım
For Each file In files
Workbooks.Open Filename:=file
Set wb = ActiveWorkbook
If wb.ProtectStructure = True Then
protectlimi = True
wb.Unprotect (1234)
End If
For Each cn In wb.Connections
If InStr(cn.ODBCConnection.Connection, eski) > 0 Then
cn.ODBCConnection.Connection = Replace(cn.ODBCConnection.Connection, eski, yeni)
End If
Next cn
'protection olanlarda tekrar koyalım
If protectlimi = True Then wb.Protect (1234)
protectlimi = False 'tekrar false yapıyorum ki, döngüye tekrar girdiğinde True olarak gitmesin
Next file
Diğer
Workbook'un başka özellik ve metodları da bulunmaktadır. Ben burada
önemli olduğunu düşündüklerimi vermeye çalıştım. Sizler diğer üyeleri
araştırabilir ve kendiniz deneyebilirsiniz.
Bununla beraber RefreshAll ve Connection gibi üyeleri ise VeriTabanı
işlemlerinde ayrıca ve detaylıca ele alacağım için burada değinmedim.