PDA

View Full Version : سوال: انتقال اطلاعات از datagridview به جدول در sql



maryam8159
سه شنبه 28 بهمن 1393, 07:34 صبح
با سلام
دوستان کدهای زیر را برای انتقال اطلاعات از دیتا گرید به جدول sql نوشتم که در هنگام اجرا به فرمت کدهایی که برای بیرون کشیدن اطلاعات از سلولهای دیتا گرید نوشته ام خطا میگیرد


برای ثبت اطلاعات دونوع کد نوشتم که به هر دو اشکال گرفته می شود لطفا ایراد کدها را مشخص نماببد.


privatevoid btnRegister_Click(object sender, EventArgs e)
{
if ( cmbBranch.SelectedIndex == -1 || cmbManager.SelectedIndex == -1 || cmbMonth.SelectedIndex == -1)
{
MessageBox.Show("لطفا همه اطلاعات را وارد نمایید", "توجه", MessageBoxButtons.OK, MessageBoxIcon.Warning);


return;
}


try
{
//cmd.Connection = new SqlConnection(Lib.sqlstr);
//cmd.CommandType = CommandType.Text;
//SqlDataAdapter sda = new SqlDataAdapter();
//DataTable dt = new DataTable();


for (int i = 0; i < dataGridGoal.RowCount - 1; i++)
{
//if (Convert.ToInt32(dataGridGoal.Rows[i].Cells[5].Value) == 0) return;
//else
//{


cmd.Connection = newSqlConnection(Lib.sqlstr);
cmd.CommandType = CommandType.Text;


SqlDataAdapter sda = newSqlDataAdapter();
DataTable dt = newDataTable();
cmd.Parameters.Clear();


//cmd.CommandText = "INSERT INTO GoalManagerT(IdBranch,IdMonth,WNameFamily,IdGood,N Good,NGroup,IdSub,Number)values(" + cmbBranch.SelectedValue +
// ",'" + cmbMonth.SelectedValue + ",'" + cmbManager.SelectedValue + ",'" +Convert.ToInt32(dataGridGoal.Rows[i].Cells[1].Value) + ",'"
// +Convert.ToInt32(dataGridGoal.Rows[i].Cells[2].Value) + ",'" + dataGridGoal.Rows[i].Cells[3].Value.ToString() + " ,'" + Convert.ToInt32(dataGridGoal.Rows[i].Cells[4].Value) +
// ",'" +Convert.ToInt32(dataGridGoal.Rows[i].Cells[5].Value) + ")";


cmd.CommandText =
"INSERT INTO GoalManagerT (IdBranch,IdMonth,WNameFamily,IdGood,NGood,NGroup, IdSub,Number)values(@b,@m,@mo,@ig,@g,@gp,@s,@n)";


int idgood = Convert.ToInt32(dataGridGoal.Rows[i].Cells[0].Value);


//string ngood = dataGridGoal.Rows[i].Cells[1].Value.ToString();
//string ngroup = dataGridGoal.Rows[i].Cells[2].Value.ToString();
//int idsub = Convert.ToInt32(dataGridGoal.Rows[i].Cells[3].Value);
//int number = Convert.ToInt32(dataGridGoal.Rows[i].Cells[4].Value);


cmd.Parameters.AddWithValue("@b", cmbBranch.SelectedValue);
cmd.Parameters.AddWithValue("@m", cmbMonth.SelectedValue);
cmd.Parameters.AddWithValue("@mo", cmbManager.SelectedValue);
cmd.Parameters.AddWithValue("@ig", idgood);
cmd.Parameters.AddWithValue("@g", dataGridGoal.Rows[i].Cells[1].Value);
cmd.Parameters.AddWithValue("@gp", dataGridGoal.Rows[i].Cells[2].Value);
cmd.Parameters.AddWithValue("@s",dataGridGoal.Rows[i].Cells[3].Value);
cmd.Parameters.AddWithValue("@n", dataGridGoal.Rows[i].Cells[4].Value);


sda.SelectCommand = cmd;
sda.Fill(dt);
}


//}


MessageBox.Show("اطلاعات با موفقیت ثبت شد", "توجه", MessageBoxButtons.OK, MessageBoxIcon.Information);
cmbBranch.SelectedIndex = cmbManager.SelectedIndex = -1;
cmbBranch.Focus();
}


catch (SqlException ex)
{
//MessageBox.Show(SqlServerErrorManagement.ShowError (ex.Number, "هدف مدیران"), "خطا", MessageBoxButtons.OK, MessageBoxIcon.Error);
}


}

ali_md110
سه شنبه 28 بهمن 1393, 13:12 عصر
شما باید تعریف پارامترها و دستور اسکیول رو بیرون از حلقه انجام بدید و مقداردهی اون پارامترها ودستور ExecuteNonQuery توی حلقه انجام بشه

مثال :

using (SqlConnection cnn = new SqlConnection(base.ConectionString))
{
cnn.Open();

using (SqlCommand cmd = new SqlCommand("AccountByInfoInsert", cnn))
{
cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add("@AccID", SqlDbType.Int, 4);
cmd.Parameters.Add("@AccName", SqlDbType.NVarChar, 30);

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

cmd.Parameters["@AccID"].Value = dataGridGoal.Rows[i].Cells[1].Value"];
cmd.Parameters["@AccName"].Value = dataGridGoal.Rows[i].Cells[2].Value"];
;
cmd.ExecuteNonQuery();



}

maryam8159
سه شنبه 28 بهمن 1393, 15:51 عصر
هم با نمونه کدهای نوشته شده توسط خودم و هم با نمونه کدهای فوق پیغام خطای فوق داده می شود لطفا کمک کنید



An unhandled exception of type 'System.InvalidCastException' occurred in System.Data.dll
Additional information: Failed to convert parameter value from a DataRowView to a Int32.



private void btnRegister_Click(object sender, EventArgs e)
{
if (cmbBranch.SelectedIndex == -1 || cmbManager.SelectedIndex == -1 || cmbMonth.SelectedIndex == -1)
{
MessageBox.Show("لطفا همه اطلاعات را وارد نمایید", "توجه", MessageBoxButtons.OK, MessageBoxIcon.Warning);


return;
}


try
{
cmd.Connection = newSqlConnection(Lib.sqlstr);
cmd.CommandType = CommandType.Text;
SqlDataAdapter sda = newSqlDataAdapter();
DataTable dt = newDataTable();
sda.SelectCommand = cmd;
//cmd.Parameters.Clear();
cmd.CommandText = "INSERT INTO GoalManagerT (IdBranch,IdMonth,WNameFamily,IdGood,NGood,NGroup, IdSub,Number)values(@b,@m,@mo,@ig,@g,@gp,@s,@n)";


cmd.Parameters.Add("@b", SqlDbType.Int);
cmd.Parameters.Add("@m", SqlDbType.Int);
cmd.Parameters.Add("@mo", SqlDbType.Int);
cmd.Parameters.Add("@ig", SqlDbType.Int);
cmd.Parameters.Add("@g", SqlDbType.NVarChar);
cmd.Parameters.Add("@gp", SqlDbType.NVarChar);
cmd.Parameters.Add("@s", SqlDbType.Int);
cmd.Parameters.Add("@n", SqlDbType.Int);


for (int i = 0; i < dataGridGoal.RowCount - 1; i++)
{
cmd.Parameters["@b"].Value = cmbBranch.SelectedValue;
cmd.Parameters["@m"].Value = cmbMonth.SelectedValue;
cmd.Parameters["@mo"].Value = cmbManager.SelectedValue;
cmd.Parameters["@ig"].Value = dataGridGoal.Rows[i].Cells[0].Value + "";
cmd.Parameters["@g"].Value = dataGridGoal.Rows[i].Cells[1].Value + "";
cmd.Parameters["@gp"].Value = dataGridGoal.Rows[i].Cells[2].Value + "";
cmd.Parameters["@s"].Value = dataGridGoal.Rows[i].Cells[3].Value + "";
cmd.Parameters["@n"].Value = dataGridGoal.Rows[i].Cells[4].Value + "";
}
sda.Fill(dt);
MessageBox.Show("اطلاعات با موفقیت ثبت شد", "توجه", MessageBoxButtons.OK, MessageBoxIcon.Information);
cmbBranch.SelectedIndex = cmbManager.SelectedIndex = -1;
cmbBranch.Focus();
}
catch (SqlException ex)
{
MessageBox.Show(SqlServerErrorManagement.ShowError (ex.Number, "هدف مدیران"), "خطا", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

aslan
سه شنبه 28 بهمن 1393, 19:24 عصر
سلام
داخل حلقه for برای هر ردیف ( cell انتخابی) عملیات تبدیل نوع داده ( برابر با نوع تعریف شده برای پارامترها ) را انجام دهید

safa55
سه شنبه 28 بهمن 1393, 19:31 عصر
سلام
داخل حلقه for برای هر ردیف ( cell انتخابی) عملیات تبدیل نوع داده ( برابر با نوع تعریف شده برای پارامترها ) را انجام دهید

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

ali_md110
سه شنبه 28 بهمن 1393, 20:27 عصر
خطای نشون داده شده به علت عدم تبدیل نوع داده هست دوستمون aslan راهنمایی کردند
از System.ConvertToint32استفاده کنید
روش درج گروهی bulk نیاز هست تا رکوردهای درون دیتاگراید با یک حلقه ریخته بشه درون یک Temp دیتاتیبل و اون دیتاتیبل پاس داده بشه به تابع bulkCopy.WriteToServer
باز فرقی نمیکنه و نیاز به حلقه هست
اگر دیگه خود دیتاگراید خاصیتی داشته باشه که مستقیم عمل Costing انجام بده و اطلاعتش تبدیل به کلکسیون DataRow بشه روش bulk مناسب هست

maryam8159
سه شنبه 28 بهمن 1393, 21:08 عصر
برای خطوط 41 و 42 که مقادیر int داریم از convert.toint32 استفاده کرده بودم هم با تبدیل مقدار داخل سلول به استیرینک و هم بدون تبدیل به استرینگ اما باز هم خطا می داد متن خطا به صورت زیر است


An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll


Additional information: Input string was not in a correct format.

محمد آشتیانی
سه شنبه 28 بهمن 1393, 22:15 عصر
سلام
اصلا اینهمه کدی که شما نوشتی نیاز نیست ، کل کاری که لازمه شما انجام بدید اینه که اطلاعات دیتاگریدتون رو داخل یه دیتاتیبل بریزی و اطلاعات دیتاتیبل رو از طریق SqlBulkCopy داخل دیتابیس ثبت کنی.

این متد اطلاعات دیتاگرید رو به داخل یه دیتاتیبل میریزه (چیزی که برمیگردونه یه دیتاتیبل هست)

private DataTable GetDataTableFromDGV(DataGridView dgv)
{
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (column.Visible)
{
dt.Columns.Add();
}
}


object[] cellValues = new object[dgv.Columns.Count];
foreach (DataGridViewRow row in dgv.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
cellValues[i] = row.Cells[i].Value;
}
dt.Rows.Add(cellValues);
}


return dt;
}


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

private void InsertDTtoDB(string ConnectionString, string TableName, DataGridView DGV)
{
DataTable dt = new DataTable();
dt = GetDataTableFromDGV(DGV);


using (SqlConnection cn = new SqlConnection(ConnectionString))
{
cn.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(cn))
{
//فقط اینجا دقت داشته باشید شماره ایندکس فیلدهای مبدا و مقصد درست درج شوند
//یعنی برای مثال ممکن است ایندکس فیلد نام در دیتاتیبل 2 و در جدول دیتابیس 5 باشد
//بنابراین در مپینگ این ترتیب را مد نظر داشته باشید
copy.ColumnMappings.Add(0, 0);
copy.ColumnMappings.Add(1, 1);
copy.ColumnMappings.Add(2, 2);


copy.DestinationTableName = TableName;
copy.WriteToServer(dt);
}
}
}


خب میمونه نحوه استفاده ، کافیه متد InsertDTtoDB رو با ارسال پارامترهای مربوطه فراخوانی کنید

InsertDTtoDB("YourConnectionString", "YourTable", dataGridView1);

*کانکشن استرینگ خودتون و نام جدول مورد نظرتون رو بعنوان پارامتر اول و دوم مشخص کنید
** نام dataGridView1رو به نام دیتاگرید خودتون اصلاح کنید.


دوباره تاکید میکنم ترتیب فیلدهای مبدا و مقصد رو در Mapping رعایت کنید



موفق باشید.

safa55
چهارشنبه 29 بهمن 1393, 10:26 صبح
دوست عزیز من هم روی همچین چیزی کار می کنم.
برای گرفتن داده های datagridview هم از کد زیر استفاده می کنم.
DataTable dt = (DataTable)dataGridView1.DataSource;
البته به روش bulk
بدون نیاز به حلقه.

محمد آشتیانی
چهارشنبه 29 بهمن 1393, 11:24 صبح
دوست عزیز من هم روی همچین چیزی کار می کنم.
برای گرفتن داده های datagridview هم از کد زیر استفاده می کنم.
DataTable dt = (DataTable)dataGridView1.DataSource;
البته به روش bulk
بدون نیاز به حلقه.

سلام
روش شما درسته و البته زمانی کار میکنه که دیتاگرید قبلا به یک دیتاتیبل بایند شده باشه ، در غیر اینصورت اگر دیتاگرید بصورت دستی پر شده باشه روش شما کار نمیکنه چون
dataGridView1.DataSource مقدار null برمیگردونه.




موفق باشید.

maryam8159
چهارشنبه 29 بهمن 1393, 12:33 عصر
با اینکه کدهای شمارو همه را نوشتم باز هم پیغام خطا فرستاده میشه

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll


Additional information: The given value of type String from the data source cannot be converted to type int of the specified target column.

کد
InsertDTtoDB را در ایونت کلیک باتن ثبت نوشتم

محمد آشتیانی
چهارشنبه 29 بهمن 1393, 12:55 عصر
دوست عزیز چه کد بنده و چه کد خودت ، شما مقادیری که توی دیتابیست بصورت int هستن رو باید به همون صورت ارسال کنی
یعنی مثلا این دو تا پارامتر توی کد شما

cmd.Parameters["@s"].Value = dataGridGoal.Rows[i].Cells[3].Value + "";
cmd.Parameters["@n"].Value = dataGridGoal.Rows[i].Cells[4].Value + "";


نوعشون رو int تعریف کردی اما موقع انتساب مقدار ، تبدیلشون نکردی و حتی "" رو هم به انتهاشون اضافه کردی ، باید موقع مقدار دهی کاری شبیه به این انجام بدی

cmd.Parameters["@s"].Value = Convert.ToInt32(dataGridGoal.Rows[i].Cells[3].Value);
cmd.Parameters["@n"].Value = Convert.ToInt32(dataGridGoal.Rows[i].Cells[4].Value);


دقت کن داخل سلول هایی که به int کانورت میکنی فقط عدد باشه ، در غیر اینصورت طبیعتا باز هم خطا رخ میده

ghasem110deh
چهارشنبه 29 بهمن 1393, 13:17 عصر
سلام
آقای آشتیانی این همون روشی که واسه ثبت و چاپ فاکتور از طریق دیتاگریدویو استفاده میشه ؟
اگه همونه ، راهی هست که اطلاعاتش رو تقسیم کرد ؟ (به این صورت که مشخصات خریدار تو یه جدول و مشخصات کالا و ... تو یه جدول دیگه)
...

محمد آشتیانی
چهارشنبه 29 بهمن 1393, 14:00 عصر
توضیحاتی که در پست 8 دادم اطلاعات دیتاگرید رو با شرایطی که تو همون پست عرض کردم داخل دیتابیس Insert میکنه.
حالا شما میتونی برای ثبت ریز فاکتور ازش استفاده کنی. برای ثبت مشخصات کلی فاکتور مثل اطلاعات مشتری و ... به نظر میرسه باید جداگانه عمل کنی و البته وقتی مشخصات فاکتور رو ثبت کردی ، آیدی اون فاکتور رو هم باید همراه اطلاعات ریزفاکتور داخل جدول ریز فاکتور ثبت کنی (کلید خارجی میشه در واقع).




موفق باشید

ghasem110deh
سه شنبه 05 اسفند 1393, 21:55 عصر
سلام
الان چطور مجموع فاکتور رو بدست بیارم ؟ (عکسهای ضمیمه)
بعد اگه جمع رو بدست بیارم باید توی هر سطر جمع کل رو وارد کنم (بنظرم جداول بانکم اشتباهه)
.
.
.
راستی یه سری فونت خارجی نسب کردم (حالا به جای ریال توی دیتاگریدویو) از علامت $ بجای ریال استفاده می کنه ! کدش خط آخره
مشکل چیه ؟

ghasem110deh
سه شنبه 05 اسفند 1393, 23:15 عصر
این عکس (ضمیمه) :
دیتاگرید ویو هستش ؟

ghasem110deh
شنبه 16 اسفند 1393, 15:06 عصر
سلام
آقا این خطا واسه چیه ؟
------------------------
بجز اون یکی که متنی بقیه int هستن !