Makale Özeti

Bu makele dizisinde VBA'de geliştirilmiş olan kodların, VSTO ile VB.NET'e geçirilmesinde dikkat edilmesi gereken noktalara kod örnekleri ile değinilmektedir. Bu bölümde, konuya giriş yapılmakta, ardından veri tipleri, sabit uzunluktaki metinler, windows sabitleri, enum yapıları, dizi yapıları, metod çağırımı ve parametre geçişi konuları incelenmektedir.

Makale

VBA Kodlarını VB.NET’e Taşımak – Bölüm 1

Bu makalede, VBA ile geliştirilmiş ofis uygulamalarının, Visual Tools For Office ve Visual Basic.NET’e geçişinde kodlama seviyesinde dikkat edilmesi gereken noktalara değinilmiştir.

Visual Studio 2005 Tools For Office

Microsoft Visual Basic for Applications (VBA) yıllardır, Microsoft Office uygulamaları geliştirebilmek için eldeki tek dil ve platformdu. Bu platform .NET uygulama geliştirme ortamı ile karşılaştırıldığında oldukça kısıtlıydı. VBA kullanmak durumunda olan ofis uygulama geliştiriciler, VB 6.0’da dahi rahatça geliştirdikleri yapıları, VBA ortamına geçirmeye çalıştıklarında birçok problemle karşılaşabiliyorlardı. Diğer yandan, VBA’yi kullananlar yalnızca uygulama geliştiriciler değildi; finans, satış, insan kaynakları gibi departmanlarında çalışan teknik olmayan bazı çalışanlar da, VBA ile kendi kendilerine uygulama geliştirebilir hale gelmişlerdi.

Microsoft’un 2003 yılında, Office 2003’ü sıkı XML desteği ile çıkarması, Microsoft’un ofis uyglamaları geliştirme konusunda getireceği yeniliklerin ilk sinyallerini verdi. Visual Studio 2005 içerisindeki Visual Tools For Office (VSTO) ile ofis uygulama geliştirme süreçleri başka bir boyuta girmektedir: ofis uygulamalarını .NET Framework üzerinde geliştirmek mümkün hale gelmektedir.

Neden VSTO’ya Geçiş Yapmalı?

VBA’den VSTO’ya geçiş yapmakla öncekikle güncel teknolojiye geçiş yapılır. Bu bağlamda, geliştirme süreçerinde verimlilik artışı sağlanır. VSTO’ya geçmenin en önemli avantajlarından biri, ofis uygulamaları geliştirirken Visual Studio 2005 geliştirme ortamını kullanabilmektir. Visual Studio 2005 ve VSTO birbirlerine tamamen entegredir. Ofis uygulama geliştirme sürecinizi, son beş yılın kod geliştirme konusundaki geliştirmeleri ile pekiştirdiğnizde, kod geliştirme verimliliğiniz artacaktır.

.NET Framework üzerinde halihazırda bulunan yeni güvenlik modelini kullanarak, güvenlik açısından VBA tabanlı uygulamalardan çok daha sağlam uygulamalar geliştirilebilir. Yönetilir kodların kurulumu, dağıtımı ve versiyonlama mekanizmaları VBA platformundan çok daha gelişkindir ve uygulaması kolaydır. VSTO kullanılarak geliştirilecek ofis uygulamalarında, .NET Framework ile gelen tüm avantajlardan yararlanılabilir. Bunlar içerisinde XML işleme sınıfları, veri işleme (ADO.NET) ve web servisi erişim kütüphaneleri sayılabilir. VSTO kullanılarak geliştirilen uygualmalarda, VB.NET’in nesne yönelimli programlamaya verdiği tam destekten faydalanılabilir.

VBA Kodlarını VB.NET Kodlarına Çevirmek

Bu bölümde VBA’den VB.NET’e geçirilirken, veritipleri, sabit uzunluktaki metinler, windows sabitleri, enumeration’lar, diziler, tarih alanları, değişken kapsama alanları, metod çağırımında parantez kullanımı ve parametre geçişlerinde dikkat edilmesi gereken konulara değineceğiz.

Veri Tipleri

VBA’deki Variant, Integer, Long, Currency gibi bazı veri tiplerinin, VB.NET’te karşılığı farklıdır. Örneğin, VBA’deki Integer veri tipinin, VB.NET’teki karşılığı Short, Long veri tipinin , VB.NET’teki karşılığı da Integer’dır.

Sabit Uzunluktaki Metinler

Dizi ve structure yapıları VB.NET’in, C#.NET gibi diğer dillerle uyumlu olması için değiştirlmiştir. Buna bağlı olarak sabit uzunluktaki metinler artık desteklenmemektedir. Eğer VBA kodunuzdaki sabit uzunlukta tanımlanmış metinlerin mutlaka sabit uzunlukta olması gerekmiyorsa (sadece sabit uzunlukta tanımlanmışsa), bu durumda sözkonusu metin alanlarını aşağıdaki gibi VB.NET’te çevirebilirsiniz.



Ancak, VBA’de tanımlamış olduğunuz sabit uzunluktaki metinin gerçekten sabit uzunlukta olması zorunlu ise, bu durumda VBA kodunuzu aşağıdaki gibi, VB.NET’te bir byte dizisine çevirmeniz gerekecektir.



Windows Sabitleri yerine Literal Değerleri

VBA’de kodlama yaparken, standart Microsoft Windows Sabitlerini kullanmak yerine, özel değişkenler kullanmış iseniz, VSTO’ya geçiş sırasında normalden daha fazla efor harcamanız gerekcektir. Özel sabitlerin kullanıldığı durumlarda, önce onların Windows Sabitleri içerisindeki karşılıkları bulmanız, ve VB.NET kodu içerisinde bulduğunuz bu sabitleri kullanmanız gerekecektir. Örneğin:



Enumerations

VB.NET içerisinde enumeration sabitlerinin tam ismini kullanmak gerekmektedir. VBA kodlarında genelde sözkonusu sabitlerin kısaltmaları kullanılır. Örneğin:



Diziler

Diziler’in varsayılan başlangıç indeks değeri VBA’de de, VB.NET’te de sıfır (0) dır. Ancak, VBA’de Option Base kullanılarak başlangıç indeks değeri değiştirilebilir. Genede, Bir (1) olarak değiştirilir. Buna karşın, VB.NET’te dizilerin balangıç indeks değeri değiştirilemez; Option Base komutunun karşılığı yoktur.

Option Base kullanılarak, dizi indeks başlangıç değeri 1 olarak belirlenmiş VBA uygulamalarının VB.NET’e geçirilmesinde kullanılabilecek bir yöntem: VB.NET’te diziyi tanımlarken uzunluğunu bir fazla vermektir. Böylece kodlar düzegün bir şekilde çalışmaya devam ederken, .NET Framework bu durumdaki her dizi için Sıfır indeksinde fazladan bir eleman içerir. Kod içerisinde bu elemana referans edilmez. Bu durum, hafıza açısından da fazla yük getirmeyecektir. Bir örnek vermek gerekirse:



VBA kodunun LBOUND fonksiyonu kullanıldığında, geçerili olan dizi alt sınırının 0 değil de 1 olur. Bu gibi durumlarda yukarıdaki yaklaşım yanlış olmaktadır.

Option Base’in kullanıldığı durumlarda, dizi yapısını en baştan VB.NET’e uygun olarak; başlangıç indeks değeri Sıfır olacak şekilde, yeniden kurmak da başka bir yöntemdir. Bu yolla hafıza en verimli biçimde kullanılır ancak diğer yollara göre biraz daha efor harcamak gerekecektir.

Dizilerin kullanıldığı VBA kodlarını, VB.NET’e geçirirken, ortaya çıkan başka bir problem de yeniden dizinin büyüklüğünü belirleyen ReDim komutunun kullanımında ortaya çıkmaktadır. VB.NET’te daha önce büyüklüğü verilmiş bir dizinin büyüklüğü ReDim komutu ile değiştirilememektedir. Ayrıca, “new” anahtarı ile bir dizinin büyüklüğünü değiştirmek istediğinizde başka problemler de oluşmaktadır. Örneğin, aşağıdaki kod VBA’de problemsiz biçimde çalışırken, VB.NET’e geçirilirken bir dizi problemle karşılaşılabilir.



Bu durumda izlenecek yollardan biri, istenen büyüklükte yeni bir dizi yaratıp, eskisinin elemanlarını bu yeni diziye aşağıdaki gibi kopyalamaktır.



Tarih Alanları

VBA’de tarih alanları tamsayı olarak kullanılabilir, sayısal işlemlere tabi tutulabilirler. Bir tarih değeri ile bir tamsayıyı topladığınızda başka bir tarih değeri elde edebilirsiniz. Tarih alanları ile sayılar arasında yapılan her işlem sonucunda sayısal değerlere ulaşılabilir.

Aşağıdaki örnekte, içerisinde islemBaslangicTarihi, islemBitisTarihi isimli iki “named range” olan bir Excel 2003 workbook’una bağlı VBA kod örneği bulunmaktadır. Bu örnekte, tarihler ile sayısal değerlerin bilrlikte nasıl kullanıldığı görebilir:



Kodlar VBA’den VB.NET’e geçirilirken, tarih alanları ile ilgili tüm bu durumlar göz önünde tutulmalıdır. VBA’in iç yapısında gerçekleştirilen otomatik işlemlerin ayrıştırılması ve VB.NET kodunda FromOADate ve ToOADate metodlarını kullanarak, bu işlemleri ayrıca kodlamaları gerekmektedir. Bu bağlamda, yukarıdaki kod VB.NET’te aşağıdaki gibi implemente edilebilir:



Değişken Kapsama Alanları (Scope)

VB.NET içerisinde artık değişkenlerin kapsama alanları vardır. VBA’de metodun herhangi bir yerinde tanımlanmış tüm değişkenler, metodun içerisinde herhangi bir yerden erişilebilir; bunun nedeni VBA’de metod içerisinde tanımlanmış tüm değişkenlerin metod çağırıldığı anda yaratılmasıdır. Diğer bir deyişle, VBA’deki tüm lokal değişkenler içerisinde tanımlanmış oldukları metod seiviyesinde kapsama alanına sahiptir. Buna karşın, VB.NET’te, bir değişken, örneğin bir For döngüsü içerisinde tanımlanmışsa, o değişken For döngüsü dışından erişilemez; kapsama alanı içerisinde tanımlanmış olduğu döngüdür. Örneğin:



Metod Çağırımında Parantez Kullanımı

VBA’deki fonksiyon ve metodları çağırırken, argüman listesini kapsayacak parantez kullanmanın gerekip gerekmediği her zaman kafa karıştırıcıdır. Örneğin, parametresi olmayan fonksiyon ve yordamları çağırırken parantez kullanmaya gerek yoktur. Bir yordamı çağığrırken, doğrdan yordam ismi kullanılabilirken, yordam isminden önce Call komutu da kullanılabilir. Yordam ismini doğrudan çağırdığınızda parantez kullanmanıza gerek yoktur. Parametreleri olan bir fonksiyonu Call komutu ile birlikte çağırdığınızda ise parantez kullanmanız gerekir. Buna karşın, parametreleri olmayan bir fonksiyon çağırırken Call komutunu da kullansanız, parantez kullanmaya gerek yoktur. Bunların yanında, yazım kuralları, fonksiyonun sonucunu doğrudan bir değişkene atamanız veya atamamanız durumunda da değişmektedir.

VB.NET’te sadece çağırılan fonksiyonun parametrelerine değer geçiliyorsa parantez kullanılır. Buna ek olarak, VB.NET’te fonksiyonlar parantezle çağırıldığında farklı, parantezsiz çağırıldığında farklı işlenir. Bunun iki nedeni vardır. Bunlardan birincisi, fonksiyon parametrelerinin VB.NET tarafından değişik biçimde işlenmesi, ikincisi, parantez kullanımının fonsksiyonun geri dönüşü olup olmadığını belirlemesidir. Aşağıdaki örneklerde yordam ve fonksyionların argümanlı ve argümansız kullanımı örneklenmiştir:

Durum VBA Kodu VB.NET Kodu
Argümansız Yordam Çağırımı IslemeBasla IslemeBasla()
Call Komutu ile Argümansız Yordam Çağırımı Call IslemeBasla Call IslemeBasla()
Argümanları olan Yordam Çağırımı Kaydet “Ali Veli” Kaydet(“Ali Veli”)
Call komutu ile Argümanları olan Yordam Çağırımı Call Kaydet(“Ali Veli”) Call Kaydet(“Ali Veli”)
Argümanları Olan ve Doğrudan bir Değişkene Atanan Fonksiyon Çağırımı Toplam = ToplamHesapla(3,8) Toplam = ToplamHesapla(3,8)
Argümanları Olan ve Doğrudan bir Değişkene Atanmayan Fonksiyon Çağırımı ToplamHesapla(3,8) veya ToplamHesapla 3, 8 ToplamHesapla(3,8)


Parametre Geçişi

VBA’de, parametrelerin varsayılan geçiş şekli ByReference’ken, VB.NET’te, ByValue’dur. Aşağıdaki kodlar ByRef ve ByVal parametrelere sahip fonksiyolara örnekler vardır:



Bu kodu VB.NET’e geçirirken, parametreleri geçerken dikkat etmeniz gerekir.



Bu makalenin diğer bölümlerinde VBA kodlarını VB.NET'e geçirme sürecinde dikkat edilmesi gereken, atama işlemleri, varsayılan değerler, "exception handling", "late binding", kontrol yapıları, çoklu değişken ilanları, Windows API'leri, typeof fonksiyonları gibi konulara değinilecektir.