Axapta’da Sıfırdan Proje Geliştirmek

Axapta’da geliştirme yapmaya başladığınız da ilkte kolay gibi gelir, içerisine daha derinlemesine girdikçe aslında gözüken ilk o yüzün arkasında çok karmaşık süreçler olduğu bir yapı vardır bu yapı da zamanla üzerinde daha fazla çalıştıkça anlamaya ve kavramaya başlarsınız. Biz de bu yazımızda axapta üzerinde sıfırdan bir proje nasıl oluşturulur adımlarıyla işliyor olacağız. Kurgumuz, İşletmemizde oluşan duruşları tutmak istediğimizi düşünüyoruz.bunun için duruş nedenlerimizi çıkarıyoruz ve bu duruşları hat üretim ekranları üzerinden girişlerinin yapılacağını hayal ediyoruz. İlk öncelikle Duruş / Arıza kayıtlarımızı girmek için bir çalışmaya başlayalım.   1.Adım  - Proje Klasörü oluşturmak Axapta’da yeni bir proje gelişirken her zaman yeni bir proje klasörü oluşturmanızı öneririm. Çünkü geliştirmekte olduğunuz uygulama için oluşturduğunuz AOT nesnelerine tabi ki yine AOT üzerinden görebilirsiniz. Fakat daha rahat kullanım, daha düzenli bir yapı ve istediklerinize daha rahat ulaşabilmeniz için bir proje klasörü oluşturmak gerekir. Ctrl+Üst Krkt+P kısa yolu ile Project penceresini açabiliriz. MDI_HaltCards adında bir proje dosyası oluşturalım.     Project dosyası içerinde oluşturacağınız AOT nesnelerini visual studio Solution explorer’da formları,classları klasörleştirdiğimiz gibi ax tarafında  da Group nesnesi sayesinde ayrıştırabiliriz. 1-DataDictionary adında bir group oluşturalım. 2-Özelliklerine gidelim ve Project Group Type’ni Data Dictionary olarak belirleyelim. Project Group Type özelliği  group’a belirlenen type için group altında hangi nesneleri oluşturabileceğimiz  gibi bir özellik kazandırır.   ve artık İlk tablomuz olan Duruş Kart tablomuzu için alanlarımızı oluşturalım. 2.Adım – ExtendedDataTypes Oluşturmak axapta bir geliştirici olarak ilk öğrenmeniz en önemli konu ExtendedDataTypes’leridir.  ExtendedDataTypes kullanımı ne işe yarardıklarını çok iyi anlamak gerekir.   ExtendedDataTypes aslında bildiğiniz string,integer,date gibi typelerdir fakat çok daha yetenekli ve yapabildikleri inanılmazdır. Bunlarda bazıları, -Ana Tabloya git özelliği -Numara serileri -ilişkiler -Basit filtrelemeler -Açılan pencere kutucukları (Lookuplar) Axapta da projeleriniz daha önceden oluşturulmuş ExtendedDataTypes kullabilir ya da yeniden sıfırdan oluşturabiliriz. Genel de ilk başlarda sorulan soru çoğu peki işimize yarayacak bir type bu tablolar için yada class’lar içinde geçerlidir nasıl buluruzdur bu yetenek zamanla kazanılacak bir durumdur genelde danışmanlardan sizi bu konuda yönlendirir ve bir kaçta axaptanın biz developer lara sağladığı kolaylıklar sayesinde bunları bulabiliriz bunların şuanlık özetle geçiyorum.   Aşağıdaki gibi ExtendedDataTypes  oluşturalım. HaltCode :String (30) HaltType = Enums  (label etiketi sonrası anlatılmaktadır.) Name = String (60) Description : String (60)   Kalın font olan belirtilmiş olan Extended Data Types sıfırdan bizim oluştuklarımız iken , diğer Extended Data Types  axaptanın sürükle bırak yöntemi ile daha önceden oluşturulmuş standart extended Extended Data Types olduğunu belirtmektedir. ExtendedDataTypes özellikler penceresini açmışken kısaca bir konu ya daha da değineyim. ax üzerinde label önemli bir yer verilmiş Best Practices bir geliştirici olmak için ilk dikkat etmeniz gereken konulardan biri de labellardır. property de label tıkladığınızda size aşağıdaki bir form açarak burada farklı Dil’lere göre bu etiketin karşılığı girmeniz sağlanır. bu özellikliği bir query ,job yazarken de metin içerikler için kullanılabilmektesiniz.     Enum Oluşturma
  1. BaseEnums group sağ tık BaseEnum Oluştur. (HaltTypes)
  2. HaltTeys Yeni Element oluştur.
Oluşturduğumuz bu enumu daha sonra sürükle bırak yaparak ExtendedDataTypelarımızın arasına atıyoruz.   3.Adım – Tables Oluşturmak Projemiz içerisinde Tables Groubumuzda sağ tıklayıp Tables diyerek MDI_HaltCards adında bir table oluşturuyoruz ve içerisine oluşturduğumuz ExtendedDataType’leri fields sürükleyip bırakalım. Tablolarımızın önemli ve en çok kullandığımız özelliklerine kısaca bir bakalım,     1-CacheLoookup : hangi durumlarda tablomuzun cacheleneceği belirlenir.
  • None  : Cacheleme yapılmaz.
  • Found:genelde çok sık değişmeyen tablolar için kullanılır kayıt ilk kez bulunduğunda cachelenir.
  • FoundAndEmpty:found tek farklı eğer sorgu boş gelirse de sorgu bu boş haliyle cache’leme yapılacaktır.
  • NotInTSS:TtsCommit gibi bir işlem başarılı şekilde biterse bu sorgu cachlenir eğer ttsbegin işlemi yani bir hata oluşursa cache’leme gerçekleşmeyecektir.burada ki ttsCommit .net tarafında ki SqlTransaction gibidir.
  • Entire Table:Bu parametre genelde değiştirilme özelliği çok nadir olan tablolar için kullanılmaktadır.
  2-Createby , CreateDateTime vb özelliklerini  Yes yaptığımız da tablomuza bu kayıtlar için field oluştur ve bu kayıtları tutmaya başlar. 3-FormRef : Ana Tabloya git özelliğini değiştirmek için kullanılır eğer boş bırakılırsa EDT üzerinde ilişkilendirilir. 4-Temporary:Bu özelliklikle tabloya girilen verilerin veritabanına yazılıp yazılmayacağı belirlenir eğerYes seçilir bu kayıtlar AOS serverın bulunduğu sunucunun belleğinde tutulacaktır.  5-ConfigurationKey:tablonun bulunduğu güvenlik hiyerarişinini belirler. 6-SecurityKey:Tablomuza erişimi belirlemek için kullanılır.   Table Field Group Field grouplar oluşturacağımız formlarda ,raporlarda vb kullanmak için fieldlarımızı grouplamamıza olanak sağlarlar. Örneğin standart Auto Report alanı içerisinde koyduğumuz filed’leri bir rapor otomatik olarak çekerek basit bir rapor elde edebiliriz. Tablomuz içerisinde Field Grouplarımızı sağ tıklayarak yeni bir group oluştur diyerek HaltCards isiminde bir group oluşuralım. Ve içerisine yine aynı şekilde fieldlerden istediğimiz alanları sürükleyerek bırakalım.     Tablolarda indexes oluşturmak, indexler bilindiği gibi bize temel anlamda arama,sıralama,gruplama gibi işlemler yaparken bizler için oluşturulmuş ön bilgilerdir. Axapta da iki temel index türü mevcuttur , bunların 1.Tekil(unique) index 2.Tekil olmayan (Non unique) index. Tekil(unique) index tabloda sadece bir kere tekrarlanmasını izin verilirken, Tekil olmayan (Non unique) olmayan indexler ise genel aramaların hızlandırılması için kullanılır. 1-Tablomuzda Indexes gelen ve Yeni index oluştur  diyerek IdxHaltCode adında bir index oluşturalım.
  1. IdxHaltCode index sağ tıklayarak Field diyerek yeni bir field oluşturalım.
  2. Field özelliklerinde DataField’ını daha önce oluşturduğumuz HaltCode olarak belirleyelim.
Eğer indeksimiz tekil olacak ise tablolarda tekrarlanmasını istemiyorsak indeximizin AllowDuplicationözelliğini No yapın.eğer tablo içerisinde bulunan kayıtlar buna uygun değilse size hata mesajı döndürecektir.            4.Adım- Form Oluşturmak 1-Projemizde Forms  adıyla bir group oluşturalım. 2-Forms sağ tık Yeni Form diyerek MDI_HaltCards adında bir form oluşturalım. 3-Data Source kısmına oluşturduğumu MDI_HaltCards tablosunu sürükleyip bıralım. 4-Desings bölümü açalım ve  Desing sağ tıklayıp yeni control bölümü geçelim bura da bir Grid oluşturalım. Burada görüldüğü gibi onlarca kullanabilceğimiz nesnler mevcut durumda 5-Gridin özelliklerini penceresini açalım.       6-DataSource formumuz içerisindeki MDI_HaltCards  seçelim.       7-DataGroup özelliğine hatırlarsanız daha önce oluşturduğumuz Halt Cards groubunu seçelim.     Birde formumuzda gridmizin altında bize akfit kayıtımızı gösteren textboxlar koyalım ve yazma özelliklerini özelliklerini AllowEdit = No yaparak kapatalım. 8-Desing – Yeni Control – Group Ekle 9-Oluşturduğumuz groupta –Yeni Control –String Edit Ekleyelim. String Editlerimizi olurup özellikler penceresinden DataSouce:MDI_HaltCrads DataField:gösterilecek field seçelim. AllowEdit:No yaparak yazmaya kapalım.     Gelin bakalım şimdi formumuz nasıl oldu, Temel olarak şuan kadar axapta bir proje nasıl geliştirilir adımlarıyla gördük. Peki bu zaman kadar geliştirirken unuttuğumuz bir çok önemli girmediği özellikler oldu bunları nasıl tespit edebiliriz . Axaptanın burada  Derleme(F7) özelliği imdadımıza yetişiyor ve unuttuğumuz security key ,HelpText,TitleFiled1 gibi özellikleri bize önerilen Uygulamalar tagı altında belirtiyor.   Bu proje Microsoft Dynamics AX 2009 versiyonunda geliştirilmiştir.

C# ile Lisanslama Aracı Geliştirmek

Geliştirdiğimiz uygulamaları her zaman bir lisanslama, izinsiz kullanımları engelleme ihtiyacı duyarız. Bu hatta basit çaplı geliştirdiğimiz uygulama için bile bazen ihtiyacımız söz konusu olur. Genellikle yazılım firmaları, geliştiriciler kendi lisanslama algoritmaları oluşturur ya da 3.parti (TNTLicensing )gibi yazılımlar kullanma yoluna gider. Bizde şimdi kendi algoritmamızı oluşturarak, geliştirdiğimiz uygulamaları lisanslamak için bir araç geliştirelim. Kurgumuz, 13 haneden oluşan bir serimiz olduğu düşünelim, Serimizin ilk3 hanesi  (Yil + (Saniye * 12) + Ay) İkinci 3 hanesi  (Gün + (Saniye * 7)+ Saat) Üçüncü 3 hanesi  (Dakika + (Saniye * 19)+Saniye) serimizin son 4 hanesi de işlemcinin Id numarasından oluşsun. Bu sayede uygulamamız lisanslamadığı sürece her açıldığı farklı bir seri üretmiş olacağız. Şimdi aşağıdaki gibi form oluşturalım, Nesnelerimiz, btnSeriUret                        :Button btnAnahtarUrt                    :Button txtSeriUret                        :MaskedTexBox txtAnahtaUret                    :MaskedTexBox   Btn_SeriUret butonumuzda oluşturarak istediğimiz seriyi üretmek için kodlarımızı yazmaya başlayalım,

string cpuInfo = String.Empty;

string temp = String.Empty;

int sayiDeger = 1000;

// işlemcimizin Id içerisinde bulunan sadece sayısal değerleri alarak başlangıç değeri olarak atadığımız 1000 üzerine ekletiyoruz.

ManagementClass mc = new ManagementClass("Win32_Processor");

ManagementObjectCollection moc = mc.GetInstances();

foreach (ManagementObject mo in moc)

{

if (cpuInfo == String.Empty)

{

string deger = mo.Properties["ProcessorId"].Value.ToString();

for (int i = 0; i < deger.Length; i++)

{

if (Char.IsDigit(deger[i]))

{

sayiDeger += deger[i];

}

}

}

}

txtSeri.Text =

 

// 1 (Yil + (Saniye * 165) + Ay)

 

(Convert.ToInt32(DateTime.Now.Year)

<ul>
<li>Convert.ToInt32(DateTime.Now.Second * 12)</p></li>
<li><p>Convert.ToInt32(DateTime.Now.Month)).ToString().Substring(1, 3)</p></li>
</ul>

<p>&nbsp;

//2 (Gün + (Saniye * 896)+ Saat)

&nbsp;

<ul>
<li>(DateTime.Now.Day.ToString() + Convert.ToInt32(DateTime.Now.Second * 7)</p></li>
<li><p>DateTime.Now.Hour.ToString()).Substring(0, 3)</p></li>
</ul>

<p>&nbsp;

//3 (Dakika + (Saniye * 648)+Saniye)

&nbsp;

<ul>
<li>(DateTime.Now.Minute.ToString() + Convert.ToInt32(DateTime.Now.Second * 19)</p></li>
<li><p>DateTime.Now.Second.ToString()).Substring(0, 3)</p></li>
</ul>

<p>&nbsp;

//4  İşlemci Id

&nbsp;

<ul>
<li>sayiDeger.ToString().Substring(0, 4);</li>
</ul>

  Kabaca bir seri ürettiğimiz göre şimdi bu seriyi eşleyecek bir anahtar kontrolü yazmamız gerekecek,   12 haneli 4 gruplardan oluşan ve seri numarasından değerler alarak basitçe bir anahtar numarası üretelim.   BtnAnahtarUret butonumuz da, oluşturmak istediğimiz anahtar numaramızı üretmek için kodlarımızı yazalım.   // Daha rahat okumanız adına 12 tane değerleri tutması için string değişkenler tanımladım ve bu değişklerimizde kuracağımız formüllerin değerlerini atayacağız.

string _deger1 = null

, _deger2 = null

, _deger3 = null

, _deger4 = null

, _deger5 = null

, _deger6 = null

, _deger7 = null

, _deger8 = null

, _deger9 = null

, _deger10 = null

, _deger11 = null

, _deger12 = null;

&nbsp;

//  (Math.Abs((Seri10 - Seri1 + Seri5 +Seri4 + Seri7) * 19 * (seri8 + seri2))) % 10)

&nbsp;

_deger1 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(13, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(0, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(5, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(9, 1)))</p></li>
<li><p>19</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(10, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(1, 1)))) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

//  (Math.Abs(( Seri10 + Seri11 – Seri12 + Seri8) - (Seri8 + (Seri5 + Seri3)))* 7) % 10)

_deger2 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(13, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(14, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(10, 1)))</p></li>
</ul>

<p>&nbsp;

-(Convert.ToInt16(txtSeri.Text.Substring(10, 1))

+(Convert.ToInt16(txtSeri.Text.Substring(6, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(2, 1))))*7) % 10).ToString();</li>
</ul>

_deger3 = (Math.Abs(
(Convert.ToInt16(txtSeri.Text.Substring(1, 1))
* Convert.ToInt16(txtSeri.Text.Substring(5, 1))
* Convert.ToInt16(txtSeri.Text.Substring(9, 1)))

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(2, 1))</li>
<li>(Convert.ToInt16(txtSeri.Text.Substring(6, 1))</li>
<li>(Convert.ToInt16(txtSeri.Text.Substring(10, 1))</li>
<li>Convert.ToInt16(txtSeri.Text.Substring(0, 1)))))* 6) % 10).ToString();</li>
</ul>

_deger4 = (Math.Abs(
(Convert.ToInt16(txtSeri.Text.Substring(12, 1))
- Convert.ToInt16(txtSeri.Text.Substring(0, 1))
+ Convert.ToInt16(txtSeri.Text.Substring(6, 1))
+ Convert.ToInt16(txtSeri.Text.Substring(5, 1))
+ Convert.ToInt16(txtSeri.Text.Substring(8, 1)))
- 19
- (Convert.ToInt16(txtSeri.Text.Substring(10, 1))
+ Convert.ToInt16(txtSeri.Text.Substring(1, 1)))) % 10).ToString();

&nbsp;

&nbsp;

//

_deger5 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(10, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(14, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(5, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(0, 1)))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(5, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(8, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(0, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(1, 1))) + 19) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

//

_deger6 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(1, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(4, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(9, 1)))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(2, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(10, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(14, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1))) - 19) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

//

_deger7 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(12, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(14, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1)))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(13, 1))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(8, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(4, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(0, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(2, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1))) * 6) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

//

_deger8 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(13, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(14, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(10, 1)))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(10, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(2, 1)))) * 19) % 10).ToString();</p></li>
</ul>

<p>//

_deger9 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(12, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(14, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1)))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(13, 1))</li>
</ul>

&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(8, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(4, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(0, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(2, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1))) * 6) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

&nbsp;

//

_deger10 = (Math.Abs(

&nbsp;

(Convert.ToInt16(txtSeri.Text.Substring(13, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(14, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(15, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(10, 1)))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(10, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(2, 1)))) * 7) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

//

&nbsp;

_deger11 = (Math.Abs(

(Convert.ToInt16(txtSeri.Text.Substring(6, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(8, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(9, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(1, 1)))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(9, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(4, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(8, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(4, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(9, 1))))))+4) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

//

_deger12 = (Math.Abs(

(Convert.ToInt16(txtSeri.Text.Substring(5, 1))

<ul>
<li>Convert.ToInt16(txtSeri.Text.Substring(8, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(6, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(4, 1)))</p></li>
</ul>

<p>&nbsp;

<ul>
<li>(Convert.ToInt16(txtSeri.Text.Substring(10, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(8, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(2, 1))</p></li>
<li><p>(Convert.ToInt16(txtSeri.Text.Substring(1, 1))</p></li>
<li><p>Convert.ToInt16(txtSeri.Text.Substring(0, 1)))))) * 19) % 10).ToString();</p></li>
</ul>

<p>&nbsp;

&nbsp;

//  Anahtar MaskedTexbox umuza değerlerimi atayalım.

&nbsp;

txtAnahtar.Text =  _deger1 + _deger2 + _deger3 + _deger4 + _deger5

<ul>
<li>_deger6 + _deger7 + _deger8 + _deger9 + _deger10</p></li>
<li><p>_deger11 + _deger12;</p></li>
</ul>

<p>
    Kabaca bir Lisanslama aracı geliştirmiş olduk şimdi de uygularımızda bu lisanslama aracını nasıl kullanabiliriz bir bakalım. İlk öncelikle geliştirmiş olduğumuz farklı bir uygulamamız çalışmadan önce lisanslama yapılıp yapılmadığı kontrol edelim. Bildiğiniz gibi projelerimizde program.cs dosyası çalıştırılma anında ilk çalışandır biz de burada daha formlarımız falan yüklemeden lisanslama işleminin yapılıp yapılmadığını bir kontrol edelim.   Bunun içinde uygulamızın properties.setting de Lisans adında özellik oluşturalım ve default değeri:0 olsun   1-Solution Projemizi seçelim 2- Project -> Properties –> Setting 3-Yeni bir row oluşturalım (Lisans) 4-Value = 0     Program.cs   // Lisanslamanın yapılıp yapılmadığını kontrol edelim.      

static void Main()

{

if (Properties.Settings.Default.Lisans == 0)

{

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new Form_Lisans());

}

else

{

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new Form_Login());

 

}

}

Lisanslama ekranı için sizde aşağıdaki gibi örnek bir form oluşturun ve daha önce yazdığımız kodlarımızı burada kullanın   Onay butonumuz da elde ettiğimiz anahtarımız ile Anahtar textbox girilen değeri kontrol edelim. Geçerli bir anahtar girilmiş ise Lisans value değerini = 1 yapalım.
if (txtAnahtar.Text == _Onay )
{
Properties.Settings.Default.Lisans = 1;
Properties.Settings.Default.Save();
MessageBox.Show("Lisanslama işlemi başarıyla gerçekleştirildi."
, "Bilgi"
, MessageBoxButtons.OK
, MessageBoxIcon.Information
, MessageBoxDefaultButton.Button1);
}
else
{
MessageBox.Show("Geçersiz bir Anahtar kodu girdiniz."
, "Bilgi"
, MessageBoxButtons.OK
, MessageBoxIcon.Information
, MessageBoxDefaultButton.Button1);
}

Devexpress Grid Filtering Yerelleştirme L10N

Devexpress componentleri gibi 3.parti componentler yazılımcıların eli ayağı olmuş durumda sağladıkları rahatlık,kolaylık üzerimizde ki bir çok yükün alıyor. Devexpress te bize sağladığı rahatlıklardan biri de gridcontrol üzerinde son kullanıcılara filtreleme yapma olanağı sağlamasıdır.. Bunun için sadece Gridcontrolumuz de  AllowFilter=True   ve ShowAutoRilterRow= True yapmamız yeterlidir. Peki farklı dillerde kullanmak istersek gridcontrol deki  Filtreleme ekranlarını nasıl özelleştirebiliriz? Bunun için GridLocalizer ve Localizer sınıflarından faydalanacağız. Yeni bir Devexpress Windows Form Application oluşturalım.   Aşağıda Columns üzerinde sağ tıkladığımızda bize açılan menünün ve alan özel fitreleme ekranlarımızın İngilizce olduğu görmekteyiz Türkçe olarak özelleştirmek için sınıfımızı yazmaya başlayalım.         TurkishGridFilterLocalizer.cs adında bir sınıf oluşturalım.  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class TurkishGridFilterLocalizer : GridLocalizer
    {
        // Oluşturabileceğimiz farklı diller için hangi dili çalıştırdığımızı tutalım.
        public override string Language { get { return "Turkish"; } }
        public override string GetLocalizedString(GridStringId id)
        {
            string ret = "";
            switch (id)
            {
                // Grid Filtre adlandırmalarımız  -  BTKulübü Mustafa Demircioğlu
                case GridStringId.GridGroupPanelText: return "Grouplamak istediğiniz alanları buraya sürükleyiniz.";
                case GridStringId.MenuColumnClearSorting: return "Sıralamayı Kaldır";
                case GridStringId.MenuGroupPanelHide: return "Grouplama Alanını Gizle";
                case GridStringId.MenuColumnRemoveColumn: return " Sütünü Kaldır";
                case GridStringId.MenuColumnFilterEditor: return " Filtreleme & Düzenleme";
                case GridStringId.MenuColumnFindFilterShow: return "Aramayı Göster";
                case GridStringId.MenuColumnAutoFilterRowShow: return "Otomatik Filtreleme Satırı Göster";
                case GridStringId.MenuColumnSortAscending: return " Artan";
                case GridStringId.MenuColumnSortDescending: return "Azalan";
                case GridStringId.MenuColumnGroup: return "Bu alan için Grupla";
                case GridStringId.MenuColumnUnGroup: return "Çöz";
                case GridStringId.MenuColumnColumnCustomization: return "Özel Sütün";
                case GridStringId.MenuColumnBestFit: return "En uygun Genişlik";
                case GridStringId.MenuColumnFilter: return "Filtrele";
                case GridStringId.MenuColumnClearFilter: return "Filtremeyi Kaldır";
                case GridStringId.MenuColumnBestFitAllColumns: return "Tüm Sütünler Optimal";
                case GridStringId.CustomFilterDialogFormCaption :return "Filtreleme Ekranı";
                case GridStringId.CustomFilterDialogRadioAnd: return "VE";
                case GridStringId.CustomFilterDialogRadioOr: return  "VEYA";
                case GridStringId.CustomFilterDialogOkButton: return "Tamam";
                case GridStringId.CustomFilterDialogCancelButton: return "İptal";
                case GridStringId.CustomFilterDialogEmptyOperator: return "Operatör Seçiniz.";
                case GridStringId.CustomFilterDialogEmptyValue: return "Değer Giriniz.";
                case GridStringId.CustomFilterDialogHint: return "BTKulübü - Mustafa Demircioğlu";
                case GridStringId.CustomFilterDialogCaption: return "BTKulübü - Mustafa Demircioğlu";
    
                default:
                    ret = base.GetLocalizedString(id);
                    break;
            }
            return ret;
        }
    }
  Özel Filtreleme ekranımızda ki opetörlerimizi isimlendirmek için TurkishFiltersLocalizer adında bir sınıf oluşturalım.  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class TurkishFiltersLocalizer : Localizer
    {
        public override string Language { get { return "Turkish"; } }
        public override string GetLocalizedString(StringId id)
        {
            switch (id)
            {
                case StringId.FilterClauseLessOrEqual: return "Küçük veya Eşit Olanlar";
                case StringId.FilterClauseLike: return "içerenler";
                case StringId.FilterClauseNoneOf: return "Hiçbiri";
                case StringId.FilterClauseNotBetween: return "Arasında Değil";
                case StringId.FilterClauseNotLike: return "Gibi olmayanlar";
                case StringId.FilterClauseDoesNotEqual: return "Eşit Olmayanlar";
                case StringId.FilterClauseDoesNotContain: return "İçermeyen";
                case StringId.FilterClauseIsNull: return "içeren";
                case StringId.FilterClauseIsNullOrEmpty: return "Null veya Boş";
                case StringId.FilterClauseEquals: return "Eşittir";
                case StringId.FilterClauseLess: return "Küçük";
                case StringId.FilterClauseGreaterOrEqual: return "Büyük veya Eşit";
                case StringId.FilterClauseGreater: return "Büyük";
                case StringId.FilterClauseIsNotNull: return "Boş Olan";
                case StringId.FilterClauseIsNotNullOrEmpty: return "Boş olmayan";
            }
            return "";
        }
    }
    Formumuz yüklenirken aktif  GridLocalizer olarak TurkishGridFilterLocalizer , Localizer olarakta TurkishFiltersLocalizer verelim.
1
2
3
4
5
6
private void Form1_Load(object sender, EventArgs e)
        {
            GridLocalizer.Active = new TurkishGridFilterLocalizer();
            Localizer.Active = new TurkishFiltersLocalizer();
        }
         

Sql Server Aktif Kullanıcıların Bağlantılarını Kesmek

Sql server sunucumuz da bağlantı da olan kullanıcıların hangi program aracılığyla ,hangi bilgisayardan yaptığını vb izleyebilir  ve istersek dilediğimiz veritabanına bağlantı da olan kullanıcının bağlantısı kesebilir.   Özet olarak aktif bağlantıları görüntüleyelim

SELECT
nt_domain AS 'Domain'
,nt_username AS 'Kullanıcı Adı'
,hostname AS 'Bilgisayar Adı'
,program_name AS 'Kullanılan Program'
FROM
sys.sysprocesses
WHERE
nt_domain IS NOT NULL
AND nt_domain NOT IN('','NT AUTHORITY')
GROUP BY
nt_domain
,nt_username
,program_name
,hostname;

Çıktı sqlaktifbaglanti1     Detaylı olarak aktif bağlantıları görüntüleyelim

SELECT
nt_domain AS 'Domain'
,nt_username AS 'Kullanıcı Adı'
,hostname AS 'Bilgisayar Adı'
,loginame AS 'SQL User'
,program_name AS 'Kullanılan Program'
,login_time AS 'Giriş Tarih/Saati'
FROM
sys.sysprocesses
WHERE
nt_domain IS NOT NULL
AND nt_domain NOT IN('','NT AUTHORITY')
ORDER BY
login_time desc

Çıktı sqlaktifbaglanti3         bağlantının kesilmesi, MirAcle_HasssanTest databasenin de aktif bağlantı da olan BUSSINESSPC  hostname bağlantılarını keselim.

DECLARE @Database sysname

SET @Database = 'MirAcle_HasssanTest'

DECLARE @id int

SELECT @id = min(spid) from master.dbo.sysprocesses where dbid = db_id(@Database) and hostname ='BUSINESSPC'

WHILE @id IS NOT NULL

BEGIN EXECUTE ('KILL ' + @id)

SELECT @id = min(spid) from master.dbo.sysprocesses where dbid = db_id(@Database) AND spid > @id END

  Sql Aktif Kullanıcı İzleyici Uygulaması aktifkullaniciizlemeapp1 aktifkullaniciizlemeapp2     Download.     Software Developer Mustafa Demircioğlu www.mustafademircioglu.net www.mustafademircioglu.org mustafa.demircioglu@outlook.com

Sql Server Trigger Kullanımı

Trigger(tetikleyici) update,delete,insert gibi işlemler sonrasında devreye girerek bu tetikleme işlemiyle ilgii bize yeni eventlar oluşturmamıza olanak sağlar. Trigger oluşumları 2 ayrı tabloda tutulmaktadır. 1. Tablo inserted anlaşılacağı gibi bu tablo da insert olan kayıtlar tutulmaktır. 2.Tablomuz delected bu tabloda update ve delete işlemleri ilgli kayıtlar tutulmaktadır. senaryomuz, Tedarikçiden gelen ürünlerimizin çeki listelerinin yüklendiği bir palet tablomuz olsun, Ürünlerimizin stok hareketlerini tutuğumuz farklı bir tablomuz da insert , update ve delete işlemleri oluştuğunda ürünlere atadığımız referans aracılığıyla belirlediğimiz bir depoda ürünün güncel mevcut miktarını Palet Tablomuzda da güncelleyeceğimiz bir triger oluşturalım. tetiklenecek olan Stok Hareket tablomuzda triggerımızı yazmaya başlayalım,
USE [MustafaDemircioglu_DataTest]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[AcleUpd_BarkodPalet] ON [dbo].[M3_Stok_HarFis_Detay]
AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
SET NOCOUNT ON; 
DECLARE @Stok varchar(40)
    DECLARE @SthD_PartiNo varchar(40)
    DECLARE @SthD_SeriNo varchar(40)
    DECLARE @SthD_Stok varchar(50) 
    DECLARE @SthD_Turu varchar(10)
    DECLARE @SthD_Miktar float 
    DECLARE @Depo varchar (20)
    DECLARE @StokCinsi varchar (30)
    
    
    -- Sabit değerlerimiz
    SET @Depo='02'
    SET @StokCinsi ='KİMYASAL'

	
	--Delete , Update işlemlerimiz
	DECLARE CRS_AcleUpd_BarkodPalet CURSOR FOR 
		   SELECT  SthD_Stok,SthD_PartiNo,SthD_SeriNo,SthD_Turu FROM deleted 
	OPEN CRS_AcleUpd_BarkodPalet
	--deleted tablomuz içerisinde ürünlere while ile tek tek ulaşıyoruz.
	FETCH NEXT FROM CRS_AcleUpd_BarkodPalet INTO  @SthD_Stok,@SthD_PartiNo, @SthD_SeriNo ,@SthD_Turu
    WHILE @@FETCH_STATUS = 0
		BEGIN
		
			SET @SthD_Miktar=(Select Sum((CASE Left(SthD_Turu,3) WHEN 'ALM' THEN SthD_Miktar1 ELSE SthD_Miktar1 * -1 END)) 
			From M3_Stok_HarFis_Detay with(nolock,Index(Std_KeyStkDepPrtSeri)) 
			Where SthD_Stok=@SthD_Stok And SthD_PartiNo=@SthD_PartiNo And SthD_SeriNo=@SthD_SeriNo AND SthD_Depo=@Depo)
			if @SthD_Miktar is NULL SET @SthD_Miktar=0
	
	-- Turumuz alım irsaliye işlemi ise bu türe bir ayrıcalık tanımlayıp irsaliyeler zaten ilk işlemler deyip bu türü es geçiyoruz		
	IF @SthD_Turu <> 'ALM2IRS' BEGIN
	
	-- Turumuz ALM2IRS değilse Palet Tablomuzu güncelliyoruz.
	UPDATE [M3_Barkod_Palet]
		SET
		Bpl_Miktar1 =@SthD_Miktar
		FROM [M3_Barkod_Palet] X JOIN [M3_Stok_Kart] Y ON X.Bpl_Stok = Y.St_Kod
		WHERE 
				Y.St_Kod=@SthD_Stok
		  AND	Y.St_OzelAlan03=@StokCinsi
		  AND	X.Bpl_PartiNo = @SthD_PartiNo
		  AND	X.Bpl_SeriNo = @SthD_SeriNo
	 END			
		
	    FETCH NEXT FROM CRS_AcleUpd_BarkodPalet INTO @SthD_Stok,@SthD_PartiNo, @SthD_SeriNo,@SthD_Turu
	END
   Close CRS_AcleUpd_BarkodPalet
   DEALLOCATE CRS_AcleUpd_BarkodPalet
   
   
    --insert işlemlerimiz
	DECLARE CRS_AcleUpd_BarkodPalet CURSOR FOR 
		   SELECT  SthD_Stok,SthD_PartiNo,SthD_SeriNo FROM inserted 
	OPEN CRS_AcleUpd_BarkodPalet
	--inserted tablomuz içerisindeki ürünlere tek tek ulaşıyoruz.
	FETCH NEXT FROM CRS_AcleUpd_BarkodPalet INTO @SthD_Stok, @SthD_PartiNo, @SthD_SeriNo
	WHILE @@FETCH_STATUS = 0
		BEGIN
		
		    -- İlgili referans numaralı ürünümüzün tablo stok mevcutunu buluyoruz
			SET @SthD_Miktar=(Select Sum((CASE Left(SthD_Turu,3) WHEN 'ALM' THEN SthD_Miktar1 ELSE SthD_Miktar1 * -1 END)) 
			From M3_Stok_HarFis_Detay with(nolock,Index(Std_KeyStkDepPrtSeri))
			 Where SthD_Stok=@SthD_Stok And SthD_PartiNo=@SthD_PartiNo And SthD_SeriNo=@SthD_SeriNo AND SthD_Depo=@Depo)
			
			-- Eğer @SthD_Miktar boş gelirse diye önlemimizi alıyoruz.
			if @SthD_Miktar is NULL SET @SthD_Miktar=0
			--Palet Tablomuzu güncelliyoruz.
					UPDATE [M3_Barkod_Palet]
				SET
				Bpl_Miktar1 =@SthD_Miktar
				FROM [M3_Barkod_Palet] X JOIN [M3_Stok_Kart] Y ON X.Bpl_Stok = Y.St_Kod
				WHERE 
						Y.St_Kod=@SthD_Stok
				  AND	Y.St_OzelAlan03=@StokCinsi
				  AND	X.Bpl_PartiNo = @SthD_PartiNo
				  AND	X.Bpl_SeriNo = @SthD_SeriNo
		  
	    FETCH NEXT FROM CRS_AcleUpd_BarkodPalet INTO  @SthD_Stok,@SthD_PartiNo, @SthD_SeriNo
	END
   Close CRS_AcleUpd_BarkodPalet
   DEALLOCATE CRS_AcleUpd_BarkodPalet

END

Software Developer Mustafa Demircioğlu www.mustafademircioglu.net www.mustafademircioglu.org mustafa.demircioglu@outlook.com