Ngồi đọc và kiểm tra cả buổi sáng cuối cùng cũng tìm được cách khắc phục. Đó là do dùng chương trình import data từ access vào SQL nên nó mất đi Primarykey. Khi vào SQL đặt khóa chính cho trường dữ liệu thì nó cho edit liền. Nhưng các bạn thử phân tích cái này nhé.Cùng với 1 đoạn code dùng cho access+SQL2000 thì phải khai báo Index/key; Primary còn dùng với VB6+SQL2000 thì bất cầnAh, làm thế nào để gán giá trị vào combobox khi vừa có recordset hả các bác, nếu em dùng cách addItem thì nó chỉ ra được 1 giá trị trong khi em muốn combo box có thể có nhiều giá trị (column). Thông thường trong access thì tại rowsource của comboxbox chỉ cần chọn SELECT gt1,gt2 FROM table là Ok, còn với cái recordset này em vẫn phải loay hoay mãi
 

hoatim_ngoaisan

New Member
Trích:
Nguyên văn bởi behattieu Private Sub Form_Load()
sqlstr = "select * from tbl_bangphong "
Dim db As Connection
Set db = New Connection
db.CursorLocation = adUseClient
' Cau lenh ket noi sql
db.Open "PROVIDER=MSDASQL;driver={SQL Server};server=(local);uid=sa;pwd=sa;database=qlns ;"

Set adoPrimaryRS = New Recordset
' adoPrimaryRS.Open sqlstr, db, adOpenStatic, adLockOptimistic
adoPrimaryRS.Open sqlstr, db, dbOpenDynaset, dbSeeChanges

Set Me.Form.Recordset = adoPrimaryRS

End Sub

các bạn thử xem nó chưa ổn chỗ nào giúp em nhé.Ah, mà em update office2003 chỉ có file Northwind thôi làm gì có cái nào dính với SQL đâu nhỉ
PS: 2 bac phatnq và muontennguoi co YM bất cho em 1 cái để liên lạc cho tiện, nhiều khi post bài bất biết bao giờ mới được trả lời
Y!M: muontennguoi
Trong office2003 có 2 cái sample: 1 cái có da ta Access, 1 cái bất có phải kết nối vào SQL server.
Cái có data là NorthwindCS.mdb còn cái bất có là NorthwindCS.apd

ĐOạn lệnh của bạn chạy trên máy của tui thì nó báo lỗi: biến chưa khai báo tường minh.
Ngoài ra nên khai báo rõ dùng giao diện recordset, connection nào ...

Private Sub Form_Load()
Dim db As Connection
Dim sqlstr As String
sqlstr = "select * from tbl_bangphong "
Set db = New ADODB.Connection
db.CursorLocation = adUseClient
' Cau lenh ket noi sql
db.Open "PROVIDER=MSDASQL;driver={SQL Server};server=(local);uid=sa;pwd=sa;database=qlns ;"
'Chỗ này chỉ nên dùng 1 trong 2: Provider hay driver thôi.
Set adoPrimaryRS = New ADODB.Recordset
adoPrimaryRS.Open sqlstr, db, 3,3 'xem thêm nhận xét phía dưới
Set Me.Form.Recordset = adoPrimaryRS
End Sub

Chỗ open recordset: sqlstr, db, 3,3 hay sqlstr, db, 3,4 đều được.
Nhưng như vừa nói hôm trước nên chọn 3,3 để update ngay từng record khi vừa rời khỏi record đó.
Nếu chọn 3,4 thì phải dùng lệnh UpDateBatch và dùng để update toàn bộ recordset 1 lần.
 
Hãy quên đi cái chuyện tự động Primary Key của Access.
Đó là chuyện phải nhớ kiểm soát chặt chẽ. Dữ liệu phải được kiểm soát tính hợp lệ thường xuyên.

Còn những chuyện recordset thì bất có gì thay đổi cả.
Dù là da ta có nằm chung file .mdb hay bất thì các resoure cũng luôn luôn là recordset.
Việc tách data riêng ra bất hề làm xáo trộn hay thay đổi phần giao diện của các đối tượng.
 
Đúng là chuyển sang ADP có nhiều thứ phải thay đổi quá. Bác có phương án nào giải quyết vấn đề này không:1. Em có 1 form(form1) truy vấn ADO từ table1, trên form1 có 2 textbox txtMaphong, txtTenphong. Trường maphong chỉ có trong table1, còn cả 2 trường maphong,tenphong đều có trong table2. Trước chỉ cần dùng Dlookup("Tenphong","table2","txtMaphong=maphong") tại ô txtTenphong là OK. Giờ em muốn tại ô txtTenphong giá trị được gán theo txtMaphong mà chưa được.2. Tại ô txtmaphong(form1) khi click đúp thì mở form bảngphòng chốngra. Khi click đúp vào giá trị của ngựa phòng(form2) thì đóng bảngphòng chốnglại và chuyển giá trị đó vào ô ngựa phòng (form1).Còn vụ kết nối và sửa dữ liệu thì em làm được rồi. Có 2 cái đều bất cho sửa dữ liệu1. Không khai báo Index,key2.Bỏ mất dòng db.CursorLocation = adUseClientNhưng vẫn chưa hiểu tại sao cái thằng VB nó bất cần khai báo cả 2 cái trên mà vẫn can thiệp được vào dữ liệu
 
Trích:
Nguyên văn bởi behattieu Đúng là chuyển sang ADP có nhiều thứ phải thay đổi quá. Bác có phương án nào giải quyết vấn đề này không:
1. Em có 1 form(form1) truy vấn ADO từ table1, trên form1 có 2 textbox txtMaphong, txtTenphong. Trường maphong chỉ có trong table1, còn cả 2 trường maphong,tenphong đều có trong table2. Trước chỉ cần dùng Dlookup("Tenphong","table2","txtMaphong=maphong") tại ô txtTenphong là OK. Giờ em muốn tại ô txtTenphong giá trị được gán theo txtMaphong mà chưa được.
Có 1 đống cách. Tuỳ theo hứng thích làm theo cách nào.
Tuỳ theo lúc đó đang có cái gì và dự định làm cái form đó để làm gì.
Không thấy cái file của bạn, bất biết bạn đang làm cái gì thì sao trả lời được.

Trích:
Nguyên văn bởi behattieu 2. Tại ô txtmaphong(form1) khi click đúp thì mở form bảngphòng chốngra. Khi click đúp vào giá trị của ngựa phòng(form2) thì đóng bảngphòng chốnglại và chuyển giá trị đó vào ô ngựa phòng (form1).
Đã nói ở topic của tienduyet.

Trích:
Nguyên văn bởi behattieu Còn vụ kết nối và sửa dữ liệu thì em làm được rồi. Có 2 cái đều bất cho sửa dữ liệu
1. Không khai báo Index,key
2.Bỏ mất dòng db.CursorLocation = adUseClient
Nhưng vẫn chưa hiểu tại sao cái thằng VB nó bất cần khai báo cả 2 cái trên mà vẫn can thiệp được vào dữ liệu
Lâu lâu sẽ hiểu ..
 
Của behattieu là file kèm theo phía dưới đây.
Trong chương trình của bạn còn khá nhiều vấn đề chưa xử lý.
Chẳg hạn như: nếu query mà bất có record nào thoả điều kiện thì recordset sẽ là rỗng, khi đó gán vào form nó sẽ ra sao?
Nếu dùng Access trên cùng 1 file thì thực ra Access vừa tự xử lý. Nay ta tự connect thì phải nhớ xử lý.
Chính nhờ tự làm lấy mà ta hiểu rõ hơn hoạt động của máy, điều mà thực ra Access mà ta dùng bấy lâu nay vẫn có làm nhưng ta bất biết.
 

dinhviet30_01

New Member
Thank bác nó cũng tạm ổn nhưng ý em muốn mở rộng lớn nó hơn chắc nói ở trên chưa rõ lắm. Với ví dụ trên1. VÌ form frm_hosocanhan có nhiều ô lấy dữ liệu tương tự bảng nơi khám (trong file ví dụ nên em cắt bớt đi) nên nếu làm ra (tạo) query như trên rất phức tạp. Nếu có cách khai báo dạng rs1, rs2 rồi link được dữ liệu thì tốt hơn. Bên cạnh đó với query như bác có những người họ chưa xác định được nơi KCB thì sẽ thiếu ngay trong form hiện thị. Cái này nếu dùng query chắc phải dùng kiểu relationship left, right, chứ bất theo kiểu trực tiếp như thế được. Hồ sơ nhân sự được nhập ngay từ khi họ mới vào làm việc, nhưng chuyện cấp phát thẻ phải từ sau khi đóng BHXH nên hồ sơ sẽ còn tại trước mặc dù trường MaKCB có thể là Null2.Tại ô gán Tag, em bất muốn chỉ định cụ thể là ô MaKCB mà là 1 ô bất kỳ nào đó đang nhận focus (vì có thể trên form này tên của nó là MaKCB, trên form khác là MaKCB1,..)Thực ra mục đích là Control1 ban đầu kích hoạt Control 2. Control2 sau khi thao tác và close lại thì trả focus cho control 1
 

Euen

New Member
Thì viết ra thêm. Mỗi ô cần gán thì đặt 1 button "Find" kế bên ô đó.

Muốn dùng cho nhiều chuyện khác nhau thì chính cái form Find đó phải thiết kế linh động hơn nữa để nhận tham số truyền vào.
Giống y cái Dlookup vậy thôi.

Nếu lập trình CSDL server-cleint thì hãy quên đi cái relationhship.
Chỉ sử dụng những gì mà chắc chắn rằng tất cả phần mềm CSDL luôn luôn có.
Nếu bất sẽ bất tương thích nhau, giảm tiềm năng khai thác.
 

soi_hoang_7

New Member
Khi em làm ra (tạo) 1 query trong data,mdb có dạng sau:SELECT a.*, b.MaKCB AS xxx, b.TenNKBFROM tbl_hosocanhan AS a LEFT JOIN tbl_0Bangnoikham AS b ON a.MaKCB = b.MaKCB;Thì tại query đó có thể chỉnh sửa dữ liệu bình thường. Tuy nhiên khi sử dụng câu lệnh SQL này cho form frm_hosocanhan thì form frm_hosocanhan lại bất thể chỉnh sửa được.
 

chuot_vip

New Member
Khai báo table nào là Unique để máy biết là MaKCB của table đó là bất chỉnh sửa.
Xem kỹ lại mẫu của tui trong bài trước.
 

thaothanh_298

New Member
Em vừa xử lý được vấn đề này, bất cần dùng Unique, và source của frm_hosocanhan cũng chỉ lấy từ chính tbl_hosocanhan. Cái này có thể áp dụng để mở rộng lớn ghi chú trên mainform mà bất cần thay đổi nguồn vào cho main form.
 

huyen14_10

New Member
Đúng đó. Đó là cách cần làm.
Đừng phụ thuộc trên relationhship.
Query nhiều table chỉ nên dùng để xem.
Cần xem xét cách nào giảm tải cho server.
 

namthanhhnt

New Member
Ah, Bác cho em hỏi 1 cái. Em đang định dùng 1 table để lưu trữ các câu lệnh SQL . Làm thế nào để làm ra (tạo) 1 Function kết nối dạng Public để dùng chung cho toàn bộ các kết nối. Ví dụPrivate Sub Form1_Load()sql="Câu lệnh đựoc lấy từ table SQL"Call ketnoiEnd sub-' + '-' + '-' + '-' + '-' + '-' + '-' + '-Private Sub Form2_Load()sql="Câu lệnh đựoc lấy từ table SQL"Call ketnoiEnd sub-' + '-' + '-' + '-' + '-' + '-' + '-' + '-Module kết nối giờ phải khai báo như thế nào ?-Tiện thể: Có cách nào để gán source object cho 1 subform (dạng datasheet) 1 recordset mà bất tạo thêm 1 table, query hay form khác bất (Chỉ có duy nhất 1 form và trong nó có 1 ô subform còn bất có bất kỳ 1 đối tượng nào khác)
 

phuonghan123

New Member
Trích:
Nguyên văn bởi behattieu Ah, Bác cho em hỏi 1 cái. Em đang định dùng 1 table để lưu trữ các câu lệnh SQL . Làm thế nào để làm ra (tạo) 1 Function kết nối dạng Public để dùng chung cho toàn bộ các kết nối. Ví dụPrivate Sub Form1_Load()sql="Câu lệnh đựoc lấy từ table SQL"Call ketnoiEnd sub-' + '-' + '-' + '-' + '-' + '-' + '-' + '-Private Sub Form2_Load()sql="Câu lệnh đựoc lấy từ table SQL"Call ketnoiEnd sub-' + '-' + '-' + '-' + '-' + '-' + '-' + '-Module kết nối giờ phải khai báo như thế nào ?-Tiện thể: Có cách nào để gán source object cho 1 subform (dạng datasheet) 1 recordset mà bất tạo thêm 1 table, query hay form khác bất (Chỉ có duy nhất 1 form và trong nó có 1 ô subform còn bất có bất kỳ 1 đối tượng nào khác)
Ý bạn tui chưa hiểu lắm, nên hỏi lại bạn cái:Bạn muốn rằng cứ mỗi form thì bạn sẽ cho open cái recordset tương ứng với câu lệnh SQL mà bạn chọn, đúng không?Nếu thế thì bạn làm cái function trả về kết quả là 1 ADODB.Recordset, ví dụ như:public Function MyRecordset(stSQL As String) As ADODB.RecordsetDim connStr As String, dim conn As New ADODB.ConnectionconnStr = "Data Source=servername;Initial Catalog=databasename;User Id=username;Password=password;"On Error Goto err_ConnectionWith conn.ConnectionString = connStr.OpenEnd With Dim rs As New ADODB.RecordsetWith rs.ActiveConnection = conn.LockType = ... 'tùy.CursorLocation = ... 'tùy.Open (stSQL)End WithMyRecordset = rsend_MyRecordset:Exit Functionerr_Connection:MsgBox err.DescriptionMyRecordset = NothingResume end_MyRecordsetEnd FunctionĐại khái vậy.Còn cái câu tiện thể, cũng bất hiểu luôn. Tuy nhiên về nguyên tắc thì subform phải có một source object, có thể là một table, một query, hay một form khác.Nếu là một recordset thì bạn cũng phải làm ra (tạo) form, rồi gán recordsource cho form đó từ cái recordset của bạn.Sau đó bạn lấy cái form đó làm source object cho subform.
 

Cuinn

New Member
Trích:
Nguyên văn bởi phatnq2002 Ý bạn tui chưa hiểu lắm, nên hỏi lại bạn cái:Bạn muốn rằng cứ mỗi form thì bạn sẽ cho open cái recordset tương ứng với câu lệnh SQL mà bạn chọn, đúng không?Nếu thế thì bạn làm cái function trả về kết quả là 1 ADODB.Recordset, ví dụ như:public Function MyRecordset(stSQL As String) As ADODB.RecordsetDim connStr As String, dim conn As New ADODB.ConnectionconnStr = "Data Source=servername;Initial Catalog=databasename;User Id=username;Password=password;"On Error Goto err_ConnectionWith conn.ConnectionString = connStr.OpenEnd With Dim rs As New ADODB.RecordsetWith rs.ActiveConnection = conn.LockType = ... 'tùy.CursorLocation = ... 'tùy.Open (stSQL)End WithMyRecordset = rsend_MyRecordset:Exit Functionerr_Connection:MsgBox err.DescriptionMyRecordset = NothingResume end_MyRecordsetEnd FunctionĐại khái vậy.
Cái đoạn code này hình như bị thiếu từ khóa set tại myrecordset=rs. Em vừa chạy như thế này nhưng bị lỗi:private Sub Form_Load()MyRecordset("select * from table1")set me.form.recordset=rs(hay bằng myrecordset)End Subđều bất chạy được. các bạn thử xem giúp em nó bị do nguyên nhân gì với.-' + '-' + '-' + '-Nếu bất sửa được chuỗi kết nối cho ADP==> nó bắt buộc phải kết nối với SQLserver?. NHư vậy muốn thay đổi chuỗi kết nối như bác muontennguoi nói phải dùng .mdb hay .mde rồi.
 
Trích:
Nguyên văn bởi behattieu Cái đoạn code này hình như bị thiếu từ khóa set tại myrecordset=rs.
Em vừa chạy như thế này nhưng bị lỗi:

Private Sub Form_Load()
MyRecordset("select * from table1")
set me.form.recordset=rs(hay bằng myrecordset)
End Sub
đều bất chạy được. các bạn thử xem giúp em nó bị do nguyên nhân gì với.
Nguyên nhân: trật cơ bản.
Private Sub Form_Load()set me.form.recordset = MyRecordset("select * from table1")End Sub-' + '-' + '-' + '-
Trích:
Nguyên văn bởi behattieu Nếu bất sửa được chuỗi kết nối cho ADP==> nó bắt buộc phải kết nối với SQLserver?. NHư vậy muốn thay đổi chuỗi kết nối như bác muontennguoi nói phải dùng .mdb hay .mde rồi.
Thì mdb hay mde vừa sao nào?
Bồ tưởng xài adp cho khác thường là xịn, là ngon hơn người ta ư?
.adp mặc định connect vào 1 SQL server data.
Tuy nhiên bồ vẫn có thể đóng nó lại và mở .mdb để lấy data.
CurrentProject. CloseConnection '<-' + '-' + '-' + '-' + '-' + '- đóng connection và set nó thành null.
Sau đó làm ra (tạo) 1 connection mới và lấy data.
 

Khoa_Rus

New Member
Trích:
Nguyên văn bởi behattieu Ah, Bác cho em hỏi 1 cái. Em đang định dùng 1 table để lưu trữ các câu lệnh SQL . Làm thế nào để làm ra (tạo) 1 Function kết nối dạng Public để dùng chung cho toàn bộ các kết nối. Ví dụ
Private Sub Form1_Load()
sql="Câu lệnh đựoc lấy từ table SQL"
Call ketnoi
End sub
-' + '-' + '-' + '-' + '-' + '-' + '-' + '-
Private Sub Form2_Load()
sql="Câu lệnh đựoc lấy từ table SQL"
Call ketnoi
End sub
-' + '-' + '-' + '-' + '-' + '-' + '-' + '-
Module kết nối giờ phải khai báo như thế nào ?

-Tiện thể: Có cách nào để gán source object cho 1 subform (dạng datasheet) 1 recordset mà bất tạo thêm 1 table, query hay form khác bất (Chỉ có duy nhất 1 form và trong nó có 1 ô subform còn bất có bất kỳ 1 đối tượng nào khác)
Bạn vừa từng làm:
Dim conn As ADODB.Connection
... open conn ....
Rồi sau đó:
Dim rs As ADODB.Recordset
rs = New ADODB.Recordset
rs.open srtSQL, conn ...
Hiển nhiên là cũng có thể tiếp:Dim rs1 As ADODB.Recordset
rs1 = New ADODB.Recordset
rs1.open srtSQL, conn ...
Dim rs2, rs3, rs4 ...
Tóm lại:
1 Connection dùng để làm ra (tạo) 1 kết nối đến 1 data.
Các Recordset dùng để chứa các kết quả query.

Khai báo public để các form khác có thể nhìn thấy.


Như vậy ta chỉ cần dùng nhiều conn khi cần connect đến nhiều data cùng lúc (các data có thể là khác nhau, thậm chí khác hệcoi nhưSQL server, MySQL, Foxpro, Excel ...).


Vấn đề nữa, bạn vừa từng:Set conn = Nothing
Set rs = Nothing
Điều đó nghĩa là gì?

Bởi vì trong môi trường server-cleint thì cùng lúc có nhiều connect từ phía cleint vào cùng 1 data trên server, do đó, nếu lưu giữ handle của data đó quá lâu hơn mức cần thiết sẽ làm server nhồi máu cơ tim...
Vì thế, bạn vừa cắt đường connect ngay sau khi vừa lấy đủ dữ liệu về máy.

Hãy suy nghĩ khi quyết định: giữ connection để có ngay khi cần; hay là mỗi lần cần thì mỗi lần connect?

Chỉ 1 mình mình dùng trên máy đơn thì hay trên server nhỏ thì chắc bất có hiện tượng quá nhiều connection cùng lúc vào 1 data. Nhưng cần nhớ xoá handle khỏi bộ nhớ khi đóng project. VÌ lúc đó ODBC vẫn còn đang mở data. Phải báo đóng lại bằng Set conn= Nothing
Với Access nghe nói có thể chịu cùng lúc 31 connection.
Nhưng khi tui thử trên máy của tui thì chưa bao giờ nó nối nổi cùng lúc 12 connection.
Nghe nói SQL server có thể chịu nổi cùng lúc hàng ngàn connection.
 

aprina28

New Member
1/Đang gán đoạn code của bác vào chương trình nhưng chưa chạy. Ý của em cụ thể thế này:Trong chương trình ta có nhiều form. Mỗi form sẽ được gán bằng 1 recordset. Thay vì phải theo dõi đoạn code rất dài và mỗi lần sửa thì phải thay thế các khai báo kết nỗi trong từng form thì ta khai báo chung 1 function kết nối. Khi kích hoạt mỗi form thì chỉ cần khai báo chuỗi SQl cho form rồi gọi function để kết nối với SQL khai báo. Nếu rộng lớn hơn nữa về sau ta chỉ cần thay đổi các thông tin kết nối được lưu trữ trong 1 table để kết nối từ chươngtrình đến CSDL2/Còn về cái mục tiện thể thì em đi được 1/2 quãng đường rồi. Trước đây dữ liệu của em rất nhiểu quan hệ 1-nhiều nên phải dùng kiểm master-Detail nên toàn dùng mainform và subform. Nay em chỉ muốn dùng 1 form mà thể hiện Master/Detail. Sau một hồi hì hục thì vừa nghĩ ra là dùng 1 cái kết nối với master còn thay thế subform bằng datagrid. Tuy nhiên mới đựoc 1 nửa đoạn đường vì thằng datagrid chưa biết làm sao để update dữ liệu (có thể edit nhưng chưa biết cách update). Bên cạnh đó dữ liệu tại datagrit nó bất có dạng nhiều dòng trong 1 ô mặc dù vừa để chiều cao của dòng dữ liệu chứa được đến vài dòng. các bạn giúp chuyện edit cái datagrid hộ em vớiBài viết vừa rồi của bác muontennguoi chính là cách thức mà em vừa sử dụng để làm ra (tạo) các ghi chú cho mainform
 

Các chủ đề có liên quan khác

Top