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
ShapesveOleObjects
Ileriseviyekonular
VBAMakro
VBAMakro İleri seviye konular 3

Shape(s)'ler ve OleObject(s)'ler

Geldik, en kafa karıştıran konulardan birine. Bu bölümde, Shape(sayfa içi nesneler) ve onların bir alt grubu olan OleObject kavramlarına değineceğiz.

Özellikle, dashboard tasarlayanlar, çok fazla ActiveX veya form kontrolü kullananlar, Slicer/Chart gibi nesnelerin görünürlük ve konum bilgilerini dinamik olarak yönetmek isteyenler için önemli olmakla birlikte çalışmalarına görsellik katmak isteyen herkesin bilmesinde fayda olan bir konudur.

Giriş

Burada bu nesnelerin sayfa düzeni, sitil özellikleri, görünürlük gibi "şekle özgü" özelliklerine bakacağız. Özellikle kafanızın karışmaması gerek nokta şudur: AutoShape dışındaki şekillerin nesne modelindeki özelliklerine burada girmeyeceğiz. Örneğin bir Slicer'la ilgili seçim yapma, filtreleri kaldırma gibi özelliklerden ziyade Slicer'ın sayfanın neresinde konumlandırılacağı, gösterilip gösterilmeyeceği gibi özellikler kapsamımızda olacaktır. Bu nesnelerin, nesne modeline ait konuları kendilerine ait sayafalarda bulunacaktır. Slicer ve ChartForm kontrolleri gibi.

Şimdi, elimizde aşağıdaki şekilleri içeren bir sayfa olduğunu düşünün. İsterseniz bunları içeren dosyayı buradan indirebilirsiniz.

Shape on worksheet

Burada hemen her türden nesne(Grafik, Slicer, TextBox, Konuşma balonu, Resim, gömülü pdf dosyası, Form Buton, ActiveX button) var. PivotTable ve Table dışında buradaki herşey bir Shape nesnesidir ve bunlar doğal olarak Shapes collection'ının bir üyesidir.

Aslında bir range'e yayılmamış olan herşey bir Shape'tir diye düşünebilirsiniz. Bu bağlamda, bir range bölgesi olan Table ve PivotTable'lar Shape olmamakta. Bunlar sırasıyla ListObjects ve PivotTables collectionlarının üyeleridir.

OleObject'ler de Shape'lerin bir alt türüdür, yani her OleObject aynı zamanda bir Shape'tir. Bu yukarıdaki örnekte; ActiveX commandbutonu,  gömülü pdf dosyası ve linkli powerpoint sunumu. Zaten bunlara tıkladığımızda fonksiyon çubuğunda ya EMBED ile başlayan bir ifade görürüz: =EMBED("Forms.CommandButton.1";"") ve =EMBED("Acrobat Document";"") ya da Link adresi, "=PowerPoint.Slide.12|'C:\Users\Volkan\Videos\Movavi Screen Capture Studio\Udemy Kurslar\2-ileri vba-makro\dosyalar\İLERİ EXCEL VBA(MAKRO) EĞİTİMİ - Giriş.pptx'!'!265'"

Şimdi bunlara yakından bakalım.

Shapes Collection'ı ve Shape Nesnesi

Yukarıda belirttiğimiz gibi, bir Range'ten ziyade sayfa üzerinde ayrı bir nesne gibi duran ve mouse ile seçildiğinde köşelerinde ve kenar ortalarında küçük yuvarlaklar çıkaran herşey Shape'tir.

Shape'lerle ilgili önemli birkaç özellik/metod aşağıdaki gibidir.

Activesheet.Shapes.SelectAll 'sayfadaki tüm shapeleri seçer
Activesheet.Shapes.Count 'sayfadaki shapelerin sayısını verir
Activesheet.Shapes.Addxxx 'xxx yerine şekil tipi gelir, Ör:AddOLEObject

Shape'lere erişim

Tüm diğer collection(workbooks, worksheets v.s) tiplerinde olduğu gibi shape'lerde de indeks(indeks no veya isim) ile tekil shape'lere ulaşabiliyor ve sonra bunlara ait özellikler veya metodları kullanabiliyoruz.

Activesheet.Shapes(i).Delete 'i. şekili siler
ActiveSheet.Shapes("Button 1").Visible = msoFalse 'Button 1 isimli shape grünmez yapar

Tüm shapelerde dolaşmak için aşağıdaki gibi bir döngü kullanabiliriz.

Sub shapelerde_dolaş()
Dim şekil As Shape

For Each şekil In ActiveSheet.Shapes
    Debug.Print şekil.Name
Next şekil
End Sub

Type property'si ile de ilgili şeklin tipinin enumeration değeri döner. Bunlara ait değerleri buradan görebilirsiniz. Aşağıda en sık kullanılanlara ait bir tabloyu bulabilirsiniz.

Name Value Description Örnek
msoShapeTypeMixed -2 Mixed shape type TimeLine
msoAutoShape 1 AutoShape Diktörtgen
msoChart 3 Chart Grafik
msoEmbeddedOLEObject 7 Embedded OLE object Gömü PDF
msoLinkedOLEObject 10 Linked OLE object Linkli PowerPoint
msoOLEControlObject 12 OLE control object ActiveX CommandButton
msoPicture 13 Picture Resim
msoTextBox 17 Text box
msoSlicer 25 Slicer Slicer

Bu Type özelliği, özellikle If ile kontrol yapıp sadece belirli şekillerle işlem yapmak istediğimizde kullanışlıdır. Mesela aşağıdaki kod ile sayfadaki tüm grafikleri silebiliriz.

Sub shapleerde_dolaş()
Dim şekil As Shape

For Each şekil In ActiveSheet.Shapes
    If şekil.Type = 3 Then 'veya msoChart
        şekil.Delete
    End If
Next şekil
End Sub

Aşağıdaki kod ile de grafik ve comment dışındaki tüm şekilleri siliyoruz.

If şekil.Type <> msoChart And şekil.Type <> msoComment Then şekil.Delete

OleObjects Collection'ı ve OleObject Nesnesi

Insert menüsünden "Object" olarak eklenenler ve Developer menüsünden eklenen ActiveX objeleri OleObject olarak görünür. ActiveX dışı OleObjeler sayfaya gömülü veya linkli olurlar. OLEType özelliği ile ilgili nesnenin linkli mi yoksa gömülü mü olduğu tespit edilebilir. Alacağı değerler şöyledir:

  • Linkli:0(xlOLELink),
  • Gömülü:1(xlOLEEmbed) ve
  • ActiveX Kontrol:2(xlOleControl).

Nesnelere Erişim

Bunlarda da tekil objelere yine indeks ile ulaşırız.

Activesheet.OLEObjects("ListBox1").Delete 'veya indexno

Yine döngüyle tüm oleobjeleri dolaşalım:

Sub oleobjelerdedolaş()
Dim oleo As OLEObject

For Each oleo In ActiveSheet.OLEObjects
    Debug.Print oleo.Name
Next oleo
End Sub	

Collectionlarla toplu işlemler de gerçekleştirebiliriz.

Activesheet.OLEObjects.Visible = False 'hepsini gizler

Sayfaya dinamik olarak OleObje eklemek de mümkündür.

Worksheets(1).OLEObjects.Add FileName:="arcade.gif" 'gömülü gif dosyası
Worksheets(1).OLEObjects.Add ClassType:="Forms.ListBox.1" 'ActiveX kontrolü

Nesnelerin Özelliklerine erişim

Gömülü/Linkli nesneler

Gömülü/Linkli öğelerde daha çok Visible ve Top/Left gibi konum özellikleriyle ilgilineceğiz.

Gömülü bir pdf dosyasındaki özelliklere erişime bir bakalım.

ActiveSheet.OLEObjects("Ole1_embed_PDF").Visible = True

Bu özelliklerin bir kısmına Shapes collection'ı üzerinden de ulaşabiliriz. Ne de olsa tüm OleObjectler aynı zamanda bir Shape'tir. Enabled gibi bazı öellikler Shape class'ında bulunmadığı için bunları kullanamayız, dolayısıyla mecburen OleObject nesnesini kullanırız.

ActiveSheet.Shapes("Ole1_embed_PDF").Visible = msoFalse 'False yerine msoFalse
'ama
ActiveSheet.OLEObjects("Ole1_embed_PDF").Enabled = True

Özellikler dışında bir de Activate ve Verb gibi metodlarla da ilgilenebiliriz. Mesela bir pdf dokümanına tıklandığında onu açtıracak kodu aşağıdaki gibi yazabiliriz.

Sub Ole1_embed_PDF_Click()
    ActiveSheet.OLEObjects("Ole1_embed_PDF").Verb xlOpen
End Sub

ActiveX kontrolleri

ActiveX kontrollerinde ise durum biraz karışıktır. Bu case'de OleObjectler, içinde bu kontrolü barındıran bir sarmalayıcı objeden oluşur. Bazı durumlarda sarmalayıcının özelliklerini kullanmak bazen içteki nesneyi bazen de ikisini kullanmak gerekebilir. Yine bunların bir kısmına Shapes collection'ı üzerinden de ulaşabiliriz.

Bu iç kısımdaki esas objeye ulaşmak için OLEObject nesnesinin Object propertysi kullanılır, veya buna Shape nesnesi üzerinden ulaşıyorsak önce Oleobject'yi elde etmek için OLEFormat'ı, sonra da bunun Object property'si kullanılır. Özetle aşağıdaki ifadeler özdeştir:

Shapes("Ole1_embed_PDF").OLEFormat.Object ile OLEObjects("Ole1_embed_PDF") 'sarmalayıcı oleobject nesnesi
Shapes("Ole1_embed_PDF").OLEFormat.Object.Object ile OLEObjects("Ole1_embed_PDF").Object 'iç kısımdaki kontrol

Shape ve OleObject bir arada

Tüm OleObject'lerin aynı zamanda bir Shape de olduğunu söylemiştk. Peki bir Shape döngüsü içindeyken veya bir şekilde elimizde bir shape nesnesi varken bunların OleObect özelliklerine erişmek istersek ne yaparız? Öncelikle OLEFormat özelliğini kullanırız. Bu bize bir OleFormat nesnesi döndürür, bu nesnenin de Object özelliğini kullanarak OleObject nesnesine erişiriz. Bu nesne bir ActiveX nesnesi ise ilk Object property'siyle sarmalayıcı nesneye erişmiş oluruz. OleObjectin sarmaladığı içteki esas kontrole ulaşmak için ise bir Object propertysi daha kullanırız. Evet çok karışık oldu, farkındayım, şimdi hemen kodlara bakalım, sonra açıklamayı tekrar okuyalım.

Mesela yukarıdaki pdf dokümanının Click eventine aşağıdaki kodu da yazabilirdik.

Sub Ole1_embed_PDF_Click()
    ActiveSheet.Shapes("Ole1_embed_PDF").OLEFormat.Object.Verb xlOpen
End Sub

Veya tüm Shapelerde dolaşırken OleObject olanların isim bilgisini öğrenmek için aşağıdaki kodu yazabiliriz.

For Each şekil In ActiveSheet.Shapes
    If TypeName(şekil.OLEFormat.Object) = "OLEObject" Then
        Debug.Print şekil.OLEFormat.Object.Name
    End If
Next şekil

İç kısımdaki objeye ulaştıktan sonra bu sefer onun özelliklerine erişebilrsiniz. Malesef adından anlaşılacğı üzere bu bir Object olduğu için intellisense çıkmamaktadır. İnstellisenseten yaralanmak isterseniz ilgili tipte bir nesne tanımlamanız gerekir. Aşağıdaki örnekte sayfada duran iki adet CommandButtonun Caption özelliklerine ulaşıyorum, tabi bunların Caption özelliğine sahip olduklarını bildiğimiz için intellisense çıkmamış olsa bile ezberden yazabiliyoruz.

Sub oledetay()
Dim şekil As Shape
Dim oo As OLEObject

For Each şekil In ActiveSheet.Shapes
    Set oo = şekil.OLEFormat.Object
    Debug.Print oo.Name, oo.OLEType, TypeName(oo), TypeName(oo.Object), oo.Object.Caption, oo.Left
Next şekil

End Sub

Sonuç:

CommandButton1 2 OLEObject CommandButton Düğme1 66 
CommandButton2 2 OLEObject CommandButton Düğme2 150,6 

Dikkat ettiyseniz sarmalayıcının Type'ı OLEObject iken iç nesnelerin CommandButton çıkıyor.

 

Özelliklere erişim yöntemleri

Şimdi buraya kadar öğrendiklerimizi yice pekiştirmek adına 3 tür erişim şekline bakalım.

Gömülü nesne(PDF dokümanı, Word veya PowerPoint dokümanı v.s) için Visible özelliği

Shape üzerinden
ActiveSheet.Shapes("Ole1_embed_PDF").Visible = msoFalse
OleObject üzerinden

Buna da istersek OleObject nesnesi üzerinden doğrudan veya Shape üzerinden dolaylı olarak erişebiliriz.

ActiveSheet.OLEObjects("Ole1_embed_PDF").Visible = True 'Doğrudan
'veya
ActiveSheet.Shapes("Ole1_embed_PDF").OLEFormat.Object.Visible = True 'Dolaylı

ActiveX kontrolü ile Visibile özelliğine erişim

Shape üzerinden
ActiveSheet.Shapes("Ole2_embed_ActiveXcmdbuton").Visible = msoFalse
OleObject üzerinden

Buna da istersek OleObject nesnesi üzerinden doğrudan veya Shape üzerinden dolaylı olarak erişebiliriz.

ActiveSheet.OLEObjects("Ole2_embed_ActiveXcmdbuton").Visible = True 'Doğrudan
'veya
ActiveSheet.Shapes("Ole2_embed_ActiveXcmdbuton").OLEFormat.Object.Visible = True 'Dolaylı

NOT:Visible özelliği sadece sarmalayıcı obje için sözkonusudur, dolayısıyla içteki Obje'ye ulaşarak bu nesnenin Visible özelliğine değer atayamayız.

ActiveX kontrolü ile Enabled özelliğine erişim

Shape üzerinden

Shape'in bu özelliği bulunmamaktadır.

OleObject üzerinden

Buna da istersek OleObject nesnesi üzerinden doğrudan veya Shape üzerinden dolaylı olarak erişebiliriz.

ActiveSheet.OLEObjects("Ole2_embed_ActiveXcmdbuton").Enabled = False 'Sarmalayıcı nesneye doğrudan
'veya
ActiveSheet.Shapes("Ole2_embed_ActiveXcmdbuton").OLEFormat.Object.Enabled = False 'Sarmalayıcı nesneye dolaylı

Ayrıca Enabled özelliği, içteki esas kontrol için de bulunduğu için içteki nesne üzerinden de ulaşabiliriz.

ActiveSheet.OLEObjects("Ole2_embed_ActiveXcmdbuton").Object.Enabled = True 'İç nesneye doğrudan
'veya
ActiveSheet.Shapes("Ole2_embed_ActiveXcmdbuton").OLEFormat.Object.Object.Enabled = True 'İç nesneye dolaylı

ActiveX kontrolü ile FontSize özelliğine erişim

Shape üzerinden

Shape'in bu özelliği bulunmamaktadır.

OleObject üzerinden

Yukarıdaki Visible özelliğinde karşılaştığımız durumun tersine Font'un Size bilgisi gibi bilgilere sadece iç nesne aracılığı ile ulaşılmaktadır. Dış nesneden bu özelliğe erişim yoktur.

ActiveSheet.OLEObjects("Ole2_embed_ActiveXcmdbuton").Object.Font.Size = 11 'Doğrudan
'veya
ActiveSheet.Shapes("Ole2_embed_ActiveXcmdbuton").OLEFormat.Object.Object.Font.Size = 14 'Dolaylı

Özelliklere erişimle ilgili örnek

Örnek dosyamız üzerindeki tüm shape'lerin çeşitli bilgilerini aşağıdaki gibi yazdırmak için bir kod yazalım.

Başlıkları manuel yazdığımızı düşünecek olursak, L2 hücresine konumlanıp aşağıdaki kou çalıştırınca bu çıktıyı elde ederiz.

Sub shapleerde_dolaş()
Dim şekil As Shape
Dim dict As New Dictionary
'OLEType,FormControlType ve AutoShapeType'lar da dictionary yapılarak isimleri yazdırılabilir
'OleType basit: (0,1,2:Linkli, Embedded, Control)
'https://docs.microsoft.com/en-us/office/vba/api/excel.xlformcontrol,
'https://docs.microsoft.com/en-us/office/vba/api/office.msoautoshapetype

dict.Add 1, "msoAutoShape"
dict.Add 2, "msoCallout"
dict.Add 20, "msoCanvas"
dict.Add 3, "msoChart"
dict.Add 4, "msoComment"
dict.Add 27, "msoContentApp"
dict.Add 21, "msoDiagram"
dict.Add 7, "msoEmbeddedOLEObject"
dict.Add 8, "msoFormControl"
dict.Add 5, "msoFreeform"
dict.Add 28, "msoGraphic"
dict.Add 6, "msoGroup"
dict.Add 24, "msoIgxGraphic"
dict.Add 22, "msoInk"
dict.Add 23, "msoInkComment"
dict.Add 9, "msoLine"
dict.Add 29, "msoLinkedGraphic"
dict.Add 10, "msoLinkedOLEObject"
dict.Add 11, "msoLinkedPicture"
dict.Add 16, "msoMedia"
dict.Add 12, "msoOLEControlObject"
dict.Add 13, "msoPicture"
dict.Add 14, "msoPlaceholder"
dict.Add 18, "msoScriptAnchor"
dict.Add -2, "msoShapeTypeMixed"
dict.Add 19, "msoTable"
dict.Add 17, "msoTextBox"
dict.Add 15, "msoTextEffect"
dict.Add 26, "msoWebVideo"
dict.Add 25, "msoSlicer"


For Each şekil In ActiveSheet.Shapes
    'ilk 3ü ole
    If şekil.Type = msoEmbeddedOLEObject Then
        Dizi = Array(şekil.Type, dict(şekil.Type), şekil.Name, şekil.OLEFormat.progID, şekil.OLEFormat.Object.Name, TypeName(şekil.OLEFormat.Object), "TypeName(şekil.OLEFormat.Object.Object)", şekil.OLEFormat.Object.OLEType)
    ElseIf şekil.Type = msoLinkedOLEObject Then
        Dizi = Array(şekil.Type, dict(şekil.Type), şekil.Name, "ole ama linkte N/A", şekil.OLEFormat.Object.Name, TypeName(şekil.OLEFormat.Object), "TypeName(şekil.OLEFormat.Object.Object)", şekil.OLEFormat.Object.OLEType)
    ElseIf şekil.Type = msoOLEControlObject Then
        Dizi = Array(şekil.Type, dict(şekil.Type), şekil.Name, şekil.OLEFormat.progID, şekil.OLEFormat.Object.Name, TypeName(şekil.OLEFormat.Object), TypeName(şekil.OLEFormat.Object.Object), şekil.OLEFormat.Object.OLEType)
    'form butonu
    ElseIf şekil.Type = msoFormControl Then
        Dizi = Array(şekil.Type, dict(şekil.Type), şekil.Name, "N/A", "N/A", "N/A", "N/A", şekil.FormControlType)
    'diğer hepsi
    Else
        Dizi = Array(şekil.Type, dict(şekil.Type), şekil.Name, "N/A", "N/A", "N/A", "N/A", şekil.AutoShapeType)
    End If
    Range(ActiveCell, ActiveCell.Offset(0, 7)).Value = Dizi
    ActiveCell.Offset(1, 0).Select
Next şekil
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ç

17065

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

SoruID:... Şu an için bu konu için soru bulunmamaktadır. İletişim menüsünden örnek sorularınızı bana iletebilirsiniz.




ÖDEVLER

0
0
ÖdevNo:... Şu an için bu konu için ödev bulunmamaktadır. İletişim menüsünden örnek ödev sorularını bana iletebilirsin.
Çözüme bakın(Başka türlü de çözülebilir tabi, bu benim çözümüm.)




=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.