PDA

View Full Version : Adodc



A.Noor
چهارشنبه 08 مرداد 1382, 14:08 عصر
با سلام

در اکثر سوالات مطرح شده در این قسمت وقتی می‌خواهند با بانک اطلاعاتی کار کنند از شی Adodc استفاده می‌کنند اما بهتر نیست که از طریق کدنویسی با بانک ارتباط برقرار کنیم?
مثلا اگر نام بانک ما Heasab.mdb باشد و بخواهیم از جدولی بنام Sanad رکوردست تشکیل دهیم در قسمت Declaration ماجول تعریف کنیم


Public DB As New ADODB.Connection
Public SanadRS As New ADODB.Recordset ' Sanad Table

و در هر جا از پروژه که لازم باشد بانک و رکودست را به این شکل باز کنیم :

Dim SDBName As String
Dim StrSQL As String

DB.CursorLocation = adUseClient
SDBName = "Driver={Microsoft Access Driver (*.mdb)};dbq=" + App.Path + "\Hesab.mdb"
DB.Mode = adModeReadWrite
DB.Open SDBName

StrSQL = "SELECT * FROM Sanad ORDER BY Row "
SanadRS.Open StrSQL, DB, adOpenKeyset, adLockOptimistic

حسن این روش اینست که در هر جای پروژه به رکوردستمان دسترسی داریم و ضمنا می‌توانیم چند رکوردست دیگر هم با همین کانکشن ( DB ) باز کنیم.

می‌خواستم نظر دوستانی که با هر دو روش کار کرده‌اند را بپرسم که محاسن و معایب هر کدام چیست و برنامه‌نویسان حرفه‌ای کدام روش را استفاده می‌کنند؟

Abbas Arizi
چهارشنبه 08 مرداد 1382, 14:32 عصر
اتفاقا من هم بارها میخواستم این مطلب رو اینجا عنوان کنم ولی بنا به دلایلی از این کار خودداری کردم. حالا که شما گفتید این مطلب رو من اضافه میکنم که کنترل Adodc رو مایکروسافت تنها به عنوان یک ابزار کمکی برای آشنایی با ADO توی کامپوننتهای VB قرار داده و برای کار جدی و حرفه ای استفاده از اون زیاد جالب نیست.
ضمن اینکه با استفاده از این کنترل فقط امکان استفاده از ADO 2.0 را خواهیم داشت و از امکانات نسخه های جدید (فکر کنم آخرین نسخه اون ورژن 2.7 باشه) محروم خواهیم بود.

S.Azish
چهارشنبه 08 مرداد 1382, 14:42 عصر
بله, به مطلب خوبی اشاره کردید. دوستان سعی کنید به هیچ وجه از ADODC استفاده نکنید و از روشهای زیر استفاده کنید. به این شکل هم کنترل خیلی بیشتری روی کد دارید و هم برنامه شما بسیار سریعتر اجرا میشه.


اول یک متغیر Global برای Connection در سطح پروژه داشته باشید و اونو در Sub Main باز کنید




Option Explicit
Public gCn As ADODB.Connection


'It's better to always start your applications from (Sub Main)
'You can change it in project properties in Project menu
Public Sub Main()
'
'********
'Creating a new instance of the connection
Set gCn = New ADODB.Connection

'opening the new connection
With gCn
.ConnectionString = "your connection string"
.CursorLocation = adUseClient
.Open
End With

'**********
'Start the actual application
'like frmMain.show
'
End Sub



بعد هر جایی که در پروژه نیاز به Recordset دارید اونو باز کنید





'

'Never use New keyword in Dim statement because it will slow down the process of accessing the object
Dim rsTmp As ADODB.Recordset


'Creating a new instance of recordset object
Set rsTmp = New ADODB.Recordset


'For readonly recordsets use this statement
Set rsTmp = gCn.Execute("SELECT * FROM tblTest")

'for non readonly recordset use this statement
rsTmp.Open "SELECT * FROM tblTest", gCn, adOpenDynamic, adLockOptimistic


'if you want to execute an sql statement without any return use this statement
Call gCn.Execute("UPDATE tblTest SET FName = 'something'")



'always close your recordset and free resources
rsTmp.Close
Set rsTmp = Nothing
'



و زمانی که قصد بستن Application رو دارید Connection رو از بین ببرید




'
gCn.Close
Set gCn = Nothing
'



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

کم حوصله
چهارشنبه 08 مرداد 1382, 19:05 عصر
سلام
این روش بسیار عالی و خوب است ولی معایبی هم دارد و آن حساسیت خیلی بالای آن است
بطوری که اگر شما بخواهید با دستوری مقداری را داخل یکی ار textbox که به این شی وصل است بریزید هنگام update شدن پیغام خطا می دهد مخصوصا اگر تعداد فیلد های شما ار 40 عدد بالا برود


برای پروژه های معمولی این روش مناسبه. برای پروژه های بزرگ با تعداد کاربرهای زیاد روشهای بهتری هست.
آقا دمت گرم قرار نشد فقط تعریف کمی و دلمان را به تاپ تاپ بندازی :cry:
بگو بدونیم قضیه چیه آخه من یک پروژه دستمه که حدودا 170 فرم داره و هر کدام از فرمها تقریباً مابین 235 تا 275 فیلد در خود دارند و امکان باز شدن فرمها همزمان باید یاشد ولی مشکلی که الان من باهاش مواجه شدم اینکه نعداد فرمهای باز شده از 10 -12 که می گذره زار می زنه :cry:
چه کنم راه حلش چیه (اون موضوع بالایی یادت نره :oops: )

sunboy
چهارشنبه 08 مرداد 1382, 20:12 عصر
سلام
اقا ما این کاری که شما گفتید کردیم ولی این پیغامو گرفتیم



User-defied type not defined

من با این نوع کانکت شد یکیمی اشنام توی ASP کار کردم ولی الان این می گه چی کار کنم

Abbas Arizi
چهارشنبه 08 مرداد 1382, 20:24 عصر
شما باید قبلش از منوی
Project<Refrence<Microsoft ActiveX Data Objects 2.0 Library
ADO رو به refrence های پروژه اضافه کنی که احتمالا این کار رو انجام ندادی.
البته به غیر از 2.0 ممکنه ورژنهای 2.1 و 2.5 و 2.6 و .... رو هم ببینی.

sunboy
چهارشنبه 08 مرداد 1382, 22:08 عصر
سلام
اقا اون کاری که گفتید من انجام دادم ولی یه مشکل دیگه پیدا شد
من این کدرو می نویسم


Dim str As String
con.CursorLocation = adUseClien
str = "Driver={Microsoft Access Drive(*.mdb)};dbq=g:\test visualbasic.mdb"
con.Mode = adModeReadWrite
con.Open str
' command
con.Close

End Sub

ولی این پیغامو وقتی رو دکمه کلیک می کنم می ده

'object variable or with block variable not set



راستی من نمی تونم از DNS ها استفاده کنم
نظرتون در این باره چیه ؟

Abbas Arizi
چهارشنبه 08 مرداد 1382, 23:31 عصر
احتمالا فراموش کردی که شیی Connection رو Set کنی

Set adoConn = New ADODB.Connection
در ضمن برای اتصال اگه از این روش استفاده کنی فکر کنم راحتتر باشه.

adoConn.Provider = "Microsoft.Jet.OLEDB.4.0"
adoConn.Open FileName

جلوی Open فقط کافیه که نام و مسیر فایل رو بنویسی.
اگه بانکت Access 97 باشه به جای 4.0 باید بنویسی 3.51

A.Noor
پنج شنبه 09 مرداد 1382, 07:53 صبح
rsTmp.Open "SELECT * FROM tblTest", gCn, adOpenDynamic, adLockOptimistic

adOpenDynamic ظاهرا برای وقتی خوب هست که رکوردست توسط چند کاربر در شبکه بطور همزمان استفاده میشه و برای اینکه آخرین تغییرات ایجاد شده توسط اونها به رکودست سایر کاربران هم منعکس بشه از روش دینامیک استفاده می‌کنند . خواستم ببینم که درسته یا نه؟

S.Azish
پنج شنبه 09 مرداد 1382, 15:00 عصر
مسلمآ ‌این روش رو که من گفتم برای Bind کردن کنترلها مناسب نیست و باید تمام کارها به صورت دستی انجام بشه. روش دوم که بهتر از روش اول هست ایجاد یک کلاس به ازای هر موجودیت Entity در Database هست و بعد تولید فیلدها به صورت Property به مثال زیر دقت کنید:



'a class module
Option Explicit
Private connDB As ADODB.Connection
Private mFirstName As String
Private mLastName As String
Private Changed As Boolean
Private m_ID As Long

Private Sub Class_Initialize()
'

Set connDB = New ADODB.Connection
With connDB
.ConnectionString = "your connection string"
.Open
End With
'
End Sub

Private Sub Class_Terminate()
'
If Changed Then Call Update
connDB.Close
setconndb = Nothing
'
End Sub

Public Property Get FirstName() As String
FirstName = mFirstName
End Property

Public Property Let FirstName(ByVal vNewValue As String)
'
mFirstName = vNewValue
Changed = True
'
End Property

Public Property Get LastName() As String
LastName = mLastName
End Property

Public Property Let LastName(ByVal vNewValue As String)
'
mLastName = vNewValue
Changed = True
'
End Property

Public Property Get ID() As Long 'This property id read only because I supposed it's identity or autonumber in db
ID = m_ID
End Property

Public Sub RetriveDate(ByVal ID As Long)
'
Dim rsTmp As ADODB.Recordset

Set rsTmp = connDB.Execute("SELECT * FROM tblTest WHERE ID = " & ID)

If rsTmp.State = adStateOpen Then
With rsTmp
m_ID = ID
mFirstName = .Fields("FirstName") & ""
mLastName = .Fields("LastName") & ""
.Close
End With
End If
Set rsTmp = Nothing
'
End Sub

'To get a list of whole records in table
Public Function GetList(ByRef rsResult As ADODB.Recordset) As Long
'
Dim lngRecAffects As Long

Set rsResult = connDB.Execute("SELECT * FROM tblTest;", lngRecAffects)
GetList = lngRecAffects
'
End Function

'adds a new record
Public Function AddNew() As Long
'
Dim strSQL As String
Dim lngRecAffects As Long

strSQL = "INSERT INTO tblTest (FirstName, LastName) VALUES('" & mFirstName & "', '" & _
mLastName & "');"

Call connDB.Execute(strSQL, lngRecAffects)

AddNew = lngRecAffects
'
End Function

'Updates changes
Public Function Update() As Long
'
Dim strSQL As String
Dim lngRecAffects As Long

strSQL = "UPDATE tblTest SET FirstName = '" & mFirstName & "', LastName = '" & mLastName & _
"' WHERE ID = " & m_ID

Call connDB.Execute(strSQL, lngRecAffects)

Update = lngRecAffects
Changed = False
'
End Function


و برای استفاده از اون



Option Explicit
Private mCustomer As Customer

Private Sub Form_Load()
'

Set mCustomer = New Customer

Call mCustomer.RetriveDate(1)
txtFirstName.Text = mCustomer.FirstName
txtLastName.Text = mCustomer.LastName
'
End Sub

Private Sub cmdAddNew_Click()
'
With mCustomer
.FirstName = txtFirstName.Text
.LastName = txtLastName.Text
.AddNew
End With
'
End Sub

Private Sub cmdUpdate_Click()
'
With mCustomer
.FirstName = txtFirstName.Text
.LastName = txtLastName.Text
.Update
End With
'
End Sub


این روش از قبلی بهتره ولی هنوز بهترین روش نیست. در ضمن پروژه شما چی هست!

sunboy
پنج شنبه 09 مرداد 1382, 15:54 عصر
یه دفترچه تلفن