30 Haziran 2015 Salı

Dinamik Sql (Dynamic Sql) ile Raporlama


Merhaba arkadaşlar,

bu yazımda, özellikle muhasebe programları için çokça talep edilen raporlardan biri olan nakit akış raporunun bir ucundan tutmaya çalışacağız. Oluşturacağım rapor scriptleri dinamik olarak oluşacak. Yani raporumun scripti kod içinde bazı karşılaştırmalar neticesinde adım adım oluşacak.

Öncelikle oluşturacağımız raporu tanımaya çalışalım;

nakit akış raporu, vadeli işlenen (cari) faturaların bir projeksiyonudur diyebiliriz. muhtelif vadelerle işlenmiş alış ya da satış faturaları, vadesi itibarıyla ilgili oldukları ayda tahsil ya da tediye edilecek. yani kestiğim faturalar için tahsilatlarım olacağı gibi bana kesilen faturaların vadeleri geldiğinde de ödemelerim olacak. bu sayede de ilgili dönemlerde firmamın mali durumunu gözlemlemiş olacağım (bunu sadece muhasebeyle sınırlandırmamak lazım. aynı yöntemle siparişlerimi ya da tekliflerimi termin tarihlerine göre gruplaya da bilirdim).

işte bu sebeplerden ötürü faturaları alış/satış tiplerine göre gruplayıp gelecek aylar bazında toplamlarını görmek istemekteyim.

elimizde alış ve satış faturalarını işlediğimiz "Faturalar" adında bir tablomuz var (tüm muhasebe programlarında aşağı yukarı bu tarz bir tablo vardır.).

tablonun yapısı; 



select faturatipi,SUM(tutar) as Toplam from Faturalar where vade>GETDATE() group by faturatipi  sorgusuyla vadesi gelmemiş faturalarımın sadece toplamlarını alabilmekteyim;



bu şekilde aldığım rapor bana yalnız toplam borç alacak durumumu vermekte. bu rakamlara bakarak bu ay ya da önümüzdeki ay yapacağım tahsilatları görmem mümkün olmamakta.

İşte bu amacı karşılayacak rapor şu şekilde olmalı;



talebi açıkça anladığımıza göre artık kodumuzu yazabiliriz;

--bu değişken dinamik scriptimizi adım adım oluşturup atadığımız değişkenimiz.
declare @SQLStr nvarchar(max)='',@ay int=0;
declare @minVade datetime = (select MIN(vade) from Faturalar);
--burada maximum vadeli faturaya kadar kaç ay olduğunu hesaplıyoruz.
declare @aySayisi int = (select DATEDIFF(MONTH,min(vade),max(vade)) from Faturalar);

set @SQLStr = ' 
select 
 
faturatipi, '
/*
scriptimizi toplam ay sayısı kadar döndürüp, her dönüşte fatura vadesinin ilgili ay içerisinde olup olmadığına bakıyorum.
eğer fatura vadesi ilgili ay içerisinde ise tutar değerini alıyorum değil ise 0 alıyorum
*/
while(@ay<=@aySayisi)
begin
 set @SQLStr=@SQLStr+
 'sum(convert(decimal(18,2),case when dateadd(day,DATEDIFF(day,0,vade),0) between '''
--ayın ilk gününü buluyorum

 + 
 CONVERT(varchar(8),dateadd(MONTH,DATEDIFF(MONTH,0,dateadd(MONTH,@ay,@minVade)),0),112)
 + ''' and '''


--ayın son gününü buluyorum  
 + CONVERT(varchar(8),dateadd(month,1+datediff(month,0,dateadd(MONTH,@ay,@minVade)),-1),112)
 + ''' then tutar' 

--sıra geldi oluşturduğumuz alana isim vermeye. ismi "yıl-ay" kombinasyonu olarak ayarlıyorum.   
 set @SQLStr=@SQLStr+ 
 ' else 0.0 end)) as ['
 + datename(MONTH,dateadd(MONTH,@ay-1,@minVade))
 + '-'+ datename(YEAR,dateadd(MONTH,@ay-1,@minVade))
 + ']'
 if @ay<@aySayisi
   set @SQLStr = @SQLStr + ','

 set @ay=@ay+1
end
--son olarak ta dinamik scriptimin çalışacağı kaynak tabloyu gösteriyorum.
set @SQLStr=@SQLStr+ 

from Faturalar
group by faturatipi  

'

exec (@SQLStr)

GO


tablonun create scriptini ve oluşturduğumuz dinamik scripti buradan indirebilirsiniz. bir kaç satır faturatipi, vade ve tutar bilgilerini doldurup kodu deneyebilirsiniz.

İhtiyaçlarımız doğrultusunda scripti geliştirebiliriz. Örneğin, scriptte haftalık bazda yapılacak revizyonla daha kısa dönemli projeksiyonlar yapılması mümkün kılınabilir. ayrıca işin içine farklı para tiplerini dahil ederek, istenen kura ya da fatura ya da vade tarihlerindeki kurlara göre değerlendirmeler yapılabilir.

Bir sonraki yazımda görüşmek dileğimle,
Yaşar Şahin.

Hiç yorum yok:

Yorum Gönder