VBAMakro | Dört Temel Nesne | 4 |
Nesnelerin Efendisi - Application
Giriş
Önceki bölümlerden hatırlayacağınız üzere, Excel, nesneler hiyerarşisi
üzerine kurulmuş bir Nesne Modeline sahiptir ve işte şimdi göreceğimiz
Application nesnesi
de hiyerarşinin en tepesinde bulunur.
Application nesnesi Excelin ta kendisidir ve bu yüzden de default
nesnedir. Bu şu demek, bazı durumlarda bu ifadeyi
yazmanıza gerek olmadan buna ait özellik ve metodları kullanabiliriz. Yani
Application.ActiveWorkbook yazmak ile ActiveWorkbook yazmak arasında hiçbir
fark yoktur. Ancak bazı durumlarda da Application'ı açıkça yazmak gerekir.
Aslında bu konu Global sınıfı ile ilgili bir konu olup önbilgi adına
buraya bakabilirsiniz.
Eğer Excelin kendisiyle ilgili bir işlem olacaksa o zaman Application'ı açıkça
yazmamız gerekir. Mesela Excelden çıkış için Quit metodunu kullanmak,
Excelin ekrandaki boyutlarını ayarlamak gibi. Bununla beraber benim tavsiyem,
Application'ı her durumda yazmanızdır, ancak olur da internette araştırma
yaparken Application'ın yazılmadığını görürseniz de şaşırmayın. Aşağıda
özellik ve metodların tanıtımında Application'ın yazılması gereken durumlar
için bunu açıkça yazdım, diğer durumlar için yazmadım, ancak kod
örneklerinde size verdiğim tavsiyeyi tuttm ve Applicationu hep yazmaya
çalıştım.
Bu arada herhangi bir nesnenin Application özelliğini kullanarak da bu
Application nesnesini elde edebiliriz. Daha teknik bir ifadeyle, bazı
nesnelerde bulunan Application özelliği(propertysi) Application tipinde
değer döndürür, yani Application nesnesi elde edersiniz. Tabi bazen kullandığımız nesne Excel
Nesne Modeline ait bir nesne değil de mesela bir Outlook nesnesi olabilir,
böyle bir durumda Application propertysi kullandığınızda dönen değer
tabiki Excel değil, Outlook olacaktır. Bunları
Diğer Ofis uygulamlarıyla
çalışmak bölümünde göreceğiz.
Genel Görünüm ve Uygulama Seviyesi İşlemleri
Excel'in genelini ilgilendiren birçok üye mevcuttur. Bunların birçoğu
File>Options'tan ulaşabileceğiniz ayarların VBA karşılıklarıdır.
Önemlilerine, daha doğrusu kısa ve orta vadede kullanma ihtimaliniz olan
üyelere bir bakalım.
Application.DisplayFullScreen özelliği:
Boolean tipinde değer döndürür.True atandığında Ribbon olsun durum
çubuğu olsun hiçbirşey göstermez, sadece hücreler ve formül çubuğu
görünür.
Application.DisplayFormulaBar özelliği: Bu da Boolean
tiplidir. False atanırsa formül çubuğu gösterilmez. Bunu bazen formülleri
göstermemek için(protection yaparak da sağlanır) bazen de Displayfullscreen
özelliği ile birlikte, ekranda maksimum alanda yer açmak kullanılır.
Application.DisplayScrollbars özelliği:Bu
da Boolean tiplidir, scrollbarları
gösterir veya gizler.
Application.Interactive özelliği:
Boolean döndürür. Diyelim ki çok fazla copy-paste yapan bir makronuz
var, kodunuz da uzun sürüyor, beklerken o sırada Word veya Outlook'ta
vakit geçireyim dediniz. Outlookta yazdığınız bir metni kesip başka bir
yere kopyalamaya karar verdiniz, ancak tam az önce de Excel VBA kodunuz da bi
kesme işlemi yapmıştı, siz şimdi clipboarda Outlook metnini almış
oldunuz ve kodunuz hızlıca akıp geçti, ve paste işlemini yaparken
Excelden aldığı parçayı değil, Outlooktaki metni yapıştırdı. İşte böyle
bir durum olmasın diye bu tür işlemlerinizin olduğu kodlarınızın başına
bu özelliği yazıp False değerini atayabilir, kodun sonunda bunu yine
True'ya döndürebilirsiniz.
Application.Interactive = False
'kodlar
Application.Interactive = True
Application.Quit metodu:Excelden çıkış için
kullanılır.
Bu arada Excelden çıkış yapılmasını yakalayacak bir event yok malesef. Bunu farklı
yöntemlerle tespit eden bazı makaleler gördüm ama oldukça karışık olduğu için buraya almak istemedim.
Ben şahsen, bunun yerine Personal.xlsb dosyasının kapanıp
kapanmadığını bu dosya içindeki Workbook_Beforeclose olayı ile yakalıyorum, bunun kapanması demek zaten
birçok durumda Excelin kapanması demek oluyor, ki bu da işimi görüyor.
Bunların detayını Olaylar(Events) bölümünde göreceğiz.
Application.StatusBar: Görev çubuğuna
mesaj yazmak için kullanılır. Özellikle kullanıcıları hem bilgilendirmek
hem de bilinçli bir şekilde mesaj kutusu çıkarmak istemediğinizde
faydalıdır. (Bazen schedule edilmiş işlerde arkadan gelen kodların
takılmasını engellemek için, bazen de kullancılardan gelen "Bu kadar
mesajbox çok can sıkıcı" itirazlarını ele almak için). Ancak
unutulmamalıdır ki, MsgBox kadar da dikkat çekici değildir, hatta bazı
durumlarda verdiğiniz mesaj gözden kaçabilir de. O yüzden kritik
mesajları MsgBox ile vermenizi tavsiye ederim. Aşağıda bu özelliği ProgressBar olarak nasıl
kullanıyoruz, onu da göreceğiz.
Son Söz
Object Browser veya MSDN üzerinden Uygulama seviyesinde yapılabilecek
daha bir çok ayarlama olduğunu görebilirsiniz, buraya önemli olduğunu
düşündüklerimi aldım, diğerlerini siz de araştırabilrsiniz. Bunların
çoğu Excel Options üzerinden yapacağınız ayarlamalara denk gelir. Ör:
Autorecover ayarı, autocorrect ayarı, dosyalar açıldığında linkleri
update etsin mi ayarı gibi.
Kod hızlandırıcılar
Aşağıdaki 5 özellik kodlarınızın başında False, sonunda True olarak
ayarlandığında performans kazanımı sağlar.
Application.ScreenUpdating özelliği:Uzunca bir
makro çalışırken ekranın bi gidip geldiğini, titrediğini görmüşsünüzdür(veya göreceksinizdir),
hele hele farklı workbooklar arasında gidip gelme sözkonusu ise bu durum
çok daha göze çarpar. Aslında tüm bu ekran hareketleri, genel süreci uzatan bir
rol oynar, zira işlemciniz o sırada ekranı güncellemekle de
ilgilenmektedir. O yüzden bu ekran hareketini kapatarak kodunuzu
hızlandırabilirsiniz. Bunu da bu özelliğe False değeri atayarak
yapıyoruz. Kod bitmeden hemen önce açmayı unutmayın tabi.
Kod çok uzun sürüyorsa ScreenUpdating=False durumunda kullanıcılar
Excelin kitlendiğini düşünebilir, o yüzden arada bir hareket göstermek
iyi olabilir. Bunu da Doevents metodu
ile yapabiliriz.
'Genellikle bir döngü içinde mantıklıdır
Application.ScreenUpdating=False
Do Until oldumu = True
'ara kodlar
DoEvents 'burda ekran tazelenir
Loop
Application.DisplayAlerts özelliği: Kodunuz
çalışırken Excel bize bazı uyarılar çıkarabilir, bunlar da genelde can sıkıntısı
yaratabilir. Özellikle schedule edilmiş makrolarınız varsa ve bunların
birinde bir sayfa silme, veya varolan dosya üzerine yazma gibi size uyarı
çıkaran kodlar varsa, bu özelliğe False atamazsanız ekran ilk uyarıda
takılı kalır ve sizin bir cevap vermenizi bekler. Eğer bir seri schedule
edilmiş kodunuz varsa, böyle bir durum kabul edilemez. O yüzden en faydalı
bulduğum özelliklerden biri budur. Bu özelliğe false atandığında uyarılara
varsayılan cevap verilir ve kod devam eder. Kod bittiğinde de bu özelliğe
otomatik True değeri atanır.
Ancak bu özellik iki durumda işe yaramaz.
- Mesaj kutularında. Özellikle schedule programınız varsa içinde
mesaj kutusu kullanmamaya çalışın. Hata yönetimi işlemlerinde bile
kullanmayın, onun yerine kendinize mail gönderebilir,
StatusBarı kullanabilir veya
Log kaydı
tutabilirsiniz.
- İçinde başka dosyalara link olan dosyalar açıldığında Linkleri
update edeyim mi sorusu. Burda DisplayAlerts yerine Workbook.Open
metodunun UpdateLinks parametresi kullanılır.
Buradan bakabilirsinz.
Gerçi bunu da aşmanın bir yolu var, ama dikkatli kullanılmasında
fayda var.Application.AskToUpdateLinks özelliğine False atanırsa
linkler otomatik güncellenir, ve bu soru karşımıza çıkmaz, böylece her
Workbook.Open metodunda tek tek Updatelinks özelliğine değer girmek zorunda
kalmayız. Ama bazı durumlarda otomatik update olmasın isterseniz bunu kullanmak yerine
Workbook.open metodunun Updatelinks parametresini kullanın.
NOT: Kodunuzda bir uyarı mesajı çıkma durumu yoksa bu özellik
ekstra bir hızlanma sağlamayacaktır.
Application.EnableEvents özelliği: DisplayAlerts
ile birlikte en çok değer verdiğim bir diğer özellik de budur. Hatta
QuickAccess barda bu özelliği True ise False, False ise True yapan bir
düğmem bile var. Bunu biraz sonra açıklayacağım. Öncelikle ne işe
yarar ona bakalım.
Bu özellik, herhangi bir event(olay) tetiklenmesin diye kullanılır.
İki tür kullanım şekli olabilir.
- Bir programın en başına false, en sonunua tekrar true olacak şekilde.
Böylece tüm kod boyunca hiçbir olay tetkilenmez.
- Bir döngü içinde satır silme, hücre değeri değiştirme gibi bir işlem vardır, ve
sayfa modüllerin birinde Worksheet_change eventiniz de vardır, sadece bu event
tetiklenmesin diye ilgili döngünün başına ve sonuna konur. Böylece döngüden
çıkıldığında diğer eventlerin tetiklenmesine imkan verilmiş olur.
Application.DisplayStatusBar özelliği:Bu
da Boolean tiplidir, En alttaki durum çubuğunu gösterir veya gizler.
(Application.StatusBar özelliği ile karıştırılmamalıdır, bu ikincisinde durum
çubuğunda yazan metni alırız veya metin yazarız.). Excel, her işlem sırasında
StatusBar'ı güncellemekle uğraşmayacağı için performansa katkısı olacaktır.
ActiveSheet.DisplayPageBreaks
özelliği:Bu özellik herne kadar Application nesnesine ait
olmasa da bağlam olarak buraya daha uygun olduğu için buraya aldım.
Kodunuz çalışırken Excel page berakleri tekrar tekrar hesaplamak
durumunda kalabilir. Bunu kapatarak(False atayarak) performansı
iyileştirebilirsiniz.
Application.Calculation özelliği:Bu özelliğe aşağıda detaylı değineceğim.
Ben çok faydalı bulduğum bu 5 özelliği bir prosedüre bağladım, ve birçok
makroya girerken bunlara(bazen sadece ikisine) false değerini atıyorum, koddan çıkarken de
tekrar true değerine döndürüyorum. Fonksiyon ve kullanım şekli
aşağıdaki gibidir:
'Ana prosedürü
Public Sub AlertUpdatingEvent(a As Boolean, u As Boolean, p As Boolean, c As Boolean, Optional e As Boolean = True)
With Application
.DisplayAlerts = a
.ScreenUpdating = u
If c = False Then
.Calculation = xlCalculationManual
Else
.Calculation = xlCalculationAutomatic
End If
.EnableEvents = e
End With
ActiveSheet.DisplayPageBreaks = p
End Sub
'Prosedürü çağırma şeklim
Sub hızlandırıcılar()
On Error GoTo hata
AlertUpdatingEvent False, False, False, False 'Son parametreyi eklemediğimi için default değeri olan True atanır. Böylece eventler çalışmaya devam et sin ama diğer özellikler kapansın demiş oldum
'çeşitli kodlar
'....
AlertUpdatingEvent True, True, True, True 'eski hallerien getirdim
Exit Sub
hata:
AlertUpdatingEvent True, True, True, True 'eski hallerien getirdim
End Sub
Calculation özelliği True/False değeri almadığı için IF kontrolü ile
bunu çözdük. Bir diğer husus da henüz görmediğimiz hata yakalama
bloklarını kullanmış olduk. Olur da bir şekilde kodumuz tam bitmeden
ortada bi yerde patlarsa bu False atadığımız tüm özellikleri hata
bloğunda tekrar True'ya döndürmüş oluyoruz.
Hesaplama, Zamanlama(Scheduling) ve Bekle(t)me
Bu başlıktaki konular her zaman olmamakla birlikte genelde birarada
kullanılmaktadırlar, en azından bir kullanım yakınlığı vardır diyebiliriz.
Hesaplama işleri
Application.Calculation özelliği: Excelin
formüller için hesaplama yöntemini seçmenizi sağlar. Excelin bu özelliğini
bildiğinizi varsayıyorum, bilmiyorsanız öncesinde mutlaka
buraya,
buraya ve
buraya bakın.
Bu özelliğin alabileceği 3 enumaration değeri var.
xlCalculationAutomatic
:Varsayılan değer budur. Herhangi bir hücrede değişiklik olduğunda tüm
workbooklarda formüller yeniden hesaplanır.
xlCalculationSemiautomatic
:Table'lar dışında herşey otomatik hesaplanır.
xlCalculationManual
:Hesaplama işlemi kapalıdır. Kullanıcı hesaplama yapana kadar da öyle kalır.
Özellikle büyük formüllü dosyalarda bir makro çalıştıracaksanız ve herhangi
olumsuz bir etkisi olmayacaksa öncesinde hesaplama kapatılıp makro bitmeden
hemen önce de tekrar açılabilir.
Application.Calculation = xlCalculationManual
'burada diğer işler yapılır
Application.Calculation = xlCalculationAutomatic
Calculate metodu: Tüm workbooklardaki
yeni, değişmiş ve volatil formüllerin hesaplanmasını sağlar(o anda Manuel hesaplama seçimi
yapıldıysa anlamlıdır, aksi halde zaten formüller hesaplanmıştır ve
gerek yoktur).
Calculation property'sinin aksine bunda Application denmesine gerek
yoktur. Örnek biraz aşağıda bulunmaktadır.
Application.CalculationState özelliği: Hesaplamanın ne
durumda olduğunu gösterir. Alabileceği değerleri bir kodla görelim.
Sub CalcState()
If Application.CalculationState = xlDone Then 'enumeration değeri 0
MsgBox "Hesaplama Bitti"
ElseIf Application.CalculationState = xlPending Then 'Görev çubuğunda "Calculate" yazar 'enumeration değeri 2
MsgBox "Tetiklendi ama henüz hesaplama başlamadı"
Else 'xlCalculating 'enumeration değeri 1
MsgBox "Hesaplama devam ediyor 'Görev çubuğunda %sel bir oran görünür
End If
End Sub
Done ve Calculating gayet aşikar fakat
Pendingi tam olarak anlamamış
olabilirsinz. Hani bazen Excel manuel hesaplama modundayken,
formüllerden birine baz teşkil eden bir hücreyi değiştirdiğinizde en
alttaki durum çubuğunda Calculate yazar, bazen de dosyanızda çok sayıda
formül varsa Excel bu kadar
formülle başa çıkamaz ve en altta yine Calculate yazar. İşte bu durum
xlPending durumudur. Böyle durumlarda Excelde hesaplama yapmak için Formulas
menüsünden Calculate demek veya F9'a basmak gerekir.
NOT:Bir de kısırdöngülü
formüllerde Calculate yazdığını görürsünüz, bu da bir xlPending
durumudur ancak onun çözümü aşağıdakiler değil, kısırdöngüye neden olan
formülü düzeltmektir.
İnternette birçok forumda yaygın bir kullanım örneği olarak aşağıdaki
kod parçası verilir. Deniyor ki, "kodunuz çalışmaya başlamıştır,
büyük bir hesaplama yapıyordur, ancak daha hesaplama bitmeden bir
sonraki satıra geçer, bu da hatalı sonuçlar neden olabilir, o yüzden
aşağıdaki kod ile kodununzun aşağı satıra geçmesini engellersiniz".
Application.Calculate 'hesaplamaya başladınız
Do While Application.CalculationState <> xlDone
DoEvents
Loop
'kodun kalan kısmı
Halbuki Calculate metodu asynchoronus değildir, yani hesaplama
bitmeden zaten bir sonraki satıra geçmez. O yüzden yukarıdaki tavsiye
bence anlamsızdır. Ancak bir şekilde(forumlarda yardım isteyen diğer
kişilerin başına gelen çok özel durumlarda, artık neyse o özel durumlar bilemiyorum)
böyle birşey olduğunu farkederseniz bu kodu kullanabilirsiniz.
Bu arada şu farkı iyi anlamanız gerekiyor; Calculate metodunu
uyguladığınızda sanki Excelde F9'a basmış veya Calculation menüsünden
Calculate butonuna basmış gibi olursunuz ve formüller yeniden hesaplanır ancak sayfanız o an hala Manuel modda kalmaya devam eder ve
sonraki aşağı/sağa formül kaydırma işlemleri sonucunda formüller hesaplanmaz. Halbuki Calculation özelliğine xlAutomatic atayarak hem
hesaplamayı
açmış olurusunuz hem de statüyü kalıcı olarak Otomatiğe çevirmiş
olursunuz ve sonraki formül kaydırmalarda formüller hemen hesaplanır.
Hangisi ihtiyacınıza uygunsa onu kullanmalısınız. Eğer ki geçici bir hesaplama yapmak istiyorsanız Calculate metodunu, kalıcı hesaplama için ise Calculation özelliğini kullanabilirsiniz.
Önemli bir husus da şudur; Application, Worksheet ve Range nesnleri için varolan Calculate metodu
Workbook için bulunmamaktadır. Ancak aşağıda gibi bir kod ile sadece Activeworkbook'un
Calculation işlemini yapabilrsinz.
Sub CalcBook()
Dim ws As Worksheet
Application.Calculation = xlManual
For Each ws In ActiveWorkbook.Worksheets
ws.Calculate
Next
Set ws = Nothing
End Sub
Application.CalculateFull: Otomatik veya Manuel
modda olun farketmez, tüm formüllü hücreleri yeniden hesaplar. Calculate
metodundan farklı olarak, sadece yeni, değişmiş ve volatil formülleri
değil, tüm formül içeren hücreleri tekrar hesaplar. Bu yüzden
genelde(her zaman değil) normal Calculate metoduna göre daha yavaştır. Durum
çubuğunda ısrarla Calculate yazıyorsa yani xlPending durumundan bir
türlü çıkamıyorsanız bunu kullanabilrsiniz.
Klaveye kısayolu Ctrl+Alt+F9'dur.
Application.CalculateFullRebuild:Bu metod
CalculateFull ile aynı işi yapıyor gibi görünüyor, Excel 2007 ve sonrası
kulanıcıların çok kullanacağı bir metod değildir. Özetle şunu diyebilirim
ki, 2007 öncesi versiyonlarda aşırı formülden dolayı hesaplama zinciri
bozulduysa ve F9 yaptığınız halde Excel hesaplama yapmıyorsa bu metod işe
yarayacaktır. Ancak sanki tüm hücrelere formülleri
tekrar girmek gibi iş yaptığı için CalculateFull'e göre biraz daha yavaştır.
Application.CalculationInterruptKey:Hesaplamanın
hangi tuşla iptal edileceğini söyler. Bunun pratik kullanımı,
Personal.xlsb'nin Workbook_Open makrosu içine yazma şeklindedir. Ben
şahsen sadece ESC tuşuna(xlEscKey) basıldığında hesaplamanın iptal
edilmesini istiyorum, size de bunu öneririm. Zira eliniz yanlışlıkla bi
ok tuşuna değse bile o anda %90larda olan calculation tekrar %0dan
başlayacaktır.
Genel öneriler
- Önce normal Calculation yapın. Sonra state kontrol edin, hala
xlPendingse CalculateFull uygulayın.
- Kod hızlandırıcılar bölümündeki 3 özelliğe bazen bu Calculation'ı
da ekleyerek daha hızlı kod çalıştırabilirsiniz. Ancak kullanımı konusunda
dikkatli olmak gerekir, zira arada bir yerlerde formül çekme/uzatma ve sonra
Copy-Paste işlemi varsa Calculation sonucunda hatalı durumlar
oluşabilir.
Sub Calculationlar()
AlertUpdatingEvent False, False, False
Application.Calculation = xlCalculationManual
'kodlar buraya gelir
'arada bir açmak gerekebilir
ActiveSheet.Calculate 'duruma göre Application.Calculate veya Range("...").Calculate
If Application.CalculationState=xlPending then Application.CalculateFull
'tekrar kapatalım
Application.Calculation = xlCalculationManual
'diğer kodlar
'çıkışta tekrar eski haline getiriyoruz
AlertUpdatingEvent True, True, True
Application.Calculation = xlCalculationAutomatic
End Sub
Son olarak Calculate işlemlerinin VBA ve Excel ilişkilerini tekrar şöyle
bir özetleyelim:
İşlem |
Excel |
VBA |
Tüm workbookları hesaplatmak |
Calculation>Calculate(veya F9) |
Application.Calculate |
Aktif sayfayı hesaplatmak |
Calculation>Calculate Sheet(Shift+F9) |
ActiveSheet.Calculate |
Aktiveworkbook hesaplatmak |
- |
Döngü içinde Sheet.Calculate |
Belli bir range'i hesaplatmak |
- |
Range.Calculate |
Full hesaplama yapmak |
Ctrl+Alt+F9 |
Application.CalculateFull |
Calculation için örnek bir senaryo
Şimdi diyelim ki departmanınızdaki kişilerin kullanması için çok
sayfalı ve çok formüllü bir excel dosya hazırladınız. İlk sayfada tek
sayfalık bir karne/skorkart tarzı birşey var, diğer sayfalarda ise toplu
listeler. Hepsi de datayı gizli bir sayfadan alıyor.
Liste sayfalarında çok fazla satır ve sütun ve hep SUMIFS tarzı
formüller olduğu için bunlarda sort veya filter işlemleri çok ağır
olmaktadır, zira bu iki işlem de calculation tetikleycisidir. Çözüm
şöyle olabilir:
Dosyanın Workbook_Activate(Neden Workbook_Open olmadığını az sonra
belirteceğim) eventine dosya açılır açılmaz Calculation'ı xlManual yapan
kodu ekledim, ve bi mesajbox ile bunu kullanıcıya bildiriyorum.(Mesajbox
sinir bozucu gelirse statusbara da yazdırabilirsiniz). Karne sayfasına
gelince ise Worksheet_Change eventine yazdığm kod ile
sadece belli hücreler değiştiğinde hesaplama yapmasını sağlıyorum. Kullanıcı olur da o sırada başka
dosyalarda işlem yapmak isterse Workbook_Deactivate eventine
calculationı tekrar otomatik yapan bir kod yazdım ki, kullanıcı o sırada
Calculationın kapatıldığını unutup diğer dosyalarda formül uzatma gibi işler yaparsa hep aynı
sonucun yazdığını görüp
şaşırmasın. Hatta ortalama bir kullanıcı Excelin Calculation özelliğinden
bihaberdardır bile diyebiliriz. Kodlar şöyle:
Private Sub Workbook_Activate()
Application.Calculation = xlCalculationManual
Application.StatusBar = "Dosya aktive olduğu için Calculation yine geçici olarak Manuel yapıldı"
End Sub
Private Sub Workbook_Deactivate()
Application.Calculation = xlCalculationAutomatic
Application.StatusBar = "Başka dosyayı açtığınız için Calculation tekrar otomatik yapıldı"
End Sub
Application.Volatile metodu:Bu metoda
UDF bölümünde değindiğimiz için burada ayrıca bahsetmiyorum.
Erteleme ve bekleme
Application.OnTime metodu: Site boyunca
zaman zaman programlanmış işlerden veya İngilizce tabiri ile işleri schedule
etmekten bahsediyorum,
mutlaka dikkatinizi çekmiştir. İşte bu işi bu harika metod ile
başarıyorum. Genel kullanım şeklini aşağıda veriyorum ama bu konuyla
ilgili uzunca bir örneğe
şu sayfada ele aldım.
Şimdi metodun genel syntaxına bakmadan önce görevini açıkça
belirtelim: Bir prosedürün belirli bir anda çalışmasını sağlar, ki bu
tanım bize onu asıl amacı dışında(ama faydamıza olacka şekilde) kullanacağımızı da söylemektedir, yani Wait ve Sleep
metodları yerine. Bunlara da hemen bu metoddan sonra değineceğiz.
Syntax: ApplicationObject.OnTime(EarliestTime, ProcedureName, LatestTime,
Schedule
Tam açıklaması şöyle oluyor. ProcedureName ismindeki makro
EarlistTimeda başlasın, o sırada başka bir makro çalışıyorsa veya Exceli
meşgul eden başka birşey varsa da LatestTime'a kadar çalıştırmayı
denesin. Eğer LatestTime belirtilmezse, excelin meşguliyeti bitene kadar
bekler ve sonra çalıştırır. Yani eğer, "Kod,programladığım saatten en geç
1 saat içinde çalışsın, yoksa çalışmasının bi anlamı yok, çünkü o rapor
artık işe yaramaz olur" dediğiniz bir durum varsa bu parametreyi
"EarliestTime + 1 saat" olarak belirtebilirsiniz, aksi durumda boş bırakın.
Schedule parametresi default değeri True'dur ve genelde yazılmaz, schedule
ettiğiniz bir prosedürü iptal etmek için bu değere False atarsınız.
Önemli Not:Excelden her çıkış yaptığınızda, tüm schedule programı
sonlanır. Eğer, recursive(tekrarlı) yani bittikten sonra yeniden
schedule edilen programınız varsa Exceli hep açık bırakmanız gerekir, ki
benim bilgisayarımda olan budur. Ve bence bu metoddan verim almanın en
güzel yolu onu recursive bir şekilde kullanmaktır. Şimdi küçük bir örnek
bakalım, siz sonra yukarda linkini verdiğim yerden daha detaylı örneği
incelersiniz.
Sub ontimeornek()
Application.OnTime Now + TimeSerial(0, 0, 3), "mesajver" 'Asynhronous metoddur
MsgBox "beklemeden çalıştım"
End Sub
Sub mesajver()
MsgBox "selam"
End Sub
Örnekte gördüğünüz üzere mesajver makrosunun çalıştırılacağı zamanı
Run tuşuna bastıktan 3 sn sonra çalıştıracak şekilde parametrik verdim.
Yani burada spesifik bir saat belirtmek yerine, şimdiye(Now) referansla
bir saat de verebiliyoruz. Örnek gösterimler şöyle olabilir.
Application.OnTime "22:30:00"
Application.OnTime Now + TimeValue("00:10:00") 'Şimdiden 10 dk sonra
Application.OnTime Now + TimeSerial(0,10,0) 'Bu da aynı. TimeSerial'de saat, dakika ve saniye virgülle ayrılır
Application.Wait metodu: Programın belirli
bir süre durmasını(beklemesini) sağlar. Peki neden? Neden programınızın
bir süre durmasını bekleyesiniz ki? İşte örnek senaryolar olmayınca
malesef makro öğrenimi çok zor olmaktadır. Önce gelin nasıl
kullanılacağına , sonra nedenine bakalım.
Sub bekle()
Application.Wait (Now + TimeValue("0:00:10")) 'Synhronous metoddur
MsgBox "bekleyip çalıştım"
Call mesajver
End Sub
Sub mesajver()
MsgBox "selam"
End Sub
Bu metod Boolean döndürdüğü için belirli bir zaman geçip geçmediğini
kontrol etmek için de kullanılır.
If Application.Wait(Now + TimeValue("0:00:10")) Then '10 sn geçtiyse. =True demeye gerek görmeyebiliyoruz, önceki konuları hatırlayacak olursanız
Application.Speech.Speak "Zaman doldu" 'Evet, Excel 2013ten itibaren artık konuşuyor
End If
Dikkat: Bu metod kullanılırken çok dikkat
etmek gerekir, zira ilgili süre geçene kadar Excel kitlenir.
Şimdi de örnek bir senaryo düşünelim. Diyelim ki bir makronuzu
sabah/gece 5'e
schedule ettiniz: Kodunuz bir veritabanını güncel veri gelmiş mi diye 10 dk'da bir tarıyor, ve sonunda 5:40ta yani 4. seferinde güncel datayı gördü ve
hemen çekti, bikaç işlem yaptı, 5.43te işi bitti ama kod devam ediyor,
ettiği yerde başka bir veritabanı bağlantısı yapacak, ama siz biliyorsunuz
ki o veritabanı 6:30da doluyor, 5.43te buraya bağlanmaya çalışırsa
güncel olmayan veriyi alabilir, işte böyle bir durumda kodu 6:30a kadar
bekletmek gerekebilir.
Application.Wait "06:30:00"
Hatta bunu bir de saat 6:30dan önce mi diye kontrol etmek
lazım, eğer ilk veritabanını sorgulanması 5:40 değil de 6:30dan sonraya
kaldıysa ikinci veritabanı için beklemelik bir durum olmayacaktır, o
yüzden Wait kullanmamak gerekir, aksi halde ertesi sabah 6:30'a kadar
Exceliniz bloke olur.
Bir diğer örnek durum da şu olabilir. Veritabanı işlemlerinde
göreceğiz gerçi ama RefreshAll gibi asyncrohnous(sonraki
satıra geçmek için beklemeyen) bir metod çalıştığında
kod okuma devam eder. Eğer tüm refresh işleminin bitmesini beklesin
istiyor ve tahminen refreshin ne kadar süreceğini biliyorsanız
ilgili süre kadar bekletebilirsiniz.
'Önceki kodlar
Me.RefreshAll
Application.Wait Now + "00:30:00" '30 dakika yeterlidir
'diğer kodlar
Yine bu
linkte sorulan soruya da güzel bir yanıt verilmiş. Soru şu: "Bir
veritabanından 3000 farklı kayıt okumaya çalşıyorum, ancak bazen kod o
kadar hızlı akıyor ki, bazı kayıtları okuyup hedef dosyaya yazdıramıyorum.
Excelin her kayıt için yeterince beklemesini nasıl sağlarım." Buna verilen
cevap oldukça güzel, gerçi bunda Wait metodu yerine hemen bir alttaki
Sleep fonksiyonu kullanılmış. Ayrıca DoEvents bilgisi de gerekiyor, ki o da
Sleepten
hemen sonraki konu.
Sleep Metodu: Bu metod VBA metodu
olmayıp Windows fonksiyonudur, bu yüzden bunu kodumuzun başına import
etmek gerekir. Wait ile aynı işi yapar, tek farkı, milisaniye cinsinden
paremetre almasıdır. İmport işlemi dahil tam bir kod örneği aşağıda
bulunmaktadır. (import işlemleri hakkında detaylı bilgi
burada mevcuttur)
'bu kısım import kısmıdır, kod sayfasının en tepesine yazılır
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) '64 Bit Sistemler için
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) '32 Bit Sistemler için
#End If
'bu kısım esas kod kısmı
Sub sleepmetodu()
MsgBox "Başlıyorum"
Sleep 10000 '10bin mili saniye yani 10 sn bekliyoruz
MsgBox "Süre bitti"
End Sub
Yukarda belirttiğimiz gibi, OnTime metodunu da amacı dışında bir nevi
bekleme amacı olarak kullanabiliriz, ancak Wait ve Sleepte kod akışı o
satırda duruken OnTime'da durmaz devam eder, o yüzden OnTime eğer bu
amaçla kullanılacaksa ilgili prosedürün son satırı olmasında fayda var.
Sub tetikleyici()
'çeşitli kodlar
Application.OnTime Now + TimeSerial(1,0,0), "makrom"
End Sub
'şimdi bu durumda 1 saat sonra makrom makrosu başlayacak. Ekran 1 saat boyunca serbest.
Sub makrom()
'çeşitli kodlar
End Sub
Bunların dışında bir de farklı bir yaklaşım var ki, bunda da
OnTime'da olduğu gibi bekleme süresince Excele erişimimiz açık
durmaktadır, zira bunda bir döngü içinde DoEvents
metodu kullanılmaktadır.
Dim newTime As Date
newTime = Now + TimeValue("00:00:10")
Do While Not Now >= newTime
DoEvents
Loop
MsgBox "selam
DoEvents: MSDN açıklaması
çok yüzeysel malesef, ben yine de bu açıklamayı vereceğim, sonra nerelerde kullanıldığını
söyler ve birkaç örnek gösterirsem daha anlaşılır olur.
MSDN açıklaması: Program akışını işletim sistemine verir.
Şimdi MSDN'nin açıklamasını biraz
daha açalım. Bir Windows uygulamasında aynı anda onlarca program
çalışabilmektedir. Sizin Excel VBA kodunuz işlemciyi çok fazla bloke
ederse Windows buna sinirlenebilir, hatta bakar ki Excelden ses seda
yok, bunun kitlendiğini düşünüp kapatmaya çalışabilir, çünkü belleksiz
kalan diğer gariban programlar çalışsın diye
düşünür. İşte böyle durumlarda araya bi DoEvents sokmak gerekebilir,
ki Windows Excel'in yaşadığını düşünsün. Peki genel olarak nerelerde kullanırız ona bakalım:
Bu yukardaki ilk iki maddeyi içeren bir örnek verelim. Uzun bir
döngüsel işleminiz var diyelim, hızlı çalışsın diye ScreenUpdating=False
yaptınız. Kullanıcı program kitlendi sanmasın diye, DoEvents metodu
Statusbarı bir nevi Progressbar gibi kullanmamızı sağlayacak. Tabi bu aşağıdaki
örnekte %1den %100e giden bir progressbar yapmış olduk ancak siz
isterseniz başka ölçüler kullanabilrisiniz. Mesela 20 bölgelli bir
bankada her bölgenin işi 1 dk sürüyorsa, her döngü sonuna "20 bölgede "
& i & " adedinde işlem tamam" gibi bir metin yazdırabilirsiniz.
Sub doeventprogressbar()
Dim i As Long
Dim bas As Double
bas = Timer
Application.ScreenUpdating = False
For i = 1 To 100000 '100.000in 100lük dilimlere böldüğümüzde her bir bölümün büyüklüğü
Cells(1, 1) = i
If i Mod 1000 = 0 Then
DoEvents
Application.StatusBar = "%" & i * 100 / 100000
End If
Next i
Application.ScreenUpdating = True
MsgBox Round(Timer - bas) & " sn sürdü"
End Sub
Bu arada bu koddan screenupdatingi çıkarın, programın ne kadar
yavaşladığını göreceksiniz.
Dosya ve Klasör işlemleri
Bazen kullanıcıdan, üzerinde işlem yapılacak bir dosya veya klasör
seçmesini isteriz. Bazı durumlarda seçilen dosya ile sadece işlem
yapılırken bazen dosyanın açılması sağlanır.
Bu bölümde anlatılan konular genel olarak, seçilen dosyayı açma veya
bir şekilde dosya/klasör ismi elde etme amacıyla kullanılan işlemlerle
ilgilidir. Daha genel olarak tüm dosya işlemlerini
şurada ele alıyor olacağız.
Kullanıcıdan dosya/klasör bilgisi istemenin en ilkel yolu bunu bir
inputboxla sormak olacaktır, ancak şükür ki VBA'de bunu yapmamızı
sağlayan daha iyi yöntemler var. Şimdi bunlara bakalım:
Application.FileDialog özelliği: 2002
yılında gelen bu özellik bundan daha önce varolan GetOpenFilename ve
GetSaveAsFileName özelliklerinin gelişmiş halidir. O yüzden bu ikisinin
artık çok kullanmaya gerek yok, ama başka kodlarda görmeniz durumunda
ne olduğunu bilmeniz için onlara da kısaca değineceğiz. Bu
özelliğin FileDialogType şeklinde tek bir parametresi vardır ve o da MsoFileDialogType
sabitlerinden biri olabilir. Bunlar:
-
msoFileDialogFilePicker: Dosya seçtirir, path
dahil tam
ismini döndürür(Ör:"C:\Hedefler\Satış\2016.xlsx"
- msoFileDialogFolderPicker: Klasör seçtirir,
path dahil tam
ismini döndürür(Ör:"C:\Hedefler\Satış"
- msoFileDialogOpen: Açılacak dosyayı seçtirir(onu
açmaz, sadece seçtirir)
- msoFileDialogSaveAs:Farklı Kaydet dialog
kutusunu açar, dosyayı kayderken ismin ne olacağını girmenizi sağlar(dosyayı
kaydetmez,sadece isim ve adres belirlersiniz)
Bu property ile FileDialog nesnesi elde edilir. Bu nesnenin de kendi
metod ve özellilikler vardır. Genel olarak önce bu tipte bir değişken
yaratmak ve ona atama yapmak intellisense açısından uygun olacaktır.
Bu nesnenin iki metodu var, pratikte en çok kullanacağınız metodu
Show metodudur. Bir seçim yapıldıysa -1(True) döndürür, seçim
yapılmadan işlem iptal edilirse 0(False) döndürür.
Bu sayfada
gördüğümüz gibi, bu metod arka planda bir function prosedür olarak
hazırlanmıştır, çünkü bize bir değer döndürüyor.
Seçim sonucu True ise Execute metodunu
yazarak duruma göre uygun işlemi de yaptırabilrisiniz. Ancak bunun
yerine Workbook.Open veya Workbook.SaveAs gibi metodlar da
kullanılabilir. Execute yazmak basit görünse de arka planda seçim tipi
ve sonucunu karşılaştıran bir koşullu yapı barındırdığı için perfomans
sorununa neden olabilir, özellikle büyük kodlarda. O yüzden doğrudan
Workbook metodlarını kullanmanızı tavsiye ederim.
Önemli propertyler ise şöyledir.
- AllowMultiSelect: Çoklu seçim yaptırma imkanı verir,
sadece dosyalar için geçerlidir, klasörlerde çoklu seçim yapılamaz.
- Title:Dialog kutusunun başlığını değiştirebilirsiniz.
- InitialFileName:Seçim yaptırırken sık kullanılan bir dosya/klasör
varsa default olarak bunu seçtirebilirsiniz, SaveAs yaparken de yine
aynı mantıkla default bir adres ve isim belirleyebilirsiniz.
- Filters:Hangi tür dosyaların gösterileceğini
belirlersiniz.
- SelectedItems:Seçilen dosyaların/klasörlerin
tam adresini verir. Tek seçim yapıldıysa SelectedItems(1) şeklinde
kullanılır.
Şimdi ilk olarak dosya seçme örnekleriyle başlayalım, sonra da
diğerlerine geçelim.
Aşağıdaki örnekte dosya seçtiriyorum ve seçilen dosyaları siliyorum. Bu arada With .. End With yapısını nasıl kullandığımıa dikkat edin. Bilgi almak için buraya tıklayın.
Sub Dosyaislemlerim()
Dim i As Byte
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = True
.Title = "Silinecek dosyaları seçin"
.Show
For i = 1 To .SelectedItems.Count
Kill .SelectedItems(i) 'buradaki kill metodunu sonra göreceğiz, şimdilik sadece sdosya silmeye yaradığını bilin
Next
End With
End Sub
Dialog kutusunu seçim yapmadan kapadığımızda bunu anlayan bir kontrol noktası koyalım. Bu
kontrol noktasını doğrudan metodun sonuç değeri ile yapıyoruz.
Sub Dosyaislemlerim()
Dim i As Byte
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = True
.Title = "Silinecek dosyaları seçin"
If .Show = 0 Then
MsgBox "Seçim yapmadan çıkış yaptınız"
Exit Sub
End If
'iptal edilirse buraya gelmeden program sonlanır, çünkü Exit Sub denildi
For i = 1 To .SelectedItems.Count
Kill .SelectedItems(i)
Next
End With
End Sub
Şimdi de diğer 3 tip için de örnekler yapalım. Önce dosya aç:
Sub Dosyaislemlerim()
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogOpen)
With fd
'.AllowMultiSelect = True
.Title = "Açılacak dosyayı seçin"
.InitialFileName = "C:\deneme.xlsx"
If .Show = True Then
.Execute 'veya Workbooks.Open (.SelectedItems(1))
End If
End With
End Sub
Şimdi default dosya adı belirtmeyelim, kullanıcı seçsin ama çok
kalabalık dosya türünü barındıran bir görüntü de olmasın, sadece excel
dosyaları olsun.
Sub Dosyaislemlerim()
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogOpen)
With fd
'.AllowMultiSelect = True
.Title = "Açılacack dosyayı seçin"
'.InitialFileName = "C:\inetpub\wwwroot\ee\yuklemeler\pivot - data.xlsx"
.Filters.Clear 'varsayılan olakra 20 tane dosya tipi var, bunları temizlzeyelim
.Filters.Add "Excel dosyaları", "*.xls*"
.Filters.Add "Tüm dosyalar", "*.*"
If .Show = True Then
.Execute 'veya Workbooks.Open (.SelectedItems(1))
End If
End With
End Sub
Eğer farkettyiseniz msoFileDialogFilePicker ve msoFileDialogOpen ifadelerinin her ikisini de dosya açmada kullanabiliriz. Hatta dosya silme işlemi için bile msoFileDialogOpen kulanılabilir. Yukarıdaki msoFileDialogFilePicker ile yapılmış dosya silme örneğinde kendiniz deneyip görebilirsiniz. O halde neden iki ayrı ifadeye gerek var diye düşünüyor olabilirsiniz. Buna malesef benim de cevabım yok. O kadar araştırdım ancak bir açıklama bulamadım. Bulduğum zaman bu paragrafı
güncellerim.
Şimdi de folder işlemlerine bakalım
Sub folderislemleri()
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
With fd
.AllowMultiSelect = True 'buna True dense bile çoklu seçim yaptırmaz
.Title = "klasör sçein"
If .Show = True Then
MsgBox .SelectedItems(1) & " klasörünü seçtniz"
End If
End With
End Sub
Son olarak da SaveAs işlemi yapalım.
Sub Dosyaislemlerim()
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogSaveAs)
With fd
.InitialFileName = "C:\deneme.xlsx"
If .Show = True Then
.Execute 'veya Workbooks.Saveas ile
End If
End With
End Sub
Application.GetOpenFilename ve Application.GetSaveAsFilename:
Yukarıda bahsettiğim gibi yeni kodlarınızda bu iki metod yerine
FileDialog yöntemini kullanmanızı tavsyie ederim. Bunları sadece geriye
dönük uyumluluk adına ve karşınıza bunları içeren bir kod
geldiğinide anlamanız için bilmeniz gerektiğini düşünüyorum.
Syntax: GetOpenFilename( GetOpenFilename(FileFilter, FilterIndex, Title, ButtonText, MultiSelect)
Bunda FileDialogda olduğu gibi bir nesne yaratmaya gerek yok,
doğrudan kullanılabilir. Bundan dönen değer üç şey olabilr. Seçim
yapılmadıysa False(Boolean) veya tek bir dosya seçim yapıldıysa
dosyanın tam adını(path dahil) veren bir string ya da çoklu seçim
yapıldıysa bir dizi. O yüzden dönüş tipi varianttır ve tanımlanırken de böyle
tanımlanmalıdır.
Yine FileDialogda olduğu gibi burda da doğrudan dosya açma veya
kaydetme yok sadece dosya ismi elde edilir, sonrasında ayrı bir satırda
dosya açma işlemi yapılır.
Sub getopenfilenameornek()
Dim filtreler As String
Dim başlık As String
Dim dosya As Variant
filtreler = "Excel dosysaları(*.xls*),*.xls*, Tüm dosylar (*.*),*.*"
başlık = "Açılacak dosyayı seçin"
dosya = Application.GetOpenFilename(filtreler, 5, başlık, , True)
If IsArray(dosya) Then 'multi parametresini true belirlediğimiz içn öncelikle dizi olup olmadıını kontrol etmemiz lazım
For Each a In dosya
Workbooks.Open (a)
Next a
Else
If dosya = False Then
MsgBox "seçim yapılmadı"
Else
Workbooks.Open dosya
End If
End If
End Sub
SaveAsFileName de bunun aynısı olup sadece save etmeye yarıyor.
FindFile: Bu da,
GetopenFileName ve FileDialog gibi yine Open File dialog kutusunu getirir
ancak geriye bir dosya adı döndürmez. Eğer seçim yapıldıysa dosyayı açar
ve True değerini döndürür, seçim olmadıysa False döndürür. Bunu
diğerleriyle bir anlam bütünlüğü var diye buraya aldım ancak açıkçası
pratikte nasıl bir kullanımı olur bilmiyorum, şahsen ben şimdiye kadar
hiç kullanmadım.
Diğer üyeler
Application.ActivateMicrosoftApp metodu:
Bu metod, başka bir MS Office uygulamasını açar. Eğer halihazırda ilgili
uygulama açıksa onu aktive eder yoksa yenisini yaratır ve açar. Ancak bunu
bu şekilde doğrudan kullanmak yerine ilgili Office uygulamasını obje olarak yaratıp onun
Nesne modeline ulaşmak istemeniz durumunda ise(ki daha çok bu yöntemi
kullanacaksınız) farklı bir yöntem kullanılır. Bunu da bu
buradan
görebilirsiniz. Bu metoda dönecek olursak aşağıdaki örnek kodda Word
uygulaması açılmakta.
Application.ActivateMicrosoftApp xlMicrosoftWord
Application.Inputbox metodu: Bunu
burada
inceledik.
Application.OnKey metodu: Excel, bir makroyu kaydederken
bize bunu bir kısayol tuşuna atayıp atamayacağımız konusunda bir imkan
sunar, ancak bunun bir sınırı vardır ki o da sadece Ctrl tuşunu
kullanmak zorunda olmamızdır ve bu da bir noktadan sonra yetersiz kalmaya başlıyor. İşte bu noktada OnKey
metodu yardıma koşuyor, bununla istediğiniz tuş kombinasyonlarına atama
yapabiliyorsunuz ve bu tuşlara bastığınızda bir olay tirgger olmuş gibi
istediğiniz makro çalışmaya başlıyor.
Bu tuş kombinasyonu, sadece mevcut Excel oturumunda geçerli
olmaktadır. Excel, kapatılıp tekrar açıldıktan sonra kullanılamazlar.
Süreklilik kazandırmak için bunları Personal.xlsb dosyanızın
Workbook_Open makrosuna yazabilirsiniz.
Ör:
Private Sub Workbook_Open()
Application.CalculationInterruptKey = xlEscKey
Application.OnKey "+^{F}", "Calculationlar"
End Sub
OnKey metodunu, Çeşitli Windows veya Office kısayol tuşlarını kontrol
etmek için de kullanabilirsiniz. Mesela Cut/Copy işlemlerini engellemek
için kullanabilirsiniz. Bunu da yine Workbook eventleri ile birlikte
kullanmak gerekiyor. Bununla ilgili örnek biraz daha uzun olduğu için
onu Workbook
Eventleri sayfasına aldım.
Application.Version:Bu özellikle Excelin versiyonunu öğreniyoruz. Böylece kullanıcının Excel versiyonuna göre davranışımızı değiştirebiliyoruz. Mesela 2010 versiyonu ile birlikte gelen Slicer'larla ilgili bir işlemi 2007 ve öncesi kişilerde yapmaya çalışırsak hata alırız. Keza, Slicerlar 2010'da geldi ama sadece Özet tablolarda kullanılmak üzere gelmişti. Table'lar üzerinde kullanımı 2013 versiyonuyla geldi. Bu yüzden bir Table üzerinde Slicer kullanımı olacaksa yine hata alınır.
Şimdi Excelin konuşması özelliğini kullanan başka bir örnek düşünelim. Bu özellik 2013 versiyonuyla geldiği için versiyon numarası 15.0'dır. Versiyon numaralarına buradan ulaşabilirsiniz. Diyelim ki, ortak kullanım için bir Add-in yaptınız ve bu addinde Kokpit adında tüm raporlara ulaşmayı sağlayan bir UserForm var. Kullanıcıların raporlara Kokpit üzerinden ulaşmasını istiyorsunuz, çünkü buradan ulaştıklarında raporlar Readonly açılıyor. Böylece siz raporlarda bir düzenleme yapmak istediğinizde kimsede açık bulunmamış oluyor ve düzenlemelerinizi rahatlıkla yapabiliyorsunuz. Ancak bazı yaramaz arkadaşlar dosyalara ortak alandan ulaşmaya çalışabilir. İşte onlar için ThisWorkbook modülünün Workbook_Open makrosuna aşağıdaki kodu yazabilirsiniz.
Private Sub Workbook_Open()
'diğer kodlar(Kullanıcının siz olması durumunda aşağıdaki kodun çalışmamasını sağlayacak kodlar dahil, şimdilik kafa karıştırmasın diye bunları atladım)
If Not Me.ReadOnly Then
If Val(Application.Version) >= 15 Then
Application.Speech.Speak ("Hey. Bana ortaka alandan değil, Kokpit formu üzerinden gir") 'Konuşarak iletişim
Else
MsgBox "Hey. Bana ortaka alandan değil, Kokpit formu üzerinden gir" 'MsgBox ile iletişim
End If
Logger "Bilgi", 0, "Ortak alandan girmeye calisma"
Me.Close savechanges:=False
End If
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ç
273162
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.
5
3
0
0
Soru No:59.
Kodun çalıştığı PC'deki Excel sürümü aşağıdakilerden hangisi ile elde edilir?