Bu döngüyü bir türlü kuramadım,hemde aylardır :(

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
serkan
Üye
Mesajlar: 666
Kayıt: 10 Tem 2003 12:08
Konum: bursa

Bu döngüyü bir türlü kuramadım,hemde aylardır :(

Mesaj gönderen serkan »

merhaba arkadaşlar saatler,haftalar,aylarca bir problem üzerinde durunca insan gözünün önündeki şeyide göremiyor...Bana artık imkansız gibi geliyor böyle bir kod :lol:

Yani gerekirse ücreti mukabili yardım istiyorum sorunumu çözecek arkadaşlardan..

Sorun nedir derseniz..aşağıda bir ürüne ait giriş ve çıkış hareketleri var.bunlar stokhrkt tablosunda tutuluyor ben sql ile girisleri ayrı çıkışları ayrı listeliyorum..
gelelim döngüye..Fifodöngüsü kurmak istiyorum çıkışlar tablosunun sonuna gelene kadar cıkış miktarlarını giriş miktarlarından eksiltecek ve giriş hareketinin kullanılan ve kalan yerlerine yazacak..

Örneğin..
ilk çıkış hareketi 300 ilk giriş hareketi 423 buna göre 423lük girişin 300ü kullanıldı 123 kaldı,bir sonraki çıkış hareketine gelecek buda 444,ilk hareketten 123 kalmıştı onu kullandı ikinci giriş hareketine geçecek oda 56, 56' yıda kullanacak çünkü daha 444'ü toplayamadı,tekrardiğer giriş hareketine geçecek 24 olana yani onuda kullanacak ve nihayet 345 olan giriş hareketine geçecek..123+56+24=203 203 kg toplamıştık 444-203=241 kg ihtiyacımız var 345'in 241 kg.sini kullanıp diğer çıkış hareketine geçecek ve aynı işlemleri bunun içinde yapacak...

Kafada herşey tamam..aralıklarla aylardır bunun için uğraşıyorum..

Bunları koda dökecek arkadaştan şimdiden allah razı olsun..dediğim gerekirse ücreti ilede yardımcı olabilirsiniz.. Teşekkürler şimdiden


Resim
Kullanıcı avatarı
fatihtolgaata
Üye
Mesajlar: 382
Kayıt: 04 Mar 2004 09:46
Konum: K.çekmece / İstanbul
İletişim:

Mesaj gönderen fatihtolgaata »

Kod: Tümünü seç

var
  GirisToplamlari, Cikis: Integer;
begin
  GirislerTablosu.First;
  CikislarTablosu.First;
  while not CikislarTablosu.Eof do
  begin
    Cikis := CikislarTablosu.FieldByName('CikisDegerAlani').AsInteger;
    GirisToplamlari := 0;
    while GirisToplamlari < Cikis do
    begin
      if not GirislerTablosu.Eof then
        GirislerTablosu.Next
      else //
        Break; //Girisler Tablosunda kayıt bitti!! Döngüden çıkıyoz.
      GirisToplamlari := GirisToplamlari +
        GirislerTablosu.FieldByName('GirisDegerAlani').AsInteger;
    end;
    //Döngüden çıktıktan sonra artık GirisToplamlari CikisDegerinden küçük
    //Tabi giriş tablosunda yeterli kayıt varsa
    //Giriş tablosunda yeterli kayıt yoksa sonuç eksi olacaktır.
    GirislerTablosu.Edit;
    GirislerTablosu.FieldByName('FarkAlani').AsInteger := Cikis - GirisToplamlari;
    GirislerTablosu.Post;
    CikislarTablosu.Next;
  end;
end;
Kodda açıklama var. Değişken isimlerinden de ne olduğu çıkar zannedersem.
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba,
Bence kalan ve kullanılan alanları için calculated alan tanımlamalısınız.
o calculated alanlarda bir fonksiyona şuan üzerinde bulunduğu girişin tarihini parametre vermeli.
Parametredeki tarihten küçük ve eşit olan girişler ve çıkışların toplamı alınıp aritmetik işleme alınmalı. Sonuç (-) ise hesaplama durdurulmalı çünkü fifo da (-) diye bir şey olmaz. Artı ise çıkışların toplamı kullanılan alanına yazılacak,
giriş toplamı-çıkış toplamı ise kalan kısmına yazılacak.
Hocam vt olarak firebird mü kullanıyorsunuz?
Yazdıklarımdan bir şey anlamadıysanız vt nizi söyleyin. Bir kaç ay da biz sizin yerinize cebelleşelim. :lol: :lol: :lol: Devir teslimi yapın.

Ayrıca ticari programlarda artık tarih değil saat değerine göre bile fifo çıkarıyorlar. Sizin örneğinizde bile bu belli oluyor. Mesela 15.01.2007 tarihinde önce hangisini alacak girişi mi çıkışı. Kullandığım Lks programı fişlerin saatinin önceliğine göre bile hesaplıyor.
İyi çalışmalar.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
serkan
Üye
Mesajlar: 666
Kayıt: 10 Tem 2003 12:08
Konum: bursa

Mesaj gönderen serkan »

veritabanı firebird 1.5..

fatihtolgaata'nın verdiği kodu deniycem..
gönüllü cebelleşecekler varsa olabilir :)

ayrıca saat ve tarih bilgileri var hareket tablosunda döngüyü kurduktan sonra sen merak etme saniyenin milyonda biri için bile fifo hesaplarım... :lol:
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba Serkan Bey,
Ben yeni mesaj yazarken farkettim programlama kısmına yazmışsınız ben örneği ibexpertte yaptım. İnşallah işinize yarar.
Verdiğiniz örnekteki verilere göre bir vt yaptım. Sizinkinden farklı olarak
saat ve ürün kodu ekledim. Ayrıca tüm giriş çıkışları miktar alanına girip GCTURU alanına"GIRIS" ve "CIKIS" değerleri vererek giriş çıkış ayrımını yaptım.
Kodu aşağıdaki gibi kullanabilirsiniz.

Kod: Tümünü seç

select * from serkanfifo('40602')
40602 ürün kodudur. yazılan stored procedure ise aşağıdaki gibidir.

Kod: Tümünü seç

SET TERM ^ ;

CREATE PROCEDURE SERKANFIFO (
    STOK_KODU VARCHAR(16))
RETURNS (
    TARIHI DATE,
    EVRAKNOSU VARCHAR(16),
    GIRIS_MIKTARI INTEGER,
    KULLANILAN_MIKTAR INTEGER,
    KALAN_MIKTAR INTEGER)
AS
DECLARE VARIABLE SAATI TIME;
DECLARE VARIABLE TOPLAM_CIKISLAR INTEGER;
DECLARE VARIABLE TOPLAM_GIRISLER INTEGER;
begin

FOR
select TARIH,SAAT,EVRAKNO,MIKTAR from serkanhrk
WHERE STOKKODU=:stok_kodu AND GCTURU='GIRIS'
ORDER BY TARIH+SAAT
INTO :tarihi,:SAATI ,:evraknosu,:giris_miktari

DO BEGIN
TOPLAM_CIKISLAR=0;
TOPLAM_GIRISLER=0 ;
           /* TOPLAM ÇIKIŞLARI BULMAK İÇİN */

         SELECT CASE WHEN SUM(MIKTAR)>0 THEN SUM(MIKTAR) ELSE 0 END
          FROM serkanhrk
         WHERE STOKKODU=:stok_kodu AND GCTURU='CIKIS' AND TARIH+SAAT<=:tarihi+:SAATI
         into :toplam_cikislar   ;

           kullanilan_miktar=:toplam_cikislar;

/* TOPLAM GIRIŞLERİ BULMAK İÇİN */
        SELECT CASE WHEN SUM(MIKTAR)>0 THEN SUM(MIKTAR) ELSE 0 END
          FROM serkanhrk
         WHERE STOKKODU=:stok_kodu AND GCTURU='GIRIS' AND TARIH+SAAT<=:tarihi+:SAATI
         into :toplam_girisler   ;

           KALAN_MIKTAR=:toplam_girisler-:toplam_cikislar;

  /* Procedure Text */
  suspend;
  END
end
^

SET TERM ; ^

GRANT SELECT ON SERKANHRK TO PROCEDURE SERKANFIFO;

GRANT EXECUTE ON PROCEDURE SERKANFIFO TO SYSDBA;


Evrak nosu 2 olan satırın saatini :08:45:00 , evrak nosu RD-4 olan satırın saatini 16:40:00 yapınca 15.01:2007 tarihinde ki satır

Kod: Tümünü seç

tarih              evrak nosu   giriş miktarı   kullanılan miktar  kalan miktar
-------------   --------------  --------------   -------------------   ---------------  
15.01.2007        2                   56                     0                      479
25.01.2007        3                    24                  300                     203
Evrak nosu 2 olan satırın saatini :19:00:00 , evrak nosu RD-4 olan satırın saatini 16:40:00 yapınca 15.01:2007 tarihinde ki satır

Kod: Tümünü seç

tarih              evrak nosu   giriş miktarı   kullanılan miktar  kalan miktar
-------------   --------------  --------------   -------------------   ---------------  
15.01.2007        2                   56                  300                     179
25.01.2007        3                   24                  300                     203
şeklinde sonuçlar çıktı. Yani bu da saati gözönüne aldığını gösterir.

Bu şekilde bir deneyin. Belki işinize yarar.
İyi çalışmalar.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
serkan
Üye
Mesajlar: 666
Kayıt: 10 Tem 2003 12:08
Konum: bursa

Mesaj gönderen serkan »

hocam merhaba 2 gündür şehir dışındaydım cevabını şimdi gördüm..en kısa zamanda deniycem..zahmet olmuş teşekkür..
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

Diğer cevapları hakkını vererek inceleyemedim ama kendimce olan çözümü yazayım dedim. Şimdi girişleri ve çıkışları ayrı alanlarda tutmuş olduğundan aşağıdaki sorgu ile bakiye miktarını bulabilirsin.

Kod: Tümünü seç

select sum(cikis),sum(isNull(giris,0)-isNull(cikis,0)) from stokhrkt
Bu bakiye miktarından sonra aşağıdaki sorgu ile çıkış kadar ileri gidip, sıradan gerektiği kadar kayıtları çekmek işinizi görecektir.

Kod: Tümünü seç

select * from stokhrkt where isNull(Cikis,0)=0 order by Tarih, Evrakno
Bu iki sorgu ile durumu kod ile toparlarsak

Kod: Tümünü seç

QryBakiye.SQL.Text:='select sum(cikis), sum(isNull(giris,0)-isNull(cikis,0)) from stokhrkt';
QryBakiye.Open;
TopCikis:=QryBakiye.Fields[0].AsFloat;
Bakiye:=QryBakiye.Fields[1].AsFloat;
QryListe.SQL.Text:='select * from stokhrkt where isNull(Cikis,0)=0 order by Tarih, Evrakno';
QryListe.Open;
Cikan:=TopCikis;
//FIFO ile ...->
while not QryListe.Eof do begin
  if Cikan>QryListeCikis.AsFloat then Cikan:=Cikan-QryListeCikis.AsFloat
  else begin
    ilkMiktar:=QryListeCikis.AsFloat-Cikan;{<-FIFO sonucu toplam çıkış bitmiş ve bu da ele alınacak ilk kaydın miktar değeri}
    Break;
  end;
  QryListe.Next;
end;
//<-.. elimizden çıkan kayıtlar atlanarak dikkate alınmaz
Kalan:=Bakiye;
while not QryListe.Eof and (Kalan>0) do begin
  if ilkMiktar=0 then Mik:=QryListeGiris.AsFloat else Mik:=ilkMiktar;
  if Kalan>Mik then Kalan:=Kalan-Mik;
  end else begin
    Mik:=Kalan;
    Kalan:=0;
  end;
//bu döngü içindekiler listelenecek kayıtlardır-->
//--------------FIFO--------------
//------------LİSTELEME-----------
//-------------KODLARI------------
//<--Miktar olarak giriş alanındaki değer değil Mik değişkenindeki değer kullanılmalı.
  ilkMiktar:=0;
  QryListe.Next;
end;
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
ofenX
Üye
Mesajlar: 397
Kayıt: 09 Nis 2005 10:24
Konum: Diyarbakır
İletişim:

Mesaj gönderen ofenX »

Merhaba,
Ben de kontrol yapmadığımı farkettim. ve yeni versiyonu çıkardım. :lol:
Önceki örneğime ek olarak. Tarih ve saate göre ilk hareket çıkış ise procedure den çıkıyor. Ayrıca fifo_durumu alanında hareketin durumu belirleniyor. OK ise gelinen noktaya kadar problem yok. HESAPLANAMIYOR ise fifo mantığına göre o satırdan itibaren terslik olduğu anlaşılıyor.

Kod: Tümünü seç

SET TERM ^ ;

CREATE PROCEDURE SERKANFIFO (
    STOK_KODU VARCHAR(16))
RETURNS (
    TARIHI DATE,
    EVRAKNOSU VARCHAR(16),
    GIRIS_MIKTARI INTEGER,
    KULLANILAN_MIKTAR INTEGER,
    KALAN_MIKTAR INTEGER,
    FIFO_DURUMU VARCHAR(15))
AS
DECLARE VARIABLE ILK_HAREKET VARCHAR(5);
DECLARE VARIABLE SAATI TIME;
DECLARE VARIABLE TOPLAM_CIKISLAR INTEGER;
DECLARE VARIABLE TOPLAM_GIRISLER INTEGER;
begin
   FIFO_DURUMU='OK';
    ILK_HAREKET='';

   select FIRST (1) gcturu from serkanhrk
   WHERE STOKKODU=:STOK_KODU
   order by tarih+saat
   into :ILK_HAREKET    ;
   if (:ilk_hareket='CIKIS') then  exit;




FOR
select TARIH,SAAT,EVRAKNO,MIKTAR from serkanhrk
WHERE STOKKODU=:stok_kodu AND GCTURU='GIRIS'
ORDER BY TARIH+SAAT
INTO :tarihi,:SAATI ,:evraknosu,:giris_miktari



DO BEGIN
TOPLAM_CIKISLAR=0;
TOPLAM_GIRISLER=0 ;
           /* TOPLAM ÇIKIŞLARI BULMAK İÇİN */

         SELECT CASE WHEN SUM(MIKTAR)>0 THEN SUM(MIKTAR) ELSE 0 END
          FROM serkanhrk
         WHERE STOKKODU=:stok_kodu AND GCTURU='CIKIS' AND TARIH+SAAT<=:tarihi+:SAATI
         into :toplam_cikislar   ;

           kullanilan_miktar=:toplam_cikislar;

/* TOPLAM GIRIŞLERİ BULMAK İÇİN */
        SELECT CASE WHEN SUM(MIKTAR)>0 THEN SUM(MIKTAR) ELSE 0 END
          FROM serkanhrk
         WHERE STOKKODU=:stok_kodu AND GCTURU='GIRIS' AND TARIH+SAAT<=:tarihi+:SAATI
         into :toplam_girisler   ;

           KALAN_MIKTAR=:toplam_girisler-:toplam_cikislar;


                if (KALAN_MIKTAR<0) then     FIFO_DURUMU='HESAPLANAMIYOR';

  /* Procedure Text */
  suspend;
  END
end
^

SET TERM ; ^

GRANT SELECT ON SERKANHRK TO PROCEDURE SERKANFIFO;

GRANT EXECUTE ON PROCEDURE SERKANFIFO TO SYSDBA;
İyi çalışmalar.
http://www.aysbergbilgisayar.com
Logo Go özel eğitim, web tasarım, teknik servis
Cevapla