14.E-Business(Business+IT) 

          Business Application ေရးမယ့္ Developer ေတြအတြက္ paper ေလးတစ္ခုလုပ္ထားပါတယ။္ Business ဆိုတာဘာလဲ၊ IT နဲ႕ Business ဘယ္လိုဆက္စပ္ေနလဲ၊Business မွာ ဘယ္လို Information ေတြရွိလဲ၊အဲဒါကို ဘယ္လို Computerized လုပ္လို႕ရလဲ၊ဘယ္လိုအက်ိဴးေက်းဇူးေတြရနိဳင္လဲ အဲဒါေတြနဲ႕ပတ္သတ္ၿပီး အနည္းငယ္စုေဆာင္းၿပီး တင္ၿပထားတာပါ။အက်ိဴးရွိမယ္လို႕ ေမ်ွာ္လင့္ပါတယ္။

ဒီကေန download ယူပါ။


13.Show Progress Bar while Report Loading

       StoreProcedure သံုးၿပီး ႏွစ္ခ်ဴပ္ Report ေတြ၊ calculation လုပ္ရတာမ်ားတဲ့ report ေတြၿပတဲ့အခါမွာ အခ်ိန္ၾကာတတ္ပါတယ္။အဲဒီအခ်ိန္မွာ သာမန္ wait cursor ၿပမယ့္အစား progress bar ေလးၿပထားေတာ့
user အတြက္ အဆင္ေၿပတာေပါ့။အဲလိုၿပခ်င္ရင္ StoreProcedure မွာ RaiseError function ကို
သံုးၿပီး ၿပလို႕ရပါတယ္။.net coding ဘက္ကေန SqlInfoMessageEventHandler event
နဲ႕ၿပန္ဖမ္းရပါမယ္။StoreProcedure မွာလည္း သာမန္ Select statement တစ္ေၾကာင္းထဲအတြက္ဆိုရင္ေတာ့ အသံုးမ၀င္ပါဘူး။
statement အမ်ားၾကီးထဲမွာမွ ဘယ္ statement ၿပိးရင္ ဘယ္ေလာက္ percent progress ၿဖစ္တယ္ဆိုတာ
လွမ္းၿပန္ရမွာပါ။


 Create PROCEDURE [dbo].[TEst]   
AS
BEGIN
    SET NOCOUNT ON;

Create Table #temp
(

Name varchar(20)

)

RAISERROR('Message',10,10) WITH NOWAIT


    Insert into #temp
    SELECT * from Table_1


RAISERROR('Message',10,20) WITH NOWAIT

    Insert into #temp
    SELECT * from Table_1


RAISERROR('Message',10,50) WITH NOWAIT

     Select * from #temp


RAISERROR('Message',10,90) WITH NOWAIT

     Delete from #temp


RAISERROR('Message',10,100) WITH NOWAIT

END

---------------------------------------------------------------

RaiseError ရဲ႕ first parameter မွာ ကိုယ္ၾကိဳက္တဲ့ message ကိုထည္႕လို႕ရပါတယ္။third parameter မွာေတာ့

percentage ဘယ္ေလာက္ၿပီးၿပီဆိုတာ ထည္႕ေပးရပါမယ္။

အဲဒါက coding ကေန ဒီလိုၿပန္ဖမ္းပါတယ္။(c# example)


       private void button1_Click(object sender, EventArgs e)
        {
            SqlConnection con = new SqlConnection();

            con.ConnectionString = "Data Source=.\\SQLEXPRESS;Initial Catalog=test;Integrated Security=True";
            con.InfoMessage += new SqlInfoMessageEventHandler(ProgressStatus);

            SqlCommand cmd = new SqlCommand("Test", con);
            cmd.CommandType = CommandType.StoredProcedure;

            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataSet ds = new DataSet();
            da.Fill(ds);
            Application.DoEvents();
            dataGridView1.DataSource = ds.Tables[0];
        }

        private void ProgressStatus(object sender, SqlInfoMessageEventArgs e)
        {
            if (e.Errors.Count > 0)
            {
                string message = e.Errors[0].Message;
                int state = e.Errors[0].State;                      
                progressBar1.Value = Convert.ToInt32(e.Errors[0].State);              
                Application.DoEvents();
             
            }

        }
 

ဒီေလာက္ဆိုရင္ေတာ့ ၿပည္႕စံုၿပီလို႕ထင္ပါတယ္။



12.String Vs string in .Net

   C# မွာ string variable ေၾကၿငာရင္ string အေသးနဲ႕
အၾကီး ၂မ်ိဴးၿဖစ္ေနပါတယ္။ဘာပဲသံုးသံုးၿပသနာေတာ့
မရွိပါဘူး။ဒါေပမဲ့ သူတို႕ကြာၿခားခ်က္က ဘာလဲေမးရင္
Value Type နဲ႕ Ref Type ကြာတယ္လို႕ေၿပာၾကပါတယ္။
Forum ေတြမွာလဲ အဲလိုေၿပာတဲ့လူေတြရွိပါတယ္။
တကယ္တမ္းက string အေသးက
C# အတြက္ shorthand /alias လုပ္ေပးထားတာပါ။
Ref type မဟုတ္ပါဘူး။သူလည္း System.String ပါပဲ။
ဘာသံုးသံုးကြာၿခားခ်က္မရွိပါဘူး။ဒါေပမဲ့ coding standard အရ
variable ေၾကၿငာရင္ string အေသးနဲ႕ပဲသံုးရပါမယ္။
အေသးစိတ္သိခ်င္ရင္ေတာ့ ဒီမွာ
http://www.yoda.arachsys.com/csharp/strings.html  ဖတ္ပါ။

11.ဘာလာလာ Query Filtering

 SQL SELECT query IN() function မွာ စစ္မယ့္ value ကတစ္ခုထဲဆိုအဆင္ေၿပပါတယ္။value အမ်ားၾကီးကိုို StoreProcedure ကေန parameter တစ္ခုထဲေပးၿပီးသံုးရင္ေတာ့ အလုပ္မလုပ္ပါဘူး။ဥပမာ-

Declare @filterID varchar(100)

set @filterID='A,B,C'

Select * From Table Where ID In(@filterID)

ဒီလိုေရးမယ္ဆိုရင္ အလုပ္မလုပ္ပါဘူး။အဲဒီေတာ့ @filterID ကိုတခုခ်င္းစီဖ်က္ထုတ္ဖို႕လိုလာပါၿပီ။အဲဒီအတြက္ Function ေလးကို
ရွာေတြ႕ထားပါတယ္။သူက Table return function ပါ။
---------------------------------------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

     
    ALTER FUNCTION [dbo].[Split](@String varchar(8000), @Delimiter char(1))      
    returns @temptable TABLE (items varchar(8000))      
    as      
    begin      
        declare @idx int      
       declare @slice varchar(8000)      
        
       select @idx = 1      
           if len(@String)<1 or @String is null  return      
        
       while @idx!= 0      
       begin      
           set @idx = charindex(@Delimiter,@String)      
           if @idx!=0      
               set @slice = left(@String,@idx - 1)      
           else      
               set @slice = @String      
            
           if(len(@slice)>0) 
               insert into @temptable(Items) values(@slice)      
  
          set @String = right(@String,len(@String) - @idx)      
           if len(@String) = 0 break      
       end  
   return      
   end 
------------------------------------------------------------
အဲဒီ function ကိုသံုးၿပီးၿပန္ေရးပါမယ္။
Select * From Table Where ID In(Select items from  dbo.Split(@filterID,',') )

 ',' က ဖ်က္ထုတ္ဖို႕အတြက္ပါ။ဒါဆိုအဆင္ေၿပသြားပါၿပီ။
ေနာက္တဆင့္က user က Filter ကို From To လည္းၾကည္႕ခ်င္တယ္။ၾကိဳက္သလိုလဲ selected လုပ္ၾကည္႕ခ်င္တယ္။ဘာမွ filter မလုပ္ပဲ အကုန္လဲၾကည္႕ခ်င္ၾကည္႕မယ္။အဲဒါကို query တေၾကာင္းထဲနဲ႕အဆင္ေၿပေအာင္ေရးဖို႕ၿပသနာပါ။coding ထဲကေန string concat လုပ္ရင္ေတာ့အဆင္ေၿပပါတယ္။ဒါေပမဲ့ StoreProcedure နဲ႕ပဲသံုးခ်င္တယ္။StoreProcedure မွာလည္း query ကို string အေနနဲ႕ Execute() လုပ္ရင္ရပါတယ္။ဥပမာ-
----------------------------------------------------------
Declare @TableName varchar(20)
set @TableName='Product'
declare @sql varchar(4000)
     select @sql='select * from [' + @TableName +']'
    exec (@sql)

---------------------------------------------------------
 Where condition ကို parameter အေနနဲ႕ေပးလိုက္ရင္ရပါတယ္။ဒါေပမဲ့ query ရွည္လာရင္ ဖတ္ရတာအဆင္မေၿပေတာ့ၿပန္ဘူး။
အဲဒါေတြအားလံုးအဆင္ေၿပမယ့္ပံုစံတစ္ခုကို ၿပခ်င္ပါတယ္။
--------------------------------------------------------
declare @productid_IN varchar(50) --In() အတြက္ value ထည္႕ဖို႕ var ပါ။
declare @productid_BetweenAnd varchar(50) --Between And(FromTo) အတြက္ value ထည္႕ဖို႕ var ပါ။
--ဒီ var ၂ခုက SP မွာ parameters အၿဖစ္လက္ခံရမွာပါ။

declare @productidAll varchar
declare @f_productid varchar(50)
declare @t_productid varchar(50)
--ဒီ var ၃ခုက SP မွာ local variable အၿဖစ္ေၾကၿငာၿပီးသံုးရမွာပါ။


set @productid_IN='' --'A,B,E,C,Z'
set @productid_BetweenAnd ='' --'A,Z'

--တကယ္လို႕ FromTo ေရာ IN() ေရာက ဘာမွထည္႕မေပးလိုက္ဘူးဆိုရင္ All ေပါ့။အဲဒီအတြက္ 1=1 ဆိုတာကိုသံုးထားပါတယ္။
All ဆိုရင္ 1=1 ။တခုခု filter ပါလာရင္ 1='' ပါ။
if(@productid_IN='' and @productid_BetweenAnd ='') set @productidAll='1' else set @productidAll=''

--FromTo က value ၂ခုပါလာမွာဆိုေတာ့ သူ႕ကိုၿပန္ဖ်က္ထုတ္ၿပီး From သက္သက္ To သက္သက္ local var ၂ခုထဲၿပန္ထည္႕လိုက္ပါမယ္။
if(@productid_BetweenAnd ='')
begin
    set  @t_productid=''
    set @f_productid=''
end
else
begin
    select @t_productid=substring(@productid_BetweenAnd ,charindex(',',@productid_BetweenAnd )+1,len(@productid_BetweenAnd ))
    select  @f_productid=substring(@productid_BetweenAnd ,1,charindex(',',@productid_BetweenAnd )-1)
end

--ၿပီးရင္ေတာ့ ဒီ query တစ္ေၾကာင္းေရးလိုက္ရံုပါပဲ။

select * from product where productid>=@f_productid and productid<=@t_productid
or productid in(select items from dbo.Split(@productid_IN,',')) or 1=@productidAll

----------------------------------------------------------------------------------------
အားနည္းခ်က္ကေတာ့ Filter တစ္ခုအတြက္ Parameter က ၂ ခု၊ local variable က ၃ခု လိုပါတယ္။



10.Choosing INT and VARCHAR Type for PK,FK

         Sql မွာ Table ၂ခု ကို PK ,FK ေပးၿပီးခ်ိတ္မယ္ဆိုရင္ Key Column ကုိ DataType varchar ထားၿခင္းနဲ႕ int ထားၿခင္းကိုႏႈိင္းယွဥ္ၾကည္႕မယ္ဆိုရင္ join ၿပီး select ဆြဲတဲ့ေနရမွာ int နဲ႕ဆိုပိုၿမန္ပါတယ္။row အေရအတြက္က ၁ သိန္း ၂ သိန္းေလာက္ဆိုရင္ေတာ့ သိပ္မသိသာပါဘူး။ဒါေပမဲ့ row က ၆ သိန္း ၇ သိန္းေလာက္လဲက်ေရာေတာ္ေတာ္ေလးကြာသြားပါတယ္။ varchar နဲ႕ဆြဲလို႕ ၁မိနစ္ေလာက္ၾကာရင္ int နဲ႕ဆို စကၠန္႕ ၃၀ေက်ာ္ေလာက္ပဲၾကာပါတယ္။တ၀က္နီးပါးေလာက္ပါ။ဒါေၾကာင့္ကိုယ့္ client အေၿခအေနကိုၾကည္႕ၿပီး int နဲ႕ varchar ေရြးဖို႕စဥ္းစားသင့္ပါတယ္။


9.UNION or JOIN

အလုပ္၀င္ကစက UNION ကိုေကာင္းေကာင္းမသံုးတတ္ခဲ့လို႕ ပေရာဂ်က္တစ္ခုမွာ concept လြဲခဲ့ဖူးတယ္။
project flow က ရန္ကုန္က order မွာလိုက္ရင္ နယ္စပ္ဘက္ကေန မွာတဲ့ order အေပၚမူတည္ၿပီး
ပစၥည္း၀ယ္ရတယ္။အဲဒါကို client က ဘယ္ေလာက္မွာၿပီး ဘယ္ေလာက္၀ယ္တယ္၊ဘယ္ေလာက္က်န္ေသးတယ္ဆိုတာသိခ်င္တယ္။
အဲဒါကို က်ေနာ္တို႕က Balance တြက္ရေတာ့မယ္ဆိုေတာ့ JOIN ရမယ္ေပါ့။JOIN ၿပီဆိုေတာ့ သူတို႕၂ခုၾကားမွာ
common ၿဖစ္တဲ့ field တခုသိမ္းရေတာ့မယ္။ProductID ကေတာ့ ၂ခုလံုူးမွာရွိတယ္။ဒါေပမဲ့ many to many ဆိုေတာ့အဆင္မေၿပဘူး။အဲဒီေတာ့ Purchase Table မွာ OrderID ကိုသြားသိမး္မယ္ဆိုၿပီးၿဖစ္လာတယ္။client က တခါတေလ order မမွာပဲ ၀ယ္ရတာမ်ိဴးလဲရွိတယ္။အခုက်ေနာ္တို႕လုပ္တဲ့ပံုအတိုင္းဆို order မမွာလို႕မရေတာ့ဘူး။
အစဥ္အတိုင္းသြားရမလိုၿဖစ္ေနတာ။က်ေနာ္တို႕က ဒီပံုစံပဲရမယ္ဆိုေတာ့ သူလည္းလက္ခံလိုက္ရတယ္။တစ္ခုေၿပာစရာရွိတာက တကယ္တမ္း သိ္မ္းဖို႕လိုတာမ်ိဴးဆိုရင္ေတာ့ သိမ္းရမွာေပါ့။ဥပမာ အေရာင္းvoucher အလိုက္ ပိုက္ဆံရွင္းတာမ်ိဴးဆိုရင္
cash table မွာ voucherID သိမ္းဖို႕လိုတယ္။ခုဟာက client ကအဲလိုမ်ိဴးလည္း အတိအက်မဟုတ္ဘူး။ဒါေပမဲ့ က်ေနာ္တို႕ကၿပန္ခ်ိတ္ေပးလိုက္ေတာ့ အတိအက်သေဘာၿဖစ္သြားတယ္။အမွန္တကယ္ အဲဒီကတည္းက UNION ကိုစဥ္းစားမိရင္
ဒီလိုလုပ္စရာမလိုေတာ့ဘူး။Order နဲ႕ Purchase သက္သက္စီဆြဲၿပီး UNION လုပ္ရံုပဲ။ဒါေပမဲ့ UNION ကsub query ေတာ့သံုးရတယ္။အဲဒီေတာ့ JOIN မလား UNION လုပ္မလားဆိုတာ ေသခ်ာစဥ္းစားဖို႕လိုပါတယ္။


8.Converting Sql row to column(Pivot Query)



တခါတေလ report ထုတ္တဲ့အခါမွာ rows တန္ဖိုးကို column ေထာင္ၿပရတာမ်ိဴးေတြရွိတတ္ပါတယ္(crosstab report)။
အဲဒီအခါမွာ sql ရဲ႕ pivot ဆိုတဲ့ keyword ကိုသံုးၿပီး column ေထာင္လို႕ရပါတယ္။ဥပမာ -User တစ္ေယာက္ခ်င္းစီရဲ႕ score ကိုသူ႕လအလိုက္ column ေထာင္ၿပီးၿပခ်င္တယ္။ဒါေပမဲ့ Month က row အေနနဲ႕ရွိေနမွာ။ဒါဆို က်ေနာ္တို႕ pivot သံုူးၿပီးၿပလို႕ရပါတယ္။


ဒါဆို query ကို ဒီလိုေရးရပါမယ္။

သူ႕ရဲ႕ထြက္လာမယ့္ result က

ဒီေလာက္ဆိုက်ေနာ္တို႕ လိုခ်င္တဲ့ပံုစံရၿပီထင္ပါတယ္။

Resource:Codeproject


7.Desing Patterns



တကယ္တမ္း coding ေတြကို standard က်က်OOP က်က် ေရးမယ္ဆိုရင္ ၿပသနာေလးေတြအနည္းနဲ႕အမ်ားၾကံဳေတြ႕ႏိုင္ပါတယ္။
object ေတြကိုဘယ္လိုေဆာက္မလဲ။ဘယ္လိုခ်ိတ္မလဲဆိုတာ ေတြေပါ့။Desing Patterns ဆိုတာ တကယ္ေတာ္တဲ့ developer guru ၾကီးေတြကသူတို႕ၾကံဳခဲ့ရတယ့္ အခက္အခဲေတြကိုဘယ္လိုပံုစံနဲ႕ေၿဖရွင္းထားတယ္ဆိုတာေတြပါ။သူတို႕ကေၿဖရွင္းၿပီးသားဆိုေတာ့က်ေနာ္တို႕က အဆင္သင့္ယူသံုးလိုက္ရံုေပါ့။တကယ့္ Professional Developer ၿဖစ္ခ်င္တယ္ဆိုရင္ Desing Patterns ေတြကိုမသိလုိ႕မရပါဘူး။


Desing Patterns မွာ category ၃ခုရွိပါတယ္။

  •  Creational Patterns
  •  Structural Patterns
  •  Behavioral Patterns

category  တခုခ်င္းေအာက္မွာမွ သက္ဆိုင္ရာ patterns ေတြအမ်ားၾကီးရွိပါတယ္။
 Creational Patterns ေအာက္က  Singleton Pattern
ကိုနမူနာစမ္းသံုးၾကည္႕ရေအာင္...

Singleton Pattern

ဒီဥပမာေလးက Database က္ို connection ခ်ိတ္တဲ့ class ကိုေရးၿပထားတာပါ။

//Not use Singleton Pattern
Class Connection
{
    String ServerName;
    String UserName;
    String Password;
}


//implement from Program (1)
Connection con1=new Connection
con1.ServerName="servername";
con1.UserName="username";
con1.Password="password";

//implement from Program(2)
Connection con2=new Connection
con2.ServerName="servername";
con2.UserName="username";
con2.Password="password";

တကယ္တမ္း Connection ကတခုပဲရွိရမွာ။ဒီအတိုင္းသာဆိုရင္ Connection object ေတြအမ်ားၾကီးၿဖစ္ကုန္မွာေပါ့။တခါသံုးတိုင္းတခါအသစ္ေဆာက္ရင္။ဒီၿပသနာကို  Singleton Pattern သံုးၿပီးေၿဖရွင္းမယ္ဆိုရင္။

//Applying Single Pattern
class Connection
{    String ServerName;
    String UserName;
    String Password;
    Statci Connection con=null;

    private Connection(){}
   
    public static Connection createConnection()
    {
        if(con==null)
            con=new Connection();
        return con;
    }
}
Instance တခုပဲသံုးခြင့္ေပးလိုက္ေတာ့ ဘယ္ေလာက္ပဲ object ေဆာက္ေဆာက္
ရွိၿပီးသားကိုပဲ implement လုပ္သြားမွာပါ။

Desing Patterns အေၾကာင္းအေသးစိတ္ေလ့လာခ်င္ရင္ ဒီဆိုက္ေလးက ေတာ္ေတာ္ေကာင္းပါတယ္။က်ေနာ္ဖတ္ၿဖစ္တဲ့ ebook ေလးေတြကိုလည္းဖတ္ၾကည္႕ပါ။လြယ္လြယ္ကူကူရွင္းရွင္းလင္းလင္းနဲ႕ဖတ္ရအဆင္ေၿပပါတယ္။c#ေရာ java ေရာပါပါတယ္။


6.Isolation Levels in Sql

က်ေနာ့္တို႕ေရးတဲ့ ပရိုဂရမ္ဟာ user တစ္ေယာက္၊စက္တစ္လံုးဆိုရင္ေတာ့ၿပသနာမရွိပါဘူး။ဒါေပမဲ့ client ေတြအမ်ားၾကီးက တၿပိဳင္ထဲတခ်ိန္ထဲသံုးၾကမယ္ဆိုရင္ေတာ့ transaction ေတြကိုထိန္းဖို႕လိုလာပါၿပီ။တၿခားတစ္ေယာက္က ကိုယ္သံုးေနတဲ့ record ကိုတေနရာကဖ်က္သြားတာမ်ိဴးမၿဖစ္ရေအာင္ ထိန္းထားေပးဖို႕လိုပါတယ္။အဲဒီအတြက္ Isolation levels ေတြကိုနားလည္ရမွာပါ။ဒီဆိုက္ေလးကေတာ့ ဖတ္ဖူးသမ်ွထဲမွာ အၿပည္႕စုံဆံုးနဲ႕အရွင္းလင္းဆုံုးဆိုက္ေလးပါပဲ။ဖတ္ၾကည္႕သင့္ပါတယ္။

Isolation levels come into play when you need to isolate a resource for a transaction and protect that resource from other transactions. The protection is done by obtaining locks. What locks need to be set and how it has to be established for the transaction is determined by SQL Server referring to the Isolation Level that has been set. Lower Isolation Levels allow multiple users to access the resource simultaneously (concurrency) but they may introduce concurrency related problems such as dirty-reads and data inaccuracy. Higher Isolation Levels eliminate concurrency related problems and increase the data accuracy but they may introduce blocking.

Go to Link:http://www.sql-server-performance.com/articles/dba/isolation_levels_2005_p1.aspx


5.DateTime DataType Index Optimization


Date Between @fdate And @tdate Vs Date>=@fate and Date<=@tdate

ွSql query  မွာ Date ကို Filter လုပ္ရင္ >,< နဲ႕စစ္တာထက္
Between And ကိုသံုးၿပီးစစ္တာပိုေကာင္းပါတယ္။
Between And သံုးရင္ table ကို full scan မဖတ္ပဲ index ကို seek လုပ္ၿပီး
Filter လုပ္ပါတယ္။
>,< သံုးရင္ေတာ့  table ကို full scan ဖတ္ၿပီး condition နဲ႕ညီတာကို
ဆြဲထုတ္တဲ့အတြက္ ပိုၾကာပါတယ္။ဒါေၾကာင့္ Between And ကပိုေကာင္းပါတယ္။
အေသးစိတ္ဖတ္ခ်င္ရင္ေတာ့ ဒီကို ကိုသြားပါ။

4.MSDN Magazine ထဲက Query သံုးတာနဲ႕ StoreProcedure သံုးတာကြာၿခားခ်က္ေလးပါ။

၁.Query သံုးရင္ execute လုပ္တိုင္းမွာ syntax ကိုၿပန္ၿပန္စစ္ရတယ္။
  SP က Create မွာတည္းက တခါတည္းစစ္ၿပီး execute  လုပ္ရင္ထပ္မစစ္ေတာ့ဘူး။
၂.Query မွာ where ေနာက္မွာစစ္ထားတဲ့တန္ဖိုးေတြပါရင္ သူ႕အတြက္ autoparameterization
  ၿပန္လုပ္ရတယ္။where name='MgMg' ဆို sql processor က parameter ၿပန္ေၾကၿငာ
(varchar,int,etc)ရတဲ့အတြက္ performance က်ပါတယ္။
SP ကေတာ့ parameter ပါရင္ developer ကေၾကၿငာေပးထားတဲ့အတြက္ မလုိေတာ့ပါဘူး။
ဒီေတာ့ ၿဖစ္ႏိုင္ရင္ တတ္ႏိုင္သေလာက္ SP ပဲသံုးေစခ်င္ပါတယ္။


3.Previous & Global Variable in Crystal  Report

က်ေနာ္ crystal report တစ္ခုေရးတုန္းကအေတြ႕အၾကံဳေလးပါ။
ေရးရမွာက customer တစ္ေယာက္ခ်င္းစီရဲ႕ အေရာင္း နဲဲ႕ေငြေခ်တာကို
Date အလုိက္ၿပ႔ရင္း Balance ကိုႏႈတ္နႈတ္သြားရတယ္။
Debit & Credit ေပါ့။

               DebitAmt     CreditAmt     Balance
1.Sale         100                   0             100
2.Cash           0                  50              50
3.Sael         200                   0             250
etc

အဲလိုပံုစံေပါ့။ေနာက္ဆံုး balance ကိုအေပၚကတန္ဖိုးကိုၿပန္ၿပန္ယူၿပီးတြက္ရတာ။
ပထမေတာ့က်ေနာ္က storeprocedure မွာ တေၾကာင္းခ်င္းစီဆြဲၿပီး cursor ပတ္ၿပီး
နႈတ္ႏႈတ္လိုက္တာေပါ့။tmp table ထဲထည္႕ၿပီး။ဒါကတကယ္တမ္းက်ေတာ့ performance မေကာင္းဘူးေလ။
cursor သံုးတာတို႕ tmp table သံုးတာတို႕က။ဒါေၾကာင့္မို႕ crystal မွာပဲတြက္ရင္ေကာင္းမယ္ဆိုၿပိး
စဥ္းစားမိတယ္။ဒါနဲ႕ အင္တာနက္မွာရွာၾကည္႕ေတာ့ keyword ေလး၂ခုကိုသြားေတြ႕တယ္။
previous နဲ႕ global variable ။function မွာအဲဒီ၂ခုသံုူးၿပီးတြက္လိုက္ေတာ့ အဆင္ေၿပသြားတယ္။
cursor ပတ္စရာမလုိေတာ့ဘူးေပါ့။

ဒါက အင္တာနက္က previous နမူနာေလးပါ။
Item       Date           Amount     1WkChg      4WkChg
1001      01/01/09    100.00            0.00            0.00
1001      01/08/09    100.00            0.00            0.00
1001      01/15/09    200.00        100.00            0.00
1001      01/22/09    200.00            0.00        100.00
1001      01/29/09    300.00        100.00        200.00
1001      02/04/09    350.00          50.00        150.00

Each row is a weekly snapshot of the progress of the item that needs to show current value and difference
in value of the same item previous week and 4 weeks ago.
The first 3 weeks would produce 0 as no change and week 4 would subtract current week amount from the "3rd previous" record.
I use something like this for the 1WkChg column:
If Previous({Item}) = {Item}
then ({Amount} - Previous({Amount})) else 0

ဒါက global variable အတြက္နမူနာ။
//Call the function WhileReadingRecords
WhileReadingRecords;
Global NumberVar x;
x := x + 1

အေသးစိတ္သိခ်င္ရင္ေတာ့
http://www.crystalreportsbook.com/Forum/forum_posts.asp?TID=7259
http://publib.boulder.ibm.com/infocenter/rtnlhelp/v6r0m0/index.jsp?topic=/com.businessobjects.integration.eclipse.doc.crdesigner/reportdesigner/crconglobalvariablescrystalsyntax.htm

ဒီ၂ခုမွာဖတ္ၾကည္႕ပါ။က်ေနာ္ကအခ်ိန္မရလို႕ index ပဲေပးလိုက္ပါတယ္။ကိုယ္လိုခ်င္တဲ့ပံုစံရေအာင္ေတာ့
ကိုယ္ဟကိုယ္ပဲ ဖန္တီးရမွာေပါ့။


2.Multi Branch DataWarehouse Autogenerated ID Column Issue 


က်ေနာ္တို႕အခုေရးေနတဲ့ program က muti branch ပါတယ္။
ဒါေၾကာင့္ branch ေတြက database ေတြကိုယူၿပီး
datawarehouse တစ္ခုမွာၿပန္ေပါင္းထည္႕ရတယ္။
အဲဒီအခါမွာ Transaction ေတြက head & detail table ေတြမွာ
id column ေတြနဲ႕ခ်ိတ္ထားေတာ့ ၿပသနာရွိလာတယ္။
ထပ္ကုန္မွာကိုး။code ေတြရွိေပမဲ့ သူက varchar type ဆိုေတာ့
ခ်ိတ္ရင္ performance က်မွာ။id က int type ဆိုေတာ့ အဆင္ေၿပတယ္။
သူငယ္ခ်င္းတေယာက္ကေတာ့
သူတို႕ဆီမွာ branch ေတြအတြက္ id ထုတ္ရင္ range ကိုခြာေပးထားတယ္ေပါ့။
YGN Branch မွာ 1 ကေန 100 ဆို
MDY Branch မွာ 100 ကေန1000 ။အဲလိုမ်ိဴးေပါ့။
YGN မွာ 100 ၿပည္႕ရင္ ေနာက္အသစ္ၿပန္လုပ္ေပါ့။ၿပည္႕မၿပည္႕ေစာင့္ၾကည္႕ေနရတာေပါ့။
ဒါလည္းသိပ္မေကာင္းဘူး။အေတြ႕အၾကံဳရွိတယ့္လူအတြက္ ဘာမွမဟုတ္ေပမဲ့
က်ေနာ္တို႕က မၾကံဳဘူးဖူးေလ။ေမးရမယ့္လူလည္းမရွိေတာ့ ဒုတ္ခေရာက္ေရာ။
ဒါနဲ႕သူငယ္ခ်င္းေတြနဲ႕စဥ္းစားၾကတာေပါ့။
အဲဒီမွာအေၿဖတစ္ခုထြက္လာတယ္။

BranchA -BranchID 1             BranchB-BranchID 2
if AutogenerateID                  if AutogenerateID
1 then 1+BranchID=>11        1 then 1+BranchID=>12
2 then 2+BranchID=>21        2 then 2+BranchID=>22
etc                                        etc

အဲလိုမ်ိဴးထုတ္မယ္ေပါ့။ဒါဆို ေပါင္းတယ့္အခါထပ္စရာမရွိေတာ့ဘူး။
id ထုတ္ဖို႕ function ေတာ့လုိလာတာေပါ့။အရင္လို AutogenerateID   သံုးလို႕မရေတာ့ဘူး။
MAXID  ဆြဲၿပီး ေပါင္းထည္႕ရမွာ။MAXID  ဆြဲတဲ့အခါလည္း ေနာက္က BranchID ကိုဖ်က္ထုတ္ၿပီး
ဆြဲရမွာေပါ့။ဒီလုိမ်ိဴးစဥ္းစားမိပါတယ္။ဒီထက္ေကာင္းမယ့္idea ရွိရင္လည္း
ေ၀မ်ွၾကပါဦး။



1.Links

User Interface နဲ႕ .Net performance အတြက္ေဆာင္ရန္ေရွာင္ရန္အခ်က္ေလးေတြပါ။အခ်ိန္မရလို႕ link ပဲတင္ေပးလိုက္ပါတယ္။

ဖတ္ၾကည္႕ပါ။

http://www.joelonsoftware.com/uibook/fog0000000249.html

http://toastytech.com/guis/uirant.html

http://www.ssw.com.au/SSW/Standards/rules/RulesToBetterdotNETProjects.aspx#DesignerVisual

http://www.codeproject.com/KB/database/sqldodont.aspx?msg=2205474#xx2205474xx


Make a Free Website with Yola.