.Net 2.0 - .Net 3.5 ile excel'den veri nasıl alınır?

April 7, 2010 at 7:04 PMoozturk

Merhaba,

Excel'den veri alabilmek için öncelikle proje referanslarına aşağıdaki iki .net kütüphanesini eklememiz gerekiyor.

- Microsoft.Office.Core

- Microsoft.Office.Interop.Excel

Bu iki kütüphaneyi ekledikten sonra artık excel'e ulaşabilir hale gelmiş oluyoruz.

Excel'i çağırmak istediğimiz class'ın olduğu dosyanın başında gerekli namespace'i import edelim.

- using Excel = Microsoft.Office.Interop.Excel;

 

Şimdi mesela bir excel dosyasının içindeki ilk sayfadan veri okumak istiyoruz diyelim. Şöyle bir kod yazmamız yeterli.

 

Excel.Application xlApp;

Excel.Workbook xlWorkBook;

Excel.Worksheet xlWorkSheet;

object misValue = System.Reflection.Missing.Value;

xlApp = new Excel.ApplicationClass();

xlWorkBook = xlApp.Workbooks.Open(@"C:\files\2010.xls", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

string ProductCode = ((Excel.Range)xlWorkSheet.Cells[1, 1]).Value2.ToString();

 

xlWorkBook.Close(true, misValue, misValue);

xlApp.Quit();

 

 

 

releaseObject(xlWorkSheet);

releaseObject(xlWorkBook);

releaseObject(xlApp);

 

 

Tabii bu kodun çalışabilmesi için bir de releaseObject fonksiyonu lazım, onu da paylaşayım hemen

 

private void releaseObject(object obj)

{

try

   {

       System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);

        obj = null;

    }

catch (Exception ex)

    {

         obj = null;

&n bsp;        MessageBox.Show("Objeyi bırakamıyorum! " + ex.ToString());

     }

finally

     {

         GC.Collect();

      }

}

 

 

Peki, excel ile çalışmak için gerken kod tamam. Ancak derlediniz ve çalışmadığını gördünüz. Sanırım şöyle bir hata alıyorsunuz

 {"Old format or invalid type library. (Exception from HRESULT: 0x80028018 (TYPE_E_INVDATAREAD))"}

Bu hata'nın neden kaynaklandığını da araştırırsanız, sorunun Excel 11.0 kütüphanesinin Culture ayarlarının US olmaması durumunda hata verdiğini öğrenebilirsiniz. Yani Excel kütüphanesinde hata var.

Peki bu hatayı nasıl aşacağız? Çok basit. Excel için çalışacak kodun başına aşağıdaki komutları yazarak, hem bilgisayarımızın Culture ayarının yedeğini alır hem de excel çalışabilsin diye US'e ayarlarız.

 

System.Globalization.CultureInfo oldCI = System.Threading.Thread.CurrentThread.CurrentCulture;

 

System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");

 

Kodun sonuna ise aşağıdak kodu yazarak tekrar bilgisayarın kendi Culture ayarlarına geri dönebiliriz.

System.Threading.Thread.CurrentThread.CurrentCulture = oldCI;

 

Bu kadar. Eğer dosya adını doğru yazdıysanız ve okumaya çalıştığınız hücrede bir değer varsa alırsınız.

 

 

İyi çalışmalar dilerim!

Posted in: .NET | C# | MS Office

Tags: ,

Abstract Class vs Interface

November 13, 2008 at 2:23 AMoozturk

  Nesne tabanlı programlama (object oriented programming) yaparken, hazırladığımız classlar için base classlar hazarlarız. Bunu yaparken normal class, abstract class, interface kullanırız. Peki hangisi ne işe yarar, hangisini hangi durumlarda kullanmalı?

  Öncelikle abstract class ve interface için şunu söyleyebiliriz; direk olarak değişken yaratamayız bunlardan. Tamamen tanım amaçlı yazıldıkları için, normal class gibi kullanılamazlar. Haliyle eğer değişkene atayıp (instance) kullanmak istiyorsak taban class'ımızı mutlaka bu seçenekler arasından normal class'ı seçmeliyiz.

   Abstract class ile interface karşılaştırması yapmak istersen öncelikle söyleyebileceğimiz bazı farklar var aralarında. Abstract classlar; abstract metodlar (methods), abstract özellikler (properties) gibi diğer üyeleri de barındırabilirler. (Tıpkı normal classlar gibi). Interfaceler ise; Zaten abstract ya da public kelimelerini kullanmamıza gerek kalmadan, içinde tanımladığımız bütün metodları ve özellikleri public ve abstract olarak taşırlar. Yani başka bir şansımız zaten yoktur. Örnek olarak aşağıdaki koda bakalım.

//Abstarct Class

public abstract class Vehicles {

        private int noOfWheel;

        private string color;

        public abstract string Engine {

            get;

            set;

        }

        public abstract void Accelerator();

      }

      //Interface

public interface Vehicles {

        string Engine {

            get;

            set;

        }

        void Accelerator();

      }

  Gördüğümüz gibi abstract classlarda özellikleri ve diğer üyeleri private olarak da tanımlayabildiğimiz gibi aynı zaman da metodları da implemente de edebiliyoruz. Esasen abstract class için gerçek dünyada kullandığmız varlıklar için daha bir tanımlayıcı bakışa sahip olduklarını ancak interfacelerin çok daha tanımlayıcı amaçla kullanıldıklarını söyleyebiliriz. Varlıklar hakkında konuşabileceğimiz iki temel konu vardır. Birincisi maksat, ikincisi ise uygulamadır. Maksat derken buradaki kasıt; durum ve davranıştır, nasıl göründüğü ya da nasıl çalıştığı değil (belki birazcık bilinebilir ama tam denilemez). Uygulama derken de; uygulanırken ki durumu (yani gerçek durumu) ve davranışıdır.

   Biraz teoriden sıyrılıp, bir örnek üzerinden bakalım konuya.

  Bir CMS düşünelim (Content Management System - İçerik Yönetim Sistemi). İçerik; makale, blog ve eleştiriler olsun. Demek ki bu üç farklı şeyin bir ortak noktası var temel olarak o da üçünün de içerik olması. Icerik bizim tabanımız olacak demek ki. Peki Icerik, normal class mı, abstract class mı yoksa interface mi olmalı? Düşündüğümüz iş mantığı (business logic) çerçevesinden bakınca eğer Icerik uygulamanın temel varlığı olmayacak ve kullanılacak bir nesne olmayacaksa - ki bu örnek bu cümleye uyuyor çünkü bu uygulama da temel varlıklar makale, blog ve eleştirilerdir - ; o zaman normal class yapmamalıdır. Geriye abstract class ve interface kalıyor.

  Bu uygulama da her içeriğin yayınlanabilmesi gerekiyor. Haliyle, Icerik tanımının mutlaka içinde bir "yayınla" komutuna ihtiyacı vardır, bu durumda Icerik tanımını mutlaka abstract class olarak yapmak gerekir. Eğer iş mantığımda her içeriğin varsayılan ortak komutu olmasaydı (yayınla komutu mesela), o zaman abstract class'a gerek kalmazdı ve interface de kullanabilrdim. Bunlar normal class, abstract class ve interface arasında seçim yapılacağı zaman en temel farklar oluyorlar. Ama şu gerçeği unutmamak lazım ki, üzerinde konuştuğumuz şey yazılım ve değişmeyen tekşey zaten değişimin ta kendisi. Mesela eğer Icerik tanımını interface olarak yapsaydım, değişiklik yapmam zorlaşırdı. Icerik de yaptığım her değişikliği aynen, Icerikten türettiğim bütün nesnelere yansıtmak zorunda kalacaktım. Bunun üstesinden Icerik'i abstract class olarak tanımlayarak gelebiliyorum ancak unutmamak gereken bir tek durum dışında; çoklu miras (multiple inheritance). Interface ve abstract classları ayıran bir değer fark da CAN-DO (yapabilir) ve IS-A (böyledir) bağlantılarıdır. Az evvel bahsettiğim gibi interface'i çoklu miras için kullanabiliyoruz. Misal olarak bir de kopyalama davranışı veren "ICopy" adında bir interface'imiz olsun ki bu da genelleştirme ve uzmanlaştırma, özelleştirme durumu için bir IS-A bağlantısıdır. Yani türemiş bütün nesneler kendi kopyalama davranışlarına sahip olmak zorunda kalırlar. Eğer makale tanımı; abstract class olan Icerik'ten ve interface olan ICopy'den türerse bu da makale nesnesinin kopyalama yapabildiğini gösterir ki bu da CAN-DO'dur.

  Biraz teorik olarak biraz pratik desteğiyle konuyu derinlemesine anlatmaya çalıştım. Konuyu toparlamak gerekirse; abstract class, temel kimliği tanımlar. Bence abstract class günü kurtarır ve hızlıca devam edebilmeyi sağlar yani interface bence daha dikkatli kullanım ve yavaşlık getirir, gerektirir. Tabi daha önce de belirttiğim gibi interface'in en büyük avantajı ve abstract class'tan farkı çoklu miras (multiple inheritance)'dır.

  İyi çalışmalar dilerim.

Posted in: .NET | C#

Tags: , , , , , ,

Masterpage ile UICulture ve Culture değerlerinin doğru kullanılası ve dropdown ile seçim imkanı sağlanması

October 28, 2008 at 5:39 PMoozturk

Merhaba,

Herkesin farklı asp.net işleri için seçtiği farklı yöntemler vardır. Bunlardan bir tanesi de masterpage kullanarak sitede değişmeyen çoğu yerin bir sefer hazırlanması ve bu alanlardaki değişikliklerin tek yerden yapılmasının sağlanmasıdır. Bu durumda sitenin bazı içeriği haliyle sabit olacaktır ve birden fazla dil kullanılıyorsa bu dil seçiminin sayfadan yapılıyor olması çok karın ağrıtıcı bir durum oluşturabilir. Mesela sayfayı ilk defa açan birine açtığı sayfayı kendi dilinde açmak istiyorsak, bu işi her sayfada kontrol etmek istemeyiz (Aslında bu durumda Page control'ünden bir başka class yaratarak da sorun çözülebilir ancak şimdi yazacağım gibi bir çözümü de var.) ve haliyle bunu da masterpage üzerinden çözme yoluna gitmek isteyebiliriz. Masterpageler sayfa olmadığı için bu iş biraz karmaşıklaşıyor.

Aşağıya yazacaklarımı adım adım yaparsanız, sonucunuz benimkiyle aynı olacaktır. 

1. Bir boş asp.net projesi açalım ve Site1.Master ve WebForm1.aspx dosyalarını ekleyelim.

2. App_LocalResources klasörünü açtığımız projenin üstüne sağ tıkladığımızda çıkan menüden Add -> Add Asp.net folder sekmesinden ekleyelim.

3. Aynı şekilde bir de App_GlobalResources klasörünü ekleyelim.

4. App_GlobalResources klasörünün altına bir resource dosyası ekleyelim ve adını Resouce1.resx koyalım.

5. Resource1.resx dosyasının üstüne iki kere tıklayarak açalım ve açılan pencere vasıtasıyla bir satır string ekleyelim. Name değeri olarak DefaultLang koyalım, değer olarak da tr yazalım.

6. Site1.Master dosyasının içine (contentplaceholder içine değil, direk olacak kendi içine); Dropdownlist (drpLang) ekleyip iki de item ekleyelim (Biri Türkçe olsun ve değeri tr olsun, öbürü de English olsun ve değeri en olsun), Label (Label1) ve son olarak da Button (Button1) ekleyelim.

7. WebForm1.aspx içine ise; Calendar (Calendar1) ve  Button (Button2) ekleyelim.

8. Site1.Master ve WebForm1.aspx adıyla eklediğimiz dosyaların design pencerelerini sırayla açarak Tools -> General local resources komutunu çalıştırarak App_Localresources klasörünün altına resource dosyalarının eklenmesini sağlayalım.

9. Site1.Master.resx ve WebForm1.aspx.resx dosyalarını sağ kulakçık ile önce copy sonra App_LocalResources klasörüne paste edelim. Bu sayede Aynı dosya için ikişer tane resource dosyası elde etmiş olacağız. Yeni eklenen 'Copy of' ile başlayan dosyaların adlarını

 - Site1.Master.en.resx

 - WebForm1.aspx.en.resx

olarak değiştirelim. Daha sonra bu uzantısından önce en yazan dosyaların içlerini açıp yazan yazıları ingilizce olarak yazalım ve ilk yarattığımız Site1.Master.resx ve WebForm1.aspx.resx dosyalarının içeriklerini de türkçeleştirelim.

10. Projeye bir class ekleyelim ve içine şunları yazalım.

using System;

using System.Web;

using System.Threading;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Globalization;

 

namespace Projeadı {

public class BaseWebPage : Page {

protected override void InitializeCulture() {

string lang = string.Empty;//default to the invariant culture

HttpCookie cookie = Request.Cookies["SelLang"];if (cookie != null && cookie.Value != null) {

lang = cookie.Value;

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang);

}

base.InitializeCulture();

}

}

}

11. WebForm1.aspx dosyamızı bu yarattığımız BaseWebPage class'ından türemesi için kodundaki : Page yerine :BaseWebPage yazalım.

12. Masterpage'imizin koduna da aşağıdaki kodu koyalım. (Kontrol adları için siz kendinize göre değişiklikler yapın.)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace globalwebtemp1{

public partial class Site1 : System.Web.UI.MasterPage {

protected override void OnInit(EventArgs e) {

base.OnInit(e);

HttpCookie cookie = Request.Cookies["SelLang"];

if (cookie != null)

if (cookie.Value != null)

drplang.SelectedValue = cookie.Value;

else

setdefaultlang();

else

setdefaultlang();

}

private void setdefaultlang() {setlang(Resources.Resource1.DefaultLang, true);

}

private void setlang(string lang, bool refresh) {

HttpCookie cookie = new HttpCookie("SelLang");cookie.Expires = DateTime.MaxValue;

cookie.Value = lang;

Response.SetCookie(cookie);

if(refresh)

Response.Redirect(Request.Path); // this is for refreshing the requested page.

}

protected void Page_Load(object sender, EventArgs e) {

}

protected void drplang_SelectedIndexChanged(object sender, EventArgs e) {setlang(drplang.SelectedValue, true);

}

}

}

İşte bu kadar. Şimdi denediğinizde herşey doğru dilde görülüyor olacak. Masterpage'in kodunda bulunan cookie.Expires = DateTime.MaxValue değerini kaldırarak her girişte kullanılan browser'ın öntanımlı dil değerinin okunmasını sağlayabilirsiniz.

 

Tabii yukarıda da belirttiğim gibi bu sorunu çözmenin birden fazla yolu var ve yapılabileceklerin sınırı yok, ihtiyaca göre birçok şey eklenip çıkartılabilir. Ben bu yazıda yalnızca bu konuda yardığı olanlar için bir fikir vermeye çalıştım.

Umarım yardımcı olabilimişimdir. Her zaman ki gibi sorunlarınız olursa e-posta atarsanız, mümkün olan en kısa zamanda cevaplarım.

İyi çalışmaları dilerim.

Posted in: ASP.NET | C#

Tags: , , , , , , , ,