cub-e.net

just coding...

Microsoft Dynamics CRM 2013 'de FetchXML ile Aggregate(Toplama Sorguları) İşlemleri

Bir önceki makalede FetchXML ile neler yapabileceğimize değindik. (Buraya tıklayarak o makaleye ulaşabilirsiniz) Eğer istersek FetchXML ile grouping ve aggregate işlemlerini de yapabilmekteyiz. FetchXML ile aşağıdaki işlemler desteklenmektedir;

·         sum

·         avg

·         min

·         max

·         count(*)

·         count(attribute name)

 

Aggregate yapabileceğimiz sorgu örneği standart olarak bildiğimiz fetchXML kurgusundan farklı değil burada sadece attribute kısmında aggregate ile ilgili keyword yer almakta. Aggregate=true diyerek bu şekilde bir sorgulama yapacağımızı sisteme söylüyoruz. Sonrasında ise sırasıyla hangi alan üzerinden işlem yapılacağını, alias yani etiketin ne olacağını ve aggregate türümüzün ne olacağını sisteme söylüyoruz.

<fetch distinct='false' mapping='logical' aggregate='true'>

  <entity name='opportunity'>

    <attribute name='name' alias='opportunity_count' aggregate='count'/>

  </entity>

</fetch>

Bu şekilde oluşturduğumuz bir sorgu ile aslında şunu demek istiyoruz : “select count('name') as opportunity_count from opportunity” yani standart bir count işleminden fazlası değil yaptığımız.

 

Bu fetchXML’i çalıştırmak için ise aşağıdaki gibi bir kod hazırladım;

 

string opportunity_count = @" <fetch distinct='false' mapping='logical' aggregate='true'>

                                                <entity name='opportunity'>

                                                    <attribute name='name' alias='opportunity_count' aggregate='count'/>

                                                </entity>

                                              </fetch>";

 

                EntityCollection opportunity_count_result = ServiseBaglan().RetrieveMultiple(new FetchExpression(opportunity_count));

 

                foreach (var c in opportunity_count_result.Entities)

                {

                    Int32 aggregate2 = (Int32)((AliasedValue)c["opportunity_count"]).Value;

                    System.Console.WriteLine("Count of all opportunities: " + aggregate2);

                }

 

Burada dikkat edilmesi gereken nokta geriye EntityCollection döndürmesi. Bir önceki makalemden hatırlarsanız normalde bu tarz sorgulama ile biz geriye account, contact gibi sitem içerisindeki nesnelerden oluşmuş bir dizi alıyoruz. FetchXML yapısı gereği tek bir metod kullanıyoruz ve bu metod sonucunda yukarıdaki örnekte olduğu gibi tek bir satır dahi dönecek olsa bile yine sonucu bir collection içerisinde almaktayız. Bu nedenle mecbur foreach içerisinde dönüyoruz ya da collection’un 0. üyesini alıyoruz. Ben örneğimde foreach ile collection içinde döndüm ve gördüğünüz gibi değeri aldım.

 

Yine bir önceki makalemde ileri düzey sorgular bölümünde anlattığım gibi eğer nesne üzerinden direkt bir değer döndürmeyeceksek sonuç her zaman AliasedValue olarak gelmekte. işte bu nedenden dolayı şu şekilde bir convert işlemi yapıyoruz;

 

Int32 aggregate2 = (Int32)((AliasedValue)c["opportunity_count"]).Value

 

Bu işlem sonucunda bu koddan aşağıdaki gibi çıktımızı alabiliyoruz.

 

 

Eğer distinct yapmak istersek de fetchXML içerisine yerleştireceğimiz bir distinct=”true” ifadesiyle ile sisteme bunu beliretebiliriz.

Aşağıda ise distinct yapılmış bir kod örneği bulunmakta;

 

<fetch distinct='false' mapping='logical' aggregate='true'>

  <entity name='opportunity'>

    <attribute name='name' alias='opportunity_distcount' aggregate='countcolumn' distinct='true'/>

  </entity>

</fetch>

 

Bu FetxhXML’i de aşağıdaki kodla çalıştırabiliriz.

 

                string opportunity_distcount = @"

                                           <fetch distinct='false' mapping='logical' aggregate='true'>

                                               <entity name='opportunity'>

                                                  <attribute name='name' alias='opportunity_distcount' aggregate='countcolumn' distinct='true'/>

                                               </entity>

                                           </fetch>";

 

                EntityCollection opportunity_distcount_result = ServiseBaglan().RetrieveMultiple(new FetchExpression(opportunity_distcount));

 

                foreach (var c in opportunity_distcount_result.Entities)

                {

                    Int32 aggregate4 = (Int32)((AliasedValue)c["opportunity_distcount"]).Value;

                    System.Console.WriteLine("Distinct name count of all opportunities: " + aggregate4);

                }

 

                Console.ReadLine();

 

Bu kod sonucunda da aşağıdaki gibi bir cevap alabiliriz sistemden;


 

Gelin olayı biraz renklendirelim. Bu sefer de bir sorgu içerisinde birden fazla aggregate seçeneğinin cevabını isteyelim. Böyle bir işlem için standart fetchXML’in içerisinde sırasıyla hangi özelliklerin bize geri döneceğini belirtiyoruz tabii unutulmaması gereken nokta ise hepsi için ayrı birer alias olması gerektiğidir.

 

<fetch distinct='false' mapping='logical' aggregate='true'>

  <entity name='opportunity'>

    <attribute name='opportunityid' alias='opportunity_count' aggregate='count'/>

    <attribute name='estimatedvalue' alias='estimatedvalue_sum' aggregate='sum'/>

    <attribute name='estimatedvalue' alias='estimatedvalue_avg' aggregate='avg'/>

  </entity>

</fetch>

 

Bu sorgu için ise aşağıdaki kodu hazırladım;

 

                string estimatedvalue_avg2 = @"

                                    <fetch distinct='false' mapping='logical' aggregate='true'>

                                        <entity name='opportunity'>

                                           <attribute name='opportunityid' alias='opportunity_count' aggregate='count'/>

                                           <attribute name='estimatedvalue' alias='estimatedvalue_sum' aggregate='sum'/>

                                           <attribute name='estimatedvalue' alias='estimatedvalue_avg' aggregate='avg'/>

                                        </entity>

                                    </fetch>";

 

                EntityCollection estimatedvalue_avg2_result = ServiseBaglan().RetrieveMultiple(new FetchExpression(estimatedvalue_avg2));

 

                foreach (var c in estimatedvalue_avg2_result.Entities)

                {

                    Int32 aggregate8a = (Int32)((AliasedValue)c["opportunity_count"]).Value;

                    System.Console.WriteLine("Count of all opportunities: " + aggregate8a);

                    decimal aggregate8b = ((Money)((AliasedValue)c["estimatedvalue_sum"]).Value).Value;

                    System.Console.WriteLine("Sum of estimated value of all opportunities: " + aggregate8b);

                    decimal aggregate8c = ((Money)((AliasedValue)c["estimatedvalue_avg"]).Value).Value;

                    System.Console.WriteLine("Average of estimated value of all opportunities: " + aggregate8c);

 

                }

 

                Console.ReadLine();

 

İşte bu şekilde aynı anda count, sum ve avg işlemlerini yapabilmekteyim. Sonuç ise aşağıdaki gibi;

 

 

Bu iki makalede FetchXML’ler üzerinde konuştuk. Umarım faydalı olmuştur.

Download LINQPad

Artık SQL dili ile değil LINQ dili ile uygulamanızın içerisinden sorgu cümleleri üretmek ve LINQ öğrenmek istiyorsanız bu uygulama tam size göre. Daha fazla bilgi ve uygulamayı indirmek için :

You interactively query SQL databases with LINQPad. LINQPad is also a best way to learn LINQ. For more information and download link:

http://www.linqpad.net/

Core Entity mi Dynamic Entity mi? ( 2.Bölüm Veri Yazma)

Dynamic Entity'ler ile ilgili birinci makalemiz veri sorgulama idi. İkinci makalede ise veri yazma yöntemlerini göreceğiz. Burada dynamic entity'i anlatmadan önce core entity yöntemiyle veri yazmaya değineceğim. Böylece aradaki farkları görmemiz daha kolay olacaktır.

Konuyu hatırarsak; bir web servisini add web reference diyerek projenize dahil ettiğinizde visual studio arka tarafta bir bir class mimarisi oluşturur ve siz o mimariyi kullanırsınız. Eğer core enitity kullanırsanız, bu class özelleştirme nedeniyle her firmada farklı bir hal alabilir ve kodu yeniden derlemize neden olur. İşte bundan kurtularak çalışma zamanında nesneler yaratıp bunlara değer atamayı göreceğiz.

Hatırlarsanız bir örnek uygulamamız vardı. Senaryo şöyle idi; bir web sitemiz olacak ve bu web sitemize insanlar ad,soyad,e-mail,ilçe ve il bilgilerini yazarak kayıt olacaklar. Fakat biz forma girilen e-mail'i kullanarak veritabanımızda bu kişinin kayıtlı olup olmadığını kontrol edeceğiz eğer yoksa müşteri adayı (lead) olarak bu kişiyi Microsoft Dynamics CRM'e kaydedeceğiz.

Kaydet düğmesinin arkasında aşağıdaki kod yer almakta.
Mail adresinin yazılıp yazılmadığına bakıyoruz. Eğer yazıldı ise
dynamicRetrieve metodu ile bu mailinde birilerinin sistemde olup olmadığına bakıyoruz.



/// <summary>
///
Kaydet Dugmesi Click Olayi
/// </summary>
///
<param name="sender"></param>
///
<param name="e"></param>
protected void btnSave_Click(object sender, EventArgs e)
{
   
if (txtMail.Text != "")
    {
       
if (!dynamicRetrieve(txtMail.Text))
        {
           
if (coreCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
           
if (dynamicCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
        }
    }
}

Birinci makalede e-mail adresinden kontrol etmeyi gördük. Kontrol sonucunda e-mail adresinin sistemde bulunmadığını ve oluşturmamız gerektiğini düşünelim.


1.Core Entity

Burada önemli 3 adım bulunmakta.
1. web servisteki lead sınıfını çağırıyoruz
        lead myLead = new lead();
2. class içerisindeki proprty'e ilgili değeri atıyoruz
        myLead.firstname = txtName.Text.ToString();
3. içersisini veri ile doldurduğumuz class'ı servise oluşturması için veriyoruz.
        MyService.Create(myLead);

/// <summary>
///
coreCreate metdodu Core Entity kavramiyla lead olusturmayi bize gosterecek
/// </summary>
private bool coreCreate()
{
   
try
   
{
       
// CRM Servis'ini cagiriyoruz
       
CrmService MyService = service();
       
//lead sınıfımız aryoruz ve üretiyoruz.
       
lead myLead = new lead();
       
       
//textbox'ın değer içerip içermediğine bakıyoruz.
       
if (txtName.Text != string.Empty)
           
//eğer değer içeriyor ise class içerisindeki ilgili attribute a değerini veriyoruz.
           
myLead.firstname = txtName.Text.ToString();
       
if (txtSurname.Text != string.Empty)
            myLead.lastname = txtSurname.Text.ToString();
       
if (txtMail.Text != string.Empty)
            myLead.emailaddress1 = txtMail.Text.ToString();
       
if (txtState.Text != string.Empty)
            myLead.address1_stateorprovince = txtState.Text.ToString();
       
if (txtCity.Text != string.Empty)
            myLead.address1_city = txtCity.Text.ToString();
       

        //Son olarak da değer atamalarımız bitince servisin Create metodu ile
        //lead imizi oluşturuyoruz.
       
MyService.Create(myLead);
       
return true;
    }
   
catch (Exception ex)
    {
        HandleException(ex);

        return false;
    }
}

2. Dynamic Entity

Eğer bu oluşturma işlemini dynamic entity özelliğini kullanarak yapmış olsaydık kod bu sefer aşağıdaki gibi olacaktı.
Ama önce ne yaptığımızı anlatalım;

1. CRM Servis'ini cagiriyoruz. Burada service(); benim yazdığım bir metod ve crm servisini oluşturuyor.

       
CrmService MyService = service();
2. DynamicEntity nesnesini yaratyoruz

        DynamicEntity leadEntity = new DynamicEntity();
3. Entity ismini veriyoruz.

       
leadEntity.Name = EntityName.lead.ToString();
4. Eger deger iceriyorsa; Property nesnemizi cagiriyoruz ve adın ve degeri veriyoruz. Boylece calisma aninda bir class'in icerisindeki bir nesneye deger vermis oluyoruz.

           
StringProperty firstname = new StringProperty();
            firstname.Name =
"firstname";
            firstname.Value = txtName.Text;

Tabii burada yeri gelmişken söz etmekte fayda var CRM sadece string türünde bir değişken biçimi ile çalışmıyor. Yukarıdaki örnek "StringProperty" classından bir değişken türeterek string oluşturmaya yarıyor. Diğer değişken türleri (sınıflar) ise aşağıdaki listede yer almakta;


Sınıf Adı Microsoft Dynamics CRM Attribute Türü
CrmBooleanProperty CrmBoolean
CrmDateTimeProperty CrmDateTime
CrmDecimalProperty CrmDecimal
CrmFloatProperty CrmFloat
CrmMoneyProperty CrmMoney
CrmNumberProperty CrmNumber
CustomerProperty Customer
DynamicEntity N/A
DynamicEntityArrayProperty N/A
EntityNameReferenceProperty EntityNameReference
KeyProperty Key
LookupProperty Lookup
OwnerProperty Owner
PicklistProperty Picklist
Property N/A
StateProperty State
StatusProperty Status
StringProperty String
UniqueIdentifierProperty UniqueIdentifier
N/A Internal

Memo

Virtual



///
<summary>
///
dynamicCreate metdodu Dynamic Entity kavramiyla lead olusturmayi bize gosterecek
/// </summary>
private bool dynamicCreate()
{
    try
   
{
       
// CRM Servis'ini cagiriyoruz
       
CrmService MyService = service();
   
       
// DynamicEntity nesnesini yaratyoruz
       
DynamicEntity leadEntity = new DynamicEntity();
       
// Entity ismini veriyoruz.
       
leadEntity.Name = EntityName.lead.ToString();
       
// Property'ler icin bir Array olusturuyoruz.
       
ArrayList arrProps = new ArrayList();
   
       
// Textbox deger iceriyor mu diye kontrol ediyoruz.
       
if (txtName.Text != string.Empty)
        {
           
// Eger deger iceriyorsa; Property nesnemizi cagiriyoruz ve
            // adn ve degeri veriyoruz. Boylece calisma aninda bir class'in
            // icerisindeki bir nesneye deger vermis oluyoruz.
           
StringProperty firstname = new StringProperty();
            firstname.Name =
"firstname";
            firstname.Value = txtName.Text;
            arrProps.Add(firstname);
        }
       
if (txtSurname.Text != string.Empty)
        {
           
StringProperty lastname = new StringProperty();
            lastname.Name =
"lastname";
            lastname.Value = txtSurname.Text;
            arrProps.Add(lastname);
        }
       
if (txtMail.Text != string.Empty)
        {
           
StringProperty mail = new StringProperty();
            mail.Name =
"emailaddress1";
            mail.Value = txtMail.Text;
            arrProps.Add(mail);

        }
       
if (txtState.Text != string.Empty)
        {
           
StringProperty state = new StringProperty();
            state.Name =
"address1_stateorprovince";
            state.Value = txtState.Text;
            arrProps.Add(state);
        }
       
if (txtCity.Text != string.Empty)
        {
           
StringProperty city = new StringProperty();
            city.Name =
"address1_city";
            city.Value = txtCity.Text;
            arrProps.Add(city);
        }
       
// Property'leri bir DynamicEntity'e teslim ediyoruz.
       
leadEntity.Properties = (Property[])arrProps.ToArray(typeof(Property));
       
       
// Ve final entity'imizi olusturmasi icin servise veriyoruz.
       
MyService.Create(leadEntity);
        return true;
    }
   
catch (Exception ex)
    {
        HandleException(ex);
   
    return false;
    }
}


Uygulamamızı çalıştırdığımızda aşağıdaki ekran görüntüsünü elde edeceğiz.



Bir makale daha burada biter. Hepiniz hoşçakalın.

Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net

 

Core Entity mi Dynamic Entity mi? ( 1.Bölüm Veri Sorgulama)

Microsoft Dynamics CRM üzerinde program geliştiriren herkes veri yazarken ve veri okurken web servisinden faydalanmamız gerektiğini bilir. (Veri okurken ek olarak fetchxml ve filteredview da kullanılabilir)
 
Peki bu işlemler sırasında web servisindeki nesnelere nasıl erişirsirsiniz?

Peki CRM üzerinde çalışacak bir uygulama geliştirdiniz ve bu uygulama web servislerini kullanarak CRM üzerine veri yazan bir uygulama olsun. Amacınız bu uygulamayı CRM kullanan firmalara satarak çok para kazanmak. Ama her müşterideki özelleştirme (customization) birbirinden farklı olacağından web servisleri de birbirinden farklı olacak. Çünkü standart yöntemde web servisindeki bir sınıf türetilerek, türetilen sınıftaki nesnelere erişilir. Her firmada nesneler de birbirinden farklı olabilir.  Sonucunda uygulamanızı her müşteri için derleyecek misiniz?

Bu çok saçma ve çok yorucu olurdu. Bu durumda bize kod zamanında değil çalışma zamanında nesneleri yönetmemizi sağlayacak bir yapıya ihtiyacımız var. Yani çalışma zamanında nesneler yaratıp bunlara değer atamalıyız.

İşte CRM içerisinde bu düşünülmüş, Core Entity yani standart nesne yönetimini yerine Dynamic Entity modeli ile nesneleri çalışma zamanında oluşturabilir ve yönetebiliriz. Dynamic Entity yöntemiyle veri sorgulayabilir ve veri yazabiliriz. Sırasıyla bu ikisini göreceğiz.

Konuyu örnek uygulamamızda irdeleyelim. Örnek uygulamamız için şöyle bir senaryo düşünelim. Bir web sitemiz olacak ve bu web sitemize insanlar ad,soyad,e-mail,ilçe ve il bilgilerini yazarak kayıt olacaklar. Fakat biz forma girilen e-mail'i kullanarak veritabanımızda bu kişinin kayıtlı olup olmadığını kontrol edeceğiz eğer yoksa müşteri adayı (lead) olarak bu kişiyi CRM'e kaydedeceğiz.




Kaydet düğmesinin arkasında aşağıdaki kod yer almakta.
Mail adresinin yazılıp yazılmadığına bakıyoruz. Eğer yazıldı ise
dynamicRetrieve metodu ile bu mailinde birilerinin sistemde olup olmadığına bakıyoruz.

/// <summary>
///
Kaydet Dugmesi Click Olayi
/// </summary>
///
<param name="sender"></param>
///
<param name="e"></param>
protected void btnSave_Click(object sender, EventArgs e)
{
   
if (txtMail.Text != "")
    {
       
if (!dynamicRetrieve(txtMail.Text))
        {
           
if (coreCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
           
if (dynamicCreate())
                lblMessage.Text =
"başarıyla oluşturuldu";
        }
    }

}

Dynamic Entity yönetemiyle veri sorgulamayı göreceğiz ilk önce. (Core entity ve diğer veri sorgulama yöntemleri ile ilgili olarak 3 makalelik bir yazı dizisi yayınlamıştım hatırlarsanız o yüzden bu makalede bu konulara girmeyeceğim.)

İlk önce kodu inceleyelim.


1. query nesnemizi oluşturuyoruz

        QueryByAttribute query = new QueryByAttribute();

2. hangi entity üzerinde sorgulama yapacağımızı söylüyoruz.

        query.EntityName =
EntityName.lead.ToString();

3. sorgulama sonucunda hangi alanları geri istiyoruz bunu söylüyoruz

       
ColumnSet cs = new ColumnSet();
        cs.Attributes =
new string[] { "firstname","lastname","address1_city" };
        query.ColumnSet = cs;

 4. koşulumuzu veriyoruz.
        query.Attributes =
new string[] { "emailaddress1" };
        query.Values =
new object[] { mail };

        Aslında buraya kadar ( " select firstname","lastname","address1_city from filteredlead where emailaddress1 = '"+ mail +"' ") dedik. Ama servis kullanarak bunu demek daha zahmetli.

5. servisimizi çağırıyoruz. Burada service(); benim oluşturduğum bir metod. CRM 3.0 ve CRM 4.0 arasında servise bağlanmakta farklılıklar var. Bunu daha önceki bir makalemde anlattığım için burada anlatmıyorum.

       
CrmService MyService = service();

6. işte can alıcı nokta burası geriye core entity değil dynamic entity istediğimizi söylüyoruz.
        retrieved.ReturnDynamicEntities =
true;

7. gelen sınıfı DynamicEntity türüne çeviriyoruz.
           
DynamicEntity entity = (DynamicEntity)responsed.BusinessEntityCollection.BusinessEntities[0];

8. işte ikinci can alıcı nokta burası. gelen DynamicEntity içinden property leri birer birer çıkartıyoruz.
Gelen property inin Value attribute 'u içerisinde değer bulunmakta bunu set ediyoruz.
           
StringProperty property = (StringProperty)entity.Properties[i];
            firstname = property.Value;

Kodun tamamı aşağıdadır.

/// <summary>
///
dynamicRetrieve metdodu Dynamic Entity kavramiyla veri cekmeyi bize gosterecek
/// </summary>
private bool dynamicRetrieve(string mail)
{
   
try
   
{
        //query nesnemizi oluşturuyoruz
        QueryByAttribute query = new QueryByAttribute();

        //hangi entity üzerinde sorgulama yapacağımızı söylüyoruz.
        query.EntityName =
EntityName.lead.ToString();

        //sorgulama sonucunda hangi alanları geri istiyoruz bunu söylüyoruz
       
ColumnSet cs = new ColumnSet();
        cs.Attributes =
new string[] { "firstname","lastname","address1_city" };
        query.ColumnSet = cs;

        //koşulumuzu veriyoruz.
        query.Attributes =
new string[] { "emailaddress1" };
        query.Values =
new object[] { mail };

        //aslında buraya kadar ( " select firstname","lastname","address1_city from filteredlead where emailaddress1 = '"+ mail +"' ") dedik.

        //
servisimizi çağırıyoruz.
       
CrmService MyService = service();
       
RetrieveMultipleRequest retrieved = new RetrieveMultipleRequest();

        //işte can alıcı nokta burası geriye core entity değil dynamic entity istediğimizi söylüyoruz.
        retrieved.ReturnDynamicEntities =
true;
        retrieved.Query = query;
       
RetrieveMultipleResponse responsed = (RetrieveMultipleResponse)MyService.Execute(retrieved);
       
if (responsed != null && responsed.BusinessEntityCollection.BusinessEntities.Length > 0)
        {

   
        //gelen sınıfı DynamicEntity türüne çeviriyoruz.
           
DynamicEntity entity = (DynamicEntity)responsed.BusinessEntityCollection.BusinessEntities[0];
           
string firstname = "";
           
string lastname = "";
           
string city = "";
           
for (int i = 0; i < entity.Properties.Length; i++)
            {
               
if (entity.Properties[i].Name.ToLower() == "firstname")
                {
           
        //işte ikinci can alıcı nokta burası. gelen DynamicEntity içinden property leri birer birer çıkartıyoruz.
                    //gelen property inin Value attribute 'u içerisinde değer bulunmakta bunu set ediyoruz.
                   
StringProperty property = (StringProperty)entity.Properties[i];
                    firstname = property.Value;
                }
               
if (entity.Properties[i].Name.ToLower() == "lastname")
                {
                   
StringProperty property = (StringProperty)entity.Properties[i];
                    lastname = property.Value;
                }
               
if (entity.Properties[i].Name.ToLower() == "address1_city")
                {
                   
StringProperty property = (StringProperty)entity.Properties[i];
                    city = property.Value;
                }
            }
           
string result = "<table border=1><tr>";
            result +=
"<td>Ad</td>";
            result +=
"<td>Soyad</td>";
            result +=
"<td>Şehir</td>";
            result +=
"</tr>";
            result +=
"<tr>";
            result +=
"<td>" + firstname + "</td>";
           
result += "<td>" + lastname + "</td>";
            result +=
"<td>" + city + "</td>";
            result +=
"</tr></table>";
            lblMessage.Text =
"eşleşen kayıtlar bulundu";
            lblMessage.Text += result;
           
return true;
        }
       
return false;
    }
   
catch (Exception ex)
    {
        HandleException(ex);
       
return false;
    }
}

Daha önceden sitemize kayıt olmuş test1 kişisinin sitemize tekrar kayıt olmaya çalıştığını düşünelim uygulama eşleşen bir kayıt bulacağından görüntü şöyle olacak.




Bu makaleye de burada noktayı koyalım. Unutmayın sırada veri yazma ile ilgili bir makale var.

Barış KANLICA
Yazılım Uzmanı – Software Specialist
brsk@e-kolay.net
www.cub-e.net