Logo Banka Hareketleri SQL: BNFLINE ile Bakiye ve Ekstre
Logo'da banka bakiyesi ve ekstre BNFLINE tablosundan hesaplanır. BNACCREF bağı, SIGN yönü, yürüyen bakiye, döviz ve aylık nakit akışı sorguları.
Erp Asistanı
Editör ekibi
9 dk okuma
İçindekiler
Logo'da banka hesabının bakiyesi hesap kartında yazmaz. BANKACC kartı yalnızca hesabın kimliğini (kod, tanım, IBAN, döviz cinsi) tutar; parayı hareket ettiren her satır BNFLINE tablosuna düşer. Yani "bankanın bakiyesi kaç" sorusunun cevabı her zaman bir toplama işlemidir: BNFLINE satırlarını SIGN yönüne göre toplamak. Bu yazıda hesap listesi bakiyesinden başlayıp tek hesap ekstresine, yürüyen bakiyeye, döviz bakiyesine ve aylık nakit akışına kadar yedi sorgu kuruyoruz. Hepsi T-SQL'dir ve gerçek bir Logo şemasındaki mantıksal tablo adlarıyla yazılmıştır.
Önce önek kuralı
BNFLINE ve BNFICHE dönem tablolarıdır; kendi veritabanınızda başına firma ve dönem öneki eklemelisiniz: LG_{firma}_{dönem}_BNFLINE (örneğin LG_323_01_BNFLINE). BANKACC ve CLCARD firma-master tablolardır: LG_{firma}_BANKACC. Aşağıdaki sorgularda okunabilirlik için önekleri kaldırdık. Tablo adlandırma mantığını daha geniş anlatan Logo tablo yapısı rehberine göz atabilirsiniz.
Hareketin üç tablosu: BNFLINE, BANKACC, BNFICHE
İlişki zinciri kısadır ve hep LOGICALREF üzerinden kurulur, kod üzerinden değil:
BNFLINE.BNACCREF = BANKACC.LOGICALREF- hareketin hangi banka hesabına ait olduğu. Bu tablodaBANKACCREFdiye bir kolon yoktur; ilk denemede en çok bu isim uydurulur ve sorgu "Invalid column name" ile düşer.BNFLINE.SOURCEFREF = BNFICHE.LOGICALREF- hareketin bağlı olduğu banka fişi (fiş no buradan gelir).BANKACC.BANKREF = BNCARD.LOGICALREF- hesabın bağlı olduğu banka kurumu.
| Kolon | Anlamı | Tuzak |
|---|---|---|
BNACCREF |
Banka hesabı bağı | BANKACCREF yazmayın, kolon adı BNACCREF |
SIGN |
0 = borç (para girişi), 1 = alacak (para çıkışı) | SUM(AMOUNT) tek başına bakiyeyi ters verir |
AMOUNT |
Yerel para tutarı | Döviz hesapta bu TL karşılığıdır, döviz tutarı değil |
TRNET / TRCURR / TRRATE |
Döviz tutarı / döviz kodu / kur | Döviz bakiye için AMOUNT değil TRNET toplanır |
DATE_ |
Hareket tarihi (datetime) | Saat bilgisi ayrı kolondadır, tarih filtresi DATE_ ile verilir |
CANCELLED |
0 = aktif, 1 = iptal | Her toplamada CANCELLED = 0 şart |
CLIENTREF |
Karşı cari (havale/EFT) | Boş olabilir; banka içi virmanda cari yoktur |
TRCODE / MODULENR |
Hareket türü / kaynak modül | 7 = banka kaynaklı, 6 = çek-senet |
Bakiye formülü tek satırdır: SUM(CASE WHEN SIGN = 0 THEN AMOUNT ELSE -AMOUNT END). Aşağıdaki tüm sorgular bu deseni kullanır.
1. Hesap listesi ve bakiye
SELECT A.CODE, A.DEFINITION_, A.CURRENCY,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE -L.AMOUNT END) AS bakiye,
COUNT(L.LOGICALREF) AS hareket_sayisi
FROM BANKACC A
LEFT JOIN BNFLINE L ON L.BNACCREF = A.LOGICALREF AND L.CANCELLED = 0
WHERE A.ACTIVE = 0
GROUP BY A.CODE, A.DEFINITION_, A.CURRENCY
ORDER BY bakiye DESC;
Bu raporu SQL yazmadan, Türkçe sorarak alın: Logo raporlama
ACTIVE = 0 aktif hesap demektir; 1 yazarsanız pasif hesapları listelersiniz. CANCELLED filtresi JOIN koşulunda olduğu için hiç hareketi olmayan hesap da listede kalır ve bakiyesi NULL döner; ekranda 0 göstermek istiyorsanız ISNULL(..., 0) ekleyin.
2. Tek hesabın giriş, çıkış ve son hareketi
SELECT A.CODE, A.DEFINITION_,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE 0 END) AS toplam_giris,
SUM(CASE WHEN L.SIGN = 1 THEN L.AMOUNT ELSE 0 END) AS toplam_cikis,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE -L.AMOUNT END) AS bakiye,
MAX(L.DATE_) AS son_hareket,
COUNT(L.LOGICALREF) AS hareket_sayisi
FROM BANKACC A
LEFT JOIN BNFLINE L ON L.BNACCREF = A.LOGICALREF AND L.CANCELLED = 0
WHERE A.CODE = 'ZIRAAT-TL'
GROUP BY A.CODE, A.DEFINITION_;
Burada 'ZIRAAT-TL' yerine kendi hesap kodunuzu yazın. MAX(DATE_) son hareket tarihini verir; hesap uzun süredir hareket görmüyorsa bu alan eski bir tarih döner ve mutabakat kontrolünde ilk bakılacak sinyaldir.
3. Hesap ekstresi: yürüyen bakiye
Ekstrede her satırın yanında o güne kadarki bakiyeyi görmek istiyorsanız pencere fonksiyonu kullanın. Sıralama DATE_ ve LOGICALREF çiftiyle yapılmalı; aynı gün içindeki hareketlerin sırası ancak LOGICALREF ile sabitlenir.
DECLARE @hesap nvarchar(50) = 'ZIRAAT-TL';
SELECT L.DATE_, L.TRCODE,
CASE WHEN L.SIGN = 0 THEN 'giris' ELSE 'cikis' END AS yon,
L.AMOUNT,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE -L.AMOUNT END)
OVER (ORDER BY L.DATE_, L.LOGICALREF
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS yuruyen_bakiye
FROM BNFLINE L
JOIN BANKACC A ON A.LOGICALREF = L.BNACCREF
WHERE A.CODE = @hesap
AND L.CANCELLED = 0
ORDER BY L.DATE_, L.LOGICALREF;
Dikkat: yürüyen bakiye, filtrelenmiş küme üzerinde hesaplanır. Tarih aralığı eklerseniz bakiye o aralığın başından itibaren birikir, hesabın açılışından değil. Açılıştan birikim istiyorsanız tarih filtresini alt sorguya taşıyıp dışarıda filtreleyin.
4. Döviz hesapta bakiye
Döviz hesabın bakiyesi AMOUNT ile değil TRNET ile toplanır. AMOUNT yerel (TL) karşılığıdır ve her satırda farklı kurla çevrildiği için TL toplamı ile döviz toplamı aynı şeyi anlatmaz.
SELECT A.CODE, A.DEFINITION_, A.CURRENCY,
SUM(CASE WHEN L.SIGN = 0 THEN L.TRNET ELSE -L.TRNET END) AS doviz_bakiye,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE -L.AMOUNT END) AS yerel_bakiye
FROM BANKACC A
JOIN BNFLINE L ON L.BNACCREF = A.LOGICALREF AND L.CANCELLED = 0
WHERE A.ACTIVE = 0 AND L.TRCURR <> 0
GROUP BY A.CODE, A.DEFINITION_, A.CURRENCY
ORDER BY doviz_bakiye DESC;
TRCURR = 0 TL hareketleri işaret eder; döviz kırılımı isterken bu koşulu koymayı unutmayın. Kur bilgisi TRRATE kolonundadır.
5. Aylık banka nakit akışı
SELECT YEAR(L.DATE_) AS yil, MONTH(L.DATE_) AS ay,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE 0 END) AS giris,
SUM(CASE WHEN L.SIGN = 1 THEN L.AMOUNT ELSE 0 END) AS cikis,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE -L.AMOUNT END) AS net
FROM BNFLINE L
JOIN BANKACC A ON A.LOGICALREF = L.BNACCREF
WHERE L.CANCELLED = 0 AND A.ACTIVE = 0
GROUP BY YEAR(L.DATE_), MONTH(L.DATE_)
ORDER BY yil DESC, ay DESC;
YEAR() ve MONTH() yalnızca datetime kolonla çalışır; DATE_ datetime olduğu için burada sorun yok. Aynı deseni int bir kolona uygularsanız "Arithmetic overflow" (8115) hatası alırsınız. Cari tarafındaki bakiye mantığını Logo stok ve cari bakiye SQL yazısında ayrıca anlattık.
6. Havale kimden geldi: cari kırılımı
SELECT C.CODE AS cari_kod, C.DEFINITION_ AS cari_ad,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE -L.AMOUNT END) AS net_tutar,
COUNT(*) AS hareket_adedi
FROM BNFLINE L
JOIN CLCARD C ON C.LOGICALREF = L.CLIENTREF
JOIN BANKACC A ON A.LOGICALREF = L.BNACCREF
WHERE L.CANCELLED = 0 AND A.CODE = 'ZIRAAT-TL'
GROUP BY C.CODE, C.DEFINITION_
ORDER BY net_tutar DESC;
CLIENTREF boş (0) olan satırlar cariye bağlanamaz, bu yüzden JOIN'de görünmez. Banka içi virmanlarda ve masraf satırlarında bu alanın boş olması normaldir; kalan farkı fiş açıklamasından takip etmek gerekir.
7. Fiş no ve hareket türü dağılımı
SELECT F.FICHENO, F.TRCODE AS fis_trcode,
L.DATE_, L.SIGN, L.AMOUNT, L.TRCURR, L.TRNET
FROM BNFLINE L
LEFT JOIN BNFICHE F ON F.LOGICALREF = L.SOURCEFREF
JOIN BANKACC A ON A.LOGICALREF = L.BNACCREF
WHERE L.CANCELLED = 0 AND A.CODE = 'ZIRAAT-TL'
ORDER BY L.DATE_ DESC, L.LOGICALREF DESC;
Fiş başlığında FICHENO ve TRCODE güvenilir alanlardır; hareketin kendi türünü ise satırdaki TRCODE verir, ikisini karıştırmayın.
Hareket türlerinin dağılımını bir kez görmek, raporun doğruluğunu teyit etmenin en hızlı yoludur:
SELECT L.TRCODE, L.MODULENR, COUNT(*) AS hareket_adedi,
SUM(CASE WHEN L.SIGN = 0 THEN L.AMOUNT ELSE -L.AMOUNT END) AS net_tutar
FROM BNFLINE L
WHERE L.CANCELLED = 0
GROUP BY L.TRCODE, L.MODULENR
ORDER BY hareket_adedi DESC;
MODULENR = 7 banka kaynaklı, 6 çek-senet kaynaklı hareketleri gösterir. Kendi verinizdeki dağılıma bakmadan "şu TRCODE havale, şu TRCODE masraf" diye kesin konuşmayın; kuruluma göre türler farklı işaretlenebilir. Hazır sorgu kalıpları için Logo hazır SQL sorguları listesine de bakabilirsiniz.
Sık yapılan hatalar
- Hesap bağını
BANKACCREFdiye yazmak. Kolon adıBNACCREFve karşılığıBANKACC.LOGICALREF. - Bakiyeyi
SUM(AMOUNT)ile almak. Yön bilgisiSIGNkolonundadır: 0 borç (giriş), 1 alacak (çıkış). CANCELLED = 0filtresini unutmak; iptal edilmiş fiş satırları bakiyeyi şişirir.- Döviz hesapta döviz bakiyesini
AMOUNTile toplamak. Döviz tutarıTRNET, yerel karşılığıAMOUNT. BANKACC.ACTIVE = 1yazarak aktif hesapları dışlamak. Logo'da aktif kartACTIVE = 0demektir.- Bakiyeyi
BNTOTFILgibi toplam tablolarından okumak. Bu tablolar trigger ile bakımlıdır, elle yazılmaz ve bazı kurulumlarda geride kalabilir; rapor için güvenilir kaynakBNFLINE. - Tabloları
CODEüzerinden birleştirmek. Tüm bağlarLOGICALREFile kurulur. - Fiş başlığında var olmayan bir kolonu (örneğin
DOCODE) sorgulamak. BNFICHE'de emin olmadığınız alanı hiç yazmayın. - Tarih filtresini int bir kolona uygulamak; tarih işlemleri yalnızca
DATE_gibi datetime kolonlarla yapılır.
Sık sorulanlar
Bakiye neden eksi çıkıyor? SIGN yönünü ters yorumluyorsunuz. SIGN = 0 para girişi, 1 para çıkışıdır; formülü SUM(CASE WHEN SIGN = 0 THEN AMOUNT ELSE -AMOUNT END) olarak kurun. Bir hesapta sonuç eksi ise ya açılış bakiyesi hiç hareket olarak girilmemiştir ya da çıkışlar girişlerden fazladır.
Hesap kodu yerine hesap adıyla filtreleyebilir miyim? Evet, BANKACC.DEFINITION_ üzerinden LIKE ile arayabilirsiniz. Ancak tanım alanı serbest metindir ve kullanıcılar tarafından değiştirilebilir; raporu CODE üzerine kurmak daha güvenlidir.
Ekstrede aynı günün hareketleri neden karışık geliyor? Sıralamayı yalnızca DATE_ ile yaptığınızda aynı tarihli satırların sırası garanti değildir. ORDER BY L.DATE_, L.LOGICALREF kullanın; yürüyen bakiye de aynı sıralama anahtarını kullanmalıdır.
Virman ve masraf satırları banka bakiyesine dahil mi? Evet, BNFLINE'daki her satır bakiyeye girer. Ayrı görmek istiyorsanız TRCODE ve MODULENR kırılımını kullanın, komisyon satırları için COMSTYPE alanına bakın.
Bu yedi sorguyu her ay elle güncellemek yerine Erp Asistanı'na ücretsiz kaydolun →: "geçen ayın banka hesap bakiyelerini ve giriş çıkış toplamlarını getir" diye Türkçe yazarsınız, sistem BNFLINE, SIGN ve LG öneklerine uygun çalışan SQL'i üretir; siz yalnızca sonucu kontrol edersiniz.
Bu raporu SQL yazmadan, Türkçe sorarak alın
Türkçe sorunuzu yazın, şemanıza uygun çalışan SQL'i ya da hazır uygulamanızı saniyeler içinde alın.




