-
Nối dữ liệu từ nhiều file Access??
btnnhut > 27-06-17, 12:35 PM
Mình đang tìm hiểu cách để nối dữ liệu của Access. Cụ thể: ta có dữ liệu DATA1, DATA2, DATA3 của Access trong đó có table cùng tên cùng cấu trúc. Một ngày đẹp trời mình muốn gộp cả 3 file DATAx này lại thành 1 file DATA, bằng 1 cú lick chuột vào nút Button tại file GopFile (như file liên kết đính kèm) !?
Làm hoài chưa được, bạn nào giúp hoặc chỉ hướng giải quyết giùm mình
.
https://drive.google.com/open?id=0BxlFQA...Wl6Nk1oWXc -
RE: Nối dữ liệu từ nhiều file Access??
tranthanhan1962 > 27-06-17, 01:47 PM
Có 2 cách: trước hết tạo CSDL có liên kết table với 3 CSDL
Dùng query union để nối: Tạo unionquery. Ưu điểm: nhanh, gọn, lẹ, chỉ cần tạo query là sử dụng luôn mà không cần sử dụng lệnh gì cả. Khuyết điểm: các record của 3 table không được trùng dữ liệu tất cả các field, nếu không các record trùng sẽ bị lọc bỏ chỉ còn 1 record duy nhất.
Dùng lệnh RunSQL của append query để chép các record của từng table của 3 DATA1, DATA2, DATA3 lần lượt vào table của DATA. Nhớ xóa trắng table của DATA trước khi chép để tránh trùng lắp dữ liệu. -
RE: Nối dữ liệu từ nhiều file Access??
cpucloi > 27-06-17, 05:17 PM
Tôi hơi thủ công chút.
Tôi có 7 table giống nhau.
B1: Tạo một bảng ....tam với cấu trúc như 7 bảng kia (từ bảng 1 tao nên bảng này)
B2: Appen các bảng khác (lần lượt từ B2 đến B7)
B3: Sau khai thác xong, xóa bảng ...tam
P/s: Đương nhiên unionquery nhanh hơn và phù hợp hơn, nhưng với những người mới và số record không lớn, tôi nghĩ phương án trên cũng khả thi -
RE: Nối dữ liệu từ nhiều file Access??
btnnhut > 28-06-17, 09:53 AM
(27-06-17, 01:47 PM)tranthanhan1962 Đã viết: Có 2 cách: trước hết tạo CSDL có liên kết table với 3 CSDL
Dùng query union để nối: Tạo unionquery. Ưu điểm: nhanh, gọn, lẹ, chỉ cần tạo query là sử dụng luôn mà không cần sử dụng lệnh gì cả. Khuyết điểm: các record của 3 table không được trùng dữ liệu tất cả các field, nếu không các record trùng sẽ bị lọc bỏ chỉ còn 1 record duy nhất.
Dùng lệnh RunSQL của append query để chép các record của từng table của 3 DATA1, DATA2, DATA3 lần lượt vào table của DATA. Nhớ xóa trắng table của DATA trước khi chép để tránh trùng lắp dữ liệu.
Cách của bạn mình đã làm được rồi, mình muốn dùng VBA code để thực hiện, cám ơn bạn góp ý. -
RE: Nối dữ liệu từ nhiều file Access??
tranthanhan1962 > 28-06-17, 10:27 AM
Code VB thì như thế này: Giả sử nút nhấn là NutChep và 3 table DATA1,DATA2, DATA3 và DATA là table tổng hợp. Code VBA như thế này:
Mã:Private Sub NutChep_Click()
Docmd.RunSQL "DELETE DATA.* FROM DATA;"
Docmd.RunSQL "INSERT INTO DATA ( Field1, Field2,... ) SELECT DATA1.Field1, DATA1.Field2, ... FROM DATA1;"
Docmd.RunSQL "INSERT INTO DATA ( Field1, Field2,... ) SELECT DATA2.Field1, DATA2.Field2, ... FROM DATA2;"
Docmd.RunSQL "INSERT INTO DATA ( Field1, Field2,... ) SELECT DATA3.Field1, DATA3.Field2, ... FROM DATA3;"
End Sub -
RE: Nối dữ liệu từ nhiều file Access??
btnnhut > 28-06-17, 01:06 PM
(28-06-17, 10:27 AM)tranthanhan1962 Đã viết: Code VB thì như thế này: Giả sử nút nhấn là NutChep và 3 table DATA1,DATA2, DATA3 và DATA là table tổng hợp. Code VBA như thế này:
Mã:Private Sub NutChep_Click()
Docmd.RunSQL "DELETE DATA.* FROM DATA;"
Docmd.RunSQL "INSERT INTO DATA ( Field1, Field2,... ) SELECT DATA1.Field1, DATA1.Field2, ... FROM DATA1;"
Docmd.RunSQL "INSERT INTO DATA ( Field1, Field2,... ) SELECT DATA2.Field1, DATA2.Field2, ... FROM DATA2;"
Docmd.RunSQL "INSERT INTO DATA ( Field1, Field2,... ) SELECT DATA3.Field1, DATA3.Field2, ... FROM DATA3;"
End Sub
Mình cũng đã giải quyết được rồi, link đính kèm có ai phân tích giùm mình cách của mình hay dở chỗ nào??(vô file GopFile click nut button "Gop File" chạy)
Cách của bạn, mình chưa hiểu lắm...Gì bạn code để mình học hỏi với
Cám ơn bạn nhiều.
https://drive.google.com/file/d/0BxlFQAQ...sp=sharing -
RE: Nối dữ liệu từ nhiều file Access??
ongke0711 > 28-06-17, 02:39 PM
Bạn có thể dùng Collection để gộp 3 cái DATA lại rồi xử lý một lần cho gọn. Dùng Insert into. Chiều rảnh code cho bạn tham khảo. -
RE: Nối dữ liệu từ nhiều file Access??
ongke0711 > 29-06-17, 01:26 AM
Nếu chỉ đơn giản là bạn muốn gộp 1 table nào đó (table "A") trong cái database thôi thì code như bên dưới.
- Code này tự động nối được nhiều trường trong table chứ không phải làm thủ công từng Field như code bạn đang làm.
Vd: rs!ten = rs1.Fields("ten").Value => Nếu table có mấy chục Field thì thêm cũng mệt nghỉ.
- Không cần khai báo một đống biến rs1, rs2, rs3, con1, con2, con3.
- Không lập lại các đoạn code Open Connection, Open Recordset giống nhau, chỉ khác tham số. Nếu gặp trường hợp cần nối 10 cái file .accdb thì code lập lại một chục lần, kéo trang mỏi tay luôn.
- Code gồm 1 cái Function GetRecordset () để lấy Recordset từ 3 table ở 3 cái database Data1, 2, 3. Tránh việc lập lại code giống nhau cho cả 3 lần như bạn đang làm.
- Gồm 1 Sub MergeTables () để gán trị của các trường trong table ở Database nguồn vào table ở database đích. Trong Sub này dùng 1 Collection để lần lượt loop qua các Database.
Mã PHP:Option Explicit
Dim DBFile As Variant
Private Sub gopFile_Click()
MergeTables
End Sub
Private Sub MergeTables()
Dim rsDest As New ADODB.Recordset
Dim rsSource As New ADODB.Recordset
Dim fld As ADODB.Field
Dim DBFileList As Collection
Dim SourceTable As String
Dim DestTable As String
Set DBFileList = New Collection
DBFileList.Add "Data1.accdb"
DBFileList.Add "Data2.accdb"
DBFileList.Add "Data3.accdb"
SourceTable = "A" 'Tên table 'A' giông nhau o tat ca cac file DATA 1,2,3
DestTable = "A"
Set rsDest = GetRecordset("SELECT * FROM " & DestTable & "", "DATA.accdb")
For Each DBFile In DBFileList
Debug.Print "Lay du lieu tu file: " & DBFile
Set rsSource = GetRecordset("SELECT * FROM " & DestTable & "", DBFile)
Do Until rsSource.EOF
rsDest.AddNew
For Each fld In rsSource.Fields
If (fld.Attributes And dbAutoIncrField) = dbAutoIncrField Then
'do nothing - bo qua field AutoNumber
Else
rsDest.Fields(fld.Name).Value = fld.Value
End If
Next
rsDest.Update
rsSource.MoveNext
Loop
rsSource.Close
Next
MsgBox "Thanh cong", vbOKOnly, "Thông báo"
rsDest.Close
Set rsDest = Nothing
Set rsSource = Nothing
End Sub
Function GetRecordset(strSQL As String, DBName As Variant) As ADODB.Recordset
On Error GoTo HandleError
Dim DBPath As String
DBPath = CurrentProject.Path
Dim conn As New ADODB.Connection
If conn.State And adStateOpen = adStateOpen Then conn.Close
With conn
.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" & DBPath & "\" & DBName & ";Uid=;Pwd=;"
.Open
End With
Dim rsCont As New ADODB.Recordset
With rsCont
.CursorType = adOpenDynamic
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.Open strSQL, conn
'.ActiveConnection = Nothing
End With
'conn.Close
Set GetRecordset = rsCont
Exit Function
HandleError:
MsgBox "Error: " & Err.Number & vbCrLf & "Description: " & Err.Description
Exit Function
End Function
Bên cạnh đó sẽ có trường hợp khác là: 3 cái database này có nhiều table và cùng tên, cùng cấu trúc yêu cầu gộp tất cả các table này vào cái database khác cũng có nhiều table cùng tên? (Gộp nhiều table chứ không phải 1 cái table như trong ví dụ của bạn). Cái này giống như cùng một file back-end bạn copy cho nhiều chi nhánh nhập liệu sau đó muốn gộp tất cả dữ liệu của các file BE ở chi nhánh thành file BE tổng công ty. Trường hợp này thì tôi chưa code cho nó. Rảnh rỗi sẽ suy nghĩ làm.
------------------------------------------------------------------------------
Code cũ của bạn:
Mã PHP:Dim rs As New ADODB.Recordset, rs1 As New ADODB.Recordset, rs2 As New ADODB.Recordset, rs3 As New ADODB.Recordset
[/font]
Dim con As New ADODB.Connection, con1 As New ADODB.Connection, con2 As New ADODB.Connection, con3 As New ADODB.Connection
Dim duongDan As String
Dim sqlS1 As String
Private Sub gopFile_Click()
Dim a As String, b As String
duongDan = CurrentProject.Path
If con.State = adStateOpen Then con.Close
With con
.CursorLocation = adUseClient
.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" & duongDan & "\DATA.accdb;Uid=Admin;Pwd=;"
.Open
End With
sqlS1 = "Select * from A"
With rs
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockOptimistic
.Open sqlS1, con, , , adCmdText
End With
If con1.State = adStateOpen Then con1.Close
With con1
.CursorLocation = adUseClient
.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" & duongDan & "\DATA1.accdb;Uid=Admin;Pwd=;"
.Open
End With
If rs1.State = adStateOpen Then rs1.Close
With rs1
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockOptimistic
.Open "A", con1, , , adCmdTable
End With
If con2.State = adStateOpen Then con2.Close
With con2
.CursorLocation = adUseClient
.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" & duongDan & "\DATA2.accdb;Uid=Admin;Pwd=;"
.Open
End With
If rs2.State = adStateOpen Then rs2.Close
With rs2
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockOptimistic
.Open "A", con2, , , adCmdTable
End With
If con3.State = adStateOpen Then con3.Close
With con3
.CursorLocation = adUseClient
.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" & duongDan & "\DATA3.accdb;Uid=Admin;Pwd=;"
.Open
End With
If rs3.State = adStateOpen Then rs3.Close
With rs3
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockOptimistic
.Open "A", con3, , , adCmdTable
End With
Do Until rs1.EOF
rs.AddNew
rs!ten = rs1.Fields("ten").Value
rs.Update
rs1.MoveNext
Loop
rs1.Close
con1.Close
Do Until rs2.EOF
rs.AddNew
rs!ten = rs2.Fields("ten").Value
rs.Update
rs2.MoveNext
Loop
rs2.Close
con2.Close
Do Until rs3.EOF
rs.AddNew
rs!ten = rs3.Fields("ten").Value
rs.Update
rs3.MoveNext
Loop
rs3.Close
con3.Close
rs.Close
con.Close
MsgBox "Thanh Cong", vbOKOnly, "Thong bao"
[font=Tahoma]End Sub -
RE: Nối dữ liệu từ nhiều file Access??
tranthanhan1962 > 29-06-17, 07:51 AM
Sorry, Quên vụ các table cùng thứ tự field và cấu trúc field (Nhờ ongke0711 mới nhớ). Có thể dùng code này:
Mã:Private Sub NutChep_Click()
Docmd.RunSQL "DELETE DATA.* FROM DATA;"
Docmd.RunSQL "INSERT INTO DATA SELECT DATA1.* FROM DATA1;"
Docmd.RunSQL "INSERT INTO DATA SELECT DATA2.* FROM DATA2;"
Docmd.RunSQL "INSERT INTO DATA SELECT DATA3.* FROM DATA3;"
End Sub -
RE: Nối dữ liệu từ nhiều file Access??
ongke0711 > 29-06-17, 10:58 AM
@btnnhut:
Đối với bài toán của bạn nếu dùng DAO sẽ gọn gàng hơn dùng ADO. Tại sao bạn dùng ADO mà không dùng DAO?
Tôi vẫn luôn thích dùng câu lênh Action SQL hơn là dùng Recordset trong VBA. Nó là câu lệnh “Insert Into…” của bác tranthanhan1962 đã hướng dẫn cho bạn đó. Đối với câu lệnh “Insert Into…”, nó cập nhật một lúc một tập các records thay vì cập nhật từng record như code cho Recordset (rs.Addnew…) .
@ bác tranhthanhan1962:
Thường thì em thích dùng db.Execute hơn là Docmd.RunSQL vì: nó có luôn phần bẫy lỗi nếu phát sinh lỗi (dbFailOnError) để trả lại hiện trạng ban đầu. Bên cạnh đó khỏi cần phải dùng cập lệnh SetWarnings True/False để tắt thông báo mặc định của Access.