PDA

View Full Version : آموزش: برنامه مدیریت انبار و فروش جهت کسب و کارهای کوچک (بنکداری)



ghasem110deh
جمعه 22 آبان 1394, 14:46 عصر
بسم الله الرحمن الرحیم
سلام به همه ...
در ابتدا از اساتید عزیز reza_ali202000 ، alibilgats ، جناب صبوحی ، استاد khokhan ، آقای آشتیانی و آقای گلبافان عزیز بخاطر راهنمایی و کمک هاشون تشکر و قدر دانی میکنم !
و از Plus که کامپوننت تاریخ طراحی ایشون و تکست باکس که آموزش یکی از کاربرای انجمن هستش (که تاپیک و اسمشون رو پیدا نکردم)
و اما بعد ...
خدمت دوستان و برنامه نویسان مبتدی (مثل خودم) هستیم با طراحی یه برنامه مدیریت انبار و فروش (جهت کسب و کارهای کوچک مثل بنکداری ها و ...) صرفا جهت تمرین و آموزش ...
امیدوارم که یه چیزی یاد بگیرید :)

مشخصات پروژه :
زبان : سی شارپ ، VS 2012
تکنولوژی : ADO
معماری : سه لایه
دیتابیس : 2012 MSSQL
ابزار گزارش : Stimul Soft 2013
کامپوننتی هم در کار نیست !

امکانات اصلی برنامه : (چون صرفا هدفم آموزش بوده خیلی روی جزئیات مانور ندادم - شاید در آینده ...)
1- تعریف شرکت (نام انبار یا ...)
2- تعریف انواع انبار - انبار - انبار مجازی (قفسه و قسمت ها مختلف انبار)
3- تعریف دسته بندی - گروه کالا - کالا (جزئیات کالا و واحد کالا)
4- ثبت و صدور فاکتور (خرید و فروش)
5- ثبت و صدور سند انبار (رسید و حواله کالا)
6- نمایش نمودار و آمار عددی میزان خرید ، فروش ، هزینه و سود حاصله ماه جاری سیستم و کل
7- نمایش میزان موجودی هر کالا (حجم ورودی ، خروجی و موجودی کل کالاها (به عدد))

امکانات جانبی :
1- تعریف کاربر و سطح دسترسی (مدیر ، انباردار ، فروشنده و تنخواه)
2- فرم لاگین (با قابلیت غیر فعال شدن پنجره ، در صورت ورود نام کاربری یا کلمه عبور برای پنج بار متوالی به مدت پنج دقیه)
3- فرم یادآوری کلمه عبور
4- فرم جستجوی پیشرفته با پروسیجر (با پارامترهای متفاوت)
5- تیره شدن فرم اصلی (داشبورد) با باز شدن پنجره های عمیلیاتی
6- پشتیبان گیری از دیتابیس (backup - restore) با ذخیره اطلاعات کاربر تهیه کننده نسخه پشتیبان . تاریخ تهیه
و ...

dll مربوط به جعبه پیغام سفارشی هم از طریق این آموزش میتونین ایجاد کنید :
http://barnamenevis.org/showthread.php?483897-%D8%AC%D8%B9%D8%A8%D9%87-%D9%BE%DB%8C%D8%BA%D8%A7%D9%85-%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C

چند تصویر از برنامه :
پنجره گزارش و برآورد (http://s3.picofile.com/file/8222516626/report.png)
پنجره ورود (http://s3.picofile.com/file/8222516192/login_lock.png)
برگ ورود و خروج کالا (http://s3.picofile.com/file/8222516392/doc_warehouse.png)
برگ فاکتور خرید و فروش (http://s3.picofile.com/file/8222516434/invoice.png)

لینک دانلود سورس کامل پروژه (http://s6.picofile.com/file/8235119200/RGF_Inventory_Bonakdar_Done.rar.html)
(http://uploadboy.com/5s70vlausxob/3287//rar)
اینم اسکریپت دیتابیس
(http://uploadboy.com/xubkg40mu7yp/3287//txt)
اینم دیتابیس
(http://uploadboy.com/29qo23jlf012/3287//rar)
پسورد : ندارد

امیدوارم به درد دوستان تازه کار بخوره :)
و اساتید هم یه نگاهی بندازن تا بتونم مشکلاتش رو تو نسخه بعدی بر طرف کنم !

دوستان عزیز لینک دانلود ستاپ برنامه (http://uploadboy.com/7ojqr6vqlgg7/3287//rar)هم اینجاست :)

*//--------------------------------------------------------

سامانه واترمیست (http://www.aparat.com/v/5fNbA)

ghasem110deh
جمعه 22 آبان 1394, 15:23 عصر
طبیعتا باید اول دیتابیس رو طراحی کنیم ...
این اسکریپت دیتابیس :
http://s6.picofile.com/file/8222516068/Bonakdar.txt.html

که می تونید از طریق کلاسی که تو این پروژه هستش ، توی sql ایجاد کنید : (باس ببخشید چون تو این برنامه بخاطر اینکه دنبال یه روش بهتر هستم نیوردمش)
http://barnamenevis.org/showthread.php?499139-%D8%AF%D8%A7%D9%86%D9%84%D9%88%D8%AF-%D8%B3%D9%88%D8%B1%D8%B3-%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D9%81%D8%B1%D9%88%D8%B4-%D9%88-%D8%B5%D8%AF%D9%88%D8%B1-%D9%81%D8%A7%DA%A9%D8%AA%D9%88%D8%B1-%D8%AA%D8%AD%D8%AA-%D8%B4%D8%A8%DA%A9%D9%87-!&p=2230143#post2230143

اینم ریلیشن دیتابیس (البته چند تا جدول دیگه وجود داره که چون ارتباطی با جداول دیگه ندارن توی ریلیشن نیست)
http://s6.picofile.com/file/8222516126/database.png

نکته : بعضیاز جداول که ممکن کاربر نام یا کد تکراری بده ، واسه جلوگیری از درج مقدار تکراری روی اون فیلد (فیلد مورد نظر) یک Index ایجاد میکنیم (از نوع Unique) مثل تصویر زیر :
http://s6.picofile.com/file/8222520700/unique_value.png

اگه کاربر مقدار تکراری توی اون فیلد وارد کنه sql خطا میده و ما تی برنامه از طریق sql exception و نامی که واسه اون ایندکس گذاشتیم ، پیغام مناسب رو به کاربر میدیم که کدوم فیلد رو مقدار تکراری وارد کرده !
در تصویر بالا اگه کاربر مقدار تکراری برای کد یا نام کالا وارد کنه ما با تشخیص استثناء ، پیغام مناسب رو برای کاربر میفرستیم :

try
{
// دستورات درج کالا در جدول مربوطه
}
catch (SqlException ex)
{
if (ex.Message.Contains("IX_Commodity_Code"))
{
Warning.ShowBox("کد کالا تکراری و در فهرست موجود است .", "کد کالا !");
Txt_Commo_Code.Focus();
}
if (ex.Message.Contains("IX_Name_Com"))
{
Warning.ShowBox("نام کالا تکراری و در فهرست موجود است .", "نام کالا !");
Txt_Commodity.Focus();
}
}


همونطور که مشاهده میکنید ، اگه فیلد کد کالا مقدار تکراری براش ارسال بشه استثناء ایجاد نام IX_Commodity_Code رو پاس میه به برنامه و ما توی برنامه مشخص کردیم که اگه کد کالا تکراری بود پیغام "کد تکراری است" رو بده و سپس فوکوس بره روی تسکت باکس کد کالا !

یه نکته دیگه ه اینکه : توی جدول های فاکتور (Invoice) و سند انبار (Document) یه فیلد به اسم Type هست که از نوع bit هستش و اگه مقدارش یک یا صفر باشه نوع فاکتور (خرید/ فروش) و نوع سند انبار (ورود کالا/ خروج کالا) رو تعیین میکنه و با توجه به این فیلد مقادیر خرید و فروش و موجودی کالا بدست میاد (یعنی از هم مجزا میشه)

ghasem110deh
جمعه 22 آبان 1394, 23:00 عصر
برای ایجاد کانکشن در لایه دیتااکسس (DAL) توی قسمت properties --> setting رفته و مثل تصویر عمل میکنیم : (البته میشه توی کانفیگ هم نوشت یا بصورت رشته)
یه کلاس ایجاد میکنیم :


using System;using System.Data.SqlClient;
using System.Data;


namespace RGF_DAL
{
public class Connection_Class
{
/// <summary>
/// کانکشن استرینگ
/// در ستینگ پروژه
/// </summary>
string ConnectionString
{
get
{
return Properties.Settings.Default.Con;
}
}
/// <summary>
/// متد جهت عملیاتهای درج ، حذف و ویرایش
/// </summary>
/// <param name="C_Type"></param>
/// <param name="C_Text"></param>
/// <param name="C_Parameters"></param>
/// <returns></returns>
public int ExecuteNoneQuery(CommandType C_Type, string C_Text, params SqlParameter[] C_Parameters)
{
SqlConnection Con = new SqlConnection(ConnectionString);
SqlCommand Com = new SqlCommand();
Com.Connection = Con;
Com.CommandType = C_Type;
Com.CommandText = C_Text;
Com.Parameters.AddRange(C_Parameters);
Con.Open();
int R_Value = Com.ExecuteNonQuery();
Con.Close();
return R_Value;
}
/// <summary>
/// متد دیتااسکالر
/// </summary>
/// <param name="C_Type"></param>
/// <param name="C_Text"></param>
/// <param name="C_Parameters"></param>
/// <returns></returns>
public object ExecuteScaler(CommandType C_Type, string C_Text, params SqlParameter[] C_Parameters)
{
SqlConnection Con = new SqlConnection(ConnectionString);
SqlCommand Com = new SqlCommand();
Com.Connection = Con;
Com.CommandType = C_Type;
Com.CommandText = C_Text;
Com.Parameters.AddRange(C_Parameters);
Con.Open();
object R_Value = Com.ExecuteNonQuery();
Con.Close();
return R_Value;
}
/// <summary>
/// متد دیتاریدر
/// </summary>
/// <param name="C_Type"></param>
/// <param name="C_Text"></param>
/// <param name="C_Parameters"></param>
/// <returns></returns>
public SqlDataReader ExecuteReader(CommandType C_Type, string C_Text, params SqlParameter[] C_Parameters)
{
SqlConnection Con = new SqlConnection(ConnectionString);
SqlCommand Com = new SqlCommand();
Com.Connection = Con;
Com.CommandType = C_Type;
Com.CommandText = C_Text;
Com.Parameters.AddRange(C_Parameters);
bool Close_Connection = false;
try
{
if (Con.State != ConnectionState.Open)
{
Close_Connection = true;
Con.Open();
}
else
{
Close_Connection = false;
}
SqlDataReader DR;
DR = Com.ExecuteReader(CommandBehavior.CloseConnection) ;
return DR;
}
catch
{
if (Close_Connection)
Con.Close();
throw;
}
}
/// <summary>
/// متد دیتاتیبل
/// </summary>
/// <param name="C_Type"></param>
/// <param name="C_Text"></param>
/// <param name="C_Parameters"></param>
/// <returns></returns>
public DataTable ExecuteDataTable(CommandType C_Type, string C_Text, params SqlParameter[] C_Parameters)
{
SqlConnection Con = new SqlConnection(ConnectionString);
SqlCommand Com = new SqlCommand();
Com.Connection = Con;
Com.CommandType = C_Type;
Com.CommandText = C_Text;
Com.Parameters.AddRange(C_Parameters);
DataTable DS = new DataTable();
SqlDataAdapter DA = new SqlDataAdapter(Com);
Con.Open();
DA.Fill(DS);
Con.Close();
return DS;
}
}
}




از این کلاس در لایه دیتااکسس برای اجرای کوئری های مورد نظر استفاده میکنیم !

ghasem110deh
شنبه 23 آبان 1394, 15:17 عصر
سلام به همه ...
بریم سراغ در اطلاعات با معماری سه لایه ، قطعا تا الان لایه های DAL و BLL رو ایجاد کردین ، تو پست قبل هم که گفتیم کلاس کانکشن استرینگ توی لایه دیتااکسس (با استفاده از ستینگ) باید ایجاد بشه ؛
و اما بعد ...

لایه دیتااکسس :


using System;
using System.Data.SqlClient;
using System.Data;


namespace RGF_DAL
{
public class Commodity_Dal : Connection_Class
{
public int Commodity(int Commodity_Code, int Group_Id, int Virtual_Warehouse_Id, string Name, string Description, string Image)
{
return ExecuteNoneQuery(CommandType.Text, "Insert Into Tbl_Commodity (Commodity_Code, Group_Id, Virtual_Warehouse_Id, Name, Description, Image) Values (@C, @G, @V, @N, @D, @I)", new SqlParameter[]
{
new SqlParameter("@C", Commodity_Code),
new SqlParameter("@G", Group_Id),
new SqlParameter("@V", Virtual_Warehouse_Id),
new SqlParameter("@N", Name),
new SqlParameter("@D", Description),
new SqlParameter("@I", Image),
});
}


public DataTable Commo_Combo()
{
return ExecuteDataTable(System.Data.CommandType.Text, "Select Id, Name From Tbl_Commodity Order By Id");
}


public SqlDataReader Full_Display()
{
return ExecuteReader(System.Data.CommandType.Text, "Select * From View_Commodity");
}


int Commo_No;
public int Commodity_No()
{
try
{
SqlDataReader DR = ExecuteReader(System.Data.CommandType.Text, "Select Count(*) From Tbl_Commodity");
if (DR.Read())
{
Commo_No = Int32.Parse(DR[0].ToString());
}
return Commo_No;
}
catch
{
return 0;
}
}
}
}




همونطور که مشاهده می کنید من چهار تا کوئری توی کد بالا داریم ، اولی که درج اطلاعات هستش (ویرایش و حذف هم همین ساختاره با این تفاوت که آیدی هم جز پارامتر هاست) ، دومی و سومی که خوندن اطلاعات جدول بانک هست (البته اینجا یکشون از ویو خونده شده) و سومی هم که شمارش یا تعداد اقلام (کالاهای تعریف شده هستش)
فکر کنم کاملا مشخص هستش که کدوم متود از کلاس کانکشن استرینگ رو واسه چه کاری استفاده کردیم (در ادامه از متدای دیگه هم استفاده میکنیم)
در ادامه باید بریم سراغ لایه بیزنس :


using RGF_DAL;
using System;
using System.Collections.Generic;
using System.Data;


namespace RGF_BLL
{
public class Commodity_Bll
{
public int _Commodity_Code { get; set; }
public string _Group { get; set; }
public string _Virtual_Warehouse { get; set; }
public string _Name { get; set; }
public string _Description { get; set; }
public string _Image { get; set; }


public static int Insert_Commodity(int Commodity_Code, int Group_Id, int Virtual_Warehouse_Id, string Name, string Description, string Image)
{
RGF_DAL.Commodity_Dal commodities = new RGF_DAL.Commodity_Dal();
int R_Value = 0;
R_Value = commodities.Commodity(Commodity_Code, Group_Id, Virtual_Warehouse_Id, Name, Description, Image);
return R_Value;
}


public DataTable Commo_No_Combo()
{
return new Commodity_Dal().Commo_Combo();
}


public static List<Commodity_Bll> Full_Show()
{
RGF_DAL.Commodity_Dal commoditytable = new RGF_DAL.Commodity_Dal();
IDataReader dr = commoditytable.Full_Display();
List<Commodity_Bll> commodityList = new List<Commodity_Bll>();
while (dr.Read())
{
Commodity_Bll commo = new Commodity_Bll();
commo._Commodity_Code = Convert.ToInt32(dr["Commodity_Code"]);
commo._Name = dr["Name"].ToString();
commo._Group = dr["Expr1"].ToString();
commo._Virtual_Warehouse = dr["Expr2"].ToString();
commo._Description = dr["Description"].ToString();
commo._Image = dr["Image"].ToString();
commodityList.Add(commo);
}
return commodityList;
}


public int Commo_No()
{
return new Commodity_Dal().Commodity_No();
}
}
}




توی لایه بیزنس یا همون بده بستون ، صرفا در اینجا داده ها رو پاس میده به لایه های دیگه و خودش خاصیت بخصوصی نداره
اما خیلی کارها میشه انجام داد که ساده ترین ش کپسوله سازی داده هاست (که خیلی نحوه پیاده سازی درستش دستم نیومده) و یه نمونه از کار با داده ها توی لایه BLL تو نمایش موجودی کالا میزارم

بعضی جاها خوندم که استفاده از List خیلی بهتر از دیتاتیبل هستش (ولی دلیل ش رو متوجه نشدم - اساتید اگه بعد از اتمام کار راهنمایی کنن ممنون میشم)
واضح که ما داده ها رو از طریق دیتاتیبل تعریف شده در دیتااکسس گرفتیم و بجای اینکه باز با دیتاتیبل پاس بدیم به لایه بالا برای نمایش به کاربر ، داده ها رو توی یک لیست قرار دادیم ... که متغیرهاش از قبل ایجاد شده و مقدار هر فیلد از دیتاتیبل رو توی متغیر مورد نظر ریختیم !

ghasem110deh
شنبه 23 آبان 1394, 21:16 عصر
اصل کار درج رو انجام دادیم (تو لایه دیتااکسس) فقط مونده که پارامترها رو با ورودی هاری کاربر پر کنیم ...
این متود واسه درج و طبق توضیحات مختصر بالا نحوه تشخیص خطا روی داده به کاربر بگیم که کدوم ورودی تکراریه

private void Insert_Commodity()
{
try
{
Commodity_Bll.Insert_Commodity(Convert.ToInt32(Txt _Commo_Code.Text), Convert.ToInt32(Cmb_Group.SelectedValue), Convert.ToInt32(Cmb_Virtual.SelectedValue), Txt_Commodity.Text.Trim(), Txt_Commo_Desc.Text.Trim(), str_selectpic);
Ok.ShowBox(" کالا با نام " + Txt_Commodity.Text + @"
ثبت شد .", "ثبت با موفقیت انجام شد !");
tc.ClearTxt(this);
}
catch (SqlException ex)
{
if (ex.Message.Contains("IX_Commodity_Code"))
{
Warning.ShowBox("کد کالا تکراری و در فهرست موجود است .", "کد کالا !");
Txt_Commo_Code.Focus();
}
if (ex.Message.Contains("IX_Name_Com"))
{
Warning.ShowBox("نام کالا تکراری و در فهرست موجود است .", "نام کالا !");
Txt_Commodity.Focus();
}
}
}


و کلید درج (بعلاوه کنترل و بررسی داده های ورودی) :

private void Btn_Commo_Insert_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(Txt_Commo_Code.Text))
{
ToolTip TT = new ToolTip();
TT.Active = true;
TT.ToolTipTitle = "کد کالا !";
TT.ToolTipIcon = ToolTipIcon.Warning;
TT.Show(string.Empty, Txt_Commo_Code, 5000);
TT.Show("کد کالا را وارد نمایید", Txt_Commo_Code);
}
else if (string.IsNullOrWhiteSpace(Txt_Commodity.Text))
{
ToolTip TT = new ToolTip();
TT.Active = true;
TT.ToolTipTitle = "نام کالا !";
TT.ToolTipIcon = ToolTipIcon.Warning;
TT.Show(string.Empty, Txt_Commodity, 5000);
TT.Show("نام کالا را وارد نمایید", Txt_Commodity);
}
else if (string.IsNullOrWhiteSpace(Cmb_Virtual.Text))
{
ToolTip TT = new ToolTip();
TT.Active = true;
TT.ToolTipTitle = " قسمت از انبار !";
TT.ToolTipIcon = ToolTipIcon.Warning;
TT.Show(string.Empty, Cmb_Virtual, 5000);
TT.Show("قسمت از انبار را انتخاب کنید", Cmb_Virtual);
}
else if (string.IsNullOrWhiteSpace(Cmb_Group.Text))
{
ToolTip TT = new ToolTip();
TT.Active = true;
TT.ToolTipTitle = "نام گروه !";
TT.ToolTipIcon = ToolTipIcon.Warning;
TT.Show(string.Empty, Cmb_Group, 5000);
TT.Show("نام گروه کالا را انتخاب کنبد", Cmb_Group);
}
else if (Txt_Commo_Code.Text != "" && Txt_Commodity.Text != "" && Cmb_Virtual.Text != "" && Cmb_Group.Text != "")
{
Frm_Commodity FC = (Frm_Commodity)Application.OpenForms["Frm_Commodity"]; // در دسترس قرار گرفتن متدهای فرم کالا
try
{
Insert_Commodity();
System.IO.File.Copy(str_path, "Data\\Image\\" + str_selectpic, true); // ذخیره عکس در پوشه مورد نظر
str_path = "";
str_selectpic = "";
Pic_Logo.Image = null;
Cmb_Virtual.ResetText();
}
catch
{
Error.ShowBox(@"مشخصات کالا ...
اتصال برنامه به دیتابیس را بررسی نمایید .", "مشخصات ذخیره نشد !");
}
}
}


همونطور که مشاهد میکنید تصویر کالا در دیتابیس ذخیره نمیشه و فقط اسم ش در دیتابیس ذخیره میشه ؛ تصویر در پوشه مورد نظر (در پوشه دیباگ) save میشه
واسه چک کردن خالی بودن فیلدهایی که نباید مقدار null بگیرن هم از بالن استفاده کردم (قشنگ تر از ارورپروایدر)

ghasem110deh
یک شنبه 24 آبان 1394, 15:00 عصر
سلام به همه :)
انشالله تا امشب توضیحات اصلی رو بدم و سورس بزارم واسه دانلود :)
و اما بعد ...

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

مورد اول (چکباکس مرا بخاطر بسپار)
توی رویداد چک شدن (منظور تیک شدن) چکباکس خیلی راحت مقادیر ورودی رو توی دو تا متغیر نام کاربری و کلمه عبور که تعریف کردیم ذخیره میکنیم :

Settings.Default.Log_Remember = true;
Settings.Default.Username = Txt_User.Text.Trim();
Settings.Default.Password = Txt_Pass.Text.Trim();
Settings.Default.Save();


و بعد توی لود_فرم درست کد رو برعکس میکنیم :

if (Settings.Default.Log_Remember == true)
{
Txt_User.Text = Settings.Default.Username;
Txt_Pass.Text = Settings.Default.Password;
}


مورد دوم (شمارنده)
کد زیر واسه تولید یه زمان سنج معکوس هستش (شمارش معکوس) :

/// <summary>
/// غیر فعال کردن فرم ورود بعد از وارد کردن اشتباه
/// کلمه عبور و نام کاربری برای پنج بار متوالی
/// </summary>
int a = 0;
int interval = 300;
void Down_Counter()
{
a++;
Settings.Default.Log_Counter = a;
Settings.Default.Save();
if (Settings.Default.Log_Counter == 5)
{
Pln_Log.Enabled = false;
User_Per.ShowBox(@"کاربر گرامی ، شما پنج بار متوالی نام کاربری
و کلمه عبور را اشتباه وارد کردید .", "عدم مجوز دسترسی !");
var startTime = DateTime.Now;
T_Log.Tick += (obj, args) => Lbl_Countdown.Text = (TimeSpan.FromMinutes(5) - (DateTime.Now - startTime)).ToString("hh\\:mm\\:ss") + @"
پنجره ورود بمدت پنج دقیقه غیر فعال می باشد !";
T_Log.Start();
Lbl_Countdown.ForeColor = Color.Black;
}
}


و تایمر :

/// <summary>
/// شمارنده معکوس و فعال شدن فرم ورود بعد از پنج دقیه
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void T_Log_Tick(object sender, EventArgs e)
{
interval--;
if (interval == 0)
{
T_Log.Stop();
Pln_Log.Enabled = true;
a = 0;
interval = 300;
Lbl_Countdown.ForeColor = Color.Gainsboro;
}
}


همونطور که مشاهده میکنید گفتیم با هر بار که روی دکمه ورود کلیک شده متغیر a یک واحد افزایش پیدا کنه و در متغیر مربوطه در ستینگ ذخیره بشه و اگر این متغیر حاوی 4 بود و کاربر بازم روی فرم ورود کلیک کرد ...
پنجره ورود غیر فعال شه (در واقع پنل) و شمارش معکوس (که توی لیبل نمایش داده میشه) شروع به مارش کنه

نکته : متود Down_Counter باید در رویداد catch دکمه ورود باشه ، یعنی وقتی اطلاعات ورود اشتباه بود و پیغام خطا صادر شد !

مورد سوم (چک کردن فعال بودن برنامه)
توی لایه بیزنس (BLL) سه تا کلاس داریم (تو پست بعد میگم) که توی رویداد لود_فرم پنجره اصلی برنامه کار چک کردن برنامه رو بر عهده داره (خیلی ساده هستش - به قول دوست گلم آقا مازیار امنیت تو برنامه های بر پایه Net. خنده داره)
واسه همین دنبال قوی کردن قفل نرم افزار تو سی شارپ نیستم (البته بدم نمیاد یکی یه قفل خوب بهم بده):قهقهه:
حالا تو فرم اصلی برنامه :

private void Expire() // فعالسازی برنامه
{
if (Properties.Settings.Default.Reg_Check == true)
{
Lbl_Details.Text = String.Empty;
MN_Active.Enabled = false;
MN_Active.Text = "نرم افزار ثبت شده است";
}
else
{
new Serial().Trial_Expired();
}
}


کد کاملا ساده و مشخصه ... میگه اگه متغیر مقدارش true بود برنامه فعاله در غیر اینصورت مراجعه بشه به کلاس Serial (پایین توضیح میدم)

ghasem110deh
یک شنبه 24 آبان 1394, 15:30 عصر
بالا گفتیم که توی لایه BLL سه تا کلاس داریم که مربوط به روال فعالسازی برنامه و چک کردن برنامه هستن :

کلاس اول (information)
تو این کلاس اطلاعات سخت افزاری سیستم رو میخونیم :


using System;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Management;


namespace RGF_BLL
{
public class Information_Bll
{
/// <summary>
/// متد تبدیل تاریخ میلادی به شمسی
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public string GetPersianDate(DateTime date)
{
PersianCalendar persianCalendar = new PersianCalendar();
int year = persianCalendar.GetYear(date);
int month = persianCalendar.GetMonth(date);
int day = persianCalendar.GetDayOfMonth(date);
return string.Format("{0:0000}/{1:00}/{2:00}", year, month, day);
}


/// <summary>
/// خواندن سریال سی پی یو
/// </summary>
/// <returns></returns>
public static string Processor_SR()
{
ManagementObjectCollection MOC = null;
ManagementObjectSearcher Choice = new ManagementObjectSearcher("Select * From Win32_processor");
MOC = Choice.Get();
string Id = "";
foreach (ManagementObject No in MOC)
{
Id = No["ProcessorID"].ToString();
}
return Id;
}


/// <summary>
/// خواند سریال مادربورد
/// </summary>
/// <returns></returns>
public static string MainBoard_SR()
{
ManagementObjectSearcher Choice = new ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard");
ManagementObjectCollection MOC = Choice.Get();
string MDB = "";
foreach (ManagementObject No in MOC)
{
MDB = (string)No["SerialNumber"];
}
return MDB;
}
}
}



یه متود هم هست که واسه تبدیل تاریخ میلادی به شمسی هستش که در نمایش تاریخ بصورت شمسی در دیتاگریدویو استفاده میشه !

کلاس دوم (Cryptor)
روش کدگذاری سریال های خونده شده :

using System;
using System.Text;
using System.Security.Cryptography;
using System.Configuration;


namespace RGF_BLL
{
public class Cryptor
{
public static string Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key ));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
}
}




مشخصه که باید کد زیر باید به کانفیگ برنامه اضافه بشه (توی سورس هست)

// کد زیر به فایل کانفیگ اضافه شود
// <appSettings>
// <add key="SecurityKey" value="Syed Moshiur Murshed"/>
// </appSettings>


و کلاس سوم که سریال های بدست اومده رو کد میکنه و شرط اصلی برنامه جهت چک کردن فعال یا منقضی شدن برنامه هستش (که خیلی هم ساده هست ش)

using RGF_UI;
using System.Windows.Forms;


namespace RGF_BLL
{
public class Serial
{
Commodity_Bll Commo_Count = new Commodity_Bll();
Invoice_Bll Inv_Count = new Invoice_Bll();
string CP = Information_Bll.Processor_SR();
string MDB = Information_Bll.MainBoard_SR();
string Serial_Hash;


/// <summary>
/// کدگذاری رشته حاوی سریال سی پی یو و مادربورد
/// </summary>
/// <returns></returns>
public string SN_Code()
{
string Serial_Info = CP + MDB;
if (Serial_Info != "")
{
Serial_Hash = Cryptor.Encrypt(Serial_Info, true);
}
else
{
Warning.ShowBox(@"عدم خواندن اطلاعات سخت افزاری رایانه !
لطفا با واحد پشتیبانی تماس حاصل فرمایید .", "هشدار");
}
return Serial_Hash;
}


/// <summary>
/// چک کردن تعداد سطرهای درج شده در جدول اصلی دیتابیس
/// </summary>
public void Trial_Expired()
{
int Quantity = Commo_Count.Commo_No() + Inv_Count.Invoice_No();
if (Quantity >= 20)
{
User_Per.ShowBox(@"شما از نسخه ثبت نشده استفاده می کنید ...
نرم افزار منقضی و غیر فعال شده است !", "نسخه ثبت نشده");
}
}
}
}



مشخصه که با دو پارامتر Commo_Count.Commo_No + Inv_Count.Invoice_No که باید در لایه DAL تعریف شده باشه و کارش گرفتن تعداد فاکتورها و کالاهای ثبت شده هست ... که اگه حاصل جمع موارد درج شده تو این دو تا جدول از بیست بالاتر بره ، در واقع برنامه منقضی میشه

ghasem110deh
یک شنبه 24 آبان 1394, 16:06 عصر
تو این فرم سریال های خونده شده به کاربر نمایش داده میشه
کاربر کد رو به شما میده و کد ثبت رو میگیره و وارد میکنه ... کد دریافتی در واقع همون سریالی هست ش که کاربر به شما و شما بهمون صورت که توی برنامه سریال رو کد کردین ، سریال سیستم کاربر هم کد میکنید و بش میدین
و برنامه هم که سریال رو خونده و یه نسخه ش رو کد کرده ، با کدی که کاربر وارد میکنه ، چک میکنه و اگه برابر بود برنامه ثبت میشه در غیر اینصورت پیغام میده
(نحوه کد گذاری هم که بالا تو کلاس cryptor هست ش از الگوریتم MD5 استفاده میکنه)

کدهای پنجره فعالسازی کردن برنامه : (ظاهرا به این روش کد تلفنی یا یه همچین چیزی میگن)

using System;
using System.Drawing;
using RGF_UI;
using RGF_BLL;
using RGF_Inventory_Bonakdar.Properties;
using System.Windows.Forms;


namespace RGF_Inventory_Bonakdar
{
public partial class Frm_Reg : Form
{
string Cpu, Mboard;
Serial SR = new Serial();


public Frm_Reg()
{
InitializeComponent();
}


private void Read_Info()
{
Cpu = Information_Bll.Processor_SR();
Mboard = Information_Bll.MainBoard_SR();
Txt_Reg.Text = Cpu + Mboard;
}


private void Reg_Check()
{
if (Settings.Default.Reg_Check == false)
{
Read_Info();
}
}


private void Frm_Reg_Load(object sender, EventArgs e)
{
Wait.ShowLoadingScreen(this);
try
{
Reg_Check();
}
catch
{
Warning.ShowBox("عدم خواندن اطلاعات سخت افزاری","هشدار");
}
Wait.CloseLoadingScreen();
this.Activate();
}


private void Btn_Reg_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(Txt_Code.Text))
{
ToolTip TT = new ToolTip();
TT.Active = true;
TT.ToolTipTitle = "سریال ثبت !";
TT.ToolTipIcon = ToolTipIcon.Warning;
TT.Show(string.Empty, Txt_Code, 5000);
TT.Show("سریال ثبت را وارد نمایید", Txt_Code);
}
else
{
try
{
if (Txt_Code.Text.Trim() == SR.SN_Code()) // اگر سریال کدگذاری شده و کد ورودی برابر بود
{
Settings.Default.Reg_Check = true; // مقدار متغیر ترو شده
Settings.Default.Save(); // ذخیره شود
Ok.ShowBox(@"با تشکر ...
نرم افزار ثبت و محدودیت استفاده رفع شد ! .", "انجام شد");
}
else
{
Warning.ShowBox(@"کد وارد شده صحیح نمی باشد ...
جهت دریافت کد با واحد پشتیبانی تماس حاصل فرمایید .", "هشدار");
Application.ExitThread();
}
}
catch
{
Error.ShowBox(@"خطا در ثبت نرم افزار ...
با واحد پشتیبانی تماس حاصل فرمایید .", "خطا");
Application.ExitThread();
}
}
}
}
}


فکر نکنم نیاز به توضیح خاصی باشه ... اگه کدها برابر باشن متغیر مربوطه توی ستینگ true میشه و اصطلاحا برنامه فعال میشه !
و دستوراتی که توی لود_فرم پنجره اصلی چک میشه و اگه متغیر true بود گزینه فعالسازی توی منوی اصلی غیر فعال میشه و متن ش به "نرم افزار ثبت شده" تغییر میکنه

ebrahim.rayatparvar
یک شنبه 24 آبان 1394, 17:43 عصر
پروسیجر؟؟:ناراحت:
در کل عالی :تشویق:

ghasem110deh
یک شنبه 24 آبان 1394, 18:39 عصر
پروسیجر؟؟:ناراحت:
در کل عالی :تشویق:

ممنون :)
فعالا بیخیال پروسیجر شدم !

ghasem110deh
یک شنبه 24 آبان 1394, 18:45 عصر
واسه اینکار یه کلاس ایجاد میکنیم که از form ارث بری کنه : (در اینجا MaskedDialog)


using System;
using System.Windows.Forms;


namespace RGF_Inventory_Bonakdar
{
public partial class MaskedDialog : Form
{
private static MaskedDialog mask;
private static Form frmContainer;
private Form ucDialog;


private MaskedDialog(Form parent, Form ucDialog)
{
this.ucDialog = ucDialog;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = System.Drawing.Color.Black;
this.DoubleBuffered = true;
this.Opacity = 0.30;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.Size = parent.ClientSize;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
parent.Move += AdjustPosition;
parent.SizeChanged += AdjustPosition;
}


private void AdjustPosition(object sender, EventArgs e)
{
Form parent = sender as Form;
this.Location = parent.PointToScreen(System.Drawing.Point.Empty);
this.ClientSize = parent.ClientSize;
}


public static DialogResult ShowDialog(Form parent, Form dialog)
{
mask = new MaskedDialog(parent, dialog);
frmContainer = dialog;
frmContainer.ShowInTaskbar = false;
frmContainer.StartPosition = FormStartPosition.CenterParent;
frmContainer.Height = dialog.Height;
frmContainer.Width = dialog.Width;
mask.MdiParent = parent.MdiParent;
mask.Show();
DialogResult result = frmContainer.ShowDialog(mask);
frmContainer.Close();
mask.Close();
return result;
}


public static void CloseDialog()
{
if (frmContainer != null)
{
frmContainer.Close();
}
}
}
}




اینطور هم ازش استفاده میکنیم :


Frm_Invoice FI = new Frm_Invoice();
MaskedDialog.ShowDialog(this, FI);

winner1
یک شنبه 24 آبان 1394, 19:30 عصر
لطفا برنام رو ستاپ کن لینک بده تا بین مردم عادی شیر بزنم کارت نتیجش به همینه

ghasem110deh
یک شنبه 24 آبان 1394, 19:49 عصر
لطفا برنام رو ستاپ کن لینک بده تا بین مردم عادی شیر بزنم کارت نتیجش به همینه
دارم آمادش میکنم ...
یکی دو تا گزارش دیگه مونده !

ghasem110deh
یک شنبه 24 آبان 1394, 20:01 عصر
یه فرم ایجاد کنید واسه فرم انتظار : (اینجا Wait)

using System;
using System.Windows.Forms;
using System.Threading;
using System.Drawing;


namespace RGF_Inventory_Bonakdar
{
public partial class Wait : Form
{
private static Thread _LoadingScreenThread;
private static Wait _ls;
private static bool _shown = false;
private static Form _parent;


public Wait()
{
InitializeComponent();
}


public static void ShowLoadingScreen(Form parent)
{
_parent = parent;
if (_LoadingScreenThread == null)
{
_LoadingScreenThread = new Thread(new ThreadStart(DoShowLoadingScreen));
_LoadingScreenThread.SetApartmentState(ApartmentSt ate.STA);
_LoadingScreenThread.IsBackground = true;
_LoadingScreenThread.Start();
}
}


public static void CloseLoadingScreen()
{
System.Threading.Thread.Sleep(250);
if (_ls != null && _ls.InvokeRequired)
{
_ls.Invoke(new MethodInvoker(CloseLoadingScreen));
}
else
{
if (_shown)
{
_shown = false;
Application.ExitThread();
}
if (_LoadingScreenThread != null) _LoadingScreenThread.Interrupt();


try
{
_ls.Close();
_ls.Dispose();
}
catch
{}
_LoadingScreenThread = null;
}
}


private static void DoShowLoadingScreen()
{
_ls = new Wait();
_ls.Wait_Progress.IsRunning = true;
_ls.ShowDialog();
}


private void Wait_Load(object sender, EventArgs e)
{
this.Activate();
}
}
}




اینطوری هم استفاده میشه :


Wait.ShowLoadingScreen(this);
try
{
// دستورات مورد نظر یا باز کردن فرم و ...
}
catch { }
Wait.CloseLoadingScreen();
this.Activate();

ghasem110deh
دوشنبه 25 آبان 1394, 09:32 صبح
سلام به همه ...
واسه ارسال مقادیر فاکتور به استیمول و تهیه گزارش نیاز به ایجاد یک دیتاتیبل داریم :

private DataTable Add_Order = new DataTable(); // ایجاد دیتاتیبل جهت وارد کردن مقادیر به دیتاگریدویو

public Frm_Invoice()
{
InitializeComponent();
initialiseTable(this.Add_Order); // اضافه کردن سفارشات به دیتاگریدویو
Dgv_Order.DataSource = this.Add_Order;
}


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

/// <summary>
/// ایجاد دیتاتیبل جهت درج سفارشات در دیتاگریدویو
/// </summary>
/// <param name="table"></param>
private void initialiseTable(DataTable table)
{
table.Columns.Add(new DataColumn("Invoice_Id"));
table.Columns.Add(new DataColumn("Commodity_Id"));
table.Columns.Add(new DataColumn("Commodity"));
table.Columns.Add(new DataColumn("Quantity"));
table.Columns.Add(new DataColumn("Price"));
table.Columns.Add(new DataColumn("Sum"));
}


و ریختن مقادیر در ستون مورد نظر :

Dgv_Order.Columns["Invoice_Id"].HeaderText = "شماره فاکتور";
Dgv_Order.Columns["Invoice_Id"].Visible = false;
Dgv_Order.Columns["Commodity_Id"].HeaderText = "شماره کالا";
Dgv_Order.Columns["Commodity_Id"].Width = 120;
Dgv_Order.Columns["Commodity"].HeaderText = "نام کالا";
Dgv_Order.Columns["Commodity"].Width = 320;
Dgv_Order.Columns["Quantity"].HeaderText = "تعداد";
Dgv_Order.Columns["Quantity"].Width = 100;
Dgv_Order.Columns["Price"].HeaderText = "قیمت واحد";
Dgv_Order.Columns["Price"].Width = 230;
Dgv_Order.Columns["Sum"].HeaderText = "جمع سطر به ریال";
Dgv_Order.Columns["Sum"].Width = 150;


و حالا ارسال داده ها به استیمول سافت جهت چاپ فاکتور : (دیتاتیبل و تکست باکس ها)

void Invoice_Report()
{
DataTable table = new DataTable("Orders_Rows");
foreach (DataGridViewColumn column in Dgv_Order.Columns)
table.Columns.Add(column.Name, typeof(string));
for (int i = 0; i < Dgv_Order.Rows.Count; i++)
{
table.Rows.Add();
for (int j = 0; j < Dgv_Order.Columns.Count; j++)
{
table.Rows[i][j] = Dgv_Order[j, i].Value;
}
}
DataTable textable = new DataTable("Invoice_Text");
DataColumn Customer = new DataColumn("Customer", typeof(string));
DataColumn Type = new DataColumn("Type", typeof(string));
DataColumn Dat = new DataColumn("Date", typeof(string));
textable.Columns.AddRange(new DataColumn[] { Customer, Type, Dat });
DataRow Dr = textable.NewRow();
Dr[0] = Cmb_Person.Text;
Dr[1] = Cmb_Type.Text;
Dr[2] = Dte_Invoice.GetText("yyyy/MM/dd");
textable.Rows.Add(Dr);
DataSet Ds = new DataSet();
Ds.Tables.Add(table);
Stimulsoft.Report.StiReport Report_Sti = new Stimulsoft.Report.StiReport();
Report_Sti.Load(System.Windows.Forms.Application.S tartupPath + @"\Data\Invoice.mrt");
Report_Sti.RegData(table);
Report_Sti.RegData(textable);
Report_Sti.Dictionary.Variables["Name"].Value = Header.Invoice_Header().Rows[0]["Name"].ToString();
Report_Sti.Dictionary.Variables["Phone_No"].Value = Header.Invoice_Header().Rows[0]["Phone_no"].ToString();
Report_Sti.Dictionary.Variables["City"].Value = Header.Invoice_Header().Rows[0]["City"].ToString();
Report_Sti.Dictionary.Variables["Address"].Value = Header.Invoice_Header().Rows[0]["Address"].ToString();
Image bmp = null;
System.IO.FileStream stream = null;
string fileName = (Application.StartupPath + @"\Data\Logo\1.png");
stream = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
byte[] buf = new byte[stream.Length];
stream.Read(buf, 0, buf.Length);
bmp = Image.FromStream(new System.IO.MemoryStream(buf));
(Report_Sti.GetComponentByName("Logo") as StiImage).Image = bmp;
Report_Sti.ReportName = "صدور فاکتور";
Report_Sti.Compile();
// Report_Sti.Design();
Report_Sti.Show();
}


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

ghasem110deh
دوشنبه 25 آبان 1394, 09:48 صبح
جستجوی پیشرفته (که البته هنوز جا واسه کار داره ...)
مثلا نتونستم توی معماری سه لایه پیادش کنم یا اینکه مثل جستجوی بر حسب یک فیلد نتونستم بهش حالی کنم که اگه یک حرف هم جستجو شد مشابه رو نشون بده :)
واسه جستجو بر اساس چند فیلد به پروسیجر زیر نیاز داریم :

USE [Bonakdar_DB]
GO
/****** Object: StoredProcedure [dbo].[SP_AdvanceSearch] Script Date: 25/08/1394 10:16:01 ق.ظ ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_AdvanceSearch]
(
@Code int,
@Name nvarchar(50)= null,
@Warehouse nvarchar(50)= null,
@Category nvarchar(50) = null,
@Group nvarchar(50) = null,
@OrderBy varchar(5) = null,
@OrderBy_Two varchar(5) = null
)
AS
BEGIN
DECLARE @Asc varchar(5) = @OrderBy
DECLARE @Asc_Two varchar(5) = @OrderBy_Two
SELECT * FROM [dbo].[View_Full_Commodity]
WHERE
(Name LIKE COALESCE(N''+@Name+'', Name)
AND Commodity_Code = COALESCE(@Code, Commodity_Code)
AND Expr1 LIKE COALESCE(N''+@Warehouse+'', Expr1)
AND Expr3 LIKE COALESCE(N''+@Category+'', Expr3)
AND Expr4 LIKE COALESCE(N''+@Group+'', Expr4)
) ORDER BY CASE WHEN @Asc = 'ASC' THEN Expr1 END ASC,
CASE WHEN @Asc_Two = 'ASC' THEN Expr3 END ASC
END






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

Tick_Order_By();
SqlCommand cmd = new SqlCommand("SP_AdvanceSearch", Con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Code", Txt_Code.Text.Trim() != "" ? (object)Convert.ToInt32(Txt_Code.Text) : DBNull.Value);
cmd.Parameters.AddWithValue("@Name", Txt_Commodity.Text.Trim() != "" ? (object)Txt_Commodity.Text : DBNull.Value);
cmd.Parameters.AddWithValue("@Warehouse", Cmb_Ware.Text.Trim() != "" ? (object)Cmb_Ware.Text : DBNull.Value);
cmd.Parameters.AddWithValue("@Category", Cmb_Cate.Text.Trim() != "" ? (object)Cmb_Cate.Text : DBNull.Value);
cmd.Parameters.AddWithValue("@Group", Cmb_Group.Text.Trim() != "" ? (object)Cmb_Group.Text : DBNull.Value);
cmd.Parameters.AddWithValue("@OrderBy", Order_Warehouse != "" ? (object)Order_Warehouse : DBNull.Value);
cmd.Parameters.AddWithValue("@OrderBy_Two", Order_Category != "" ? (object)Order_Category : DBNull.Value);
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.Fill(dt);
Dgv_Commo.DataSource = dt;
Lbl_Result.Text = "تعداد اقلام یافته شده : " + (Dgv_Commo.Rows.Count).ToString("n0") + " قلم ";


متودی که در خط اول هست واسه تعیین ترتیب نمایش هست (سعودی/نزولی) که توسط دو تا رادیو باتون مشخص میشه بصورت زیر :

void Tick_Order_By()
{
if (Rdb_Warehouse.Checked == true)
Order_Warehouse = "ASC";
if (Rdb_Category.Checked == true)
Order_Category = "ASC";
}


و خط آخر هم واسه نمایش تعداد سطرهای یافته شده و نمایش توی لیبل هست !

ghasem110deh
دوشنبه 25 آبان 1394, 10:02 صبح
بدست آوردن موجودی کالا از جدول سند ورود/ خروج کالا با استفاده از پروسیجر زیر :

USE [Bonakdar_DB]
GO
/****** Object: StoredProcedure [dbo].[SP_Inventory] Script Date: 25/08/1394 10:26:21 ق.ظ ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_Inventory]
AS
BEGIN
select Tbl_commodity.id, Tbl_commodity.name,
sum(case when Tbl_Document.type_bool=0
then (ISNULL( Tbl_Document_commodity.quantity,0)*(-1))
else (ISNULL( Tbl_Document_commodity.quantity,0)*(1)) end) AS count
from Tbl_Document,Tbl_Document_commodity,Tbl_commodity
where Tbl_Document.id=Tbl_Document_commodity.document_id and Tbl_Document_commodity.commodity_id=Tbl_commodity. id
group by Tbl_commodity.id,Tbl_commodity.name
ORDER BY Tbl_commodity.id
END




در معاری برنامه (لایه دیتااکسس و بیزنس) یه کلاس هست به اسم (Usable) که بیشتر موارد محاسبه و حساب کتاب خرید/ فروش و ... ت.ی این کلاس اورده شده
مثل همین موجودی کالا
توی لایه دیتا اکسس :

/// <summary>
/// فهرست موجودی کالا
/// </summary>
/// <returns></returns>
public DataTable Inventory_Commodity()
{
return ExecuteDataTable(CommandType.StoredProcedure, "SP_Inventory");
}


تا اینجا تمام کالا ها رو با موجودی شون خوندیم ولی میخوایم کالا هایی که مثلا تعداد موجودی رو به اتمام هست رو نشون بدیم
اگه یادتون باشه بالتر گفتیم که توی لایه بیزنس میشه کارای زیادی با داده ها انجام داد (که این یه نمونه ساده ش هست) ...
توی لایه بیزنس :

/// <summary>
/// فهرست کالاهای با موجودی کمتر از 10
/// </summary>
/// <returns></returns>
public DataView Inventory_Commodity_Down()
{
DataTable DT = new Usable_Dal().Inventory_Commodity();
DataView DW = new DataView(DT);
DW.RowFilter = "count <" + 10;
return DW;
}


مشخصه دیگه ...
دیتاتیبلی که از لایه دیتااکسس گرفته شده رو ریختیم توی یه دیتاویو و اونوقت فیلترش کردیم !
بر اساس فیلد موجودی که مقدارش کمتر از 10 باشه و بصورت زیر هم تو دیتاگریدویو نمایش دادیم :

Dgv_Down_Commodity.DataSource = new Usable_Bll().Inventory_Commodity_Down();

ghasem110deh
دوشنبه 25 آبان 1394, 10:07 صبح
دوستان گرامی !
لینک دانلود سورس پروژه در پست اول قرار گرفت ...
------------------------------------------------------
سوالی ، نظری و ... بود در خدمت هستم (البته اگه بلد باشم جواب رو)

از اساتید عزیز دوباره تشکر میکنم ؛
و امیدوارم نقاط ضعف برنامه رو گوشزد کنن و راهنمایی هاشون از بنده و دیگران دریغ نکنن !

با تشکر

sg.programmer
دوشنبه 25 آبان 1394, 15:06 عصر
جای تشکر داره و عالی هست - تست میکنم و اطلاع میدم

alibilgats
چهارشنبه 27 آبان 1394, 00:06 صبح
سلام به هه دوستان مخصوصا ghasem110deh (http://barnamenevis.org/member.php?330388-ghasem110deh) عزیز که زحمت میکشن و حاصل زحماتشو بدون چشم داشتی در اختیار بقیه دوستان قرار میدن.
منم به نوبه خودم ازت تشکر میکنم.

من برنامه تو رو تا امروز یعنی 26 آبان 94 دانلود کردم و تا حدودی بررسی کردم. یه سری نکات به ذهنم اومد که میخوام بگم.

اول اینکه تبریک میگم بخاطر ظاهر برنامت چون تونستی بدون کامپوننت خاصی ظاهر قابل قبول و سبکی رو ارائه بدی.:چشمک:

مسله ای که قبل از هر چیز به چشمم اومد اینبود که برنامت Splash نداره! و مستقیم بعد از اجرا میره توی فرم لاگین! Splash Form علاوه بر زیبایی کاربرد مهم دیگه ای هم داره و اون اینه که شما توی فرم Splash میتونی اتصال مربوط به بانک اطلاعاتیت رو بررسی کنی و درصورتی که مشکلی وجود داشت تصمیم گیری کنی!
برای مثال من برنامه تو رو قبل اینکه Connection String رو تنظیم کنم اجرا کردم و وارد فرم لاگین شدم و نام کاربری و کلمه عبور رو زدم! بعدش بهم اخطار داد رمزت اشتباهه! درحالی که اصلا اتصال به بانک اطلاعاتی در کار نبود!!!

یکی دیگه از مسائلی که برام جالب بود این بود که تو تفکیکی بین خطای عدم اتصال به بانک اطلاعاتی و اشتباه بودن کد کاربری یا رمز تفکیکی قایل نشدی!!!:متعجب:

از مسائل مهم دیگه که باید بگم اینه که تو چرا اومدی اول فرم اصلی رو اجرا میکنی و بعدش داخلش میای فرم لاگین رو باز میکنی! شاید بیشتر بخاطر اینه که گزارشات فرم اصلی رو بصورت thread استخراج میکنی! ولی به نظرم کار اشتباهیه! چون همون قضیه نبودن بانک اطلاعاتی همینجا بازم دردسرساز خواهد شد! برای مثال من بعد باز شدن فرم لاگین انصراف رو زدم و چند ثانیه طول کشید تا برنامه بسته بشه! و یه سری خطاهای مختلف بروز میکنه! البته این موضوع بیشتر سلیقه ای هستش! :لبخند:

در مورد مرا بخاطر بسپار توی فرم لاگین که حسابی اشتباه کردی! اصولا توی نرم افزارهای ویندوزی منظور از مرا بخاطر بسپار فقط کد کاربری هستش و کاربر باید هر دفعه رمز عبور رو وارد کنه! ولی شما یه اشتباه بزرگ کردی! و اونم اینه که رمز رو هم بصورت setting ذخیره میکنی! اینطوری با دوتا کلیک میشه رمز رو بیرون کشید!! حالا اون به کنار! فرض کن من الان اومدم وارد سیستم شدم و منو بخ خاطر سپرده! حالا یکی دیگه بیاد و برنامه رو اجرا کنه و اون علامت چشم رو بزنه چی میشه!!!!!:متعجب::متعجب::متعجب:
و این اشتباه بزرگ رو توی بحث فعالسازی برنامه هم انجام دادی!:متعجب: این نکته رو یادمه من قبلنا هم بهت اخطار داده بودم!!! با این روشی که تو انجام دادی خیلی راحت میشه برنامتو کرک کرد!!

در مورد یادآوری کلمه عبور هم یه سوالی ذهنمو درگیر کرد! :متفکر:
توی اینجور برنامه ها معمولا مدیر سیستم کاربران رو تعریف میکنه! و اگر یکی از کاربران رمز یادش بره خیلی راحت از مدیر سیستم میخواد که رمزشو reset کنه! و خیلی نیازی به یادآوری کلمه عبور احساس نمیشه! و جالب اینجاس که توی برنامه تو سوال و جواب امنیتی بقیه کاربران رو هم مدیر باید وارد کنه که یخورده خنده دار به نظر میاد! چون این بخش جزو خصوصی ترین مشخصات کاربره که حتی مدیر هم نباید بتونه ببینه!:لبخند:

و اینکه توی برنامت من جایی رو واسه تغییر رمز کاربر نتونستم پیدا کنم! مثلا بیاد بپرسه رمز قبلیت چیه و رمز جدید رو از کاربر بگیره و تغییر بده!

یا اینکه برای یه کاربر فیلد فعال بودن یا همون مجاز بودن برای ورود به برنامه رو بذاری تا در مواقع نیاز بشه یه کاربر رو غیر فعال کرد چون اصولا حذف کاربر تعریف شده صحیح نیست!

یا اینکه همیشه توی سیستم باید یه کاربر admin داشته باشی که نشه حذفش کرد و یا محدودش کرد بلکه فقط رمزش رو بشه عوض کرد! برای مثال الان من وارد برنامه شدم و خیلی راحت همه کاربران رو حذف کردم و از برنامه خارج شدم!! الان چطوری دوباره وارد سیستم بشم!!!:قهقهه::متعجب:

در مورد منوها هم یه تجدید نظر بکن! چون به ظاهر کلی برنامه نمیاد! یه آیکنی چیزی براشون بذار!

فعلا تا همین حد بررسی کردم! البته در مورد کد نویسیت هم یه سری مسایل بود مخصوصا بانک اطلاعاتیت که انشالا اگر عمری بود و توسط دوست عزیزم ghasem110deh (http://barnamenevis.org/member.php?330388-ghasem110deh) ترور نشدم حتما میگم:لبخند:

ghasem110deh
چهارشنبه 27 آبان 1394, 01:53 صبح
سلام علی آقای عزیز :)
اختیار دارین ، شما استاد ما هستین ؛
----------------------------------------


مسله ای که قبل از هر چیز به چشمم اومد اینبود که برنامت Splash نداره! و مستقیم بعد از اجرا میره توی فرم لاگین! Splash Form علاوه بر زیبایی کاربرد مهم دیگه ای هم داره و اون اینه که شما توی فرم Splash میتونی اتصال مربوط به بانک اطلاعاتیت رو بررسی کنی و درصورتی که مشکلی وجود داشت تصمیم گیری کنی!
برای مثال من برنامه تو رو قبل اینکه Connection String رو تنظیم کنم اجرا کردم و وارد فرم لاگین شدم و نام کاربری و کلمه عبور رو زدم! بعدش بهم اخطار داد رمزت اشتباهه! درحالی که اصلا اتصال به بانک اطلاعاتی در کار نبود!!!


یکی دیگه از مسائلی که برام جالب بود این بود که تو تفکیکی بین خطای عدم اتصال به بانک اطلاعاتی و اشتباه بودن کد کاربری یا رمز تفکیکی قایل نشدی!!!


از مسائل مهم دیگه که باید بگم اینه که تو چرا اومدی اول فرم اصلی رو اجرا میکنی و بعدش داخلش میای فرم لاگین رو باز میکنی! شاید بیشتر بخاطر اینه که گزارشات فرم اصلی رو بصورت thread استخراج میکنی! ولی به نظرم کار اشتباهیه! چون همون قضیه نبودن بانک اطلاعاتی همینجا بازم دردسرساز خواهد شد! برای مثال من بعد باز شدن فرم لاگین انصراف رو زدم و چند ثانیه طول کشید تا برنامه بسته بشه! و یه سری خطاهای مختلف بروز میکنه! البته این موضوع بیشتر سلیقه ای هستش!


در مورد یادآوری کلمه عبور هم یه سوالی ذهنمو درگیر کرد!
توی اینجور برنامه ها معمولا مدیر سیستم کاربران رو تعریف میکنه! و اگر یکی از کاربران رمز یادش بره خیلی راحت از مدیر سیستم میخواد که رمزشو reset کنه! و خیلی نیازی به یادآوری کلمه عبور احساس نمیشه! و جالب اینجاس که توی برنامه تو سوال و جواب امنیتی بقیه کاربران رو هم مدیر باید وارد کنه که یخورده خنده دار به نظر میاد! چون این بخش جزو خصوصی ترین مشخصات کاربره که حتی مدیر هم نباید بتونه ببینه!
و اینکه توی برنامت من جایی رو واسه تغییر رمز کاربر نتونستم پیدا کنم! مثلا بیاد بپرسه رمز قبلیت چیه و رمز جدید رو از کاربر بگیره و تغییر بده!
یا اینکه برای یه کاربر فیلد فعال بودن یا همون مجاز بودن برای ورود به برنامه رو بذاری تا در مواقع نیاز بشه یه کاربر رو غیر فعال کرد چون اصولا حذف کاربر تعریف شده صحیح نیست!


اینا رو قطعا تو نسخه بعدی لحاظ میکنم !


در مورد مرا بخاطر بسپار توی فرم لاگین که حسابی اشتباه کردی! اصولا توی نرم افزارهای ویندوزی منظور از مرا بخاطر بسپار فقط کد کاربری هستش و کاربر باید هر دفعه رمز عبور رو وارد کنه! ولی شما یه اشتباه بزرگ کردی! و اونم اینه که رمز رو هم بصورت setting ذخیره میکنی! اینطوری با دوتا کلیک میشه رمز رو بیرون کشید!! حالا اون به کنار! فرض کن من الان اومدم وارد سیستم شدم و منو بخ خاطر سپرده! حالا یکی دیگه بیاد و برنامه رو اجرا کنه و اون علامت چشم رو بزنه چی میشه!!!

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


با این روشی که تو انجام دادی خیلی راحت میشه برنامتو کرک کرد!!

در مورد قفل خیلی جستجو کردم تو نت ... یا چیز کامل و بدردبخوری نبود یا دروغ چرا ... چیزی از روش کار یا کد نویسی ش متوجه نشدم (اما این روش از بس ساده هست رو چشم بسته هم میرم - واسه هم با چشم بسته هم میشه کرک ش کرد :قهقهه:)


در مورد منوها هم یه تجدید نظر بکن! چون به ظاهر کلی برنامه نمیاد! یه آیکنی چیزی براشون بذار!

اتفاقا خوب شد که این مورد رو یادآوری کردین ... تو نسخه بعدی اصلا هدفم (طرحی که تو ذهنم هست) اینه که از منو استفاده نکنم (چون تو فرم اصلی میخوام از tab استفاده کنم)
و چند تا باتون گرافیکی توی اون قسمت بالایی (header) که الان خیلی جای خالی داره
نظرتون چیه ... کار درستی هست !؟

اصل مطلب هم که ایرادات و نقاط ضعف کد نویسیه (بی صبرانه منتظرم)
هر چند با EF هم میتونم کار کنم (تو همین سطح) ولی از ADO بیشتر خوشم میاد ... نظرتون چیه ، کلا بیخیال شم برم سراغ EF !؟

لطف کردین ... بایت وقتی که گذاشتین ، نکاتی که گوشزد کردین و ... (کد پنجره انتظار هم که به نوعی هدیه شما بود)
تشکر فراوان

hosseinrasouli
چهارشنبه 27 آبان 1394, 14:53 عصر
سلام مهندس . ممنون از برنامه واقعا زيباتون (مخصوصا طراحي)
يه نكته بگم اگه بخواين برنامه تون تحت شبكه باشه با مشكل مواجه ميشين . چون شما ممكنه اطلاعات سلول هاي ديتاگريد رو بگيريد در حالي كه ممكنه همون وقت كاربري اونو تغيير داده باشه.
پس بهتره از اشياء براي گرفتن اطلاعاتتون استفاده كنيد يعني وقتي كاربر روي يك ركورد كليك ديتاگريد ميكند بيايد و اطلاعات اون شي رو از ديتابيس بخوند

ghasem110deh
چهارشنبه 27 آبان 1394, 15:19 عصر
ممنون :)


پس بهتره از اشياء براي گرفتن اطلاعاتتون استفاده كنيد يعني وقتي كاربر روي يك ركورد كليك ديتاگريد ميكند بيايد و اطلاعات اون شي رو از ديتابيس بخوند

بیشتر توضیح میدین ؟ (با مثال)

با تشکر

pooya_friend
جمعه 29 آبان 1394, 15:14 عصر
سلام.واقعا دستت دردنکنه بابات اینکه این همه زحمتتو رایگان اشتراک گذاشتی. فقط نام کاربری یا مدیر هست یا خودم پسوردم هم ۱۲۳ ولی اصلا وارد سیستم نمیشه!! هی خطای نام کاربری رمز میده!! در صورتی که داده های دیتابیس همینن!؟و اینکه از چه فونتی استفاده کردید؟ چون من تو ویندوز ۱۰ و ویژوال ۲۰۱۵ اجرا کردم با فونت پیشفرض سیستم هست و جالب نیست

ghasem110deh
جمعه 29 آبان 1394, 17:48 عصر
سلام.واقعا دستت دردنکنه بابات اینکه این همه زحمتتو رایگان اشتراک گذاشتی. فقط نام کاربری یا مدیر هست یا خودم پسوردم هم ۱۲۳ ولی اصلا وارد سیستم نمیشه!! هی خطای نام کاربری رمز میده!! در صورتی که داده های دیتابیس همینن!؟و اینکه از چه فونتی استفاده کردید؟ چون من تو ویندوز ۱۰ و ویژوال ۲۰۱۵ اجرا کردم با فونت پیشفرض سیستم هست و جالب نیست

سلام و ممنون :)
فونت b yekan هستش ...
و در مورد کلمه عبور (چون دیتابیس از روی اسکریپت ساخته میشه خالی) و باید یه کاربر با سطخ دسترسی "1" ایجاد کنید !

ghasem110deh
یک شنبه 01 آذر 1394, 23:09 عصر
سلام به همه :)
دوستان ستاپ برنامه (تقریبا کامل) رو برای دانلود و استفاده گذاشتم ؛
--------------------------------------------------------------------------
البته هدف خودم تست و امتحان برنامه بعد از نصب روی سیستم دیگه هستش ...
که ببینم درست کار میکنه یا نه :متفکر:

لینک دانلود (http://s6.picofile.com/file/8224225718/Bonakdar_Setup.rar.html)

پست اول هم بروز شد !

mosi20
چهارشنبه 04 آذر 1394, 16:25 عصر
لینک دانلود دیتابیس خرابه
http://www.picofile.com/content/images/alert.gifفایلی با این آدرس وجود ندارد.

mosi20
چهارشنبه 04 آذر 1394, 16:26 عصر
سلام به همه :)
دوستان ستاپ برنامه (تقریبا کامل) رو برای دانلود و استفاده گذاشتم ؛
--------------------------------------------------------------------------
البته هدف خودم تست و امتحان برنامه بعد از نصب روی سیستم دیگه هستش ...
که ببینم درست کار میکنه یا نه :متفکر:

لینک دانلود (http://s6.picofile.com/file/8224225718/Bonakdar_Setup.rar.html)

پست اول هم بروز شد !
این لینک هم خراب است

ghasem110deh
چهارشنبه 04 آذر 1394, 16:32 عصر
این لینک هم خراب است

پست اول بروز شد :)

mosi20
چهارشنبه 04 آذر 1394, 16:39 عصر
بله الان درست شد
ممنون

vB.N3T
پنج شنبه 05 آذر 1394, 12:37 عصر
مهندس یه راهنمایی میخاستم. برنامه بنکدان شما رو نصب کردم لذت بردم عالی بود
سوالم اینه..منم دارم یه انبار داری مینویسم.میخاستم بدونم
من بانک رو به روش setup تو پروژه بزارم
یا روشی که شما قرار دادیم..ایجاد بانک توسط کاربر
روشی که شما گذاشتی چه فرقی داره با روش معمولی

ghasem110deh
پنج شنبه 05 آذر 1394, 14:32 عصر
سلام
مهندس خودتی :لبخند:
--------------------
منظورتون از روش معمولی چیه ؟
مهمترین مزیتی که داره اینه که فرقی نمیکنه چه نسخه ای از اسکیوال رو سیستم کاربر نصبه !

vB.N3T
یک شنبه 08 آذر 1394, 15:51 عصر
منظورم اینه که با روش setup گیری که میکنیم فایل دیتابیس همراه پروژه نصب بشه
مهندس اگه وقت داشتی اموزش این روشی که گذاشتی بزار خیلی کاربردیه :قلب:

ghasem110deh
یک شنبه 08 آذر 1394, 19:23 عصر
اگه خود ستاپ ساز از روی اسکریپت دیتابیس رو بسازی ، که خیلی خوبه !
(که من بلد نیستم)
--------------------
ولی چشم ایجاد از روی اسکریپت رو در ادامه توضیح میدم ....

ghasem110deh
دوشنبه 09 آذر 1394, 13:09 عصر
سلام به همه ...
این کلاس باید ایجاد کنید :


using System;
using System.Text;
using System.Data.SqlClient;
using System.IO;
using Rahgoshafan_Box;


namespace Rahgoshafan_Sell_Management
{
class DB_Generator
{
public static void ExecuteScript(StreamReader createDatabaseScriptStreamReader, SqlConnection sqlConnection) // متد اجرای اسکریپت
{
StringBuilder stringBuilder = new StringBuilder();
while (!createDatabaseScriptStreamReader.EndOfStream)
{
string line = createDatabaseScriptStreamReader.ReadLine();
if (line == "GO")
{
try
{
string command = stringBuilder.ToString();
string message;
if (command.Length > 15)
message = command.Substring(0, 15);
else
message = command;
message = message.Trim();
Console.WriteLine("Executing command \"" + message + "...\"");
SqlCommand sqlCommand = new SqlCommand(command, sqlConnection);
sqlCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine();
Console.BackgroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(ex.Message);
Console.ResetColor();
Console.WriteLine();
}
stringBuilder = new StringBuilder();
}
else
{
stringBuilder.AppendLine(line);
}
}
}


public static void Run_dbScript()
{
try
{
string sqlConnectionString = @"Data Source=.\;Initial Catalog=master;Integrated Security=True"; // کانکشن اس کیوال
StreamReader createDatabaseScriptStreamReader = File.OpenText("RahgoshafanDB.txt"); // معرفی فایل تکست
using (SqlConnection sqlConnection = new SqlConnection(sqlConnectionString))
{
sqlConnection.Open();
ExecuteScript(createDatabaseScriptStreamReader, sqlConnection); // اجرای متود بالا با پارامتر فایل تکست
sqlConnection.Close();
}
OK.ShowBox(@"! دیتابیس ایجاد شد
دیتابیس با موفقیت ایجاد شد", "تائید");
if (File.Exists("RahgoshafanDB.txt"))
{
createDatabaseScriptStreamReader.Close();
}
}
catch
{
Wait.CloseLoadingScreen();
Error.ShowBox(@"! دیتابیس ایجاد نشد
ساخت دیتابیس با خطا مواجه شد", "خطا");
}
}
}
}




اصل کار هم همینه (کد کار دوست عزیزم علی آقا هستش "alibilgats") که اسکریپت رو از فایل متنی میخونه و تو متود دوم اجرا میشه !

اینم کد ایجاد دیتابیس :


DB_Generator.Run_dbScript();


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

http://uploadboy.me/ap3346dyce14/RahgoshafanDB.txt

alitohi17
جمعه 13 آذر 1394, 19:02 عصر
پسورد این سیستم چند هست

ghasem110deh
چهارشنبه 18 آذر 1394, 16:20 عصر
علیک سلام :)
---------------
توی فایل تکست که کنار ستاپ هست موجوده !

نام کاربری : rgf
کلمه عبور : 123

E G A L E
یک شنبه 29 آذر 1394, 15:17 عصر
‍پروژه جالبی هست

فقط یه سوال چرا فونت فارسی پیش فرض فعاله؟ چجوری میشه غیر فعال کرد؟

ghasem110deh
یک شنبه 29 آذر 1394, 17:10 عصر
‍پروژه جالبی هست
فقط یه سوال چرا فونت فارسی پیش فرض فعاله؟ چجوری میشه غیر فعال کرد؟
سلام
والا متوجه منظورتون نشدم ... فونتی که استفاده شده b yekan هستش !
که اگه رو سیستم نصب نباشه از فونت پیش فرض مایکروسافت استفاده میشه و ممکن لیبل ها و متن باتون و ... کمی به هم بریزه !
باید بی یکان رو نصب کنید ...

E G A L E
یک شنبه 29 آذر 1394, 17:59 عصر
سلام
والا متوجه منظورتون نشدم ... فونتی که استفاده شده b yekan هستش !
که اگه رو سیستم نصب نباشه از فونت پیش فرض مایکروسافت استفاده میشه و ممکن لیبل ها و متن باتون و ... کمی به هم بریزه !
باید بی یکان رو نصب کنید ...

عذر میخوام منظورمو اشتباه رسوندم،
منظورم اینه که وقتی برنامه ران میشه روی کیبورد فارسی ست میشه وقتی به انگلیسی ست میکنم و روی یه لیبل کلیک میکنم اتوماتیک به فارسی سویچ میکنه.
یکی از دلایلی که برنامه همش هنگ میکرد به خاطر همین کیبورد فارسی بودنش هست.
و ضمن اینکه، این استارت آپ چجوری فرم لاگین رو میاره بالا؟ من چیزی پیدا نکردم چجوری تعریفش کردی.
و ضمن اینکه برنامه خوبی ازش در وردین و جای کار دارد. شما دیگه آپدیتش نکردین؟
چرا شما عملیات آپدیت اینزرت و دیلیت رو روی استور پروسیجر تعریف نکردین؟ چک کردن کالای موجودی و انبارداری اینها رو از طریق تریگر میتونستین خیلی راحت تعریف کنین و برنامه خیلی سبکتر میشد.

ghasem110deh
یک شنبه 29 آذر 1394, 21:53 عصر
خواهش میکنم !
------------------

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

درسته ... چون پنجره اصلی کیبورد رو فارسی میکنه ، اگه زبان رو تغییر بدین ، باز زبان به فارسی تغییر میکنه (مگر اینکه توی تکست باکس چیزیز رو تایپ کنید)
شاید بهتر باشه که با تکست باکس ها اینکار رو کرد !؟ (روش دیگه ای به ذهنم نمیرسه)

و ضمن اینکه، این استارت آپ چجوری فرم لاگین رو میاره بالا؟ من چیزی پیدا نکردم چجوری تعریفش کردی.

فرم لاگین توی رویداد لود_فرم پنجره اصلی بالا میاد (که ظاهرا اونم کار درستی نیست - بالاتر دوستان اشاره کردن)

و ضمن اینکه برنامه خوبی ازش در وردین و جای کار دارد. شما دیگه آپدیتش نکردین؟

قطعا دارم روش کار میکنم ! (هم دیتابیس - هم ظاهر برنامه و هم اگه تونستم نحوه کد نویسی)
ولی فعلا دارم با جاوا و اندروید سر و کله میزنم :لبخند:

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

E G A L E
دوشنبه 30 آذر 1394, 00:11 صبح
خوب قطعا مشکل اینجاست که اکثرا نتونستن به دیتابیست وصل شن چون کیبورد هی میره رو فارسی و هرکی هرچی وارد میکنه دیتابیس ایراد میگیره.
کلا درستش این هست که به صورت دیفالت انلگلیسی باشه که شاید بعدا مشتری نخواد همش فارسی باشه.
پروسیجر خیلی راحته همون دستورات که توی برنامه نوشتی عینا همون رو بیاری دیتابیس با یه تغییرات کوچک!. در قبالش خوانایی برنامه خیلی بالاتر میره.

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

موفق باشین.

farokh110
چهارشنبه 02 دی 1394, 00:42 صبح
مرسی عزیز بابت زحمتایی که کشیدی. ولی چرا انقدر سطحی انجام دادی؟ منم دارم یه پروژه نرم افزار حسابداری مینویسم ولی فک کنم فقط فرم ثبت کالا یک چهارم کل این پروژه توش کد زدم.
زیاد امکانات بهش اضافه نکردی. مخصوصا ثبت فاکتور که اصلی ترین قسمت اینجور برنامه هاست. در کل از معماریه سه لایه که استفاده کردی خوشم میاد ولی بدجور پیچوندیش. آدم نمیتونه یه خط کد رو تریس کنه. هی میپره اینور اونور :لبخند:
واسه فارسی کردنش که دوستان مشکل دارن به نظر من بهتره تو رویدادهای تکستباکسها اینکارو میکردی. مثلا تو فیلدهایی که قراره عدد وارد بشه توfocus و leave مینوشتی که انگیسی بشه.
یه چیز دیگه اینکه فیلدهایی که قرار نیست عمل جمع و تفریق و اینا روش انجام بشه رو چرا string نگرفتی؟ مثلا شماره تلفن. اینجوری احتمال ارور کمتره. چون تو اولین اطلاعاتی که وارد کردم مشکل پیش اومد که فونت فارسی رو به عنوان string شناخت که باید عدد میبود. اگه اجازه بدی پروژه ی خودم رو با مال شما ادغام کنم و امکاناتی که واسه خودم گذاشتم مخصوصا ثبت فاکتور که چک و نسیه و..... اینا داره بیارم رو این پروژه و بزارم همینجا که دوستان استفاده کنن. یک سری کنترل هم باید تو ورودی ها انحام بشه که ارور نده
در کل دمت گرم. ظاهرشم ساده و شیک و کابر پسنده.

ghasem110deh
چهارشنبه 02 دی 1394, 11:31 صبح
ممنون :)
----------


اگه اجازه بدی پروژه ی خودم رو با مال شما ادغام کنم و امکاناتی که واسه خودم گذاشتم مخصوصا ثبت فاکتور که چک و نسیه و..... اینا داره بیارم رو این پروژه و بزارم همینجا که دوستان استفاده کنن

چرا که نه ، حتما !
اصلا هدف خودم هم همین بوده هم اینکه یه آموزش باشه برای دیگران (در حد و سطح خودم) و هم اینکه با راهنمایی دوستان بتونم برنامه رو کارآمد تر کنم !

reza25000
چهارشنبه 02 دی 1394, 17:22 عصر
سلام
من هر کاری میکنم امکان دانلود وجود نداره
امکان داره برای من ایمیل کنی که بتونم برنامه نویسی سه لایه رو ببینم .
ممنون میشم
ادرس ایمیل من هم هست

Reza.azadbari@gmail.com
با تشکر

reza25000
چهارشنبه 02 دی 1394, 17:43 عصر
سلام
من هر کاری میکنم امکان دانلود وجود نداره
امکان داره برای من ایمیل کنی که بتونم برنامه نویسی سه لایه رو ببینم .
ممنون میشم
ادرس ایمیل من هم هست

Reza.azadbari@gmail.com
با تشکر

ghasem110deh
چهارشنبه 02 دی 1394, 18:00 عصر
سلام :)
این لینک تا 24 ساعت فعاله : (چک کردم ، مشکلی نداشت)

http://ir6.uploadboy.com:8080/d/qnnebvljjapnnnwh2mqtxxmgxtzxfqktwiy2obtlaicm4dikkd m7psts/RGF_Inventory_Bonakdar.rar

golbafan
یک شنبه 20 دی 1394, 22:04 عصر
سلام
این لینک رو ببین
http://barnamenevis.org/showthread.php?516452-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DA%A9%D8%AF-%DB%8C%D9%88%D9%86%DB%8C%DA%A9-%D9%88%D8%A7%D9%82%D8%B9%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%DA%A9%D8%A7%D9%85%D9%BE%DB%8C%D9%88%D8%AA%D8%B1&p=2296234#post2296234

aliooali
یک شنبه 04 بهمن 1394, 18:56 عصر
سلام دستان عزیز

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

مرسی

aliooali
یک شنبه 04 بهمن 1394, 19:01 عصر
سلام

اگر امکانش هستش میتونید سورس نهایی رو قرار بدین


با تشکر

ghasem110deh
یک شنبه 04 بهمن 1394, 19:29 عصر
سلام :)
اینم سورس کامل پروژه :
http://s6.picofile.com/file/8235119200/RGF_Inventory_Bonakdar_Done.rar.html

فکر کنم اون سایت آپلودبوی فایل ها رو پاک کرده (دیگه زحمت ستاپ رو خودتون بکشین)

پست اول هم بروز شد !

aliooali
یک شنبه 04 بهمن 1394, 22:18 عصر
الان بروز شده ؟!!!!!

آخه دانلود کردم ولی تو ایجاد دیتا بیس مشکل داشت

دوست عزیز اگر زحمتی نیست به لینک زیر برید

http://barnamenevis.org/showthread.php?210662-%D8%AF%D8%A7%D9%86%D9%84%D9%88%D8%AF-%DA%A9%D9%86%DB%8C%D8%AF-%D8%B3%D9%88%D8%B1%D8%B3-%DB%8C%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%DA%A9%D8%A7%D9%85%D9%84-%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D9%85%D8%B1%D8%A7%DA%A9%D8%B2-%D9%81%D8%B1%D9%88%D8%B4-%D9%88-%D8%AA%D8%B9%D9%85%DB%8C%D8%B1%D8%A7%D8%AA-%D8%AA%D9%84%D9%81%D9%86-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%D8%A8%D8%A7-40-%D9%81%D8%B1%D9%85&highlight=%D8%AA%D8%B9%D9%85%DB%8C%D8%B1%DA%AF%D8% A7%D9%87

سورس مشکل داره و اصلا نمیتونم وارد برنامه بشم اصلا صفحه یورز و پسوردش قفل هتسش

اگر امکانش هست یه بررسی کنید


با تشکر

ghasem110deh
دوشنبه 05 بهمن 1394, 08:09 صبح
الان بروز شده ؟!!!!!
آخه دانلود کردم ولی تو ایجاد دیتا بیس مشکل داشت
دوست عزیز اگر زحمتی نیست به لینک زیر برید
http://barnamenevis.org/showthread.php?210662-%D8%AF%D8%A7%D9%86%D9%84%D9%88%D8%AF-%DA%A9%D9%86%DB%8C%D8%AF-%D8%B3%D9%88%D8%B1%D8%B3-%DB%8C%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%DA%A9%D8%A7%D9%85%D9%84-%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D9%85%D8%B1%D8%A7%DA%A9%D8%B2-%D9%81%D8%B1%D9%88%D8%B4-%D9%88-%D8%AA%D8%B9%D9%85%DB%8C%D8%B1%D8%A7%D8%AA-%D8%AA%D9%84%D9%81%D9%86-%D9%87%D9%85%D8%B1%D8%A7%D9%87-%D8%A8%D8%A7-40-%D9%81%D8%B1%D9%85&highlight=%D8%AA%D8%B9%D9%85%DB%8C%D8%B1%DA%AF%D8% A7%D9%87
سورس مشکل داره و اصلا نمیتونم وارد برنامه بشم اصلا صفحه یورز و پسوردش قفل هتسش
اگر امکانش هست یه بررسی کنید
با تشکر

اون لینک که دادین ، نمی دونم مشکل ش چیه !؟ باید از همون بنده خدا بپرسین
ولی من الان با یه سیستم دیگه دانلود کردم ... دیتابیس رو هم ایجاد کرد !!!

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

vB.N3T
یک شنبه 11 بهمن 1394, 12:22 عصر
جناب ghasem110deh (http://barnamenevis.org/member.php?330388-ghasem110deh) شما در فرم اصلی تاریخ شمسی رو به این صورت نمایش دادین
شنبه 11 بهمن 94
میخاسم ببینم از چه کامپوننتی استفاده کردید
و وقتی روی دکمه ای میزنیم .یه opacity به فرم اصلی اعمال میشه
ممنون میشم جواب بدید

ghasem110deh
یک شنبه 11 بهمن 1394, 14:32 عصر
جناب ghasem110deh (http://barnamenevis.org/member.php?330388-ghasem110deh) شما در فرم اصلی تاریخ شمسی رو به این صورت نمایش دادین
شنبه 11 بهمن 94
میخاسم ببینم از چه کامپوننتی استفاده کردید
و وقتی روی دکمه ای میزنیم .یه opacity به فرم اصلی اعمال میشه
ممنون میشم جواب بدید

سلام :)
تاریخ رو توی یه کلاس داخل dll مسیج باکس نوشتم (که یه تقویم کامل هستش - کار استاد خوخان)
(الان دسترسی ندارن - آخر شب میزام)
و دومی هم که اگه منظورتون تاریک شدن فرم اصلی هستش (بعد از باز شدن پنجره جدید) که توی صفحه قبل گفته شده !

vB.N3T
یک شنبه 11 بهمن 1394, 22:44 عصر
اگه میشه نمونه کدشو برای ما قرار بدین استفاده کنیم با dll :قلب:

mp2009
دوشنبه 12 بهمن 1394, 07:56 صبح
دوست عزیز ممنون از پروژه ای که گزاشتی . واقعا کمک بزرگی به دوستانی که قصد یادگیری دارن کردی
اما ظاهرا دانلود نمیشه
اگه میشه همینجا تو سایت اپلود کن
ممنون

ghasem110deh
دوشنبه 12 بهمن 1394, 18:33 عصر
اگه میشه نمونه کدشو برای ما قرار بدین استفاده کنیم با dll :قلب:

سلام :)
ببخشید دیر شد ... این کلاس : (البته با اجازه استاد خوخان عزیز)
http://s7.picofile.com/file/8236507118/Date_Full.rar.html

آموزش ساخت dll مسیج باکس هم که تو همون تاپیک اول !


دوست عزیز ممنون از پروژه ای که گزاشتی . واقعا کمک بزرگی به دوستانی که قصد یادگیری دارن کردی
اما ظاهرا دانلود نمیشه
اگه میشه همینجا تو سایت اپلود کن
ممنون

لطف دارین ، ولی الان دانلود کردم (سورس پروژه) مشکلی نداشت !
ستاپ و ... رو نه !
اونارو رو روی آپلود بوی ریختم ، ظاهرا پاکشون کرد (رایگان از نوع انگلیسیه دیگه)

shahin60
سه شنبه 13 بهمن 1394, 17:13 عصر
این خطا رو تو اجرا میده
138784

ghasem110deh
سه شنبه 13 بهمن 1394, 20:15 عصر
پروژه رو ری بیلد کردین !!؟
این dll در واقع همون لایه بیزنس هست ... نباید خطا بده (توی پوشه bin هست ؟ )

moh64moh
چهارشنبه 14 بهمن 1394, 16:35 عصر
ممنون از زحماتتان
ظاهرا بعد از اضافه کردن فرم کارتکس دیتا بیس تغییراتی داشته
لطف کنین دیتابیس جدید رو بزارین
باز هم از زحماتتان ممنونم

ghasem110deh
پنج شنبه 15 بهمن 1394, 12:20 عصر
دیتابیس رو توی فرم لاگین برنامه میتونین بسازین !
با اسکیوال 2012 ایجاد شده

nimaakbari
جمعه 16 بهمن 1394, 13:24 عصر
سلام از شما به خاطر قرار دادن این برنامه تشکر می کنم
من یک سوال داشتم شما چطور SQLPackage رو برای ایجاد پایگاه داه طراحی کردید اگه سورس مربوط به این قسمت رو هم قرار دهید ممنون می شوم.

nimaakbari
شنبه 17 بهمن 1394, 12:00 عصر
سلام به همه ...
این کلاس باید ایجاد کنید :


using System;
using System.Text;
using System.Data.SqlClient;
using System.IO;
using Rahgoshafan_Box;


namespace Rahgoshafan_Sell_Management
{
class DB_Generator
{
public static void ExecuteScript(StreamReader createDatabaseScriptStreamReader, SqlConnection sqlConnection) // متد اجرای اسکریپت
{
StringBuilder stringBuilder = new StringBuilder();
while (!createDatabaseScriptStreamReader.EndOfStream)
{
string line = createDatabaseScriptStreamReader.ReadLine();
if (line == "GO")
{
try
{
string command = stringBuilder.ToString();
string message;
if (command.Length > 15)
message = command.Substring(0, 15);
else
message = command;
message = message.Trim();
Console.WriteLine("Executing command \"" + message + "...\"");
SqlCommand sqlCommand = new SqlCommand(command, sqlConnection);
sqlCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine();
Console.BackgroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(ex.Message);
Console.ResetColor();
Console.WriteLine();
}
stringBuilder = new StringBuilder();
}
else
{
stringBuilder.AppendLine(line);
}
}
}


public static void Run_dbScript()
{
try
{
string sqlConnectionString = @"Data Source=.\;Initial Catalog=master;Integrated Security=True"; // کانکشن اس کیوال
StreamReader createDatabaseScriptStreamReader = File.OpenText("RahgoshafanDB.txt"); // معرفی فایل تکست
using (SqlConnection sqlConnection = new SqlConnection(sqlConnectionString))
{
sqlConnection.Open();
ExecuteScript(createDatabaseScriptStreamReader, sqlConnection); // اجرای متود بالا با پارامتر فایل تکست
sqlConnection.Close();
}
OK.ShowBox(@"! دیتابیس ایجاد شد
دیتابیس با موفقیت ایجاد شد", "تائید");
if (File.Exists("RahgoshafanDB.txt"))
{
createDatabaseScriptStreamReader.Close();
}
}
catch
{
Wait.CloseLoadingScreen();
Error.ShowBox(@"! دیتابیس ایجاد نشد
ساخت دیتابیس با خطا مواجه شد", "خطا");
}
}
}
}




اصل کار هم همینه (کد کار دوست عزیزم علی آقا هستش "alibilgats") که اسکریپت رو از فایل متنی میخونه و تو متود دوم اجرا میشه !

اینم کد ایجاد دیتابیس :


DB_Generator.Run_dbScript();


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

http://uploadboy.me/ap3346dyce14/RahgoshafanDB.txt

سلام لینک دانلود مشکل داره لطفا اصلاح کنید.

ghasem110deh
شنبه 17 بهمن 1394, 21:50 عصر
سلام از شما به خاطر قرار دادن این برنامه تشکر می کنم
من یک سوال داشتم شما چطور SQLPackage رو برای ایجاد پایگاه داه طاحی کردید اگه سورس مربوط به این قسمت رو هم قرار دهید ممنون می شوم.

سلام ، ببخشید دیر جواب میدم ! امروز اینقدر سوکت شبکه زدیم که سر انگشتام سر شده :لبخند:
این کلاس رو بیخیال شین ، همون اسکیوال پکیج خوبه !

اینو دانلود کنید : Red.Gate.SQL.Toolbelt.1.8.2.372

آموزش نصب و ایجاد برنامه ساخت دیتابیس رو هم در ادامه میزارم ... البته کار باش راحته !

nimaakbari
یک شنبه 18 بهمن 1394, 01:34 صبح
با اجازه از دوست گرامی آقای ghasem110deh لینک دانلود نرم افزار رو اینجا برای دسترسی آسانتر قرار می دم. (از دو سایت مختلف)
لینک دانلود شماره 1 (http://p30download.com/fa/entry/61909/)
لینک دانلود شماره 2 (http://www.softgozar.com/WebPage/SoftwareDescription.aspx?SoftwareId=2164&Title=Red-Gate-SQL-Toolbelt-2013.1.8.2.372)
منتظر آموزش های شما در این زمینه هستیم

nimaakbari
چهارشنبه 21 بهمن 1394, 02:02 صبح
سلام ، ببخشید دیر جواب میدم ! امروز اینقدر سوکت شبکه زدیم که سر انگشتام سر شده :لبخند:
این کلاس رو بیخیال شین ، همون اسکیوال پکیج خوبه !

اینو دانلود کنید : Red.Gate.SQL.Toolbelt.1.8.2.372

آموزش نصب و ایجاد برنامه ساخت دیتابیس رو هم در ادامه میزارم ... البته کار باش راحته !

سلام منتظر آموزش ساخت پکیچ از بانک اطلاعاتی هستیم .

pooryadevil
جمعه 21 اسفند 1394, 17:47 عصر
عزیز خسته نباشید بسیار عالی ...

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

Helpco
سه شنبه 04 خرداد 1395, 10:42 صبح
سلام منتظر آموزش ساخت پکیچ از بانک اطلاعاتی هستیم .

سلام منتظر آموزش ساخت پکیچ از بانک اطلاعاتی هستیم .

winner1
سه شنبه 04 خرداد 1395, 17:48 عصر
عزیز خسته نباشید بسیار عالی ...

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

hahaie
چهارشنبه 05 خرداد 1395, 09:39 صبح
و یه سوال هم من دارم:
1.توی فرم لاگین این کادر آبی رنگ دور دکمه "ورود به برنامه" رو چطوری ایجاد کردین؟
2.فرق this.exit() با application.exitthread() یا f_login.activeform.exit چیه؟

Helpco
چهارشنبه 05 خرداد 1395, 11:38 صبح
شرمنده دوست خوب آموزش ساخت SQLPackage نمیزارید

hahaie
دوشنبه 10 خرداد 1395, 11:13 صبح
دوست عزیز کجا رفتی پس؟
پست 14 جهت پنجره wait خود برنامه شما مشکلی نداره اما وقتی خودم کدها رو منتقل کردم به پروژه خودم درست کار نمیکنه یعنی هم فرمی که قراره بعد wait نشون داده بشه نشون داده نمیشه و فرم اصلی هم Deactive میمونه.
اما اگه مثلا یه messagebox هر جایی قبل از
_ls.Dispose();
بذارم مشکل حل میشه

Helpco
پنج شنبه 13 خرداد 1395, 12:10 عصر
شرمنده دوست خوب آموزش ساخت SQLPackage نمیزارید

دوست عزیز کجا رفتی پس؟

mosafer_deltang
شنبه 15 خرداد 1395, 11:45 صبح
سلام
لینک های دانلود برنامه مشکل داره لطفا دوباره بذارید.
ممنون