Interaktivite
Makrolar kullanıcı ile belli başlı 4 şekilde iletişim kurar.
- Mesaj kutuları(MsgBox)
- Bilgi sorma kutuları (InputBox)
- Formlar(Userforms)
- File/Folder dialog kutuları
Son ikisini ayrı bölümlerde işleyeceğiz, biz şimdilik burada MsgBox ve InputBox ile haşır neşir olacağız.
InputBox
Inputbox ile kullanıcıya çeşitli sorular sorar, ondan bir şeyler
yazmasını veya sayfa üzerinde birşeyleri seçmesini bekleriz. Kullanıcının bu
girdiği değeri de bir değişken içinde depolarız. O yüzden Inputboxları tek
başına kullanmak yerine her zaman bir değişkene atama şeklinde kullanırız.
Dim ad As String
ad = InputBox("Adınızı girin")
Inputbox'a girilen her
değer bir metindir, sayı olsa bile bu metin olarak depolanır. Girilen değeri sayı olarak kullanmak istiyorsanız bunu
Valveya buna benzer bir dönüştürme metodu (Int,
CInt, CLng, CDbl gibi) ile sayıya çevirmeniz
gerekir. Aksi halde istenmeyen sonuçlar ortaya çıkabilir. Bir
örnekle bakalım
Sub input1()
a = InputBox("bir sayı girin")
b = InputBox("ikinci bir sayı girin")
Range("A1").Value = a + b
End Sub
Kodu çalıştıralım, a için 5, b için 7 girelim. A1 hücresinde 12
rakamını görmeyi bekleriz ama 57 yazar. Çünkü VBA metinler için
birleştirme operatörü olarak + işaretini de kullanılır(bir de & işareti var).
Şimdi aynı kodu aşağıda gibi çalıştıralım, aynı değerleri girelim, bu
sefer 12 sonucunu görebiliriz.
Sub input2()
a = InputBox("bir sayı girin")
b = InputBox("ikinci bir sayı girin")
Range("A1").Value = Val(a) + Val(b)
End Sub
Bir diğer alternatif de, numerik olmasını istediğimiz değişkenleri
baştan numerik olarak tanımlamaktır.
Sub input3()
Dim a As Integer
Dim b As Integer
a = InputBox("bir sayı girin")
b = InputBox("ikinci bir sayı girin")
Range("A1").Value = a + b '12 yazar
End Sub
Kullanım şekli ve diğer InputBox
Nesne Modelini anlatırken Classlardan ve Library'lerden bahsetmiştim. İşte bu yukarda gördüğümüz InputBox da
VBA Library'si
içinde Interaction class'ına ait bir fonksiyondur. Birçok fonksiyon gibi bu da
parametre alır.
Syntax'ı şöyledir:
InputBox(Prompt[,title][,default][,xpos][,ypos][,helpfile,context])
Bu parametrelerden sadece köşeli parantez içine alınmamış olan Prompt
parametresi zorunlu olup diğerleri opsiyonedir. Önemlilerin açıklaması
ise şöyledir:
- Prompt:Kullanıcıya ne girişi yapmasını söyleyeceğimiz ifade.
Ör:Adınızı giriniz.
- Title:Inputbox kutusunun başlığını set edebilirsiniz
- Default:Faydalı bir özelliktir, kullanıcıya bazı durumlarda kutu
içinde hazır bir değer sunabilirsiniz. Genelde, en çok girilen
değerleri tahmin ederek girebilirsiniz. Örneğin "Bir il kodu girin"
diyip, default değer olarak da İstanbul'un kodu olan 34ü
yazabilirsiniz.
Yukarda Inputbox'ın bize aktif sayfadan bir seçim de
yaptırabileceğini söylemiştim. Ancak yukardaki kodları
çalıştırdığınızda bunu yapamazsınız, isterseniz bi deneyin, sonra tekrar
gelin. Peki neden böyle söyledim. Çünkü bir Inputbox'ımız daha var, bu
işlemi o yapar ve kendisi Excel Library'sindeki Application
nesnesinin bir metodudur.
Terminoloji sayfasında belirttiğimiz gibi, bu Inputbox metodu diğer
metodlar gibi bir nesneye ihtiyaç duyar, yani tek başına kullanılamaz, o
nesne de Application nesnesidir. İlki function iken ikincisi metoddur.
Zaten aşağıdaki resimden de görüleceği üzere
bağlı oldukları classların iconları bile farklı.
İkinci Inputbox'ımızın syntax'ı ise şöyledir:Application.InputBox(Prompt,Title,Default,Left,Top,HelpFile,HelpContextID,Type)
Bir önceki InputBox'tan farklı olarak en sonda bir Type parametresi
görüyoruz. Bu parametrenin alabileceği değerleri ve anlamları aşağıda
verilmiştir. En sık kullanacaklarımız koyu gösterilmiştir.
Değer |
Anlam |
0 |
Formül |
1 |
Sayı |
2 |
Metin |
4 |
True/False |
8 |
Range(Bir hücre grubu) |
16 |
Hata değeri |
64 |
Dizi |
Tablodan da görüleceği üzere kullanıcıya bir hücre grubu seçtirmek
için Type parametresini 8 tipinde belirtmemiz gerekiyor. Eğer kullanıcı hem metin
hem sayısal birşey girebilecekse Type değerine toplam değer olan 3(1+2)
yazılır.
Hemen bir örnek yapalım.
Dim sonHucre As Range
Set sonHucre = Application.InputBox(Prompt:="Son hücreyi seçin", Type:=8)
Değişkenlerle ilgili
sayfadan hatırlayacağınız üzere nesnelere değer atamak için
Set ifadesini kullanıyorduk, burada da öyle yaptık.
Boş geçilen kutular(Cancel veya Esc ile iptal)
Bazen kullanıcılar hiçbir değer girmeden çıkmak
ister, o zaman ne olur.
- Klasik Inputbox'ın dönüş değeri olan
Stringtir ve bu durumda ilgili değişkene String tipinin default değeri atanır, yani
"". O yüzden değişkenin değerinin "" olup
olmadığı kontrol edilir.
- Application.Inputbox metodununu dönüş değeri Varianttır, o yüzden default değer olarak Empty bekleriz ancak
MSDN bize bu Inputbox'ta boş geçilen değerler için atanan değerin False
olduğunu söylüyor. O yüzden değişkenin değerini False olup olmadığı kontrol
edilir, ama bu klasik Inputboxa göre biraz daha alengirlidir.
Aşağıdaki örneklere bakalım.
Kodumuzda hatalı birşey olmaması için bazı kontroller yapmamız
gerekiyor. Bundan sonrasına devam etmeden önce koşullu yapıları
bildiğinizden emin olun, bilmiyorsanız
buradan kısa bir
bilgi edinip tekrar buraya gelin.
'klasik Inputbox
a=Inputbox("Bir değer girin")
If a<>"" Then
Msgbox "Giriş yapıldı"
'Diğer kodlar buraya
Else
Msgbox "Bir giriş yapılmadan çıkmayı tercih ettiniz"
End If
'Application'lı, String
Dim a As String
a=Application.Inputbox("Adınızı girin", Type:=2)
If a<>"False" Then 'False'ın tırnak içinde yazıldığına dikkat edin
Msgbox "Giriş yapıldı"
'Diğer kodlar buraya
Else
Msgbox "Bir giriş yapılmadan çıkmayı tercih ettiniz"
End If
'Application'lı, Integer(değişken tanımlanmaz, yani Varianttır)
a=Application.Inputbox("Yaşınızı girin", Type:=1)
If a<>False Then 'Variant her değeri alabilecğei için False ifadesi aynen yazılır
Msgbox "Giriş yapıldı"
'Diğer kodlar buraya
Else
Msgbox "Bir giriş yapılmadan çıkmayı tercih ettiniz"
End If
'Application'lı, Integer(değişken tanımlanır)
Dim a As Integer
a=Application.Inputbox("Yaşınızı girin", Type:=1)
If a<>0 Then 'Sayısal ifadelerde False veya False'ın rakamsal karşılığı olan 0 kullanılabilir
Msgbox "Giriş yapıldı"
'Diğer kodlar buraya
Else
Msgbox "Bir giriş yapılmadan çıkmayı tercih ettiniz"
End If
'Applicationlu, Range
'Range seçiminde eğer kullanıcı seçim yapmazsa hata oluşur, bu yüzden bir hata kontrol mekanizması da ekleriz
've ayrıca bir seçim yapıp yapmadığını da Nothing ile kontrol ederiz
On Error Resume Next 'burayı yazmassak hata alırız. Hata yönetim mekanizmaları için ilgili sayfaya gidip bilgi edinebilirsiniz
Dim a As Range
Set a = Application.InputBox("Bir hücre seçin", Type:=8)
If Not a Is Nothing Then
Msgbox "Seçim yapıldı"
'Diğer kodlar buraya
Else
Msgbox "Bir seçim yapılmadan çıkmayı tercih ettiniz"
End If
Şimdi son olarak tam bir örnek yapalım. Bu örnekte kullanıcıdan açık olan
dosyaya kaç sayfa eklemek istediğini soracağız, detaylara takılmayın, sadece
yukardaki anlatılanları pekiştirmeye çalışın.
Sub Sayfaekle()
Dim i As Integer, syf As Integer
syf = Application.InputBox("Kaç sayfa ekleyelim", Default:=3, Type:=1)
If syf = False Then 'escape'e baıslıysa veya Cancel'a tıklandıysa. Bunu ayrıca if syf= 0 diye de yapabilrdik
Exit Sub
Else
For i = 1 To syf
Worksheets.Add
Next i
End If
End Sub
MsgBox
MsgBox ile ya bilgilendirme yaparız, ya da cevabı Evet/Hayır gibi
sorular sorup bilgi ediniriz. Bilgilendirme yaptığımızda bunu bir değişkene
atamaya gerek yoktur, ancak bilgi topladığımızda Inputboxta olduğu gibi bir değişkene atamamız lazım.
MsgBox da InputBox gibi VBA Library'sindeki Interaction sınıfı içinde yer
alır ve syntax'ı şöyledir: MsgBox(prompt[, buttons]
[, title] [, helpfile, context])
Burda prompt ve title InputBoxtaki gibidir, son iki parametreden
bahsetmeyeceğim, arzu eden araştırabilir. Burda önemli bir parametre var: buttons parametresi. Bu parametrenin alabileceği değerler
şöyledir(Liste daha uzun ama çoğu gereksiz olduğu için buraya almadım, hatta
bunlardan da en çok YesNo ve YesNoCancel düğmelerini kullanacağımızı söyleyebilirim)
Aşağıda bilgilendirmeye örnek bir kod var
Sub MessageBox()
'Uzunca bir kod bloğu
MsgBox "İşlem tamamdır"
End sub
Bilgi edinme örneği ise şöyle birşey olabilir.
Sub MessageBox()
cvp = MsgBox("Ana diskinizde(Ör:'C:') 'böl' isminde bir klasörünüz var mı?", vbYesNo) ' bu bilgi toplama mesajı
If cvp= 6 Then 'yes demek oluyor
GoTo ilerle
Else
MsgBox "O ZAMAN O KLASÖRÜ YARATIP TEKRAR ÇALIŞTIR" 'bu bilgi mesajı
Exit Sub
End If
ilerle:
'diğer kodlar
End sub
Gördüğünüz üzere cvp değerinin değerini 6 gibi bir sayıyla ölçtük. İşte
VBA'da bazı sabitlerin(constant) böyle sayısal değerleri vardır, ikisi de
kullanılabilir. Tüm düğmeler ve değerleri şöyle.
Sabit |
Değer |
vbOK |
1 |
vbCancel |
2 |
vbAbort |
3 |
vbRetry |
4 |
vbIgnore |
5 |
vbYes |
6 |
vbNo |
7 |
InputBox'ta olduğu gibi MsgBox'ın da iptal edilmesi sözkonusu olabilmektedir. Tabi eğer buton türü olarak Cancel varsa. Aksi halde Esc tuşu da işe yaramamaktadır.
Bu örnekten çıkış mümkün değilken,
Sub msgbox1()
On Error GoTo hata
a = MsgBox("Cevap verirmisin", vbYesNo)
'Diğer kodlar
Exit Sub
hata:
Debug.Print Err.Description
End Sub
Ama bunu iptal edebilirsiniz.
Sub msgbox1()
On Error GoTo hata
a = MsgBox("Cevap verirmisin", vbYesNoCancel)
If a = vbYes Then
MsgBox "Evet denildi"
ElseIf a = vbNo Then
MsgBox "Hayır denildi"
Else
MsgBox "Seçimi iptal ettiniz"
End If
Exit Sub
hata:
Debug.Print Err.Description
End Sub
Önemli bir detay da, MsgBox'ın bilgi toplama formundayken mutlaka ()'ler içinde kullanılmasıdır. Mesaj verirken ise genelde () olmadan kullanılır, ama parantezli kullanımı da
sorunsuz çalışır.
Kullanıcı dostu mesajlar
Şimdi kod yazmada biraz deneyim kazandığımıza göre uzun
kodlar yazarken nelere dikkat etmemiz gerekir ona bir bakalım.
Kullanıcı dostu kodlama
Kullanıcılara bazen MsgBox ile bazen Inputbox ile çeşitli mesajlar
yayınlamak gerekecek. Kullanıcı bu mesajları rahat okusun diye gerekli
yerlerde satır geçişlerini yapmanız lazım. Bir örnekle ne demek istediğimiz
daha iyi anlatabilirim.
Şimdi aşağıdaki kodu, bir modül içine yazıp F5 ile çalıştıralım. Görüntü
aşağıdaki gibi olup, kullancının okuması açısından çok kolay değildir.
Sub satırgeçiş()
a = InputBox("Müşteri segmenti için bir değer giriniz. Bireysel müşteriler için 1, Ticari müşteriler için 2, Kurumsal müşteriler için 3")
End Sub
Şimdi bir de bu kod nasıl daha düzenli hale getirilir ona bakalım: Her cümle
ve seçenek arasına bir ifade koyarak. Bu ifade vbCrLf ifadesidir ve
cümleleri bir alt satıra taşır, bunun yerine vbCr veya vbLf veya vbNewLine
veya Chr(10) ifadeleri de
kullanılabilir. (Bunların dördü de Msgbox ve InputBox kullanımında aynı etkiye
sahiptir, ancak hücre içine birşey yazdırırken farklı etkilere sahiptir,
bunu deneyip görebilrisiniz.)
Sub satırgeçiş2()
a = InputBox("Müşteri segmenti için bir değer giriniz. " & vbCrLf & "Bireysel müşteriler için 1," & vbCrLf & "Ticari müşteriler için 2," & vbCrLf & "Kurumsal müşteriler için 3")
End Sub
Kodlamacı dostu kodlama
Şimdi yeri gelmişken bir de kullancı dostu olmakla ilgili değil ama
kodlamacı dostu olmakla ilgili bir notum olacak. Yine yukardaki kodu örnek
alalım, bu kod biz kodlamacılar için de okuması zor, çünkü VBE içinde kod
sağa doğru uzuyor, ama kodlamacı olarak benim bunu ekranda, scroolbarı sağa
sürüklemeden görebilmem lazım. Hadi gelin bunu
okunaklı hale getirelim.
Yapacağımız şey basit, cümleyi nerden kesmek istiyorsak oraya bir
boşluk ve sonrasında bir alt çizgi(_) koymak. Buna Line Contination
Character adı verilir.
Sub satırgeçiş3()
a = InputBox("Müşteri segmenti için bir değer giriniz. " & vbCrLf & _
"Bireysel müşteriler için 1," & vbCrLf & _
"Ticari müşteriler için 2," & vbCrLf & _
"Kurumsal müşteriler için 3")
End Sub
Görüldüğü gibi, kod şimdi bizim için de daha okunaklı hale geldi.
Bunu yapmanın bir yolu daha var, o da metni parçalara ayırmak.
Sub satırgeçiş4()
mesaj = "Müşteri segmenti için bir değer giriniz. " & vbCrLf
mesaj = mesaj + "Bireysel müşteriler için 1," & vbCrLf
mesaj = mesaj + "Ticari müşteriler için 2," & vbCrLf
mesaj = mesaj + "Kurumsal müşteriler için 3"
a = InputBox(mesaj)
End Sub
NOT:mesaj = mesaj + ..... şeklinde sağduyuya aykırı gibi görünen
kısım kafanızı karıştırdıysa
buradan detaylı bilgi edinebilirsiniz.
Bu iki yöntemi sadece interaktivite sağlayan yerlerde değil başka
yerlerde de kullanacağız.
Bu arada hemen iki yöntem arasındaki küçük farka da değinelim. İlk
yöntem yani _ yöntemi ile sadece metin birleştirme değil, içinde metin
bile olmayan tam bir VB kodunu da parçalara ayırabiliriz, amaç yine
aynı: Sağa doğru uzayan kodu tek bir ekranda tutmak. Aşağıdaki gibi.
Sub blabla()
Cells.Find(What:="Volkan", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False).Activate
End Sub
İkinci yöntemin ise tek amacı uzun metinleri parçalara ayırmaktır.
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ç
200944
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.