PDA

View Full Version : تغییر در datagrideview



mbaneshi
پنج شنبه 02 آذر 1396, 18:20 عصر
سلام به دوستان

من یه جدول در دیتابیس دارم که نمرات دانش اموزان توی اون ثبت میشه. وقتی اطلاعات اون جدول رو توی datagrideview لود می کنم اطلاعات به شکل زیر ظاهر میشه.


147124


ولی من می خوام اطلاعات توی دیتا گرید من به صورت زیر ظاهر بشه:

147126

به عبارت دیگر نوبت امتحانی بشه 4 تا ستون و توی هر کدوم نمره فقط یه نوبت نشون داده بشه.

ممنون میشم راهنمایی بفرمایید.

ژیار رحیمی
پنج شنبه 02 آذر 1396, 19:56 عصر
سلام .
چون نام فیلدها مشخص نیست مثالی جهت راهمایی گذاشته میشود.

کلاس پایه لیست جهت اجرا کویری

public class Lesson
{
public int LessonCode { get; set; }//کد درس
public int Part { get; set; }//نوبت امتحانی
public float Grade { get; set; }//نمره
}


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

var baseList = new List<Lesson>
{
new Lesson{ LessonCode = 5401, Part = 1, Grade = 12.5f},
new Lesson{LessonCode = 5401, Part = 2, Grade = 16},
new Lesson{ LessonCode = 5401, Part = 3, Grade = 15},
new Lesson{ LessonCode = 5402, Part = 1, Grade = 10.5f},
new Lesson{ LessonCode = 5402, Part = 2, Grade = 12.5f}
};
dataGridView1.DataSource = baseList.ToList();

و اصل کویری که نتیجه ان در DataGridView2 نمایش داده میشود

var result = baseList.GroupBy(x => x.LessonCode)
.Select(grp => new
{
Code = grp.Key,
Part1 = grp.FirstOrDefault(x => x.Part == 1)?.Grade,
Part2 = grp.FirstOrDefault(x => x.Part == 2)?.Grade,
Part3 = grp.FirstOrDefault(x => x.Part == 3)?.Grade
});
dataGridView2.DataSource = result.ToList();

mbaneshi
جمعه 03 آذر 1396, 20:43 عصر
سلام.
ممنون از بذل توجه و عنایت شما
راستش من از مثال شما سر در نیاوردم.
نمرات قبلا در جدول scores دخیره شده و فقط باید از جدول فراخوانی و در دیتا گرید نمایش داده بشه. بنا براین توی کد شما ، نباید به صورت دستی نوشته بشه.
کل کد من که هنگام لود فرم نوشته شده اینه و درست هم کار میکنه و نتیجه اون میشه عکس اولی در پست بالا. (البته نوبت امتحانی به صورت عدد در جدول ذخیره میشه که من با دستور CASE WHEN خواناترش کردم.


private void Scores_Load(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection
(string.Format("Server=.\\SQLEXPRESS;Database=" + textBox1.Text + "" + txtschoolcode.Text + ";trusted_Connection=true;"));
try
{
con.Open();


cmd.Connection = con;
da.SelectCommand = cmd;


cmd.CommandText = " SELECT studentcode,CourseCode,timeyear,ExamModel,TimeDore ,Val, FROM dbo.scores where studentcode=" + txtstudentcode.Text ;

da.Fill(ds1, "Scores");
con.Close();
dataGridView1.DataSource = ds1.Tables["Scores"];
dataGridView1.Columns["studentcode"].HeaderText = "کد دانش آموزی";
dataGridView1.Columns["CourseCode"].HeaderText = "کد درس";
dataGridView1.Columns["TimeYear"].HeaderText = "سال";
dataGridView1.Columns["ExamModel"].HeaderText = "نوبت";
dataGridView1.Columns["Val"].HeaderText = "نمره";

}
catch (SqlException ex)
{


MessageBox.Show(ex.Message);
}

اگه زحمتی نیست نمونه کد خودتون رو دقیق تر برام بفرستید تا ببینم کار میکنه.

ممنون میشم

رامین مرادی
شنبه 04 آذر 1396, 10:46 صبح
اسکریپت جدول و داده هاتون رو بزارید اینجا

mbaneshi
شنبه 04 آذر 1396, 21:57 عصر
CREATE TABLE [dbo].[Scores](
[StudentCode] [bigint] NOT NULL DEFAULT ((0)),
[CourseCode] [int] NOT NULL DEFAULT ((0)),
[TimeYear] [int] NOT NULL DEFAULT ((0)),
[TimeDore] [int] NOT NULL DEFAULT ((0)),
[ExamModel] [int] NOT NULL DEFAULT ((0)),
[AbsenceType] [int] NULL DEFAULT ((0)),
[Val] [float] NULL DEFAULT ((0)),
[SchoolCode] [bigint] NULL DEFAULT ((0)),
[GroupCode] [float] NULL DEFAULT ((0)),
[HashCode] [int] NULL DEFAULT ((0)),
CONSTRAINT [PK_Scores] PRIMARY KEY CLUSTERED
(
[StudentCode] ASC,
[CourseCode] ASC,
[TimeYear] ASC,
[TimeDore] ASC,
[ExamModel] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

رامین مرادی
یک شنبه 05 آذر 1396, 08:57 صبح
کاش همراهش چندتا داده نمونه هم بزارید. یا کل دیتابیس با داده هاتون رو بدید تا تست کنیم. چون اینجوری سخته فیلدهاتون رو پر کنیم.ولی برای نمونه من یکی ایجاد کردم برای تعداد ثابت نوبت



;with cte1 as(
select nomre,stid from testtbl
where nobat=1
)
, cte2 as(
select nomre,stid from testtbl
where nobat=2
)
, cte3 as(
select nomre,stid from testtbl
where nobat=3
)
, cte4 as(
select nomre,stid from testtbl
where nobat=4
)


select cte1.nomre as 'نمره مستمر اول',cte2.nomre as 'نمره نیمه اول',cte3.nomre as 'نمره مستمر دوم',cte4.nomre as 'نمره نیمه دوم'
from cte1 inner join cte2 on cte1.stid=cte2.stid inner join cte3 on cte1.stid=cte3.stid
inner join cte4 on cte1.stid=cte4.stid

mbaneshi
یک شنبه 05 آذر 1396, 10:23 صبح
درود. دوست گرامی.نمونه دیتا هم عکس بالا هست دیگه. نام فیلدها هم که هست. فکر کنم منظور من رو درست متوجه نشدید. دستور select از این جدول نوشته شده و کامل هست. اطلاعات هم توی دیتا گرید ویو نمایش داده میشه بدون مشکل. طبق تصاویر بالا که گذاشتم. من می خوام طرز نمایش داده ها تغییر کنه بشه مطابق تصوبر دوم پست اولی که گذاشتم.

رامین مرادی
یک شنبه 05 آذر 1396, 11:05 صبح
147149

147150

mbaneshi
یک شنبه 05 آذر 1396, 20:35 عصر
سلام
ممنون از توجه شما

این کدی که شما فرستادید توی محیط sql management اجرا کردم. درست جواب نمیده مثلا همین جدول scores که 128 رکورد داره پس از اجرای این کد حدود 686000 رکورد میده . هر رکودها داره 5360 بار تکرار میشه. نمی دونم چرا.

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

البته اگه داده های جدول testtbl رو اگه مثل من بنویسید برای شما هم نتیجه کوئری تکراری میشه.

147152

رامین مرادی
سه شنبه 07 آذر 1396, 08:54 صبح
سلام
ممنون از توجه شما

این کدی که شما فرستادید توی محیط sql management اجرا کردم. درست جواب نمیده مثلا همین جدول scores که 128 رکورد داره پس از اجرای این کد حدود 686000 رکورد میده . هر رکودها داره 5360 بار تکرار میشه. نمی دونم چرا.


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

البته اگه داده های جدول testtbl رو اگه مثل من بنویسید برای شما هم نتیجه کوئری تکراری میشه.

147152

در صورت امکان یک بکاپ از دیتا بیستون رو اینجا بزارید تا تست کنیم.

mbaneshi
سه شنبه 07 آذر 1396, 13:27 عصر
http://s8.picofile.com/file/8312919192/Backup13960907.rar.html

رامین مرادی
سه شنبه 07 آذر 1396, 15:07 عصر
الان این نتیجه مد نظرتون نیست؟(کد زیر رو اجرا کنید)

;with cte1 as (SELECT [StudentCode],[CourseCode] ,[Val],[TimeYear] FROM [dbo].[Scores]
where [ExamModel]=1)
,cte2 as (SELECT [StudentCode],[CourseCode],[Val],[TimeYear] FROM [dbo].[Scores]
where [ExamModel]=2)
,cte3 as (SELECT [StudentCode] ,[CourseCode],[Val],[TimeYear] FROM [dbo].[Scores]
where [ExamModel]=3)
,cte4 as (SELECT [StudentCode] ,[CourseCode],[Val],[TimeYear] FROM [dbo].[Scores]
where [ExamModel]=4)
select cte1.CourseCode, cte1.Val,cte2.Val,cte3.Val,cte4.Val from cte1 inner join cte2 on cte1.CourseCode=cte2.CourseCode and cte1.[TimeYear]=cte2.[TimeYear]
inner join cte3 on cte1.CourseCode=cte3.CourseCode and cte1.[TimeYear]=cte3.[TimeYear]
inner join cte4 on cte1.CourseCode=cte4.CourseCode and cte1.[TimeYear]=cte4.[TimeYear]

mbaneshi
سه شنبه 07 آذر 1396, 22:18 عصر
درود . تا اینجا عالی بود.
فقط یه ایراد هنوز داره و اون اینه که همه دروس باید در هر 4 مدل ،نمره داشته باشن تا توی خروجی ظاهر بشن. (1 تا 4). اگه مثلا درسی فقط در exammodel یک و 4 نمره داشته باشه نشون داده نمیشه. من می خوام اون دروسی که اینجوری هستند در خروجی نشون داده بشن اما اون مدل هایی که نمره ندارن خالی نشون داده بشه.

ژیار رحیمی
چهارشنبه 08 آذر 1396, 00:08 صبح
کد sql تست شده

SELECT
[Distinct1].[CourseCode] AS [کد],
[Limit1].[Val] AS [مستمر 1],
[Limit2].[Val] AS [نیمه 1],
[Limit3].[Val] AS [مستمر 2],
[Limit4].[Val] AS [نیمه 2]
FROM (SELECT DISTINCT
[Extent1].[CourseCode] AS [CourseCode]
FROM [Dana40522409].[dbo].[Scores] AS [Extent1] ) AS [Distinct1]
OUTER APPLY (SELECT TOP (1)
[Extent2].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent2]
WHERE ([Distinct1].[CourseCode] = [Extent2].[CourseCode]) AND (1 = [Extent2].[ExamModel]) ) AS [Limit1]
OUTER APPLY (SELECT TOP (1)
[Extent3].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent3]
WHERE ([Distinct1].[CourseCode] = [Extent3].[CourseCode]) AND (2 = [Extent3].[ExamModel]) ) AS [Limit2]
OUTER APPLY (SELECT TOP (1)
[Extent4].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent4]
WHERE ([Distinct1].[CourseCode] = [Extent4].[CourseCode]) AND (3 = [Extent4].[ExamModel]) ) AS [Limit3]
OUTER APPLY (SELECT TOP (1)
[Extent5].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent5]
WHERE ([Distinct1].[CourseCode] = [Extent5].[CourseCode]) AND (4 = [Extent5].[ExamModel]) ) AS [Limit4]

رامین مرادی
چهارشنبه 08 آذر 1396, 08:00 صبح
بجای inner میتونید left هم استفاده کنید تا در صورت نداشتن مستمر دوم یا سوم یا چهارم نمره مستمر اول نشون داده بشه

رامین مرادی
چهارشنبه 08 آذر 1396, 08:01 صبح
کد sql تست شده

SELECT
[Distinct1].[CourseCode] AS [کد],
[Limit1].[Val] AS [مستمر 1],
[Limit2].[Val] AS [نیمه 1],
[Limit3].[Val] AS [مستمر 2],
[Limit4].[Val] AS [نیمه 2]
FROM (SELECT DISTINCT
[Extent1].[CourseCode] AS [CourseCode]
FROM [Dana40522409].[dbo].[Scores] AS [Extent1] ) AS [Distinct1]
OUTER APPLY (SELECT TOP (1)
[Extent2].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent2]
WHERE ([Distinct1].[CourseCode] = [Extent2].[CourseCode]) AND (1 = [Extent2].[ExamModel]) ) AS [Limit1]
OUTER APPLY (SELECT TOP (1)
[Extent3].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent3]
WHERE ([Distinct1].[CourseCode] = [Extent3].[CourseCode]) AND (2 = [Extent3].[ExamModel]) ) AS [Limit2]
OUTER APPLY (SELECT TOP (1)
[Extent4].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent4]
WHERE ([Distinct1].[CourseCode] = [Extent4].[CourseCode]) AND (3 = [Extent4].[ExamModel]) ) AS [Limit3]
OUTER APPLY (SELECT TOP (1)
[Extent5].[Val] AS [Val]
FROM [Dana40522409].[dbo].[Scores] AS [Extent5]
WHERE ([Distinct1].[CourseCode] = [Extent5].[CourseCode]) AND (4 = [Extent5].[ExamModel]) ) AS [Limit4]


میتونید راجب این کد توضیح بدید.

mbaneshi
چهارشنبه 08 آذر 1396, 09:32 صبح
سلام. ممنون از توجه شما.

با left مقادیر خالی به صورت null نشون داده میشه. اما یه مشکل دیگه پیش میاد. مثلا اگه شما توی جدول اولین رکورد کد دانش اموزی رو تغییر بدید قانونا در خروجی کوئری فقط باید همون درس 5401 در exammodel یک برای کد دانش اموزی تغییر یافته نشون داده بشه و exammodel دو و سه و چهار همچنان برای کد قبلی نشون داده بشه اما اینگونه نیست و با تغییر کد دانش آموزی در exammodel یک بقیه نمرات در نوبت های 2 تا 4 برای کد دانش اموزی جدید میاره.
یا مثلا اگه کد دانش اموزی در نوبت 2 رو تغییر بدید توی خروجی همچنان نمره رو برای کد دانش اموزی قبلی میاره.

ژیار رحیمی
چهارشنبه 08 آذر 1396, 11:39 صبح
شما مفهوم View که نتیجه یک query روی جدول هست را با query های درج،ویرایش و حذف روی Table اشتباه برداشت کردید.این script یک view از جدول هست در View ها نمی توان عملیات درج ، ویراش و حذف رو انجام داد.مقادیری که دارای مقدار نیستند باید بصورت null نشون داده شود(یعنی هنوز مقداری برای آن در table درج نشده*در اول سال تحصیلی مشخصه که هنوز امتحاناتی برگزار نشده پس مقادیر ان null و تنها در پایان سال هست که هر چهار ستون دارای مقدار هست*).اگر اصلاحیه ایی در یکی از رکوردهای Table انجام شود برای دیدن نتیجه تغییرات در این View شما باید مجدد کویری آن را اجرا کنید.

در باب توضیح script:
linq کویری که در اولین پست که قرار داده شده، معادل آن به sql کویری هست.

mbaneshi
چهارشنبه 08 آذر 1396, 12:04 عصر
سلام. من این دو مفهوم را متوجه هستم. منظور من تغییر از طریق View که نیست. من گفتم اگه چنین تغییر که توضیح دادم در جدول به صورت دستی انجام بدم نتیجه کوئری درست داده نمیشه.

mbaneshi
چهارشنبه 08 آذر 1396, 12:09 عصر
البته یه من در کل می خوام خروجی این کوئری که توی دیتا گرید نشون داده میشه رو بتونم اصلاح کنم. مثلا توی دیتاگرید بتونم نمره رو تغییر بدم و ذخیره که زدم توی پایگاه تغییرات اعمال بشه. می دونم که با این کوئری نمیشه.
من دنبال راهی هستم که توی سی شارپ بتونم علاوه بر نمایش نمرات به این طریق اصلاحات هم انجام بدم و ذخیره هم بکنم.

ژیار رحیمی
چهارشنبه 08 آذر 1396, 12:16 عصر
شما اگر تغییرات در جدول را منظور شما در دیتاگرید هست باید بررسی کنی که آیا تغییرات انجام شده در دیتاگرید در جدول دیتابیس اعمال شده یا نه اگر تغییرات سمت دیتابیس انجام شده باشد حتمن با اجرای مجدد کویری تغییرات مشاهده خواهد شد.اگرم تغییراتی انجام نشده مشکل update از دیتاگرید به جدول دیتابیس را داری که ربطی به اجرای کویری ندارد.

mbaneshi
پنج شنبه 09 آذر 1396, 09:08 صبح
سلام. ممنون از شما
درسته کوئری ربطی به اون ذخیره در دیتابیس نداره. ولی همون کوئری هم درست کار نمیکنه.(توضیحاتی که در بالا داده شده)