Cập nhật hoặc thêm dữ liệu từ Excel vào Access

  • Thread starter Thread starter popog
  • Ngày gửi Ngày gửi
Liên hệ QC

popog

Thành viên chính thức
Tham gia
17/3/11
Bài viết
75
Được thích
4
Chào mọi người.
Mình đang mày mò ADO. Trên userform Excel mình tạo một nút bấm, khi bấm thì dữ liệu trên sẽ chuyển vào access, nếu mã sản phẩm có rồi thì nó thực hiện đổi tên (Update) còn nếu không thì sẽ thêm cả mã và tên vào Accces.
Dữ liệu mình có dạng như sau (ví dụ):
Code Name
120931 Cốc
390032 Máy khoan
100122 Máy nóng lạnh A
110144 Máy lọc nước
200601 Thùng carton

Dòng mã có dạng sau:
Mã:
Dim objcommand As ADODB.Command
Dim j As Long, lRecordsAffected As Long
Dim sConnect As String
....
    For j = LBound(Arr, 1) To UBound(Arr, 1)
        objcommand.CommandText = "UPDATE [DATA] " & _
        "SET [Name]='" & Arr(j, 2) & "'" & _
        " WHERE [Code] = '" & (Arr(j, 1) & "';"
        objcommand.Execute recordsaffected:=lRecordsAffected, Options:=adCmdText Or adExecuteNoRecords
        If lRecordsAffected < 1 Then
             objcommand.CommandText = "INSERT INTO [DATA] ([Code], [Name 1])" & _
             " VALUES ('" & (Arr(j, 1) & "', '" & (Arr(j, 2) & "');"
             objcommand.Execute recordsaffected:=lRecordsAffected, Options:=adCmdText Or adExecuteNoRecords
        End If
    Next i

Nhưng khi mình chạy sub thì nếu mã đã có thì tất cả các mã đó được update nhưng nếu chưa có thì chỉ mã đầu tiên chưa có của lần chạy đó được thêm vào access (nên có bao nhiêu mã mới phải chạy bấy nhiêu lần sub). Mình có thử thì thấy nguyên nhân là do thông số lRecordsAffected, nếu để lRecordsAffected = 0 ngay sau mỗi lần chạy next i thì tất cả mã mới được thêm vào hết nhưng lại không update được mã nữa.

Mình mới tập tành ADO(đọc và áp dụng luôn vào công việc, sai đâu sửa đó) nên nhiều chỗ chưa thấu. Mọi người giúp mình có phương án nào cho trường hợp này không?[/Code]
 
Lần chỉnh sửa cuối:
Tôi thường làm kiểu này, bạn thử áp dụng xem sao:

Mã:
Sub Test()
    Dim arrHangHoa
    Dim e As Long, r As Long
    Dim objAdoConn As Object, objAdoRcSet As Object
    Dim strAdoConn As String, strPath As String, strSQL1 As String, strSQL2 As String
    
    Set objAdoConn = CreateObject("ADODB.Connection")
    Set objAdoRcSet = CreateObject("ADODB.RecordSet")
    
    strPath = "C:\Users\HoangTrongNghia\Desktop\Update.accdb"
    strAdoConn = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & strPath & " ;"
    objAdoConn.Open strAdoConn
    
    e = Sheets("Sheet3").Range("A" & Rows.Count).Row
    arrHangHoa = Sheets("Sheet3").Range("A2:B" & e).Value
    
    With objAdoRcSet
        For r = 1 To UBound(arrHangHoa)
            strSQL1 = "SELECT MaHieu FROM [tblHangHoa] WHERE MaHieu='" & arrHangHoa(r, 1) & "'"
            .Open objAdoConn.Execute(strSQL1)
            If .EOF Then 'neu khong ton tai
                strSQL2 = "INSERT INTO [tblHangHoa] (MaHieu, TenHang) VALUES ('" & arrHangHoa(r, 1) & "', '" & arrHangHoa(r, 2) & "')"
                objAdoConn.Execute strSQL2
            Else
                strSQL2 = "UPDATE [tblHangHoa] SET MaHieu='" & arrHangHoa(r, 1) & "', TenHang='" & arrHangHoa(r, 2) & "' " & _
                          "WHERE MaHieu='" & arrHangHoa(r, 1) & "'"
                objAdoConn.Execute strSQL2
            End If
            .Close
        Next
    End With
    
    objAdoConn.Close
    Set objAdoRcSet = Nothing
    Set objAdoConn = Nothing
End Sub
 
Tôi thường làm kiểu này, bạn thử áp dụng xem sao:

Mã:
Sub Test()
    Dim arrHangHoa
    Dim e As Long, r As Long
 ---

Bạn cho mình hỏi, trong cái code của mình, cái chỉ số lRecordsAffected sinh ra từ lần biến đổi trước được truyền cho lần biến đổi sau hả bạn? Mình đọc tài liệu thì hiểu là mỗi lần nó sẽ sinh ra riêng một giá trị.
 
Bạn cho mình hỏi, trong cái code của mình, cái chỉ số lRecordsAffected sinh ra từ lần biến đổi trước được truyền cho lần biến đổi sau hả bạn? Mình đọc tài liệu thì hiểu là mỗi lần nó sẽ sinh ra riêng một giá trị.
Bạn chỉ đưa lên 1 phần code nên tôi không biết giá trị thực của nó như thế nào, hiện tại, tôi chỉ thấy giá trị của nó bằng 0 mà thôi.
 
Bạn cho mình hỏi, trong cái code của mình, cái chỉ số lRecordsAffected sinh ra từ lần biến đổi trước được truyền cho lần biến đổi sau hả bạn? Mình đọc tài liệu thì hiểu là mỗi lần nó sẽ sinh ra riêng một giá trị.
The number of rows changed, inserted, or deleted; 0 if no rows were affected or the statement failed; and -1 for SELECT statements.
Nếu có thay đổi nó sẽ >0 insert update, không thây đổi nó sẽ bằng không. Nếu bạn update =0 thì chắc chắn không có thay đổi thì bạn insert vào
 
Nhưng khi mình chạy sub thì nếu mã đã có thì tất cả các mã đó được update nhưng nếu chưa có thì chỉ mã đầu tiên chưa có của lần chạy đó được thêm vào access (nên có bao nhiêu mã mới phải chạy bấy nhiêu lần sub). Mình có thử thì thấy nguyên nhân là do thông số lRecordsAffected, nếu để lRecordsAffected = 0 ngay sau mỗi lần chạy next i thì tất cả mã mới được thêm vào hết nhưng lại không update được mã nữa.

Lỗi nằm ở cái biến lRecordAffected thứ 2 (ở phần Insert). Bạn bỏ nó đi.
 
Chào mọi người.
Mình đang mày mò ADO. Trên userform Excel mình tạo một nút bấm, khi bấm thì dữ liệu trên sẽ chuyển vào access, nếu mã sản phẩm có rồi thì nó thực hiện đổi tên (Update) còn nếu không thì sẽ thêm cả mã và tên vào Accces.
Dữ liệu mình có dạng như sau (ví dụ):
Code Name
120931 Cốc
390032 Máy khoan
100122 Máy nóng lạnh A
110144 Máy lọc nước
200601 Thùng carton

Dòng mã có dạng sau:
Mã:
Dim objcommand As ADODB.Command
Dim j As Long, lRecordsAffected As Long
Dim sConnect As String
....
    For j = LBound(Arr, 1) To UBound(Arr, 1)
        objcommand.CommandText = "UPDATE [DATA] " & _
        "SET [Name]='" & Arr(j, 2) & "'" & _
        " WHERE [Code] = '" & (Arr(j, 1) & "';"
        objcommand.Execute recordsaffected:=lRecordsAffected, Options:=adCmdText Or adExecuteNoRecords
        If lRecordsAffected < 1 Then
             objcommand.CommandText = "INSERT INTO [DATA] ([Code], [Name 1])" & _
             " VALUES ('" & (Arr(j, 1) & "', '" & (Arr(j, 2) & "');"
             objcommand.Execute recordsaffected:=lRecordsAffected, Options:=adCmdText Or adExecuteNoRecords
        End If
    Next i

Nhưng khi mình chạy sub thì nếu mã đã có thì tất cả các mã đó được update nhưng nếu chưa có thì chỉ mã đầu tiên chưa có của lần chạy đó được thêm vào access (nên có bao nhiêu mã mới phải chạy bấy nhiêu lần sub). Mình có thử thì thấy nguyên nhân là do thông số lRecordsAffected, nếu để lRecordsAffected = 0 ngay sau mỗi lần chạy next i thì tất cả mã mới được thêm vào hết nhưng lại không update được mã nữa.

Mình mới tập tành ADO(đọc và áp dụng luôn vào công việc, sai đâu sửa đó) nên nhiều chỗ chưa thấu. Mọi người giúp mình có phương án nào cho trường hợp này không?[/Code]
Bạn giả lập dữ liệu rồi gửi lên xem thử nhé.
 
Bạn giả lập dữ liệu rồi gửi lên xem thử nhé.

Ðây là dữ liệu giả lập của mình. Cách hoạt động như sau:
Mình có một file access chứa dữ liệu chung (tương tự sheet1) cập nhật cho nhiều người. Thi thoảng mình sẽ cập nhật: thêm mã sản phẩm (Code) hoặc đổi tên một mã đã có. Thao tác thực hiện ở sheet2: trong sheet2 mình viết một hàm lấy thông tin cột A để cập nhật vào access, nếu mã đã có thì đổi tên (UPDATE), nếu không thì thêm mới- tương tự như phần mình nêuở #1. (Trước thì mình dùng 1 file excel thay cho access để cập nhật chung nhưng đọc quyển VBA nâng cao nên mới đây mình mày mò thử phần ADO). Trong access mình đặt cột Code là key.
Trong dữ liệu của mình thì ở sheet2 dòng A4, A5 hiện tại là mã mới sẽ phải cập nhật trong excel, còn A2, A3 là mã cũ và cập nhật lại tên.

Nếu chạy theo code mình làm thì như ví dụ hiện tại, các mã trong diện update thì tất cả được cập nhật nhưng mã mới thì chỉ có 1 cái được thêm vào, chạy lần nữa thì mã mới tiếp mới được thêm vào. Nếu mình thử thêm dòng lRecordAffected =1 như minh họa:
Mã:
    For j = LBound(Arr, 1) To UBound(Arr, 1)
     lRecordAffected =1
     objcommand.CommandText = "UPDATE [DATA] " & _
Thì các mã mới sẽ được cập nhật nhưng mã cũ không được update.
---
Mình sửa theo #2 thì hết lỗi. Nhưng muốn biết vấn đề của lRecordsAffected, vì theo mình đọc và hiểu thì nó là một giá trị được trả về cho biết số lượng bản ghi bị tác động tới- tức là mình hiểu mỗi lần mình next i, đi qua câu lệnh UPDATE rồi INSERT thì giá trị này được biến đổi sau mỗi câu lệnh đó chứ?
 

File đính kèm

Lần chỉnh sửa cuối:
Thường thì người ta làm query 2 lần.
Lần thứ nhất Update với điều kiện match của nó.
Lần thứ hai Insert với điều kiện Where not Exists, hoặc điều kiện tương tự.
 
Ðây là dữ liệu giả lập của mình. Cách hoạt động như sau:
Mình có một file access chứa dữ liệu chung (tương tự sheet1) cập nhật cho nhiều người. Thi thoảng mình sẽ cập nhật: thêm mã sản phẩm (Code) hoặc đổi tên một mã đã có. Thao tác thực hiện ở sheet2: trong sheet2 mình viết một hàm lấy thông tin cột A để cập nhật vào access, nếu mã đã có thì đổi tên (UPDATE), nếu không thì thêm mới- tương tự như phần mình nêuở #1. (Trước thì mình dùng 1 file excel thay cho access để cập nhật chung nhưng đọc quyển VBA nâng cao nên mới đây mình mày mò thử phần ADO). Trong access mình đặt cột Code là key.
Trong dữ liệu của mình thì ở sheet2 dòng A4, A5 hiện tại là mã mới sẽ phải cập nhật trong excel, còn A2, A3 là mã cũ và cập nhật lại tên.

Nếu chạy theo code mình làm thì như ví dụ hiện tại, các mã trong diện update thì tất cả được cập nhật nhưng mã mới thì chỉ có 1 cái được thêm vào, chạy lần nữa thì mã mới tiếp mới được thêm vào. Nếu mình thử thêm dòng lRecordAffected =1 như minh họa:
Mã:
    For j = LBound(Arr, 1) To UBound(Arr, 1)
     lRecordAffected =1
     objcommand.CommandText = "UPDATE [DATA] " & _
Thì các mã mới sẽ được cập nhật nhưng mã cũ không được update.
---
Mình sửa theo #2 thì hết lỗi. Nhưng muốn biết vấn đề của lRecordsAffected, vì theo mình đọc và hiểu thì nó là một giá trị được trả về cho biết số lượng bản ghi bị tác động tới- tức là mình hiểu mỗi lần mình next i, đi qua câu lệnh UPDATE rồi INSERT thì giá trị này được biến đổi sau mỗi câu lệnh đó chứ?
bạn đưa cái file giả lập và cái đoạn code của bạn mình sữa cho
 
Thường thì người ta làm query 2 lần.
Lần thứ nhất Update với điều kiện match của nó.
Lần thứ hai Insert với điều kiện Where not Exists, hoặc điều kiện tương tự.

Mình từ lúc vác quyển lập trình VBA của diễn đàn phần nâng cao mới tập tành với cơ sở dữ liệu, bạn có cái phần "Where not Exists" để mình mày mò ứng dụng thêm, không nghĩ ra, hehe
Bài đã được tự động gộp:

bạn đưa cái file giả lập và cái đoạn code của bạn mình sữa cho
Code thì mình theo bài #2 sửa ngon rồi, mình sẽ tìm hiểu thêm ý ở #9, mình muốn hỏi thêm vì muốn biết cái phần này "Nhưng muốn biết vấn đề của lRecordsAffected, vì theo mình đọc và hiểu thì nó là một giá trị được trả về cho biết số lượng bản ghi bị tác động tới- tức là mình hiểu mỗi lần mình next i, đi qua câu lệnh UPDATE rồi INSERT thì giá trị này được biến đổi sau mỗi câu lệnh đó chứ? "
Mới mò DB nên nhiều cái không biết, cũng không biết đường nào mà hỏi, đành vấp đâu hỏi kĩ ở đấy vậy.
Đây là đoạn code của mình, trong đó còn nhiều dòng chú thích mình để so sánh khi cần với bài #2

Mã:
Private Sub ImportBOMtoExcel()
'Dim objcommand As ADODB.Command
Dim objcnn As ADODB.Connection
Dim objRcSet As ADODB.Recordset
Dim endr As Long, i As Long, j As Long, e As Long, Arr() As Variant, que As Integer, lRecordsAffected As Long
Dim Str1 As String, sConnect As String, Str2 As String
Application.ScreenUpdating = False
que = MsgBox("Are you sure?", vbYesNo)
On Error Resume Next
If que = vbNo Then
    Exit Sub
Else
End If
CreatLK
Str1 = Sheet2.Cells(2, 5)
Str2 = Sheet2.Cells(3, 5)
endr = Sheet3.Range(Str1 & "1000000").End(xlUp).Row
Arr = Sheet3.Range(Str1 & "2:" & Str2 & endr).Value
e = 0
If endr > 1 Then
    sConnect = "Provider = Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & LinkData & "Base Code Tecomen.accdb;" & _
    "Mode=Share Exclusive"
    'Set objcommand = New ADODB.Command
    'objcommand.ActiveConnection = sConnect
    Set objcnn = New ADODB.Connection
    Set objRcSet = New ADODB.Recordset
    objcnn.Open sConnect
    For i = LBound(Arr, 1) To UBound(Arr, 1)
        j = DicLK.Item(CStr(Arr(i, 1)))
        'If j <> 0 Then
            'Add BOM
            If Len(Arr(i, 2)) > 0 Then
                Sheet1.Cells(j + 1, 4) = Arr(i, 2)
                ArrLK(j, 4) = Arr(i, 2)
            End If
            'add price
            If Arr(i, 15) > 0 And ArrLK(j, 19) <> Arr(i, 15) Then
                Sheet1.Cells(j + 1, 19) = Arr(i, 15)
                ArrLK(j, 19) = Arr(i, 15)
            End If
            'add 4M
            If Len(Arr(i, 14)) >= 6 Then
                Sheet1.Cells(j + 1, 5) = Arr(i, 14)
                ArrLK(j, 5) = Arr(i, 14)
            End If
            'add standard
            If Len(Arr(i, 13)) > 0 Then
                Sheet1.Cells(j + 1, 15) = Arr(i, 13)
                ArrLK(j, 15) = Arr(i, 13)
            End If
            'add Name
            If Len(Arr(i, 3)) > 0 Then
                Sheet1.Cells(j + 1, 2) = Arr(i, 3)
                Sheet1.Cells(j + 1, 3) = Arr(i, 3)
                ArrLK(j, 2) = Arr(i, 3)
                ArrLK(j, 3) = Arr(i, 3)
            End If
            'add Routing
            If Len(Arr(i, 16)) > 0 Then
                Sheet1.Cells(j + 1, 14) = Arr(i, 16)
                ArrLK(j, 14) = Arr(i, 16)
            End If
            Str1 = "SELECT Code FROM [DATA] WHERE Code='" & ArrLK(j, 1) & "'"
            objRcSet.Open objcnn.Execute(Str1)
            If objRcSet.EOF Then
                Str2 = "INSERT INTO [DATA] ([Code], [Name 1], [Name 2], [BOM], [Add 4M], [UoM], [Time], [Person], [Information], [Type VA], [Image], [MRP Control], [RT Gr], [Routing], [Standard], [Norm], [Standard QC], [GC])" & _
                    " VALUES ('" & ArrLK(j, 1) & "', '" & ArrLK(j, 2) & "', '" & ArrLK(j, 3) & "', '" & ArrLK(j, 4) & "', '" & ArrLK(j, 5) & "', '" & ArrLK(j, 6) & "', #" & ArrLK(j, 7) & "#, '" & ArrLK(j, 8) & "', '" & ArrLK(j, 9) & _
                    "', '" & ArrLK(j, 10) & "', '" & ArrLK(j, 11) & "', " & ArrLK(j, 12) & ", '" & ArrLK(j, 13) & "', '" & ArrLK(j, 14) & "', '" & ArrLK(j, 15) & "', '" & ArrLK(j, 16) & "', '" & ArrLK(j, 17) & "', '" & ArrLK(j, 18) & "');"
                objcnn.Execute Str2
            Else
                Str2 = "UPDATE [DATA] " & _
                    "SET [Name 1]='" & ArrLK(j, 2) & "', [Name 2]='" & ArrLK(j, 3) & "', [BOM]='" & ArrLK(j, 4) & "', [Add 4M]='" & ArrLK(j, 5) & "', [Time]= #" & ArrLK(j, 7) & "#, [Image]='" & ArrLK(j, 11) & "', [MRP Control]= '" & ArrLK(j, 12) & ", [Routing]= '" & ArrLK(j, 14) & "', [Standard]= '" & ArrLK(j, 15) & _
                    "', [GC]='" & ArrLK(j, 18) & "', [Type VA]='" & ArrLK(j, 10) & "'" & _
                    " WHERE [Code] = '" & ArrLK(j, 1) & "';"
                objcnn.Execute Str2
            End If
            objRcSet.Close
            
            
            'lRecordsAffected = 0
            'objcommand.CommandText = "UPDATE [DATA] " & _
                "SET [Name 1]='" & ArrLK(j, 2) & "', [Name 2]='" & ArrLK(j, 3) & "', [BOM]='" & ArrLK(j, 4) & "', [Add 4M]='" & ArrLK(j, 5) & "', [Time]= #" & ArrLK(j, 7) & "#, [Image]='" & ArrLK(j, 11) & "', [MRP Control]= '" & ArrLK(j, 12) & ", [Routing]= '" & ArrLK(j, 14) & "', [Standard]= '" & ArrLK(j, 15) & _
                "', [GC]='" & ArrLK(j, 18) & "', [Type VA]='" & ArrLK(j, 10) & "'" & _
                " WHERE [Code] = '" & ArrLK(j, 1) & "';"
            'objcommand.Execute recordsaffected:=lRecordsAffected, Options:=adCmdText Or adExecuteNoRecords
            'If lRecordsAffected < 1 Then
            '    objcommand.CommandText = "INSERT INTO [DATA] ([Code], [Name 1], [Name 2], [BOM], [Add 4M], [UoM], [Time], [Person], [Information], [Type VA], [Image], [MRP Control], [RT Gr], [Routing], [Standard], [Norm], [Standard QC], [GC])" & _
                    " VALUES ('" & ArrLK(j, 1) & "', '" & ArrLK(j, 2) & "', '" & ArrLK(j, 3) & "', '" & ArrLK(j, 4) & "', '" & ArrLK(j, 5) & "', '" & ArrLK(j, 6) & "', #" & ArrLK(j, 7) & "#, '" & ArrLK(j, 8) & "', '" & ArrLK(j, 9) & _
                    "', '" & ArrLK(j, 10) & "', '" & ArrLK(j, 11) & "', " & ArrLK(j, 12) & ", '" & ArrLK(j, 13) & "', '" & ArrLK(j, 14) & "', '" & ArrLK(j, 15) & "', '" & ArrLK(j, 16) & "', '" & ArrLK(j, 17) & "', '" & ArrLK(j, 18) & "');"
            '    objcommand.Execute recordsaffected:=lRecordsAffected, Options:=adCmdText Or adExecuteNoRecords
            'End If
        'End If
    Next i
End If
ClearAll
Set objcnn = Nothing
Set objRcSet = Nothing
Application.ScreenUpdating = True
End Sub
 
Lần chỉnh sửa cuối:
Ðây là dữ liệu giả lập của mình. Cách hoạt động như sau:
Mình có một file access chứa dữ liệu chung (tương tự sheet1) cập nhật cho nhiều người. Thi thoảng mình sẽ cập nhật: thêm mã sản phẩm (Code) hoặc đổi tên một mã đã có. Thao tác thực hiện ở sheet2: trong sheet2 mình viết một hàm lấy thông tin cột A để cập nhật vào access, nếu mã đã có thì đổi tên (UPDATE), nếu không thì thêm mới- tương tự như phần mình nêuở #1. (Trước thì mình dùng 1 file excel thay cho access để cập nhật chung nhưng đọc quyển VBA nâng cao nên mới đây mình mày mò thử phần ADO). Trong access mình đặt cột Code là key.
Trong dữ liệu của mình thì ở sheet2 dòng A4, A5 hiện tại là mã mới sẽ phải cập nhật trong excel, còn A2, A3 là mã cũ và cập nhật lại tên.

Nếu chạy theo code mình làm thì như ví dụ hiện tại, các mã trong diện update thì tất cả được cập nhật nhưng mã mới thì chỉ có 1 cái được thêm vào, chạy lần nữa thì mã mới tiếp mới được thêm vào. Nếu mình thử thêm dòng lRecordAffected =1 như minh họa:
Mã:
    For j = LBound(Arr, 1) To UBound(Arr, 1)
     lRecordAffected =1
     objcommand.CommandText = "UPDATE [DATA] " & _
Thì các mã mới sẽ được cập nhật nhưng mã cũ không được update.
---
Mình sửa theo #2 thì hết lỗi. Nhưng muốn biết vấn đề của lRecordsAffected, vì theo mình đọc và hiểu thì nó là một giá trị được trả về cho biết số lượng bản ghi bị tác động tới- tức là mình hiểu mỗi lần mình next i, đi qua câu lệnh UPDATE rồi INSERT thì giá trị này được biến đổi sau mỗi câu lệnh đó chứ?
Bạn chạy code sau thử nhé:
Mã:
Sub CapNhatDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0")
        .Execute ("Update [Sheet1$] a Inner join [Sheet2$] b On a.[Code]=b.[Code] Set a.[Name 1]=B.[Name 1]")
        .Execute ("Insert Into [Sheet1$] Select [Code], [Name 1] From [Sheet2$] a Where Not Exists (Select [Code], [Name 1] From [Sheet1$] b Where a.Code=b.Code)")
    End With
End Sub
 
Trước đây mình cũng code theo nguyên lý này cũng cỡ 18 năm rồi nhưng giờ ngẫm lại thì chợt thấy cách này tiềm ẩn rủi ro khá tai hại. Giả sử mình muốn dùng mã cũ nhưng gõ nhầm mã (hoặc gõ mã mới nhưng trùng với mã cũ) thì sao? Nếu không có xác nhận mà cứ lặng lẽ thực hiện thì sau này nhiều nguy cơ đau đầu lắm.
 
Trước đây mình cũng code theo nguyên lý này cũng cỡ 18 năm rồi nhưng giờ ngẫm lại thì chợt thấy cách này tiềm ẩn rủi ro khá tai hại. Giả sử mình muốn dùng mã cũ nhưng gõ nhầm mã (hoặc gõ mã mới nhưng trùng với mã cũ) thì sao? Nếu không có xác nhận mà cứ lặng lẽ thực hiện thì sau này nhiều nguy cơ đau đầu lắm.

Access là cái chung mình lưu mã sản phẩm ra server chung rồi người khác đồng bộ về, mình đỡ phải copy cho mọi người- thấy hay hơn. Còn server mình phân quyền mọi người chỉ đọc nên không lo ai làm hại dữ liệu. File excel thì dùng dictionary để tránh lặp mã, chưa bị xử lý lộn bao giờ. Tất nhiên là vừa dùng vừa quan sát đã.
 
Access là cái chung mình lưu mã sản phẩm ra server chung rồi người khác đồng bộ về, mình đỡ phải copy cho mọi người- thấy hay hơn. Còn server mình phân quyền mọi người chỉ đọc nên không lo ai làm hại dữ liệu. File excel thì dùng dictionary để tránh lặp mã, chưa bị xử lý lộn bao giờ. Tất nhiên là vừa dùng vừa quan sát đã.
Túm lại bạn đã giải quyết vấn đề này chưa vậy?
 
Thường dạng này mình sẽ viết
1. function update
2. function insert
3. function checkIfExit
4. Dựa trên checkIfExit để split cái array kia thành 2 array = 1 dành cho update + 1 dành cho insert
5. Chạy vòng lặp cho từng array và dựa trên (1) và (2).
--------
Công việc có vẻ phức tạp nhưng lại có thể "kế thừa" cho các cái khác, dễ dành sửa chữa, kiểm tra lỗi.
 
Túm lại bạn đã giải quyết vấn đề này chưa vậy?
Mình giải quyết xong rồi. Cảm ơn bạn :)
Bài đã được tự động gộp:

Thường dạng này mình sẽ viết
1. function update
2. function insert
3. function checkIfExit
4. Dựa trên checkIfExit để split cái array kia thành 2 array = 1 dành cho update + 1 dành cho insert
5. Chạy vòng lặp cho từng array và dựa trên (1) và (2).
--------
Công việc có vẻ phức tạp nhưng lại có thể "kế thừa" cho các cái khác, dễ dành sửa chữa, kiểm tra lỗi.
Mình sẽ lưu tâm thêm, mình mới nghĩ thêm một trường ghi lại thời gian tác động đến mã đó nữa, mình sẽ tác động mã qua userform, mỗi lần hoàn thành thì lưu lại thời gian kết thúc. Khi nào update thì sẽ sort lại trường này, và so với một cái thời gian chuyển dữ liệu lần trước, cái nào có thời gian lớn hơn thì tiến hành update hoặc insert (Cộng thêm với việc phân tách ra 2 mảng như bạn nói)
 
Web KT

Bài viết mới nhất

Back
Top Bottom