# مباحث متفرقه برنامه نویسی > گزارش سازی با Crystal Report > گفتگو: گرفتن مانده بدهکار و بستانکار در برنامه حسابداری

## mina.net

سلام دوستان
مدتی هست که در تالار sql مطلبی رو مطرح تاپیکی باز کردم و داریم راجع به این موضوع بحث می کنیم با دوستان. ولی از آنجا که دیدم لازم هست موضوع از زوایای دیگر هم بررسی شود مانند بحث ایجاد گزارش با کریستال و همچنین فیلتر کردن اطلاعات در محیط vs پس تصمیم گرفتم اینجا هم مطرح شود. اگر دوستانی از تالارهای دریگر هم مایل به مشارکت هستند در تالارهای مورد نظر شون لینک بدن.

یک خواهش حتمی مطالب تاپیک زیر را مطالعه کنید و سپس اگر مطلبی دارید فقط در یکی از این سه تاپیک قرار دهید.(vb.net,SQL و کریستال ریپورت)

https://barnamenevis.org/showthread.php?t=158700
https://barnamenevis.org/showth...972#post723972

----------


## mina.net

سلام دوستان
من می خوام دستور select زیر رو تو کریستال ریپورت نمایش بدم چیکار باید کرد.


select mainid,sharh,BED,BEST,tarikh,(select case when (sum(bed)-sum(best))<0 then '0' else (sum(bed)-sum(best))end from bed_best where  tarikh <t1.tarikh+1  and id ='51' ) as mbed,(select case when (sum(best)-sum(bed))<0 then '0' else (sum(best)-sum(bed))end from bed_best where  tarikh <t1.tarikh+1  and id ='51' ) as mbest  from bed_best t1 where id = '51'  order by tarikh


دیگه دارم دیونه می شم هیچ وقت اینقدر درمونده نشده بودم لطفا کمک کنید.

----------


## adinochestva

query رو تو یک view بریز و تو کریستال از view استفاده کن

----------


## mina.net

> query رو تو یک view بریز و تو کریستال از view استفاده کن


دوست عزیز این کارو کردم ولی این کوری فقط برای هر شخص مهمه نه کلی یعنی موقعی که میگم شخص x رو به من نشون مجموع رو باید براساس همون بزنه ولی متاسفانه وقتی صرفا ازش select می کنم تعدادی از سطر که متعلق به همون شخص را سرفا نشون می ده بدون اعمال این دستوری که نوشتم. یک مقدار در هم برهمه نمی دونم درست توضیح دادم یا نه دوستای که برنامه حسابداری انجام داده اند احتمالا منظور منو گرفتن.

----------


## adinochestva

خوب بعد از ایجاد view روی همان view شرط را بزار. مثلا جدول حسابها با نام customer  و بد و بس با نام  InOut 
کد view

select * from InOut inner join customer on InOtut.customerId = customer.Id

شرط روی view

select * from View1 where customerId = "whatever"

----------


## adinochestva

اگر می خوای می تونی یک table function بنویسی که کد بگیره و سطرهارو برگردونه

----------


## Hamid.Mayeli

من برات یه Sample از کریستال می زارم که بهترین راه.

----------


## Hamid.Mayeli

این یه Sample کوچیک با اکسل، احتمالا باید آدرس اکسل رو دوباره بدید. فقط باید روی شخص فیلتر کنید.

----------


## mina.net

سلام دوستان شاید من نتونستم درست منظورم رو برسونم 
من می خوام از جدول روزنامه که اسمش تو دیتابیس من bed_best هست در هر بار گزارش ، گردش مالی یک حساب تفضیلی رو نشون بدم.
دوستان اگه هدف من صرفا نشون دادن کل sum(bed) , sum(best) براساس یک تاریخ بود مشکلی ندارم خیلی سادست. ولی من می خوام گردش مالی بگیرم.  
برای اینکه درست تر منظورم رو برسونم این عکس جدول اصلی (دفتر روزنامه) هست.  

و از جدول بالا باید گزارش تهیه شود. با اعمال چند شرط.
1- نام مثلا مهدوی
2-تاریخ بین مثلا 1/1/88 تا 12/1/88
3- در ضمن مقادیر باید براساس تاریخ سورت شود.
در حقیقت باید از جدول بالا جدول زیر select شود
 
دوستان الان دیگه مشکل من راجع به اینها نیست و تقریبا با یک دستور select نسبتا پیچیده حل شده یک مشکل کوچولو هست که در این پست توضیح دادم.
https://barnamenevis.org/showth...948#post726948
 در ضمن دستور select ی که نوشتم هم هست.

----------


## maryam_yousefii

> سلام دوستان
> من می خوام دستور select زیر رو تو کریستال ریپورت نمایش بدم چیکار باید کرد.
> 
> 
> select mainid,sharh,BED,BEST,tarikh,(select case when (sum(bed)-sum(best))<0 then '0' else (sum(bed)-sum(best))end from bed_best where  tarikh <t1.tarikh+1  and id ='51' ) as mbed,(select case when (sum(best)-sum(bed))<0 then '0' else (sum(best)-sum(bed))end from bed_best where  tarikh <t1.tarikh+1  and id ='51' ) as mbest  from bed_best t1 where id = '51'  order by tarikh
> 
> 
> دیگه دارم دیونه می شم هیچ وقت اینقدر درمونده نشده بودم لطفا کمک کنید.


یه library class بساز و بیلدش کن و تو کریستال صداش کن
من یه selecte  بزرگ داشتم این کارو کردم.جواب داد.

----------


## mina.net

> یه library class بساز و بیلدش کن و تو کریستال صداش کن
> من یه selecte بزرگ داشتم این کارو کردم.جواب داد.


دوست عزیز اگه می شه بیشتر توضیح بدید. ممنون از حسن توجهی که دارید.

----------


## maryam_yousefii

این کد کلاس لایبرری منه: برات توضیحم گذاشتم: 


namespace factor
{
publicclassfactor
{
privateconststring Constr = "Data Source=(local);Initial Catalog=shop;Integrated security=true";//in khat connection string e ke mitoni male khodeto benevisi
publicstaticIDataReader factor_load(string factnum, string factdate)//man niaz be vorodi dashtam mitoni bedone vorodiam in karo koni
{
SqlConnection con = newSqlConnection(Constr);
con.Open();
SqlCommand com = newSqlCommand("select tbl_fact_lot.factNum as factNum,tbl_model.model as model, tbl_fact_lot.lotCode as lotCode,tbl_fact_lot.count as count,price,(tbl_fact_lot.count*tbl_lot.price) as totalPrice,totalFact from tbl_lot inner join tbl_model on tbl_lot.IDmodel=tbl_model.IDmodel inner join tbl_fact_lot on tbl_lot.lotCode=tbl_fact_lot.lotCode inner join tbl_fact on tbl_fact.factNum=tbl_fact_lot.factNum and tbl_fact.factDate=tbl_fact_lot.factDate where tbl_fact_lot.factNum=" + factnum + " and tbl_fact_lot.factDate=" + factdate, con);// in khat selectete
IDataReader idataR = com.ExecuteReader();
return idataR;
}
}
}


وقتی ساختی روش کلیک راست کن build کن. بعد توی کریستالت(*.rpt)یه فرم blanko انتخاب کن بعد از پنجره field explorer روی  database field کلیک راست و گزینه database expert و انتخاب کن حالا:create new connection/ADO.NET/file pathفایل خودتو که dll ساختی ازش انتخاب کن. برای اینکه بدونی کجاست تو پنجره output ببین آدرس dll ات کجاست.
بعد تو classname اسم کلاست رو انتخاب کن. ok و تموم!
حالا report تتو بساز.
موفق باشی اگه نتونستی بهم بگو.

----------


## mina.net

سلام دوست عزیز  maryam_yousefii 
من دقیقا نگرفتم توچیکار کردی اگه می شه بیشتر توضیح بدید

اگه با این مثال بگی فکر کنم بهتر متوجه بشم. 
نام جدول من BED_BEST 
فیلد هاش 
ID_SHAKHS ,  NAME_SHAKHS  ,  ID  , TARIKH , BED , BEST  هست. 
اگه می شه براساس موارد بالا مثال بزنید ممنون می شم.

----------


## maryam_yousefii

فکر کنم من با مثال توضیح دادم ولی  
باید روی پروژت solution کلیک راست کنی add رو انتخاب کنی بعد new project از زبان برنامه نویسیت گزینه class library رو انتخاب کنی . حالا کدی که برات گذاشتم و توش بنویس
حالا   Initial Catalog=shop  کلمه shop رو پاک کن اسم database خودتو بنویس.
select tbl_fact_lot.factNum as factNum,tbl_model" این select  و کامل پاک کن و selecte خودتو بنویس.
که فکر کنم این جوری باشه
select ID_SHAKHS , NAME_SHAKHS , ID , TARIKH , BED , BEST from BED_BEST
بعد هم بقیه کارا.  
موفق باشی

----------


## bad_boy_2007

من به همین کار تو برنامه خودم احتیاج داشتم (محاسبه مانده) اومدم و داده ها رو از دیتاست خوندم و محاسبات رو تو دیتاست انجام دادم فوق العاده سریع و راحت هم هست (اینو گفتم چون دیدم خیلی وقته دنبال محاسبه مانده هستی) 
ببین فرض کن میخوای از حساب مشتری "متفرقه" گردش بگیری ، فقط گردش حساب امروزش باشه نه از اول دوره ، در این حالت میگی تمام رکوردها رو تا امروز جمع مانده حساباش رو حساب کن با sum  و واسه باقیا هم سطر به سطر محاسبه کن
حالا اگه "متفرقه" حدودا روزی 50 تا گردش داشته باشه و حسابداریت یک سال باشه که نصبه با روشی که الان داری محاسبات رو انجام میدی مجبوری زمان زیادی رو صرف کنی که مانده رو برای تک تک رکوردهای محاسبه کنی (50*365=18500) و بعد گزارش رو بر اساس تاریخ روز (امروز) فیلتر کنی (فقط 50 تا رکورد) ، یعنی محاسبات رو روی 18500-50=17450 تا رکورد بیخودی انجام دادی در صورتی که میتونستی این کار رو فقط برای 50 تا بکنی !!!
همه این توضیحات واسه این بود که اگه قانع شدی از دیتاست استفاده کنی میتونی دیتاسورس گزارش کریستالت رو بجای دیتابیست بکنی دیتاست برنامه یعنی کریستال از دیتاست اطلاعات رو جهت تهیه گزارش بگیره و تو هم تو دیتاست فیلد مانده رو با برنامه نویسی محاسبه میکنی

----------


## mina.net

دوست عزیز 
من هم به این نتیجه که شما می گید رسیدم. البته اومدم یک temp tabel به وجود اوردم و تو اون براساس تاریخ سورت کردم و سپس از طریق اون دستور select ی که تو صفحه اول همین تاپیک لینکش رو گذاشتم مانده گرفتم من 300-400 تا رکورد انجام دارم مشکلی نداشت.

----------


## bad_boy_2007

> دوست عزیز 
> من هم به این نتیجه که شما می گید رسیدم. البته اومدم یک temp tabel به وجود اوردم و تو اون براساس تاریخ سورت کردم و سپس از طریق اون دستور select ی که تو صفحه اول همین تاپیک لینکش رو گذاشتم مانده گرفتم من 300-400 تا رکورد انجام دارم مشکلی نداشت.


 من این کار رو واسه محاسبه مانده روی 23000 رکورد انجام دادم روی سیستم با CPU 1.5 زیر 2 ثانیه طول کشید که واسه برنامه من ایده آله فقط باید به یک نکته توجه کنی که دیتا تیبل به گرید وصل نشده باشه که در این صورت به دلیل بازسازی های گرید نتیجه بیش از 20 ثانیه طول میکشه

----------


## mina.net

> من این کار رو واسه محاسبه مانده روی 23000 رکورد انجام دادم روی سیستم با CPU 1.5 زیر 2 ثانیه طول کشید که واسه برنامه من ایده آله فقط باید به یک نکته توجه کنی که دیتا تیبل به گرید وصل نشده باشه که در این صورت به دلیل بازسازی های گرید نتیجه بیش از 20 ثانیه طول میکشه


درسته من هم 50000 رکورد رو از طریق یک تابع وارد کردم و تاخیر زیادی نداشته . خوب من نهایت اخرش روکورد هر حساب من به 1000 سطر برسه که این عالی هست. دوستانی که مایلند از این روشها استفاده کنند باید تاپیک های که من در 15 روز گذشته ایجاد کردم و در زیر لینک اونا رو میزارم رو دنبال کنند متوجه خواهند شد.
https://barnamenevis.org/showthread.php?t=160093
https://barnamenevis.org/showthread.php?t=161393
https://barnamenevis.org/showthread.php?t=160849
https://barnamenevis.org/showthread.php?t=160568

----------

