PDA

View Full Version : حرفه ای: صورت حساب بدهی یا طلب مشتری (هر رکورد نسبت به رکوردهای قبل محاسبه شود)



kamiloted
پنج شنبه 24 تیر 1395, 23:53 عصر
سلام دوستان عزیز.

بنده یک دیتا گرید دارم که مقداربدهی و طلبکاری و نام مشتری را از بانک دریافت میکنه. که من میخوام 2 فیلد مانده حساب و وضعیت که در جدول مربوطه نیست و به این دیتا گرید اضافه کنم. و میخوام محاسبات زیر روی آن انجام بشه:
اگر در سطر 1 مبلغ بدهی بزرگتر از صفر باشه و بستانکاری مساوی صفر باشه مانده حساب مبلغ بدهکاری رو نشان دهد یا به نحوی منها بشن. و وضعیت بدهکار را نشان بدهد.
و یا اگر در سطر 1 مبلغ بدهکاری صفر و بستانکاری بیشتر از صفر باشد مانده حساب مبلغ بستانکاری را نشان بدهد و وضعیت بستانکار را نشان بدهد.
و برای سطر های بعدی محاسبات به صورت زیر باشد.
اگر در سطر 2 بدهکاری بزرگتر از صفر باشد و بستانکاری صفر باشد.مانده حساب سطر 1 با بدهکاری سطر 2 جمع میشود. و مبلغ در مانده حساب سطر 2نمایش میدهد و وضعیت اگرمنفی شد بستانکار و اگر مثبت شد بدهکار را نشان میدهد.
یا اگر در سطر 2 بستانکاری بزرگتر از صفر باشد و بدهکاری صفر باشد.مانده حساب سطر 1 از بستانکاری سطر2 کم میشود. و مبلغ در مانده حساب سطر 2نمایش میدهد و وضعیت اگرمنفی شد بستانکار و اگر مثبت شد بدهکار را نشان میدهد.
و در سطر 3مانده حساب سطر 2 از اینها کم میشود یا جمع میشود.
وبه همین ترتیب در سطرهای بعد تا بی نهایت ادامه میدهیم.


مثال:

ردیف نام مشتری مبلغ بدهی مبلغ بستانکاری مانده حساب وضعیت

1 علی 10 0 10 بدهکار
2 علی 10 0 20 بدهکار
3 علی 10 0 30 بدهکار
4 علی 0 10 20 بدهکار
5 علی 0 10 10 بدهکار
6 علی 0 20 10- بستانکار
7 علی 0 5 15- بستانکار
8 علی 5 0 10- بدهکار
...
....
....

141472
و به همین ترتیب ادامه میدهیم.
نکته :من نمیخوام که دو فیلد مانده حساب و وضعیت رو به جدولم اضافه کنم.میخوام سمت سی شارپ به دیتاگرید اضافه کنم.

پیشاپیش ازهمه سپاسگذارم.
لطفا نمونه کد بزارین فقط.چون پس فردا باید تحویل بدم.ممنونم

reza_ali202000
جمعه 25 تیر 1395, 12:49 عصر
سلام دوست عزیز.
میتونی با حلقه سطر به سطر بخونی و تفریق بدهکار و بستانکار رو توی یه متغیر ذخیره کنی و توی همون حلقه اخر دیتاگرید اضافش کنی و همون متغییر رو تا اخر حلقه داشته باشی.
یه چیز تقریبا اینجوری:

decimal bed=0,bes=0,mande=0;
for(int i=0;i<dgv.rowcount;i++)
{
bed=convert.todecimal(dgv.rows[i].cell["bedehi"].value.tostring());
bes=...
mande=mande+(bes-bed);
string vaz="بدهکار";
if(mande>0) vaz="بستانکار";
if(mande==0) vaz="بی حساب";
dgv.rows[i].cell["vaziat"].value=vaz;
dgv.rows[i].cell["man"].value=mande.tostring();
}
}

kamiloted
جمعه 25 تیر 1395, 14:23 عصر
سلام دوست عزیز.
میتونی با حلقه سطر به سطر بخونی و تفریق بدهکار و بستانکار رو توی یه متغیر ذخیره کنی و توی همون حلقه اخر دیتاگرید اضافش کنی و همون متغییر رو تا اخر حلقه داشته باشی.
یه چیز تقریبا اینجوری:

decimal bed=0,bes=0,mande=0;
for(int i=0;i<dgv.rowcount;i++)
{
bed=convert.todecimal(dgv.rows[i].cell["bedehi"].value.tostring());
bes=...
mande=mande+(bes-bed);
string vaz="بدهکار";
if(mande>0) vaz="بستانکار";
if(mande==0) vaz="بی حساب";
dgv.rows[i].cell["vaziat"].value=vaz;
dgv.rows[i].cell["man"].value=mande.tostring();
}
}


ممنونم دوست عزیز.
اما این خطا رو میده.

141480

لطفا راهنمایی بفرمایید.

reza_ali202000
جمعه 25 تیر 1395, 16:43 عصر
ممنونم دوست عزیز.
اما این خطا رو میده.

141480

لطفا راهنمایی بفرمایید.
دوست عزیز اسم کالومن وضعیتتون هرچی هست همونو بزارید.
من این کد رو به عنوان نمونه نوشتم.

kamiloted
جمعه 25 تیر 1395, 16:45 عصر
دوست عزیز میدونم.اما من کالمن وضعیت ندارم.
من قراره مانده حساب و وضعیت رو میخوام سمت سی شارپ انجام بدم.

aryadev
جمعه 25 تیر 1395, 20:27 عصر
اگه میخوای اضافه کنی اینطوری میشه


dataGridViw1.rows.add(هرچی که میخوای اضافه کنی را بزار)

kamiloted
جمعه 25 تیر 1395, 21:37 عصر
اگه میخوای اضافه کنی اینطوری میشه


dataGridViw1.rows.add(هرچی که میخوای اضافه کنی را بزار)



ممنونم.دوست عزیز .
من هرچی اضافه میکنم.بازم همینو میگه.
لطفا یه کد منظم بهم بدین ممنون میشم

hosseines
شنبه 26 تیر 1395, 12:36 عصر
به دیتاگرید دو تا ستون بنام های vaziat و man اضافه کن بعد کد زیر رو استفاده کن..


decimal bed=0,bes=0,mande=0;
for(int i=0;i<dgv.rowcount;i++)
{
bed=convert.todecimal(dgv.rows[i].cell["bedehi"].value.tostring());
bes=...
mande=mande+(bes-bed);
string vaz="بدهکار";
if(mande>0) vaz="بستانکار";
if(mande==0) vaz="بی حساب";
dgv.rows[i].cell["vaziat"].value=vaz;
dgv.rows[i].cell["man"].value=mande.tostring();
}
}

kamiloted
شنبه 26 تیر 1395, 17:35 عصر
به دیتاگرید دو تا ستون بنام های vaziat و man اضافه کن بعد کد زیر رو استفاده کن..


decimal bed=0,bes=0,mande=0;
for(int i=0;i<dgv.rowcount;i++)
{
bed=convert.todecimal(dgv.rows[i].cell["bedehi"].value.tostring());
bes=...
mande=mande+(bes-bed);
string vaz="بدهکار";
if(mande>0) vaz="بستانکار";
if(mande==0) vaz="بی حساب";
dgv.rows[i].cell["vaziat"].value=vaz;
dgv.rows[i].cell["man"].value=mande.tostring();
}
}





ممنونم دوست عزیز.
اما 2تا ستونی که ایجاد کردم میاد اول دیتا گرید.
به این صورت:

وضعیت - مانده حساب - کد مشتری - نام مشتری - بدهکار - بستانکار
باید چطور جابه جا کنم.؟
که به صورت زیر بشه.
کد مشتری - نام مشتری - بدهکار - بستانکار -وضعیت- مانده حساب
ممنونم که وقت میزارید

hosseines
شنبه 26 تیر 1395, 17:42 عصر
ستون ها را بصورت دستی ایجاد میکنی یا با کد ...؟

kamiloted
شنبه 26 تیر 1395, 17:48 عصر
ستون ها را بصورت دستی ایجاد میکنی یا با کد ...؟

بقیه ستونها رو با کد و این 2 مورد رو که شما فرمودین به صورت دستی.

kamiloted
شنبه 26 تیر 1395, 17:53 عصر
و یه سوال دیگه.چکار کنم که در دیتا گرید و یا ریپورت مقدار منفی مثلا -200 نوشته نشه اما همچنان سیستم وضعیت رو تشخیص بده که بدهکاره یا بستانکار؟

hosseines
شنبه 26 تیر 1395, 18:09 عصر
میتونی بررسی کنی که اگه مانده منفی بود در -1 ضرب کنی..

mojtaba0912433
شنبه 26 تیر 1395, 22:38 عصر
اطلاعات را دستی وارد میکنم

reza_ali202000
یک شنبه 27 تیر 1395, 01:03 صبح
11 141506

آقا ما هم يه سوء استفاده از اين تايپيك ببريم اين كد را من ضميمه پروژه كردم ميشه راهنمايي كنيد خطايي كه ميگره مربوط به چي هست

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

for (int i = 0; i < dgv.RowCount-1; i++)

kamiloted
دوشنبه 28 تیر 1395, 21:31 عصر
اما 2تا ستونی که ایجاد کردم میاد اول دیتا گرید.
به این صورت:

وضعیت - مانده حساب - کد مشتری - نام مشتری - بدهکار - بستانکار
باید چطور جابه جا کنم.؟
که به صورت زیر بشه.
کد مشتری - نام مشتری - بدهکار - بستانکار -وضعیت- مانده حساب
ممنونم که وقت میزارید

mrprestige
دوشنبه 28 تیر 1395, 21:52 عصر
اما 2تا ستونی که ایجاد کردم میاد اول دیتا گرید.
به این صورت:

وضعیت - مانده حساب - کد مشتری - نام مشتری - بدهکار - بستانکار
باید چطور جابه جا کنم.؟
که به صورت زیر بشه.
کد مشتری - نام مشتری - بدهکار - بستانکار -وضعیت- مانده حساب
ممنونم که وقت میزارید

سلام دوست عزیز ، شما اگه به دیتاگرید دقت کنید میبینید در بالا سمت راست اون یه فلش ریز مشکی رنگ وجود داره روی اون کلیک کن و در کادری که باز میشه روی Edit Column کلیک کن پنجره ای باز میشه که ستون های جدول شما توی اون قرار داره حالا روی هر ستونی که میخوای کلیک کن کنار همون کادری که نام ستون هات قرار داره دوتا فلش مشکی رنگ هست با اون ها ترتیب ستون هات رو به صورتی که میخوای تغییر بده و Ok کن .

پیرو و موفق باشی .

aslan
دوشنبه 28 تیر 1395, 22:01 عصر
سلام
با DisplayIndex میتونید محل قرارگیری ستونها را تنظیم کنید
برای نمونه لینک زیر را ببینید :
https://msdn.microsoft.com/en-us/library/wkfe535h(v=vs.100).aspx

kamiloted
دوشنبه 28 تیر 1395, 22:35 عصر
سلام دوست عزیز ، شما اگه به دیتاگرید دقت کنید میبینید در بالا سمت راست اون یه فلش ریز مشکی رنگ وجود داره روی اون کلیک کن و در کادری که باز میشه روی Edit Column کلیک کن پنجره ای باز میشه که ستون های جدول شما توی اون قرار داره حالا روی هر ستونی که میخوای کلیک کن کنار همون کادری که نام ستون هات قرار داره دوتا فلش مشکی رنگ هست با اون ها ترتیب ستون هات رو به صورتی که میخوای تغییر بده و Ok کن .

پیرو و موفق باشی .

ممنونم دوست عزیز.
من اون 6 مورد رو با کد آوردم.و اون 2 مورد رو به این طریقی که شما میفرمایین آوردم.
اینقدر مبتدی دیگه نیستم.ممنونم

reza_ali202000
سه شنبه 29 تیر 1395, 00:16 صبح
دوست عزیز اگه سلکت رو به صورت دستی نوشتین پس ایجاد دوتا کالومن هم دستز بعد از سلکتتون بنویسید.شما میگی نمونه، شما خودت نمونتو بزار تا بتونیم برات ویرایش کنیم.واقعا خیلی ساده هست.

mrprestige
سه شنبه 29 تیر 1395, 20:58 عصر
ممنونم دوست عزیز.
من اون 6 مورد رو با کد آوردم.و اون 2 مورد رو به این طریقی که شما میفرمایین آوردم.
اینقدر مبتدی دیگه نیستم.ممنونم
قصد جسارت نداشتم دوست عزیز میدونم شما حرفه ای هستید :لبخندساده:، من وقتی جوابی به یک سوال میدم سعی میکنم طوری جواب بدم که اگه کسی هم مبتدی بود و همین مشکل رو داشت به پست بنده نگاه کرد براش نا مفهموم نباشه .

پیروز موفق باشی.

kamiloted
سه شنبه 05 مرداد 1395, 13:00 عصر
سلام .ممنونم از دوستانی که برای این تاپیک وقت گذاشتن.
اما متاسفانه اون چیزی که میخواستم کسی اشاره نکرد.خودم بالاخره موفق شدم با یه خط کد بنویسم بخش آخر سوالم رو منظورمه(نکته :من نمیخوام که دو فیلد مانده حساب و وضعیت رو به جدولم اضافه کنم.میخوام سمت سی شارپ به دیتاگرید اضافه کنم.).اگر کسی خواست تا براش توضیح بدم.

الان من میخوام مانده حساب را به این صورت به دست بیارم.
مثلا سطر اول نوشته نام مشتری علی و سطر دوم نوشته نام مشتری مهدی و سطر سوم نوشته محسن
و سطر چهارم نوشته علی وبه همین ترتیب میره تا بی نهایت.در ضمن نام علی تصادفی تکرار میشه.احتمال داره 3بار یا بیشتر پشت سر هم تکرار بشه.
حال من میخوام مانده حساب علی رو به شیوه ی بالا به دست بیارم در صورتی که بدهکاری و بستانکاری بقیه مشتری ها رو نادیده بگیره و فقط برای علی محاسبه بشه.
ممنونم اگه راهنمایی کنید.

hamid_hr
سه شنبه 05 مرداد 1395, 14:51 عصر
ببین این خوبه

dgv.Rows.Cast<DataGridViewRow>()
.All(c =>
{
c.Cells["مانده حساب"].Value =
dgv.Rows.Cast<DataGridViewRow>()
.Where(c1 => c1.Index < c.Index)
.Where(c1 => c1.Cells["نام مشتری"].Value.ToString().Equals(c.Cells["نام مشتری"].Value.ToString()))
.Select(c1 => int.Parse(c1.Cells["بستانکار"].Value.ToString()) -
int.Parse(c1.Cells["بدهکار"].Value.ToString())).Sum() +
int.Parse(c.Cells["بستانکار"].Value.ToString()) - int.Parse(c.Cells["بدهکار"].Value.ToString());

return true;
});

141665

اینم یک نمونه

kamiloted
سه شنبه 05 مرداد 1395, 17:04 عصر
141665

اینم یک نمونه

ممنونم دوست عزیز کدهاتون عالی بودن.
اگر ما بخواهیم طبق ستون شرح تصویر زیر محاسبات رو به روال قبل انجام بدیم باید چکار کنیم؟
141670
مثلا در ستون شرح متن ستون ها به صورت تصادفی تا بی نهایت اتفاق می افته.
من الان میخوام اون فیلدهایی که نوشته
فروش کالا طی فاکتور شماره 5
و خرید کالا طی فاکتور شماره 10
و تسویه فاکتور خرید شماره 10 با اسناد پرداختنی
محاسبه بشن.
و اون فیلد هایی که نوشته کالای مثلا شانی مبلغ بدهکاری وبستانکاریشون نادیده گرفته بشه.
و وضعیت مشتری هم ذکر بشه که آیا بدهکاره یا بستانکار
ممنونم که وقت میزارید

hamid_hr
سه شنبه 05 مرداد 1395, 17:31 عصر
خب من یه شرط گذاشتم به این صورت
.Where(c1 => c1.Cells["نام مشتری"].Value.ToString().Equals(c.Cells["نام مشتری"].Value.ToString()))

حالا شما باید اینو بر اساس کاری که میخواین تغییر بدین

kamiloted
سه شنبه 05 مرداد 1395, 18:06 عصر
خب من یه شرط گذاشتم به این صورت
.Where(c1 => c1.Cells["نام مشتری"].Value.ToString().Equals(c.Cells["نام مشتری"].Value.ToString()))

حالا شما باید اینو بر اساس کاری که میخواین تغییر بدین

دوست عزیز اگه من اینطور بنویسم

.Where(c1 => c1.Cells["شرح"].Value.ToString().Equals(c.Cells["شرح"].Value.ToString()))



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

مانند تصویر زیر:
141674


dataGridView1.Rows.Cast<DataGridViewRow>().Where(c 2 => !c2.Cells[3].Value.ToString().StartsWith("کالای")) .Where(c3 => !c3.Cells[3].Value.ToString().StartsWith("تخفیف"))




ممنونم که وقت میزارید

hamid_hr
سه شنبه 05 مرداد 1395, 18:28 عصر
خب باید شرطو عوض کنی
مثلا میشه
.Where(c1 => !c1.Cells["شرح"].Value.ToString().StartsWith("کالای")

kamiloted
سه شنبه 05 مرداد 1395, 18:42 عصر
خب باید شرطو عوض کنی
مثلا میشه
.Where(c1 => !c1.Cells["شرح"].Value.ToString().StartsWith("کالای")

ممنونم.اما شرط رو هر طوری مینویسم اصلا اون چیزی که میخوام نمیشه.باید چکار کنم دقیق
بعد میخوام هر مانده حساب دقیق روبروی خودش باشه طبق تصویر.کد شما همه رو تو 5 سطر اول مینویسه.

hamid_hr
سه شنبه 05 مرداد 1395, 19:13 عصر
خب اینطوری باید بشه
یه شرط اضافه میشه
dgv.Rows.Cast<DataGridViewRow>() .Where(c2 => !c2.Cells[0].Value.ToString().StartsWith("کالای"))
.All(c =>
{
c.Cells[3].Value =
dgv.Rows.Cast<DataGridViewRow>()
.Where(c1 => c1.Index < c.Index)
.Where(c1 => !c1.Cells[0].Value.ToString().StartsWith("کالای"))
.Select(c1 => int.Parse(c1.Cells[1].Value.ToString()) -
int.Parse(c1.Cells[2].Value.ToString())).Sum() +
int.Parse(c.Cells[1].Value.ToString()) - int.Parse(c.Cells[2].Value.ToString());


return true;
});

خط دوم اضافه میشه

kamiloted
دوشنبه 26 مهر 1395, 23:56 عصر
سلام دوستان.
من برای صورتحساب یه مشتری مبلغ بدهکاری رو منهای مبلغ بستانکاری میکنم و مانده حساب رو به دست میارم.مانند تصویر زیر.
143064
حال من یه کد نوشتم تا اگه مانده حساب کمتر از صفر بود بستانکار بنویسه.
و اگه بیشتر بود بدهکار و اگه مساوی صفر بود تسویه.
اما همونطور که توی شکل میبینید.همه رو تسویه نشون میده.
مشکل از چیه دوستان..؟؟
اینم کدی که برای این نوشتم:


try
{
DataTable dt = new DataTable();
Database db = new Database();
string Vaziat = "";
int MandeHesab = 0;
dt = db.MySelect("SELECT Id_Kalaei, Kod_Moshtari, Name_Moshtari, Sharh, Tedad, Takhfif, PriceVahed, PasAzTakhfif, Bedehkar, Bostankar, '" + Vaziat + "', '" + MandeHesab + "', Tarikh FROM tbl_Kalaei");

dataGridView1.DataSource = dt;


dataGridView1.Rows.Cast<DataGridViewRow>().Where(c2 => !c2.Cells[3].Value.ToString().StartsWith("کالای"))
.Where(c3 => !c3.Cells[3].Value.ToString().StartsWith("تخفیف"))
.All(c =>
{

MandeHesab = Convert.ToInt32(c.Cells[11].Value.ToString());

if (MandeHesab > 0) Vaziat = "بدهکار";
if (MandeHesab < 0) Vaziat = "بستانکار";
if (MandeHesab == 0) Vaziat = "تسویه";
c.Cells[10].Value = Vaziat;
c.Cells[11].Value = dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(c1 => c1.Index < c.Index)

.Where(c1 => !c1.Cells[3].Value.ToString().StartsWith("کالای"))

.Select(c1 => int.Parse(c1.Cells[8].Value.ToString()) -
int.Parse(c1.Cells[9].Value.ToString())).Sum() +
int.Parse(c.Cells[8].Value.ToString()) - int.Parse(c.Cells[9].Value.ToString());

return true;
} );

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}



ممنونم از همگی

ali_md110
سه شنبه 27 مهر 1395, 22:09 عصر
.Select(c1 => int.Parse(c1.Cells[8].Value.ToString()) - int.Parse(c1.Cells[9].Value.ToString())).Sum() +

int.Parse(c.Cells[8].Value.ToString()) - int.Parse(c.Cells[9].Value.ToString());




مبلغ مانده چجور بدست میارید؟
ستون بد منهای جمع ستون بس و ستون بد
به نظر من نیاز نیست به اون sum

معمولا ستون مانده اینجوری بدست میاد


total = total + Bes - Bed;

Mahmoud.Afrad
چهارشنبه 28 مهر 1395, 01:39 صبح
کل این عمل رو میتونید با کوئری SQL پیاده کنید. دنبال مطلبی با عنوان Running Total باشید.

kamiloted
چهارشنبه 28 مهر 1395, 09:45 صبح
دوستمون Mahmoud.Afrad (http://barnamenevis.org/member.php?71297-Mahmoud-Afrad) فرموده بودن که :
کل این عمل رو میتونید با کوئری SQL پیاده کنید. دنبال مطلبی با عنوان Running Total باشید.

ومن با جستجو این و پیدا کردم.
http://www.codeproject.com/Articles/300785/Calculating-simple-running-totals-in-SQL-Server

http://www.1keydata.com/sql/sql-running-totals.html
خلاصه من نمیدونم چکار کنم دوستان میشه منو راهنمایی کنید.ممنونم

Mahmoud.Afrad
چهارشنبه 28 مهر 1395, 20:48 عصر
لینک زیر روشهای مختلف همراه با پرفورمنس بررسی شده اند
https://sqlperformance.com/2014/01/t-sql-queries/grouped-running-totals

kamiloted
چهارشنبه 28 مهر 1395, 21:41 عصر
لینک زیر روشهای مختلف همراه با پرفورمنس بررسی شده اند
https://sqlperformance.com/2014/01/t-sql-queries/grouped-running-totals

سلام ممنونم .
این لینک رو دیده بودم.
من الان این کار ها رو انجام دادم.
الان فقط همون تکه کد


if (MandeHesab > 0) Vaziat = "بدهکار"; if (MandeHesab < 0) Vaziat = "بستانکار";
if (MandeHesab == 0) Vaziat = "تسویه";




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

Mahmoud.Afrad
چهارشنبه 28 مهر 1395, 22:24 عصر
وقتی سوال میپرسید در همان پست اول جتما کد و در صورت لزوم اسکریپت جدول رو بزارید تا بشه تست کرد.

اگر جدول زیر رو داشته باشیم
CREATE TABLE [dbo].[TestTable](
[Id] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NOT NULL,
[Bestankari] [decimal](18, 0) NOT NULL,
[Bedehkari] [decimal](18, 0) NOT NULL,
[Tarikh] [datetime2](7) NOT NULL
)
کوئری زیر پاسخ شماست. توجه کنید که زمان ثبت برای هر رکورد بایست وجود داشته باشه که میتونه از نوع datetime2 باشه تا بتوان بر حسب اون مجموع بدست بیاد
select
C.* ,
(CASE WHEN Mande>0 THEN N'بدهکار'
WHEN Mande<0 THEN N'طلبکار'
ELSE N'تسویه'
END) as Vaziat
from
(
select
B.Id ,
B.PersonId ,
B.Bedehkari ,
B.Bestankari ,
B.Tarikh ,
(B.RunningTotalBedehkari - B.RunningTotalBestankari) as Mande
From
(
SELECT
A.*,
RunningTotalBedehkari = (SELECT SUM(Bedehkari)
FROM dbo.TestTable
WHERE TestTable.PersonId = A.PersonId
AND TestTable.Tarikh <= A.Tarikh),
RunningTotalBestankari = (SELECT SUM(Bestankari)
FROM dbo.TestTable
WHERE TestTable.PersonId = A.PersonId
AND TestTable.Tarikh <= A.Tarikh)
FROM TestTable AS A
) AS B
) C
ORDER BY C.PersonId , C.Tarikh

kamiloted
چهارشنبه 28 مهر 1395, 23:39 عصر
وقتی سوال میپرسید در همان پست اول جتما کد و در صورت لزوم اسکریپت جدول رو بزارید تا بشه تست کرد.

اگر جدول زیر رو داشته باشیم
CREATE TABLE [dbo].[TestTable](
[Id] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NOT NULL,
[decimal](18, 0) NOT NULL,
[Bedehkari] [decimal](18, 0) NOT NULL,
[Tarikh] [datetime2](7) NOT NULL
)
کوئری زیر پاسخ شماست. توجه کنید که زمان ثبت برای هر رکورد بایست وجود داشته باشه که میتونه از نوع datetime2 باشه تا بتوان بر حسب اون مجموع بدست بیاد
select
C.* ,
(CASE WHEN Mande>0 THEN N'بدهکار'
WHEN Mande<0 THEN N'طلبکار'
ELSE N'تسویه'
END) as Vaziat
from
(
select
B.Id ,
B.PersonId ,
B.Bedehkari ,
B.Bestankari ,
B.Tarikh ,
(B.RunningTotalBedehkari - B.RunningTotalBestankari) as Mande
From
(
SELECT
A.*,
RunningTotalBedehkari = (SELECT SUM(Bedehkari)
FROM dbo.TestTable
WHERE TestTable.PersonId = A.PersonId
AND TestTable.Tarikh <= A.Tarikh),
RunningTotalBestankari = (SELECT SUM(Bestankari)
FROM dbo.TestTable
WHERE TestTable.PersonId = A.PersonId
AND TestTable.Tarikh <= A.Tarikh)
FROM TestTable AS A
) AS B
) C
ORDER BY C.PersonId , C.Tarikh

ممنونم آقای [B]Mahmoud.Afrad (http://barnamenevis.org/member.php?71297-Mahmoud-Afrad).

اگه توجه کنید من در تصویر بالا فیلتر گذاشتم ونمیخوام بعضی از بدهکاری ها و بستانکاری ها تو محاسبه بیاد.
و همینطور من 2 ستون وضعیت و مانده حساب را در جدول ندارم.
اسکریپت جدول من:


CREATE TABLE [dbo].[tbl_Kalaei](
[Id_Kalaei] [int] IDENTITY(1,1) NOT NULL,
[NumSanad] [char](10) NULL,
[Kod_Moshtari] [char](10) NULL,
[Name_Moshtari] [nvarchar](50) NULL,
[Sharh] [nvarchar](400) NULL,
[Tedad] [nvarchar](50) NULL,
[Takhfif] [nvarchar](50) NULL,
[PriceVahed] [nvarchar](50) NULL,
[PasAzTakhfif] [nvarchar](50) NULL,
[Bedehkar] [decimal](18, 0) NULL,
[Bostankar] [decimal](18, 0) NULL,
[Tarikh] [date] NULL,
CONSTRAINT [PK_tbl_Kalaei] PRIMARY KEY CLUSTERED
(
[Id_Kalaei] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


بعد آیا من کد شما رو توی استور پروسیجر بریزم؟
من اونا رو سمت سی شارپ نوشتم.
ممنونم بیشتر منو راهنمایی کنید.

Mahmoud.Afrad
پنج شنبه 29 مهر 1395, 00:09 صبح
شرطها(فیلتر) چی هست؟

در ضمن
اگر جدولی برای مشخصات مشتری دارید، نیازی به نام مشتری در tbl_Kalaei ندارید و میتونید با کدمشتری رابطه برقرار کنید.
اگر در یک روز چند رکورد برای یک شخص بخواهید ثبت کنید نیاز دارید ستون تاریخ رو از نوع Datetime2 بگیرید.(تاریخ به تنهایی کافی نیست)

kamiloted
پنج شنبه 29 مهر 1395, 01:37 صبح
شرطها(فیلتر) چی هست؟

در ضمن
اگر جدولی برای مشخصات مشتری دارید، نیازی به نام مشتری در tbl_Kalaei ندارید و میتونید با کدمشتری رابطه برقرار کنید.
اگر در یک روز چند رکورد برای یک شخص بخواهید ثبت کنید نیاز دارید ستون تاریخ رو از نوع Datetime2 بگیرید.(تاریخ به تنهایی کافی نیست)

خب من یه شرط گذاشتم به این صورت
.Where(c1 => c1.Cells["نام مشتری"].Value.ToString().Equals(c.Cells["نام مشتری"].Value.ToString()))

حالا شما باید اینو بر اساس کاری که میخواین تغییر بدین[/QUOTE]

دوست عزیز اگه من اینطور بنویسم

.Where(c1 => c1.Cells["شرح"].Value.ToString().Equals(c.Cells["شرح"].Value.ToString()))



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

مانند تصویر زیر:
141674


dataGridView1.Rows.Cast<DataGridViewRow>().Where(c 2 => !c2.Cells[3].Value.ToString().StartsWith("کالای")) .Where(c3 => !c3.Cells[3].Value.ToString().StartsWith("تخفیف"))




اگر در یک روز چند رکورد برای یک شخص بخواهید ثبت کنید نیاز دارید ستون تاریخ رو از نوع Datetime2 بگیرید.(تاریخ به تنهایی کافی نیست) دلیل این رو میفرمایید؟؟

ممنونم که وقت میزارید

Mahmoud.Afrad
پنج شنبه 29 مهر 1395, 02:18 صبح
کد زیر رو در تست کنید
select
C.* ,
(CASE WHEN Mande>0 THEN N'بدهکار'
WHEN Mande<0 THEN N'طلبکار'
ELSE N'تسویه'
END) as Vaziat
from
(
select
B.* ,
(B.RunningTotalBedehkari - B.RunningTotalBestankari) as Mande
From
(
SELECT
A.*,
RunningTotalBedehkari = (SELECT SUM(Bedehkar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh),
RunningTotalBestankari = (SELECT SUM(Bostankar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh)
FROM tbl_Kalaei AS A
WHERE A.Sharh not like N'کالای :%'
) AS B
) C
ORDER BY C.Kod_Moshtari , C.Tarikh
اینکه گفتم زمان رو هم ذخیره کنید برای اینکه در سلکت داخلی برحسب تاریخ و زمان میاد جمع رو برای رکوردهای قبل انجام میده. حالا اگر فقط تاریخ باشه، جمع ممکن هست اشتباه بشه. البته این به منطقی که پیاده کردید برمیگرده که آیا در یک روز برای یک شخص چند رکورد ذخیره میشه یا نه؟

kamiloted
پنج شنبه 29 مهر 1395, 12:32 عصر
کد زیر رو در تست کنید
select
C.* ,
(CASE WHEN Mande>0 THEN N'بدهکار'
WHEN Mande<0 THEN N'طلبکار'
ELSE N'تسویه'
END) as Vaziat
from
(
select
B.* ,
(B.RunningTotalBedehkari - B.RunningTotalBestankari) as Mande
From
(
SELECT
A.*,
RunningTotalBedehkari = (SELECT SUM(Bedehkar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh),
RunningTotalBestankari = (SELECT SUM(Bostankar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh)
FROM tbl_Kalaei AS A
WHERE A.Sharh not like N'کالای :%'
) AS B
) C
ORDER BY C.Kod_Moshtari , C.Tarikh
اینکه گفتم زمان رو هم ذخیره کنید برای اینکه در سلکت داخلی برحسب تاریخ و زمان میاد جمع رو برای رکوردهای قبل انجام میده. حالا اگر فقط تاریخ باشه، جمع ممکن هست اشتباه بشه. البته این به منطقی که پیاده کردید برمیگرده که آیا در یک روز برای یک شخص چند رکورد ذخیره میشه یا نه؟

ممنونم.کارتون 20
کدتون هم سریعه و هم جالب.
فقط مشکلاتی داره.محاسبات رو درست انجام نمیده.بعد شما اومدین کلا کالای: رو فیلتر کردین که نمایش نده.من میخوام نمایش بده اما مبالغش تو محاسبات فیلتر بشه.
دقیقا مثل این شکل:

141674

اما نتیجه کار شما شده این:
143086

kamiloted
پنج شنبه 29 مهر 1395, 13:24 عصر
چیزی که من با کد خودم یعنی این کد ایجاد کردم.


try
{
DataTable dt = new DataTable();
Database db = new Database();
string Vaziat = "";
int MandeHesab = 0;
dt = db.MySelect("SELECT Id_Kalaei, Kod_Moshtari, Name_Moshtari, Sharh, Tedad, Takhfif, PriceVahed, PasAzTakhfif, Bedehkar, Bostankar, '" + Vaziat + "', '" + MandeHesab + "', Tarikh FROM tbl_Kalaei");

dataGridView1.DataSource = dt;


dataGridView1.Rows.Cast<DataGridViewRow>().Where(c 2 => !c2.Cells[3].Value.ToString().StartsWith("کالای"))
.Where(c3 => !c3.Cells[3].Value.ToString().StartsWith("تخفیف"))
.All(c =>
{

MandeHesab = Convert.ToInt32(c.Cells[11].Value.ToString());

if (MandeHesab > 0) Vaziat = "بدهکار";
if (MandeHesab < 0) Vaziat = "بستانکار";
if (MandeHesab == 0) Vaziat = "تسویه";
c.Cells[10].Value = Vaziat;
c.Cells[11].Value = dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(c1 => c1.Index < c.Index)

.Where(c1 => !c1.Cells[3].Value.ToString().StartsWith("کالای"))

.Select(c1 => int.Parse(c1.Cells[8].Value.ToString()) -
int.Parse(c1.Cells[9].Value.ToString())).Sum() +
int.Parse(c.Cells[8].Value.ToString()) - int.Parse(c.Cells[9].Value.ToString());

return true;
} );

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}





نتیجش این شده:
143087


چیزی که من در اصل میخوام اینطور باید باشه:

143088

ممنون

Mahmoud.Afrad
پنج شنبه 29 مهر 1395, 18:08 عصر
ممنونم.کارتون 20
کدتون هم سریعه و هم جالب.
فقط مشکلاتی داره.محاسبات رو درست انجام نمیده.بعد شما اومدین کلا کالای: رو فیلتر کردین که نمایش نده.من میخوام نمایش بده اما مبالغش تو محاسبات فیلتر بشه.


در اینصورت بایست شرط فیلتر رو ببرید جایی که محاسبه انجام میشه یعنی سلکت های درونی
select
C.* ,
(CASE WHEN Mande>0 THEN N'بدهکار'
WHEN Mande<0 THEN N'طلبکار'
ELSE N'تسویه'
END) as Vaziat
from
(
select
B.* ,
(B.RunningTotalBedehkari - B.RunningTotalBestankari) as Mande
From
(
SELECT
A.*,
RunningTotalBedehkari = (SELECT SUM(Bedehkar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh
AND Sharh not like N'کالای :%'),
RunningTotalBestankari = (SELECT SUM(Bostankar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh
AND Sharh not like N'کالای :%')
FROM tbl_Kalaei AS A
) AS B
) C
ORDER BY C.Kod_Moshtari , C.Tarikh

kamiloted
پنج شنبه 29 مهر 1395, 22:57 عصر
در اینصورت بایست شرط فیلتر رو ببرید جایی که محاسبه انجام میشه یعنی سلکت های درونی
select
C.* ,
(CASE WHEN Mande>0 THEN N'بدهکار'
WHEN Mande<0 THEN N'طلبکار'
ELSE N'تسویه'
END) as Vaziat
from
(
select
B.* ,
(B.RunningTotalBedehkari - B.RunningTotalBestankari) as Mande
From
(
SELECT
A.*,
RunningTotalBedehkari = (SELECT SUM(Bedehkar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh
AND Sharh not like N'کالای :%'),
RunningTotalBestankari = (SELECT SUM(Bostankar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh
AND Sharh not like N'کالای :%')
FROM tbl_Kalaei AS A
) AS B
) C
ORDER BY C.Kod_Moshtari , C.Tarikh


ممنون.بازم نشد.

از این فرمول استفاده کنید.
Mandeh = Mandeh + (bed - bes);
فیلتر هم اشتباه بود.

Mahmoud.Afrad
پنج شنبه 29 مهر 1395, 23:59 عصر
از خروجی کوئری بنده ، عکس بزارید و بگید انتظار دارید چی باشه.
فرمول محاسبه مانده درست هست: مجموع بستانکاری منهای مجموع بدهکاری برای رکورد جاری و رکوردهای ماقبل.

kamiloted
جمعه 30 مهر 1395, 00:42 صبح
از خروجی کوئری بنده ، عکس بزارید و بگید انتظار دارید چی باشه.
فرمول محاسبه مانده درست هست: مجموع بستانکاری منهای مجموع بدهکاری برای رکورد جاری و رکوردهای ماقبل.

سلام ممنونم که وقت میزارید.

چیزی که از کد شما به دست اومده:

143096

چیزی که من میخوام:

143097

دقیقا برای هر دو عکس از یک اعداد استفاده شده.

Mahmoud.Afrad
جمعه 30 مهر 1395, 01:01 صبح
توجه کنید که به همین خاطر گفتم به چیزی مثل زمان هم نیاز دارید تا ترتیب بین رکوردها مشخص باشه چون براساس فیلد تاریخ عملیات جمع صورت میگیره(نمیشه به جای تاریخ از ID استفاده کرد چون تضمینی نیست که فیلد ID به ترتیب باشه،در sqlserver 2012 و بالاتر ممکنه پرش داشته باشه یا اصلا ستون ID از نوع uniqueidentifier باشد). ستون تاریخ رو از نوع تاریخ+زمان (datetime2) ایجاد و تست کنید و نتیجه رو بگید.

ژیار رحیمی
جمعه 30 مهر 1395, 01:18 صبح
سلام
روش مانده گیری شما دارای اشکال هست
1- شما جمع فکتور و همچنین اقلام فاکتور رو نمایش میدی که روش صحیحی نمیباشد و انتظار داری الگوریتم فقط روی جمع فاکتور یا دریافتی/ پرداختی فاکتور اعمال شود که ان هم مستلزم فیلتر کردن بر اساس فیلدی شاخص که جمع مبلغ فاکتور را با مبلغ اقلام متمایز کنی.(در کل روش شما در نمایش کل و جز فاکتور اشتباه میباشد)نمایش جمع فاکتور یا بجای ان اقلام فاکتور در محاسبه مانده کفایت میکند
2- شما ستون تشخیص(مانده) گذاشتی در صورتی که برای مانده حساب بستانکار از عدد منفی استفاده کردی.این کار اشتباه میباشد.
3- روش(الگوریتم) مانده گیری ارائه شده صحیح میباشد ولی شما روی ورودی های اشتباه(جمع فاکتور و اقلام فاکتور) پیاده سازی کردی.

kamiloted
جمعه 30 مهر 1395, 01:38 صبح
توجه کنید که به همین خاطر گفتم به چیزی مثل زمان هم نیاز دارید تا ترتیب بین رکوردها مشخص باشه چون براساس فیلد تاریخ عملیات جمع صورت میگیره(نمیشه به جای تاریخ از ID استفاده کرد چون تضمینی نیست که فیلد ID به ترتیب باشه،در sqlserver 2012 و بالاتر ممکنه پرش داشته باشه یا اصلا ستون ID از نوع uniqueidentifier باشد). ستون تاریخ رو از نوع تاریخ+زمان (datetime2) ایجاد و تست کنید و نتیجه رو بگید.

انجام شد اما متاسفانه هیچ تغییری توی نتیجه صورت نگرفت.
ممنونم

kamiloted
جمعه 30 مهر 1395, 01:49 صبح
سلام.ممنونم.

1- شما جمع فکتور و همچنین اقلام فاکتور رو نمایش میدی که روش صحیحی نمیباشد و انتظار داری الگوریتم فقط روی جمع فاکتور یا دریافتی/ پرداختی فاکتور اعمال شود که ان هم مستلزم فیلتر کردن بر اساس فیلدی شاخص که جمع مبلغ فاکتور را با مبلغ اقلام متمایز کنی.(در کل روش شما در نمایش کل و جز فاکتور اشتباه میباشد)نمایش جمع فاکتور یا بجای ان اقلام فاکتور در محاسبه مانده کفایت میکند
(منظور شما این بود؟ این انجام شده.اما من به اون صورت هم نیاز دارم.)
143099

2- شما ستون تشخیص(مانده) گذاشتی در صورتی که برای مانده حساب بستانکار از عدد منفی استفاده کردی.این کار اشتباه میباشد.(این رو برای فهم دوستان در نرم افزار پینت گذاشتم)


3- روش(الگوریتم) مانده گیری ارائه شده صحیح میباشد ولی شما روی ورودی های اشتباه(جمع فاکتور و اقلام فاکتور) پیاده سازی کردی.
(من این کار رو انجام ندادم.اگه به چنتا پست عقبتر برگردید میبینیدمن فیلتر گذاشتم و فقط برای جمع فاکتور این رو لحاظ کردم.مشکل من فقط در ستون تشخیص بود .که چرا همه رو تسویه مینویسه.همین.

روش مانده گیری شما دارای اشکال هست.
ممنون میشم یه راهنمایی کنید.و یه روش به بنده بگید.
سپاس

Mahmoud.Afrad
جمعه 30 مهر 1395, 22:04 عصر
چیزی به نظرم نمبرسه که بگم جز اینکه فیلد تاریخ برای هر رکورد بایست متفاوت باشه.
اسکریپت زیر رو در sqlserver management studio تست کنید
USE [master];

IF EXISTS(SELECT * FROM sys.databases WHERE name=N'TestDB2')
BEGIN
ALTER DATABASE [TestDB2] SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
DROP DATABASE [TestDB2];
END

CREATE DATABASE [TestDB2];

USE [TestDB2];

CREATE TABLE [tbl_Kalaei](
[Id_Kalaei] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[NumSanad] [nvarchar](100) NULL,
[Kod_Moshtari] [int] NULL,
[Sharh] [nvarchar](400) NULL,
[Tedad] [int] NULL,
[Takhfif] [decimal](18, 0) NULL,
[PriceVahed] [decimal](18, 0) NULL,
[PasAzTakhfif] [decimal](18, 0) NULL,
[Bedehkar] [decimal](18, 0) NULL,
[Bestankar] [decimal](18, 0) NULL,
[Tarikh] [datetime2](7) NULL,
);

INSERT INTO [tbl_Kalaei] ([NumSanad], [Kod_Moshtari], [Sharh], [Tedad], [Takhfif], [PriceVahed], [PasAzTakhfif], [Bedehkar], [Bestankar], [Tarikh])
VALUES ('a','1','aaa',10,0,100,1000,1000,0,SYSDATETIME()) ;
INSERT INTO [tbl_Kalaei] ([NumSanad], [Kod_Moshtari], [Sharh], [Tedad], [Takhfif], [PriceVahed], [PasAzTakhfif], [Bedehkar], [Bestankar], [Tarikh])
VALUES ('b','1','bbb',1,0,15,15,0,10,SYSDATETIME());
INSERT INTO [tbl_Kalaei] ([NumSanad], [Kod_Moshtari], [Sharh], [Tedad], [Takhfif], [PriceVahed], [PasAzTakhfif], [Bedehkar], [Bestankar], [Tarikh])
VALUES ('c','1',N'کالای : ccc',5,0,20,100,70,0,SYSDATETIME());
INSERT INTO [tbl_Kalaei] ([NumSanad], [Kod_Moshtari], [Sharh], [Tedad], [Takhfif], [PriceVahed], [PasAzTakhfif], [Bedehkar], [Bestankar], [Tarikh])
VALUES ('d','1','ddd',3,0,70,210,60,0,SYSDATETIME());
INSERT INTO [tbl_Kalaei] ([NumSanad], [Kod_Moshtari], [Sharh], [Tedad], [Takhfif], [PriceVahed], [PasAzTakhfif], [Bedehkar], [Bestankar], [Tarikh])
VALUES ('e','2','eee',8,0,30,240,200,0,SYSDATETIME());
INSERT INTO [tbl_Kalaei] ([NumSanad], [Kod_Moshtari], [Sharh], [Tedad], [Takhfif], [PriceVahed], [PasAzTakhfif], [Bedehkar], [Bestankar], [Tarikh])
VALUES ('f','2','fff',5,0,100,1000,0,200,SYSDATETIME());
INSERT INTO [tbl_Kalaei] ([NumSanad], [Kod_Moshtari], [Sharh], [Tedad], [Takhfif], [PriceVahed], [PasAzTakhfif], [Bedehkar], [Bestankar], [Tarikh])
VALUES ('g','2',N'کالای : ggg',10,0,100,1000,1000,0,SYSDATETIME());


select
C.* ,
(CASE WHEN Mande>0 THEN N'بدهکار'
WHEN Mande<0 THEN N'طلبکار'
ELSE N'تسویه'
END) as Vaziat
from
(
select
B.* ,
(B.RunningTotalBedehkari - B.RunningTotalBestankari) as Mande
From
(
SELECT
A.*,
RunningTotalBedehkari = (SELECT SUM(Bedehkar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh
AND Sharh not like N'کالای :%'),
RunningTotalBestankari = (SELECT SUM(Bestankar)
FROM dbo.tbl_Kalaei
WHERE tbl_Kalaei.Kod_Moshtari = A.Kod_Moshtari
AND tbl_Kalaei.Tarikh <= A.Tarikh
AND Sharh not like N'کالای :%')
FROM tbl_Kalaei AS A
WHERE Sharh not like N'کالای :%'
) AS B
) C
union
select
* ,
RunningTotalBedehkari = null ,
RunningTotalBestankari = null ,
Mande = null ,
Vaziat = null
from tbl_Kalaei
where Sharh like N'کالای :%'
ORDER BY Kod_Moshtari , Tarikh

143117

kamiloted
جمعه 30 مهر 1395, 23:04 عصر
داداش ممنونم.خیلی لطف کردی.
این خطا رو داد.
143116

داداش اگه یه لطف کنی مشکل کد خودم رو بگی ممنون میشم.
اصلا بیخیال این روش.
سپاس

hamid_hr
یک شنبه 02 آبان 1395, 15:23 عصر
لطفا این رو تست کنید


int M = 0;
dataGridView1.Rows.Cast<DataGridViewRow>().Where(c2 => !c2.Cells[3].Value.ToString().StartsWith("کالای"))
.Where(c3 => !c3.Cells[3].Value.ToString().StartsWith("تخفیف"))
.All(c =>
{
M = dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(c1 => c1.Index < c.Index)
.Where(c1 => !c1.Cells[3].Value.ToString().StartsWith("کالای"))
.Select(c1 => int.Parse(c1.Cells[8].Value.ToString()) -
int.Parse(c1.Cells[9].Value.ToString())).Sum() +
int.Parse(c.Cells[8].Value.ToString()) -
int.Parse(c.Cells[9].Value.ToString());
c.Cells[11].Value = M;
c.Cells[10].Value = M == 0 ? "تسویه" : (M > 0 ? "بدهکار" : "بستانکار");
return true;

});

kamiloted
یک شنبه 02 آبان 1395, 16:46 عصر
لطفا این رو تست کنید


int M = 0;
dataGridView1.Rows.Cast<DataGridViewRow>().Where(c2 => !c2.Cells[3].Value.ToString().StartsWith("کالای"))
.Where(c3 => !c3.Cells[3].Value.ToString().StartsWith("تخفیف"))
.All(c =>
{
M = dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(c1 => c1.Index < c.Index)
.Where(c1 => !c1.Cells[3].Value.ToString().StartsWith("کالای"))
.Select(c1 => int.Parse(c1.Cells[8].Value.ToString()) -
int.Parse(c1.Cells[9].Value.ToString())).Sum() +
int.Parse(c.Cells[8].Value.ToString()) -
int.Parse(c.Cells[9].Value.ToString());
c.Cells[11].Value = M;
c.Cells[10].Value = M == 0 ? "تسویه" : (M > 0 ? "بدهکار" : "بستانکار");
return true;

});



ممنونم.جواب داد.
فق سوالی که داشتم خدمتتون

کدوم روش بهتر و سریع تر و بهینه و اصولی تر هست.
که بعدا در داده زیاد باهاش به مشکل نخورم.
روش شما یا روش من


// decimal bed = 0, bes = 0, S = 0;
// for (int i = 0; i < dataGridView1.RowCount; i++)
// {
// if (!dataGridView1.Rows[i].Cells[3].Value.ToString().StartsWith("کالای :") && !dataGridView1.Rows[i].Cells[3].Value.ToString().StartsWith("تخفیف"))
// {
// bed = Convert.ToDecimal(dataGridView1.Rows[i].Cells[8].Value.ToString());
// bes = Convert.ToDecimal(dataGridView1.Rows[i].Cells[9].Value.ToString());
// MandeHesab = MandeHesab + (bed - bes);
// if (MandeHesab < 0) Vaziat = "بستانکار";
// if (MandeHesab > 0) Vaziat = "بدهکار";
// if (MandeHesab == 0) Vaziat = "تسویه";
// if (MandeHesab < 0)
// {
// S = MandeHesab * (-1);
// dataGridView1.Rows[i].Cells[11].Value = S.ToString();
// }
// else
// {
// dataGridView1.Rows[i].Cells[11].Value = MandeHesab.ToString();
// }
// dataGridView1.Rows[i].Cells[10].Value = Vaziat;
// }

// }

kamiloted
یک شنبه 02 آبان 1395, 16:55 عصر
تایمر گذاشتم با 25 تا ردیف.

کد شما در 199 میلی ثانیه انجام شد.
کد من در 299 میلی ثانیه.

آیا این زمان برای 25 ردیف خوب هست یا خیر؟

ژیار رحیمی
یک شنبه 02 آبان 1395, 17:02 عصر
روش جناب حمید اصلاحیه کدهای شماست(آنچه که بعد از راهنمایی های زیاد جناب افراد شما ترجیح دادی کد شما اصلاح شود).روش شما اشتباه میباشد(گرفتن خروجی دلیل بر روشی مناسب نیست).
شما datatable رو انتساب دادی به datagrid مجدد با cast کردن سطرها و tostring کردن سلول ها نتیجه رو بدست آوردی.
چرا این محاسبه مانده رو روی datatable انجام نمیدی سپس نتیجه رو به دیتاگرید انتساب نمیدهی؟

kamiloted
یک شنبه 02 آبان 1395, 22:43 عصر
روش جناب حمید اصلاحیه کدهای شماست(آنچه که بعد از راهنمایی های زیاد جناب افراد شما ترجیح دادی کد شما اصلاح شود).روش شما اشتباه میباشد(گرفتن خروجی دلیل بر روشی مناسب نیست).
شما datatable رو انتساب دادی به datagrid مجدد با cast کردن سطرها و tostring کردن سلول ها نتیجه رو بدست آوردی.
چرا این محاسبه مانده رو روی datatable انجام نمیدی سپس نتیجه رو به دیتاگرید انتساب نمیدهی؟

ممنونم که پاسخگو هستین.
بنده دقیقا دنبال همچین روشی هستم .اما الان به علت بد قول نشدن در تحویل پروژه فعلا مجبورم با کار غیر اصولی تحویل بدم.این نرم افزار رو 3سال قبل نوشتم و دادم رفت.الان یه چند آیتم جدیدا به در خواست مشتری بهش اضافه کردم. و امروز تحویل دادم رفت.ممنونم.
و میخوام حالا این کار رو انجام بدم و به عنوان ورژن 2 برای مشتری نصب کنم.

در ضمن من از کدهای آقای Mahmoud.Afrad (http://barnamenevis.org/member.php?71297-Mahmoud-Afrad) خیلی لذت بردم. و در تلاشم که یاد بگیرم و در پروژه انجام بدم.

ممنون میشم کمکم کنید.
جناب آقای رحیمی رک بگم بنده حقیقتا مطلبی رو که شما میفرمایین رو بلد نیستم.ممنون میشم یه نمونه آموزشی برام بزارید.
سپاس

ژیار رحیمی
دوشنبه 03 آبان 1395, 01:30 صبح
نمونه مانده گیری دو ستون بدهکار و بستانکار
بجای استفاده از جدول دردیتابیس من از یک لیست در حافظه استفاده کردم

public partial class Form2 : Form
{
private List<Document> documents;
public Form2()
{
InitializeComponent();
documents=new List<Document>();
}


private void InitDoc()
{
documents.Add(new Document { Id = 1, Code = 1, Comment = "فروش فاکتور شماره 1", Debit = 200000 });
documents.Add(new Document { Id = 2, Code = 1, Comment = "فروش فاکتور شماره 2", Debit = 235000 });
documents.Add(new Document { Id = 3, Code = 1, Comment = "دریافت بابت فاکتور شماره 1", Credit = 200000 });
documents.Add(new Document { Id = 4, Code = 1, Comment = "دریافت بابت فاکتور شماره 2", Credit = 100000 });
documents.Add(new Document { Id = 5, Code = 1, Comment = "فروش فاکتور شماره 3", Debit = 200000 });
documents.Add(new Document { Id = 6, Code = 1, Comment = "دریافت بابت فاکتور شماره 2", Credit = 100000 });
documents.Add(new Document { Id = 7, Code = 1, Comment = "دریافت بابت فاکتور شماره 2", Credit = 100000 });
documents.Add(new Document { Id = 8, Code = 1, Comment = "دریافت بابت فاکتور شماره 2", Credit = 200000 });
documents.Add(new Document { Id = 9, Code = 1, Comment = "پرداخت بابت فاکتور شماره 2", Debit = 65000 });


documents.Add(new Document { Id = 10, Code = 2, Comment = "فروش فاکتور شماره 1", Debit = 500000 });
documents.Add(new Document { Id = 11, Code = 2, Comment = "فروش فاکتور شماره 2", Debit = 295000 });
documents.Add(new Document { Id = 12, Code = 2, Comment = "دریافت بابت فاکتور شماره 1", Credit = 400000 });
documents.Add(new Document { Id = 13, Code = 2, Comment = "دریافت بابت فاکتور شماره 2", Credit = 100000 });
documents.Add(new Document { Id = 14, Code = 3, Comment = "فروش فاکتور شماره 3", Debit = 200000 });


}


private void GetRemainingByCustomerCode(int Code) //customer code
{
decimal sumDebit = 0, sumCredit = 0;
dataGridView1.DataSource = documents.Where(c => c.Code == Code)
.Select(c =>
{
sumDebit += c.Debit;
sumCredit += c.Credit;
return new
{
c.Code,
c.Comment,
c.Debit,
c.Credit,
Remainnig = Math.Abs(sumDebit - sumCredit),
Nature = (sumCredit > sumDebit) ? "بس" : (sumDebit > sumCredit) ? "بد" : "تس"
};
}).ToList();
}


private void Form2_Load(object sender, EventArgs e)
{
InitDoc();
}


private void btnShowResult_Click(object sender, EventArgs e)
{
if(string.IsNullOrEmpty(txtCustomerCode.Text))retu rn;
int code;
int.TryParse(txtCustomerCode.Text, out code);
if(code<=0)return;
GetRemainingByCustomerCode(code);
}
}


public class Document
{
public int Id { get; set; }//آی دی رکورد
public int Code { get; set; }//کد شخص
public string Comment { get; set; }//توضیحات
public decimal Debit { get; set; }//ستون بدهکار
public decimal Credit { get; set; }//ستون بستانکار
}

kamiloted
دوشنبه 03 آبان 1395, 15:12 عصر
ممنونم بابت نمونه.جناب آفای
ژیار رحیمی (http://barnamenevis.org/member.php?48557-%DA%98%DB%8C%D8%A7%D8%B1-%D8%B1%D8%AD%DB%8C%D9%85%DB%8C)
http://barnamenevis.org/images/statusicon/user-offline.png

آیا
چرا این محاسبه مانده رو روی datatable انجام نمیدی سپس نتیجه رو به دیتاگرید انتساب نمیدهی؟

این چیزی که فرمودین توی نمونه هم عملی شده است؟

توضیح میدید لطفا؟؟

بنده همیشه محاسبه ای که روی سلکت دیتا تیبل انجام میدم بدین صورته:


DataTable dt3 = getdata("SELECT tbl_AnbarKala.CodeKala,tbl_SabtMahsool.Name ,MAX(tbl_SabtMahsool.Mojoodi),MAX(tbl_SabtMahsool. Mojoodi) / (tbl_SabtMahsool.TehdadFarei),SUM(tbl_AnbarKala.Vo rodi),SUM(tbl_AnbarKala.Vorodi) / (tbl_SabtMahsool.TehdadFarei),SUM(tbl_AnbarKala.Kh oroji),SUM(tbl_AnbarKala.Khoroji) / (tbl_SabtMahsool.TehdadFarei), (MAX(tbl_SabtMahsool.Mojoodi) + SUM(tbl_AnbarKala.Vorodi)) - SUM(tbl_AnbarKala.Khoroji), ((tbl_SabtMahsool.Mojoodi + SUM(tbl_AnbarKala.Vorodi)) -(SUM(tbl_AnbarKala.Khoroji))) / (tbl_SabtMahsool.TehdadFarei) " +


بعد میریزم توی دیتا گرید.آیا منظور شما بدین صورت بود؟
ممنونم

ژیار رحیمی
دوشنبه 03 آبان 1395, 19:43 عصر
برای تبدیل دیتاتیبل به لیست قبلا در تالار بحث شده خروجی دیتاتیبل رو به لیست تبدیل کن بعد از کویری Linq که در بالا گفته شد استفاده کن

kamiloted
سه شنبه 04 آبان 1395, 22:41 عصر
سلام دوستان من میخوام یه عمل به همین صورت بر روی این فیلدها پیاده کنم.

ردیف نوع سند نام کالا تعداد ورود/خروج مانده کالا

1 فاکتور خرید سویا 250 250

2 فاکتور خرید سویا 150 400

3 فاکتور فروش سویا 25 375

4 فاکتور مرجوعی فروش سویا 12 387

5 فاکتور مرجوعی خرید سویا 5 382

6 فاکتور خرید سویا 100 482

7 فاکتور فروش سویا 60 422

8 فاکتور خرید سویا 50 472

9 فاکتور فروش سویا 70 402

10 فاکتور مرجوعی فروش سویا 20 422

11 فاکتور مرجوعی خرید سویا 10 412

12 فاکتور فروش سویا 120 292



فاکتور خرید و مرجوعی فروش به عنوان ورودی
و فاکتور فروش و مرجوعی خرید به عنوان خروجی.

من ستون تعداد را دارم
میخوام با محاسبه
ورودی منهای خروجی
مانده کالا را به دست بیارم و بریزم تو ستون مانده کالا باید چکار کنم ؟؟؟
ممنونم

hosseinbarnamenevis
چهارشنبه 05 آبان 1395, 14:56 عصر
سلام
من قبلا روش هایی که دوستان گفتن رو رفتم اما در ادامه به نظر من به مشکل هایی میخورین
برای محسابه ی بدهکار یا بستانکار جالب نیست که شما بیاین روی دیتا گرید یا دیتا لیست یا هرچیز دیگه ای این کار رو انجام بدین. بهتر اینکه ستونی داخل دیتابیستون باشه و در هنگام ذخیره سند در همون لحظه وضعیت حساب محاسبه و ذخیره بشه حتی باقیمانده کالا
باقیمانده کالا در لحظه به هیچ عنوان درست نیست. محسابات سود و غیره به درستی حساب نخواهند شد

kamiloted
چهارشنبه 05 آبان 1395, 15:08 عصر
سلام
من قبلا روش هایی که دوستان گفتن رو رفتم اما در ادامه به نظر من به مشکل هایی میخورین
برای محسابه ی بدهکار یا بستانکار جالب نیست که شما بیاین روی دیتا گرید یا دیتا لیست یا هرچیز دیگه ای این کار رو انجام بدین. بهتر اینکه ستونی داخل دیتابیستون باشه و در هنگام ذخیره سند در همون لحظه وضعیت حساب محاسبه و ذخیره بشه حتی باقیمانده کالا
باقیمانده کالا در لحظه به هیچ عنوان درست نیست. محسابات سود و غیره به درستی حساب نخواهند شد

ممنونم دوست عزیز

دوست عزیز برنامه نویسان هر کدوم یه نظری میدن.
من موندم.کی درست بیان میکنه.

میشه بفرمایید چه مشکل هایی به وجود میاد.

hamid_hr
شنبه 08 آبان 1395, 09:42 صبح
ببینین به نظر من باید این محاسبات سمت کلاینت انجام بشه
یعنی توی دیتابیس نباید براش ستون در نظر بگیرین. چون مثلا شما 100 تا ثبت داشتین حالا یکی از سطر ها باید ویرایش بشه اونوقت باید همه سطر های بعد از اون نیز ویرایش بشه تا مشکلی تو اعداد و ارقام پیش نیاد. ولی وقتی در لحظه براش محاسبات انجام بدین این مشکل پیش نمیاد.

kamiloted
شنبه 08 آبان 1395, 18:35 عصر
ببینین به نظر من باید این محاسبات سمت کلاینت انجام بشه
یعنی توی دیتابیس نباید براش ستون در نظر بگیرین. چون مثلا شما 100 تا ثبت داشتین حالا یکی از سطر ها باید ویرایش بشه اونوقت باید همه سطر های بعد از اون نیز ویرایش بشه تا مشکلی تو اعداد و ارقام پیش نیاد. ولی وقتی در لحظه براش محاسبات انجام بدین این مشکل پیش نمیاد.

ممنونم
جناب hamid_hr (http://barnamenevis.org/member.php?25531-hamid_hr)

حالا شما روشی برای این کار دارین که من توی دیتاتیبل انجام بدم و زمان بارگذاری کمتر داشته باشه.

و بتونم ستون مانده کالا رو به دست بیارم؟؟؟
سپاس

hamid_hr
یک شنبه 09 آبان 1395, 09:14 صبح
خب شما اطلاعات رو از دیتابیس میخونید ویریزید تو یک دیتا تیبل دیگه؟
اون تراکنش ها رو تو ی همون دیتاتیبل انجام بدین

kamiloted
جمعه 14 آبان 1395, 00:40 صبح
سلام دوستان من میخوام یه عمل به همین صورت بر روی این فیلدها پیاده کنم.

ردیف نوع سند نام کالا تعداد ورود/خروج مانده کالا

1 فاکتور خرید سویا 250 250

2 فاکتور خرید سویا 150 400

3 فاکتور فروش سویا 25 375

4 فاکتور مرجوعی فروش سویا 12 387

5 فاکتور مرجوعی خرید سویا 5 382

6 فاکتور خرید سویا 100 482

7 فاکتور فروش سویا 60 422

8 فاکتور خرید سویا 50 472

9 فاکتور فروش سویا 70 402

10 فاکتور مرجوعی فروش سویا 20 422

11 فاکتور مرجوعی خرید سویا 10 412

12 فاکتور فروش سویا 120 292



فاکتور خرید و مرجوعی فروش به عنوان ورودی
و فاکتور فروش و مرجوعی خرید به عنوان خروجی.

من ستون تعداد را دارم
میخوام با محاسبه
ورودی منهای خروجی
مانده کالا را به دست بیارم و بریزم تو ستون مانده کالا باید چکار کنم ؟؟؟
ممنونم

دوستان دیتا گرید رو با این کد پر میکنم// چطور مانده رو به دست بیارم؟؟



DataTable dt = new DataTable();
Database db = new Database();
string Type = "فاکتور فروش";
string Type1 = "فاکتور خرید";
string Type2 = "مرجوعی فروش";
string Type3 = "مرجوعی خرید";
int MandeKala = 0;
dt = db.MySelect(" SELECT '" + Type + "' , NameClient,SerilFactoor,Anbar, ProductName, Tehdad, CostVahed, Takhfif, PasAzTakhfif,Tehdad * PasAzTakhfif,'" + MandeKala + "', Date FROM tbl_Factoor_Kharid " +
"UNION ALL " +
"SELECT '" + Type1 + "' , NameClient,codeFactoor,Anbar, ProductName, Tehdad, CostVahed, Takhfif, PasAzTakhfif,Tehdad * PasAzTakhfif,'" + MandeKala + "', Date FROM tbl_Factoor_Foroosh " +
"UNION ALL " +
"SELECT '" + Type2 + "', Name_Client , codeFactoors,Anbar, Name_Kala, Tehdad, CostVahed, Takhfif, PasAzTakhfif,Tehdad * PasAzTakhfif,'" + MandeKala + "', Date FROM tbl_Marjoei_Foroosh " +
"UNION ALL " +
"SELECT '" + Type3 + "',Client_Name, SerialFactoors, Anbar, Kala_Name, Tehdad, CostVahed, Takhfif, PasAzTakhfif,Tehdad * PasAzTakhfif,'" + MandeKala + "', Date FROM tbl_Marjoei_Kharid");


dataGridView1.DataSource = dt;

hosseinbarnamenevis
یک شنبه 16 آبان 1395, 15:54 عصر
برخلاف گفته دوست عزیزمون حتا باید ستون یا فیلد هایی رو در نظر بگیرین. تویه حسابداری همیشه هرچیزی قابلیت ویرایش رو نداره. شما میاین یه جدول موقت تولید میکنین که اسناد وارد اون میشن. زمانی که سند توسط حسابدار قطعی شد. پردازش انجام میشه . همون مانده حساب فعلی و جدید . داخل جدول مورد نظر میشینه. بدون جدول موقت هم امکان پذیره. شما اگه سندی رو ویرایش کنین . ویرایش اون سند رو بازم میشه داخل تراز ذخیره کرد. کافیه شرحشو بزنین ویرایش سند فلان. با یکم کد نویسی میشه جزئیات ویرایش رو هم داخلش قرار داد
به نظر من محاسبه زمان اجرا اشتباهه. شما فکر اینو بکنین که ممکنه تراکنش حسابتون با یه شخص خاص زیاد باشه.
کلا ازین مسایل ممکنه خیلی پیش بیاد. در زمان اجرا ممکنه رم کامپیوتر یه نفر بیش از اندازه تسط یه نرم افزار دیگه اشغال شده باشه و و و

kamiloted
یک شنبه 16 آبان 1395, 17:32 عصر
برخلاف گفته دوست عزیزمون حتا باید ستون یا فیلد هایی رو در نظر بگیرین. تویه حسابداری همیشه هرچیزی قابلیت ویرایش رو نداره. شما میاین یه جدول موقت تولید میکنین که اسناد وارد اون میشن. زمانی که سند توسط حسابدار قطعی شد. پردازش انجام میشه . همون مانده حساب فعلی و جدید . داخل جدول مورد نظر میشینه. بدون جدول موقت هم امکان پذیره. شما اگه سندی رو ویرایش کنین . ویرایش اون سند رو بازم میشه داخل تراز ذخیره کرد. کافیه شرحشو بزنین ویرایش سند فلان. با یکم کد نویسی میشه جزئیات ویرایش رو هم داخلش قرار داد
به نظر من محاسبه زمان اجرا اشتباهه. شما فکر اینو بکنین که ممکنه تراکنش حسابتون با یه شخص خاص زیاد باشه.
کلا ازین مسایل ممکنه خیلی پیش بیاد. در زمان اجرا ممکنه رم کامپیوتر یه نفر بیش از اندازه تسط یه نرم افزار دیگه اشغال شده باشه و و و

ممنونم.کلا بیخیال ایراد و غیره

من کلا تو تاپیک بالام چگونه این عملیات رو انجام بدم همین

ممنونم که وقت میزارین