İlk VSTO Add'inimiz

Kapsam

VSTO'da iki temel çalışma yapılabiliyor. Bunların ilkinde her tür detayı ele alacağımız örnek çalışmalar olacak. Bu örnek çalışmaları sadece c# için hazırlayacağım. Bununla birlikte, Vb.Net kodunun c# kodundan önemli ölçüde ayrıştığı yerlerde bu kodları da vermeye çalışacağım(Yine de aşağıdaki indirilebilir dosyalar içinde Vb.Net versyionunu bulabilirsiniz). Bazı kısımlar deneyimli .Net kullanıcıları için sıkıcı gelebilir, hatta hatalı ifade ettiğim(veya gereksiz uzun yazdığım) yerler bile olabilir(zira c# konusunda kendimi master görmüyorum), onlar da İletişim menüsünden benle temasa geçerek bilgi verirlerse sevinirim. Bazı kısımlar da deneyimli VBA kullanıcılarına basit gelebilir, gerçi ben herkesi deneyimli VBA kullanıcısı olarak kabul etmek durumundayım. Ancak onlar da .Net dünyasının güzelliklerini keşfedince hayranlıklarını gizleyemeyecekler.

İkinci tür çalışmada ise kapsamlı örnekler yapacağız., bunları sadece c# ile yapacağım.

Çalışma türleri

Bahsettiğim iki tür çalışma şunlar: Document Level(Excel VSTO Workbook) ve Application Level(Excel VSTO Add-in). Ben daha çok Application Level'e odaklanacağım ancak özellikle büyük bir proje şeklinde bir çalışma olacaksa bunu Document Level yapıp TaskPane gibi çeşitli fonksyonalite de katabilirsinz.

İkisi arasındaki temel fark şu: Application Level projeler, sanki Personal.xlsb dosyasına yazdığınız kodlar veya Excel Add-in'ler gibiyken, Document Level projeler ise normal bir workbook içine yazdığınız kodlar gibidir, yani o dosyaya özgüdür.

Kütüphaneler

Daha önce bahsettiğimiz gibi iki ana kütüphane var:

  • Microsoft.Office.Interop.Excel: Standart Excel nesne modeli ile iletişim kurmayı sağlar. Ağırlıklı olarak bunu kullanacağız.
  • Microsoft.Office.Tools.Excel: VSTO, Excel nesne modelini genişletir, yani normalde olmayan üyeleri ekler. Mesela artık ihtyiaç kalmayan get_xxxxx metodlarını bu kütüphane sağlıyordu. Biz bunu hiç kullanmaycağız diyebilirim. (Ben şimdiye kadar denemek dışında hiç kullanmadım)

Bu arada yine bir kenara kaydetmenizi isteyeceğim linkler aşağıda. İlerleyen zamanlarda bunlara bakmanızda fayda var.

Şimdi ilk projemizi Application Level olarak yapacağız. Bunlar, adı üzerinde tüm Excel seviyesinde geçerli olurlar, tek bir workbook değil. En tipik örneği kendisine özel bir Ribbon Menüsünün eşlik ettiği projelerdir. Benim Excelent projem böyle bir projedir.

Kaynak Dosyalar

Visual Studio sayfasında başladığmız ilk örnek üzerinden devam edelim. Projenin tamamını(Vb.Net versiyonunu da) buradan indirebilirsiniz. Aslında burada Excel'le ilgili birçok örnek uygulama yer alacak. O yüzden repository'i komple tek seferde indirmek isteyebilirsiniz diye tüm repo linkini verdim. Klasör isimlerinden hangi projede çalıştığımızı anlayabilirsiniz diye düşünüyorum.

Bununla birlikte tek tek klasör indirerek gitmek istiyorsanız bunları indirmek için ara çözümlere ihtiyaç var. Özellikle yeni başlayan biriyseniz ve hazır toollara sahip değilseniz linklerde çıkan klasör isimlerini https://minhaskamal.github.io/DownGit/#/home sayfasına yapıştırmanız durumunda bir zip dosyası inecektir.

Adım adım App Level proje oluşturma

post-thumb

Bu pencereyi analiz edelim.

En üstte, VS tarafından otomatik olarak eklenen Using deyimleri bulunuyor. Onun altında da namespace tanımı var. Namespaceler sınıfları içeren containerlar olarak düşünülebilir. Genelde projemizin adıyla aynı olurlar. Biz şimdi bunun içine odaklanalım.

İlk satırdaki public partial class ifadesi, aslında bir sınıf oluşturulduğunu ancak bunun bir kısmının bu dokümanda bulunduğunu anlatır. Sınıfın kalan kısmını görmek için sağ taraftaki  Solution Explorer'da Show All Files butonuna basın ve ThisAddIn.Designer.cs dosyasına tıklayın. Bu desinger dosyaları oldukaça karışıktır, neyseki bizim onunla bi işimiz yok, VS sağolsun, bizim için işin hammaliyet kısmını hallediyor. Keza yukarıdaki kod bloğunda VSTO generated code yazan kısımda da yine VS bizim için birşeyler oluşturmuş durumda. Buralara hiç takılmadan devam ediyoruz.

post-thumb

İki metod görüyoruz. Bu iki metod, isimlerinden de anlaşılacağı üzere Application seviyesinde event handlerlardır, yani Excel açıldığında ve kapandığında devreye girerler.

Şimdi ilkinde araya küçük bir mesaj kutusu ekleyelim.

<

                    private void ThisAddIn_Startup(object sender, System.EventArgs e)
                    {
                        MessageBox.Show("Merhaba Excel!");
                    }

Bu MessageBox satırını yazdığımızda altı kırmızılı çizecektir, zira henüz bu sınıfın dahil olduğu namespace yani System.Windows.Forms henüz programa dahil edilmedi, bunu using deyimi ile ekleyelim. Bunu manuel olarak ekleyebileceğiniz gibi, aşağıdaki gibi Show potential fixes'a tıklayıp, "using System.Windows.Forms;" dersek de otomatik eklenir. Bu arada Forms namespace'i aslında projemize dahil durumda. Projeyi ilk oluşturduğumuzda VS, belli bazı sınıfları otomatikman projemize dahil eder. Bunları Solution Explorer'da References altında görebilirsiniz. Hatırlarsanız, biz using ifadesini ekleyerek bu sınıfın içindeki metodlara doğrudan erişim hakkı kazanıyorduk, uzun uzun yazmaktan kurtuluyorduk. Zaten Show potential fixes'a tıkladığınızda bu seçeneği de görebilirsiniz.

post-thumb

Şimdi kodumuzu çalıştıralım. Bunun için Debug>Start Debugging diyin veya doğrudan F5 tuşuna basın. Bu arada Excelin o sırada kapalı olması başka add-in'lerle karışmaması adına iyi olacaktır. Programı debug ettiğimizde Excel kendiliğinden açılacaktır.

Excel açıldıktan sonra mesaj kutusunu göreceksiniz, onu kapatın ve Developer menüsünden COM Addi-ins menüsüne tıklayın, Add-inimiz orada göreceksinz.

post-thumb

Şimdi, VS'yu kapatsak ve sıfırdan bi Excel açsak bile bu Merhaba Excel mesajını görürüz, çünkü artık add-in'imiz bilgisayarımıza kurulmuştur. Bunu kaldırmak istiyorsak add-in projemizi VS içinden Clean etmemiz gerkeir. Clean işlemi, derlenmiş bir programı sistemden kaldırır. Ancak clean işleminden önce gelin bir de ne tür dosyalar oluşmuş ona bi bakalım.

Proje klasörü aşağıdaki gibidir. Burada sln uzantılı olan solution dosyası olup varsa birden fazla proje için kapsayıcıdır. Biz genelde bir solution içinde bir proje ile çalışacağız. csproj uzantılı dosya da proje dosyasmızı temsil eder. Bu ikisiyle de şuan bi işimiz yok. ThisAddIn.cs'i zaten biliyoruz, zira orada çalışıyoruz.

post-thumb

Şimdi bir de bin klasörüne bakalım. Bunlardan dll dosyası bizim esas derlenmiş dosyamızdır, diğerleri kritik dğeil. VS'da bir proje derlendiğinde, kendi başına bağımsız bir progam olacaksa exe uzantılı, başka bir programa bağımlı çalışacaksa dll uzantılı olur, ki bizim durumumuzda Excel'e bağlı programlar derleyeceğiz.

post-thumb

Projeye Form ekleme

Şimdi projemize bir form ekleyip ortamı canlandıralım.

Öncelikle projemize sağ tıklayıp, Add-->New Item-->Windows Form diyelim.(Formlar, sık kullanılan nesneler olduğu için direkt açılan context menüde de bulunur, doğrudan buradan da eklenebilir)

post-thumb

Formumuza control ekleme işini başka zamana bırakalım. Şimdi bu formumuzun kod sayfasına bakalım. Bunun için formumuz açıkken F7 tuşuna basarak veya formun üzerinde sağ tklayıp View Code diyerek açabilirsiniz.

<

                    public partial class Form1 : Form
                        {
                            public Form1()
                            {
                                InitializeComponent();
                            }
                        }              

Gördüğünüz gibi Form1 isimli formumuz Form isimli base classtan türetilmiştir. Aradaki bu ":" işareti inheritance'ı ifade eder, yani kalıtımı. Kalıtım, c# gibi pure object oriented dillerin ana unsurlarından biridir. Biz şimdilik bu detaya girmeyeceğiz, sadece ne olduğunu bilmenizi istediğim için bahsettim. İç kısımdaki kodda da Form1 nesnesi yaratılmakta(constructor metod ile). Şimdilik buna da takılmayın, bunları c#'ı detaylı öğrenmeye başladığınızda incelersiniz. Şimdi bu formu nasıl açarız ona bakalım.

Form1 diye oluşturduğumuz form aslında bir sınıf olup bu sınıfı projemizin herhangi bir yerinde kullanabilmek için bu sınıftan bir Form1 nesnesi yaratmamız gerekiyor. Bunun için yukarıda eklediğimiz mesaj satırı altına aşağıdaki iki satıra daha ekleyelim ve bu nesnenin Show metodu ile bu formu ekrana getirelim. Form1, bir sınıf olduğu için, bu sınıftan istediğimiz kadar nesne yaratabiliriz.

<

                    private void ThisAddIn_Startup(object sender, System.EventArgs e)
                    {
                        MessageBox.Show("Merhaba Excel!");
                        Form1 frm1 = new Form1();
                        frm1.Show();
                        Form1 frm2 = new Form1();
                        frm2.Show();
                        Form1 frm3 = new Form1();
                        frm3.Show();
                    }      

Form konusuna burada ara verelim, sonra siz detaylı olarak incelersiniz, zira bunun VSTO ile doğrudan bi alakası yok, genel .Net konusudur.

Ribbon ekleme

Az önce bi form ekledik, ama bu formu kaparsak mevcut durumda ona bir daha ulaşmanın yolu yok. İşte ribbon arayüzü burada imdada yetişiyor. Normal Excel Add-in'lerde eski commandbar mantığıyla menüler yapabilyorduk, bunun dışında bir de Custom UI Editor diye birşeyden bahsetmiştik ama bunun örneğini yapmamıştık. İşte şimdi canlı, renkli, fonksiyonel menüler yapma zamanı. Üstelik Custom UI Editor tekniğine göre VSTO daha avantajlı, zira arakasında tüm .Net dünyası var. 

Şimdi Projemize sağ tıklayıp New Item-->Ribbon(Visual Designer) diyelim.(XML'li olan ile daha gelişmiş Ribbon'lar tasarlanabilmekte, ancak bize şuan Visual Designer yeterlidir).

post-thumb

Ribbonumuz aşağıdaki gibi projemize eklenir.

post-thumb

Buraya hemen bir buton ekleyip, bu butona tıklanınca da bi adet form1 formu açılmasını sağlayalım. Tabi bu buton bi ribbon butonu olup sol taraftaki toolbaxın en üstüne ribbon controlleri diye bi group eklenmiş oldu, butonu oradan alacağız.

post-thumb

Bu arada ribbon1.cs dosyasının içi şöyledir.

<
    public partial class Ribbon1
                        {
                            private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
                            {

                            }

                            private void button1_Click(object sender, RibbonControlEventArgs e)
                            {
                                Form1 f = new Form1();
                                f.Show();
                            }
                        }            

Gördüğünüz gibi bir tane de otomatik oluşan Ribbon1_Load event handlerı var. Buralara neler yazabiliriz, ribbonlarla ilgili başka ne tür detaylar var, bunlara Ribbon detay safyasında bakacağız. Şimdilik biz kodumuzu çalıştıralım.

post-thumb

Gördüğünüz gibi şuanki haliyle ribbonnumuz çok da hoş olmayan bir şekilde Add-ins menüsü altına yerleşti. Tamam, bir Excel Add-in gibi eski moda görüntüsü yok, sonuçta elimizde görselliği daha gelişmiş olan bir menü var ama bu haliyle yetersiz. Az önce belirttiğim gibi bunu detaylı olarak sonra ele alacağız.

Ben kendi çalışmalarımda document level'a çok odaklanmadım açıkçası ama internette sıklıkla örnekleri olabildiği için bunun için de bi yer ayırmak istedim. İlgili dosyayı buradan indirebilirsiniz. (Yukarda GitHub'dan bir klasör nasıl indirilir, bahsetmiştim)

Bunlarda da Ribbon yapılabilmektedir ancak internet örneklerinde daha çok ActionPane kullanımı olmaktadır. Sadece o dosyayla ilgili işlemler için Form açmak yerine Actionpane açmak daha makul olmaktadır. Biz de burda Actionpane kullanımına odaklanacağız.

Konu bütünlüğü adına detayları aşağıya ekledim ancak size tavsiyem, bu noktadan sonra devam etmeyin. Bunu bi yere not edin, Core VSTO bölümünü tamamen bitirdikten sonra tekrar gelin.

Projeyi yaratma

Proje menüsünde VSTO Workbook seçelim ve folder/file seçimimizi yapalım. Karşımıza VS içinde br Excel görüntüsü çıkacaktır.

post-thumb

Sağ taraftaki ThisWorkbook.cs içine girelim ve Startup(VBA'deki Workbook_Open prosedürüne benzer) metodu içine odaklanalım. Buraya, dosya açılır açılmaz ActionPane'in yaratılmasını sağlayan bir kod yazacağız. Ama öncesinde daha basit birşey yazalım ve ActionPane'i bir altta ele alalım.


                    private void ThisWorkbook_Startup(object sender, System.EventArgs e)
                    {
                    MessageBox.Show("Merhaba Doc Level");
                    } 

 Bu haliyle çalıştırırsak sanki Workbook_Open prosedürüne MsgBox("Merhaba Doc Level") yazılmış bir dosya gibi davranır.

ActionPane

Konuya geçmeden önce Actionpane'lere benzeyen Taskpane'lerden de bahsedeyim. İkisi görüntü olarak aynıdır, Actionpaneler Document Level'lda kullanırken Taskpaneler Application Level'da kullanılır. Daha detay bilgi için buraya bakabilirsiniz.

Eklemek için:

  • Taskpanelerde olduğu gibi yine Projeye sağ tıklayıp Add New Item>User Control diyeceğiz. Adı da MyUsercontrol olsun.
  • Bu kontrolün içine bir combobox ve bir de button sürükleyip kaydedelim
  • ThisWorkbook.cs içine gelelim ve aşağıdaki kodu yazalım

                    private void ThisWorkbook_Startup(object sender, System.EventArgs e)
                    {
                    //MessageBox.Show("Merhaba Doc Level");
                    uc = new MyUsercontrol();            
                    this.ActionsPane.Controls.Add(uc);
                    }       

Çalıştıralım ve sonucu görelim.

 

post-thumb

Olur da bu actionpane'i kapattık, sonra bir kez daha açabilmek için bir arayüze ihtiyacımız vardır. Bunun için bu dokümana özgü olarak bir ribbon yaratıp, ordan bu actionpanei açıp kapayan bir togglebutton ekleyebiliriz.


                    private void toggleButton1_Click(object sender, RibbonControlEventArgs e)
                    {
                    if (this.toggleButton1.Checked)
                    {
                        Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = true;
                    }
                    else
                    {
                        Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = false;
                    }
                    }  

Bu kodu çok daha pratik şekilde yazabileceğinizi biliyorsunuz. Hadi bunu tek satıra indirelim.

Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = this.toggleButton1.Checked;

Bu arada, eklediğimiz ribbonun nerde göründüğüne dikkat ettiniz mi? Bunun cevabını bilmiyorsanız yukardaki tavsiyemi dinlememişsiniz, yani CoreVSTO'yu bitirmeden devam etmişsiniz demektir. Zira bu detayları Ribbon konusunda göreceğiz.

Document Level projelerle ilgili olarak başka birşey görmeyeceğiz. Detaylı bilgiye buradan ulaşabilirsinz ancak zaten çoğunlukla Application Level bilgiler yeterli olacaktır.