PDA

View Full Version : در مورد ترتيب شماره سطرها در Datagridview



s.k711
شنبه 02 آذر 1387, 09:56 صبح
سلام دوستان.
من در انجمن خيلي سرچ كردم ولي به پاسخ سوالم نرسيدم اين شد كه مجبور شدم اين سوال تكراري و جنجالي(:لبخند:) را مطرح كنم.
من در بنامم چندين گريد دارم كه همشون يك ستون به اسم "رديف" دارند كه اين ستون ها به جداولم كه داراي فيلدي مثلا بااسمsid است بايند شده اند.(هر گريد به جدول جداگانه اي)
مسلما اين فيلد primarykeyو identity است.
مشكل من اين است كه هرموقع سطري را از گريد حذف ميكنم اگه قبلا ترتيب سطرهايم به صورت : 1و2و3و4و..و10 بوده مثلا ميشود : 1و2و5و6و7و8و10
و واضح است كه اين صورت جالبي براي كاربر برنامه من ندارد.
طبق جستجوهايم در انجمن براي رفع مشكلم دو راه دارم:
1) ستون"رديف" از گريد را به db بايند نكنم و خودم بعد از هر حذفي با استفاده از" count" و حلقه for اين ستون را مجدادا شماره گذاري نمايم.
2) ستون"رديف" از گريد را بايند بكنم اما بعد از هر حذف از گريد (كه از بنك اطلاعاتيم حذف ميشه) idها را update بكنم.
كه متاسفانه من پياده سازي هيچكدام را ياد ندارم.(:خجالت:)
در ضمن من از sql sever2000 و vb.net2005 استفاده ميكنم.
خيلي ممنون ميشم راهنمايي بفرماييد و يا اگه در وسعتون بود قطعه كدي را براي وضوح بيشتر راهنماييتان در اين تاپيك ارئه فرماييد.
( ميدونم اين مشكل همه در همه روزگاران بوده ، هست و خواهد بود . و اينكه بعضي مواقع تكرار "تكراري ها" باعث مرور "آموخته ها ميشود.:لبخندساده:)
باز هم پيشاپيش از راهنمايي دلسوزانتون متشكرم.
:لبخندساده:

s.k711
شنبه 02 آذر 1387, 12:11 عصر
There isnt NO ONe!!!!

Sub Zero
شنبه 02 آذر 1387, 13:27 عصر
شما برای پر کردن دیتاگریدت از دستور زیر استفاده کن :

SELECT row_number() OVER (ORDER BY CostumKey) AS Sid,OtherFields From YourTable

CostumKey : نام ستونیه که جدولت برا اساس اون مرتب میشه .
OtherFields : نام ستون(هایی) که میخوای نمایش بدی
YourTable : نام جدول

بعد از هر حذف با پر کردن مجدد جدول ، گرید رو Refresh کن .

البته این یکی از راههای رفع مشکل شماست .

یه راه دیگه اینه که یه تریگر برای حذف درست کنی و در اون ستون Sid رو Drop کرده و مجددا درست کنی (البته این مورد رو تا حالا خودم انجام ندادم)

s.k711
شنبه 02 آذر 1387, 21:26 عصر
سلام ممنون از راهنماييتون.
اما منظورتون از row_number() چيست؟

rooshan2008
شنبه 02 آذر 1387, 22:28 عصر
سلام:
من روش اول رو که گفتین پیشنهاد می کنم
دیتا گرید یه رویداد به نام این داره DataGridView1.RowsRemoved که وقتی سطری ازش پاک بشه تحریک میشه



Private Sub DataGridView1_RowsRemoved(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowsRemovedEventA rgs) Handles DataGridView1.RowsRemoved
For i = e.RowIndex To DataGridView1.RowCount - 1
DataGridView1.Rows(i).Cells(0).Value = i + 1
Next

End Sub

s.k711
شنبه 02 آذر 1387, 23:05 عصر
جناب rooshan2008 ممنون از راهنماييتون.اما تنها موقع حذف شماره رديف نميخوام موقعي كه بنامه بالا مي ايد هم لازم دارم.(يني هنگم لد شدن برنام) اگه ممكنه در اين مورد هم راهنمايي بفرماييد.
با تشكر

Sub Zero
یک شنبه 03 آذر 1387, 07:28 صبح
سلام ممنون از راهنماييتون.
اما منظورتون از row_number() چيست؟

row_number تابعی که برای نمایش شماره سطرها استفاده میشه.
اطلاعات بیشتر :
لینک 1 (http://msdn.microsoft.com/en-us/library/ms186734(printer).aspx)
لینک 2 (http://www.databasejournal.com/features/mssql/article.php/3572301/RowNumber-function-in-SQL-Server-2005.htm)
لینک 3 (http://www.codeproject.com/KB/database/row_number.aspx)

s.k711
یک شنبه 03 آذر 1387, 08:23 صبح
سلام دوست عزيز ممنون از راهنمايي با ارزشتون.
اما من از sqlsever2000 استفاده ميكنم نه sql2005 .
اينطور كه ديدم (لينكهايي كه زحمتش را كشيديد و گذاشتين)row_number() تابع نسخه 2005 است.
بازم ممنون از توجهتون.

s.k711
دوشنبه 04 آذر 1387, 18:33 عصر
سلام دوست عزيز آقاي Rooshan2008 من از كدتون در row_remove يكي از گريدهايم استفاده كردم.اما متاسفانه بعد از حذف كردن سطري از گريد. ستون رديفم خالي ميشه.يعني هيچ ععدي نشون نميده.
به نظرتون چه كاركنم.
ممنون.

s.k711
چهارشنبه 06 آذر 1387, 11:04 صبح
دوستان يعني هيچ كس نميتونه كمكم كنه.
يعني تا حالا اين مشكل براي كسي پيش نيومده.
من واقعا با اين موضوع مشكل دارم.
لطفا راهنمايي كنيد.
:متفکر::عصبانی::عصبانی++::نار حت::افسرده::گریه::گریه::گریه: :گریه:

rooshan2008
چهارشنبه 06 آذر 1387, 11:21 صبح
سلام
این کد رو همین الان هم اجرا کردم درست کار می کنه می شه اون کدت رو بنویسی؟

s.k711
چهارشنبه 06 آذر 1387, 11:45 صبح
Private Function rownum(ByVal i As Integer) As Integer
Dim cmd As SqlCommand
Dim dr As SqlDataReader
Dim cnt As Integer
Dim str2 As String
'str2 = "select count(name_family)as ct from [personnel]"
str2 = "select * from [personnel]"
con.Open()
cmd = New SqlCommand(str2, con)
dr = cmd.ExecuteReader
If dr.HasRows Then
'dr.Read()
' cnt = dr("ct")
dr.Close()
cnt = i
con.Close()
Else
cnt = i
dr.Close()
con.Close()
End If

Return cnt
End Function




in_cmd.Parameters.Add("@w", SqlDbType.Int).Value = 0
in_cmd.Parameters.Add("@c", SqlDbType.Int).Value = 0

in_cmd.ExecuteNonQuery()
con.Close()
cnt = rownum(n)
End If
'.................
con.Open()
da = New SqlDataAdapter
dt = New DataTable
Dim str1 As String
str1 = "select [s_type],[s_r_weight],[s_r_count],[rb_nam_fam_pers] from [temp] "
in_cmd = New SqlCommand(str1, con)
da.SelectCommand = in_cmd
dt.Clear()
da.Fill(dt)
DataGridView1.DataSource = dt
For m = 0 To cnt
DataGridView1.Rows(m).Cells(0).Value = m + 1
Next m
con.Close()
n = n + 1





Private Sub DataGridView1_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
If e.RowIndex >= 0 Then
Button4.Enabled = True
Button5.Enabled = True
Dim str As String
con.Open()
Dim s As String
s = DataGridView1.Rows(e.RowIndex).Cells(1).Value.ToSt ring
str = "select [s_type] from [temp] where ([s_type]= '" & s & "')"
Dim cmd As New SqlCommand(str, con)
Dim dr As SqlDataReader
dr = cmd.ExecuteReader()
If dr.HasRows = True Then
dr.Read()
type = dr("s_type")
dr.Close()
con.Close()
Else
dr.Close()
con.Close()
Msgbox_Custom("اطلاعاتي وجود ندارد.", 1, 1, "اخطار")
End If
End If
End Sub




Private Sub DataGridView1_RowsRemoved(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowsRemovedEventA rgs) Handles DataGridView1.RowsRemoved
Dim i As Integer
For i = e.RowIndex To DataGridView1.RowCount - 1
DataGridView1.Rows(i).Cells(0).Value = i + 1
Next
For i = 0 To no
DataGridView1.Rows(i).Cells(0).Value = i + 1
Next
End Sub

s.k711
چهارشنبه 06 آذر 1387, 11:47 صبح
خيلي ممنون از توجهتون.

rooshan2008
چهارشنبه 06 آذر 1387, 12:09 عصر
سلام
من میخوام بدونم با چه کد پاکش می کنید با این حال فکر کنم بعد از اجرای دستور Sql وقتی پاکش کردی دوباره اطلاعات رو لود میکنی .




For i = 0 To no
DataGridView1.Rows(i).Cells(0).Value = i + 1
Next



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

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

ولی اگر از همون روش استفاده میکنید بهتره از این روش بنویسید در رویداد :



Private Sub DataGridView1_RowsAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArg s) Handles DataGridView1.RowsAdded

DataGridView1.Rows(e.RowIndex).Cells(0).Value = e.RowIndex + 1
End Sub



اگه نشد به مسنجر لطف کن پیغام بده

s.k711
چهارشنبه 06 آذر 1387, 12:40 عصر
دوست عزيز اگه ممكنه يك نمونه برنام بگذاريد چون واقعا گيج شدم.
ممنون.

rooshan2008
چهارشنبه 06 آذر 1387, 23:58 عصر
سلام
این مثال رو ببینید:
من در این مثال از بانانک northwind و جدول Customer استفاده کردم .




Dim Connecting As New System.Data.SqlClient.SqlConnection("Persist Security Info=False;User ID=sa;Password =;Initial Catalog=northwind ; Data Source=(local)")
Public Command1 As New SqlClient.SqlCommand
Dim Tran As SqlClient.SqlTransaction
Dim DataAdapter As New SqlClient.SqlDataAdapter
Dim DataTable_1 As New DataTable
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DataGridView1.DataSource = Nothing

Connecting.Open()
Tran = Connecting.BeginTransaction
Command1.Transaction = Tran
Command1.Connection = Connecting
DataGridView1.Columns.Add("Num", "ردیف")
Try

Command1.CommandText = "Select * from Customers"

DataAdapter.SelectCommand = Command1
DataAdapter.Fill(DataTable_1)
DataGridView1.DataSource = DataTable_1
AllRowNumber()
Command1.Transaction.Commit()
Catch ex As Exception
Command1.Transaction.Rollback()
End Try

End Sub

Private Sub AllRowNumber(Optional ByVal Of_1 As Integer = 1)
For i = Of_1 To DataGridView1.RowCount - 1
DataGridView1.Rows(i - 1).Cells(0).Value = i
Next

End Sub

''' <summary>

''' برای حذف رکورد

''' </summary>

''' <param name="ID">این پارامتر شماره رکوردی است که در شرط حذف استفاده میشود</param>

''' <remarks></remarks>

Private Sub DeleteRecord(ByVal ID As String)
Command1.CommandText = "Delete Customers where CustomerID='" + ID + "'"

Command1.ExecuteScalar()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try

If DataGridView1.SelectedRows.Count Then

DeleteRecord(DataGridView1.SelectedRows(0).Cells(1 ).Value)
DataGridView1.Rows.Remove(DataGridView1.SelectedRo ws(0))
Else

MessageBox.Show("©کي©§ی ں뢦ں 묧ى ں«¢")
End If

Catch ex As Exception
MessageBox.Show(ex.Message)
End Try

End Sub

Private Sub DataGridView1_RowsRemoved(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowsRemovedEventA rgs) Handles DataGridView1.RowsRemoved
AllRowNumber(e.RowIndex)
End Sub



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

s.k711
پنج شنبه 07 آذر 1387, 11:00 صبح
سلام جناب آقاي rooshan 2008
من كدي را كه لطف كردينو زحمت كشيدين قرار دادين را استفاده كردم يعني يك پروژه جديد ايجاد كردم و كدهاي شما را در آنجا كپي كردم . همه چيز خوب بود اما وقتي مي خواستم حذف كنم اين پيغام را ميداد. هرچي فكر كردم نفهميدم چرا اينجوري شد.:متفکر:

rooshan2008
پنج شنبه 07 آذر 1387, 17:01 عصر
سلام
من فقط مثال زدم خودم هم اجرا گرفتم و همین پیغام رو میداد چون مشکل شما رو حل می کرد این رو گزاشتم .این خطا طبیعی هست بخاطر اینکه جدول Customer در فیلد CustomerID کلید اصلی و جدول Orders در فیلدCustomerID کلید خارجی است و شما درصورتی که Cascade Delete Realated Fields رو انتخاب نکرده باشید باید اول اطلاعات مرتبط داخل Orders رو حذف کنید و بعد رکورد Customer حذف کنید (من فقط چون توی همه سیستم ها مشترک هست از این جدول استفاده کردم براتون گذاشتم تا راحت تر بتونید اجرا بگیرید) مهم اینه که مشکل شما حل شده باشه

s.k711
شنبه 09 آذر 1387, 08:18 صبح
سلام جناب آقاي rooshan 2008 .
خيلي ممنون از توجهتون.