PDA

View Full Version : مشکل در جستجو در DataGridView



hadimtn
جمعه 06 شهریور 1394, 19:16 عصر
سلام.
داخل یک فرم، اطلاعات از طریق جعبه‌ی متن به یک DataGridView خالی فرستاده میشه؛
میخوام از ورود اطلاعات تکراری جلوگیری کنم؛ و اگر تکراری بود فیلد Number با فیلد Number قبلی عوض بشه!
شرط تکراری بودن هم نام و نام خانوادگی تکراریه!
مشکلی که دارم اینه که فقط سطر اول رو بررسی میکنه؛
یعنی اگر اطلاعاتی که در حال اضافه شدن بود با سطر اول DataGridView برابر بود، عملیات انجام میشه در غیر اینصورت نه! (سطر تکراری ثبت میشه)

کد فرم لود:
private void STForm_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Family", typeof(string));
dt.Columns.Add("Number", typeof(int));
dataGridView1.DataSource = dt;
}

کد مربوط به درج اطلاعات:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((row.Cells[1].Value.ToString().Equals(txt_Name.Text)) && (row.Cells[2].Value.ToString().Equals(txt_Family.Text)))
{
row.Cells[3].Value = txt_Number.Text;
dataGridView1.DataSource = dt;
txt_Code.Focus();
break;
}
else
{
dt.Rows.Add(txt_Code.Text, txt_Name.Text, txt_Family.Text, txt_Number.Text);
dataGridView1.DataSource = dt;
txt_Code.Focus();
break;
}
}

rasol_afkham
شنبه 07 شهریور 1394, 01:40 صبح
داداش دستور break که در بلوک else قرار داره رو پاک کن تا با اولین برخورد از حلقه خارج نشه.:قهقهه:

hadimtn
شنبه 07 شهریور 1394, 02:11 صبح
داداش دستور break که در بلوک else قرار داره رو پاک کن تا با اولین برخورد از حلقه خارج نشه.:قهقهه:
کلمه‌ی کلیدی break رو به این دلیل گذاشتم که پس از اضافه کردن سطر از حلقه خارج بشه، وگرنه به تعداد سطرهای موجود DataGridView سطر در حال اضافه شدن رو اضافه میکنه!
یعنی اگه قبلاً 5 سطر داشتیم، سطر در حال اضافه شدن پنج بار اضافه خواهد شد! :لبخند:

hadimtn
شنبه 07 شهریور 1394, 19:10 عصر
حتماً نیاز نیست که از DataTable استفاده بشه!
درج مستقیم به DataGridView بود چه جوری میشد اینکاری که توضیح دادم رو انجام بدم؟!

rasol_afkham
شنبه 07 شهریور 1394, 21:38 عصر
در هر صورت حلقه ای که شما نوشته اید کاملا مشخص که فقط یک بار اجرا می شه و اون یک بار هم تنها سطر اول رو بررسی می کنه. چون در صورت برقرار بودن و یا نبودن شرط از حلقه خارج می شه :قهقهه:

hadimtn
شنبه 07 شهریور 1394, 22:01 عصر
در هر صورت حلقه ای که شما نوشته اید کاملا مشخص که فقط یک بار اجرا می شه و اون یک بار هم تنها سطر اول رو بررسی می کنه. چون در صورت برقرار بودن و یا نبودن شرط از حلقه خارج می شه
خوب مشکل منم همون حلقه است دیگه...
این حلقه رو چه جوری بنویسم که همه ی سطرها رو چک کنه!
البته نیازی نیست همه ی سطرها چک بشه! حلقه تا جایی ادامه داشته باشه که اولین سطر مشابه پیدا بشه، چون از اول داده ی تکراری نمیتونه ثبت بشه!

Mahmoud.Afrad
شنبه 07 شهریور 1394, 22:04 عصر
DataTable dtSource = dataGridView1.DataSource as DataTable;
foreach (DataRow row in dtSource.Rows)
{
if ((row[1].ToString().Equals(txt_Name.Text)) && (row[2].ToString().Equals(txt_Family.Text)))
{
row[3] = txt_Number.Text;
txt_Code.Focus();
return;
}
}

dtSource.Rows.Add(txt_Code.Text, txt_Name.Text, txt_Family.Text, txt_Number.Text);
txt_Code.Focus();

hadimtn
شنبه 07 شهریور 1394, 23:53 عصر
DataTable dtSource = dataGridView1.DataSource as DataTable;
foreach (DataRow row in dtSource.Rows)
{
if ((row[1].ToString().Equals(txt_Name.Text)) && (row[2].ToString().Equals(txt_Family.Text)))
{
row[3] = txt_Number.Text;
txt_Code.Focus();
return;
}
}

dtSource.Rows.Add(txt_Code.Text, txt_Name.Text, txt_Family.Text, txt_Number.Text);
txt_Code.Focus();

جواب نداد! در هر صورت داده‌های جدید رو به عنوان سطر جدید وارد DataGridView می‌کنه. (اصلاً وارد حلقه نمیشه)
کدی که خودم نوشتم کار می‌کنه ولی فقط با سطر اول چک می‌کنه!

hadimtn
یک شنبه 08 شهریور 1394, 02:13 صبح
دوستان عزیز؛ الآن DataGridView مستقل از هر منبع داده‌ای کار می‌کنه!
میخوام اگه یک سلول خاص (مثلاً Name) از سطر در حال اضافه شدن، با سلول متناظر خودش توی DataGridView یکسان بود، عملیات درج به بروز رسانی تبدیل بشه، و یک سلول خاص (مثلاً Age) از همان سطر تکراری رو به روز کنه!
لطفاً ایراد این حلقه رو بگین:

if (dataGridView1.RowCount == 0)
{
dataGridView1.Rows.Add(txt_name.Text, txt_fname.Text, txt_age.Text);
}
else
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["name"].Value.ToString() == txt_name.Text)
{
row.Cells["name"].Value = txt_age.Text;
break;
}
else
{
dataGridView1.Rows.Add(txt_name.Text, txt_fname.Text, txt_age.Text);
}
}
}

erfan_urchin
یک شنبه 08 شهریور 1394, 17:29 عصر
دوستان عزیز؛ الآن DataGridView مستقل از هر منبع داده‌ای کار می‌کنه!
میخوام اگه یک سلول خاص (مثلاً Name) از سطر در حال اضافه شدن، با سلول متناظر خودش توی DataGridView یکسان بود، عملیات درج به بروز رسانی تبدیل بشه، و یک سلول خاص (مثلاً Age) از همان سطر تکراری رو به روز کنه!
لطفاً ایراد این حلقه رو بگین:

if (dataGridView1.RowCount == 0)
{
dataGridView1.Rows.Add(txt_name.Text, txt_fname.Text, txt_age.Text);
}
else
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells["name"].Value.ToString() == txt_name.Text)
{
row.Cells["name"].Value = txt_age.Text;
break;
}
else
{
dataGridView1.Rows.Add(txt_name.Text, txt_fname.Text, txt_age.Text);
}
}
}
دوست عزیز شما تا کامل توضیح ندی که دقیقا چی میخوای و این کدی که شما نوشتی چه خروجی ای میده که شما باهاش مشکل داری کسی نمیتونه کمکت کنه
الان من مشکلی تو این کد نمیبینم ولی شما میگی مشکل این کد چیه؟ الان کامپایلر به شما ارور خاصی میده؟ یا این کد خروجی موردنظر شما رو نمیده؟
مثلا شما میگی میخوای سلول age به روز بشه در حالی که با کد row.Cells["name"].Value = txt_age.Text; داری سلول name رو به روز میکنی!!

rg_BlackRose
یک شنبه 08 شهریور 1394, 23:33 عصر
سلام

اگر کدهای ذخیره و ویرایش جدول همین کدهایی که قرار دادین باشه، فقط کافیه که قسمت else رو به بیرون از foreeach انتقال بدین.(کدهایی که آقای محمود افراد قرار دادن درسته دیگه.)

foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((row.Cells[1].Value.ToString().Equals(txt_Name.Text)) && (row.Cells[2].Value.ToString().Equals(txt_Family.Text)))
{
row.Cells[3].Value = txt_Number.Text;
txt_Code.Focus();
return;
}
}


dt.Rows.Add(txt_Code.Text, txt_Name.Text, txt_Family.Text, txt_Number.Text);
txt_Code.Focus();


در غیر اینصورت(بعد یا قبل از این کدها، اگر کدی دارید)توصیه میکنم کدهاتون رو به توابع کوچکتر تجزیه بکنید.(اینجوری خوانایی و عیب یابی کدها راحت تر میشه)


نمای کلی از کدهای مرمتب شده:

using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;


namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public DataTable Dt = new DataTable();


public Form1()
{
InitializeComponent();
}


private void Form1_Load(object sender, EventArgs e)
{
CreateNewGuid();


Dt.Columns.Add("ID", typeof(Guid));
Dt.Columns.Add("Name", typeof(string));
Dt.Columns.Add("Family", typeof(string));
Dt.Columns.Add("Number", typeof(int));
dataGridView1.DataSource = Dt;
}


private void button1_Click(object sender, EventArgs e)
{
if (!UpdateRecords(txt_Name.Text, txt_Family.Text, Convert.ToInt32(txt_Number.Text)))
AddNewRecord(new Guid(txt_Code.Text), txt_Name.Text, txt_Family.Text, Convert.ToInt32(txt_Number.Text));
}


void AddNewRecord(Guid id, string fname, string lname, int number)
{
Dt.Rows.Add(id, fname, lname, number);
MessageBox.Show(@"Added New Record Successfully");
CreateNewGuid();
}


bool UpdateRecords(string fname, string lname, int number)
{
if (dataGridView1.RowCount < 1)
return false;


foreach (var row in dataGridView1.Rows.Cast<DataGridViewRow>().Where(row => (row.Cells[1].Value.Equals(fname)) && (row.Cells[2].Value.Equals(lname))))
{
row.Cells[3].Value = number;
MessageBox.Show($"Updateed Record '{row.Index}' Successfully");
return true;
}


return false;
}


void CreateNewGuid()
{
txt_Code.Text = Guid.NewGuid().ToString();
}
}
}


موفق باشید.

hadimtn
دوشنبه 09 شهریور 1394, 00:11 صبح
دوست عزیز شما تا کامل توضیح ندی که دقیقا چی میخوای و این کدی که شما نوشتی چه خروجی ای میده که شما باهاش مشکل داری کسی نمیتونه کمکت کنه
الان من مشکلی تو این کد نمیبینم ولی شما میگی مشکل این کد چیه؟ الان کامپایلر به شما ارور خاصی میده؟ یا این کد خروجی موردنظر شما رو نمیده؟
دقیقاً این کد خروجی مورد نظر منو نمیده! دوباره میگم؛ فرم زیر رو در نظر بگیرید:

134775

در قسمت "صدور لیست فروش" وقتی دکمه‌ی "لیست" رو میزنم، نام کالا + نشان + تعداد + و ... وارد DataGridView میشه؛
حالا می‌خوام اگه دوباره همین کالا با نشان تکراری وارد شد، سلول مربوط به "تعداد" کالا، با مقدار قبلی جمع بشه!


مثلا شما میگی میخوای سلول age به روز بشه در حالی که با کد row.Cells["name"].Value = txt_age.Text; داری سلول name رو به روز میکنی!!
یه مثال بود که روش کار رو یاد بگیرم! اون چیزی که گفتم درسته! اینجا اشتباه درج شده! :لبخندساده:
مشکل بنده در نوشتن حلقه است!
چه جوری باید همه‌ی سطرها رو بررسی کنم و اولین سطر تکراری رو پیدا کنم؟!
در واقع دکمه‌ی "لیست" هم کار درج سطر جدید رو انجام میده؛ و هم در صورت وجود سطر تکراری کار بروزرسانی!
یه همچین چیزی هم نوشتم:

try
{
for (int i = 0; i =< dataGridView1.RowCount; i++)
{
if ((dataGridView1.Rows[i].Cells[0].Value.ToString()) == txt_Sname.Text)
{
MessageBox.Show(dataGridView1.Rows[i].Cells[0].Value.ToString()); // دستور به روز رسانی

}
else
{
dataGridView1.Rows.Add(txt_Sname.Text, txt_Sfname.Text, txt_Sage.Text); // دستور اضافه کردن
}
}
}
catch (Exception ex)
{
MessageBox.Show("خطای پیش بینی نشده: " + ex.Message);
}

hadimtn
دوشنبه 09 شهریور 1394, 00:26 صبح
از همه ی دوستان ممنونم که جواب دادن؛
پیدا کردن سطر تکراری همونطور که توضیح دادین انجام دادم!
اگر مشکلی بود در همین رابطه تو همین تاپیک مطرح میکنم!