Sửa lỗi không sửa và không xóa được dữ liệu trong lập trình VBA (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

kimcanh.nguyenhoang@gmail

Thành viên mới
Tham gia
8/4/20
Bài viết
6
Được thích
0
Em chào các Anh/Chị.

Em là 1 thành viên mới chưa biết tẹo nào về lạp trình VBA.
Em có tìm hiểu trên Youtobe và tự copy các code VBA về tập làm 1 phần mềm excell cho riêng mình
tuy nhiên thì có 1 số điểm chưa hoàn thiện được.
Hôm nay Em gửi File tự làm của em lên diễn đàn nhờ các Anh/ chị chỉ bảo và sửa file cho hoạt động hết các tính năng giúp Em.
File này của Em bị 3 lỗi khi em copy code vào thì không hoạt động được, và có 1 số chỗ em vẫn phải dùng công thức để tính toán dữ liệu
Lỗi 1: khi thực hiện tìm kiếm dữ liệu thì chỉ tìm được đến dòng 427, còn thông tin các dòng tiếp theo thì không tìm được
Lỗi 2: chức năng cập nhật khi sửa dữ liệu không thực hiện
Lỗi 3: chức năng cập xóa dữ liệu không thực hiện
Điểm cuối cùng là có 1 số chỗ em vẫn phải sử dụng công thức excell để tính toán và tìm kiếm điều kiện: VD: hàm Sum, hàm countifs, hàm if..
Vậy Nhờ Anh/chị sửa giúp em ah.
EM chân thành cảm ơn các Anh/chị.
Trong file em có để password đăng nhập: Username: admin và password:123456
 

File đính kèm

rốt cục cái này bạn tự viết hay là bổ sung code vào cái có sẵn của người ta, vì một người không biết gì về VBA, chỉ thông qua youtube để copy code vào để tự tạo tool cho mình thì ... khá là đỉnh đó :)
Với lại file của bạn chỉ có 1 cái Private Sub Worksheet_Change và 1 cái Sub laydulieu() thôi (sub này củng chỉ là lấy dữ liệu từ sheet 3 sang sheet 5, khá đơn giản), vậy làm sao có nhiều chức năng như bạn kể được.
 
Lần chỉnh sửa cuối:
Upvote 0
Code bên trong không nhiều, nhưng đặt cái form đăng nhập nhìn chuyên nghiệp. File hơi nặng và tiêu đề để chữ trắng nền vàng hơi khó nhìn. Bạn nên chỉ rõ đoạn code nào có vấn đề thì người giúp sẽ tập trung hơn. Hiện tại mình vẫn chưa rõ bạn muốn sửa chữa cụ thể chỗ nào.
 
Upvote 0
rốt cục cái này bạn tự viết hay là bổ sung code vào cái có sẵn của người ta, vì một người không biết gì về VBA, chỉ thông qua youtube để copy code vào để tự tạo tool cho mình thì ... khá là đỉnh đó :)
Với lại file của bạn chỉ có 1 cái Private Sub Worksheet_Change và 1 cái Sub laydulieu() thôi (sub này củng chỉ là lấy dữ liệu từ sheet 3 sang sheet 5, khá đơn giản), vậy làm sao có nhiều chức năng như bạn kể được.
[/QUO
Bài đã được tự động gộp:

Dạ. Cái này em xem qua các video hướng dẫn và lèm theo ah.
Khi Em muốn sửa dữ liệu qua userform mà không muốn vào trực tiếp các sheet để sửa ah.
Tiếp nữa là các sheet bên trong vẫn còn đang sử dụng công thức và em muốn các anh viết giúp em code cho nó tự động tính mà không phải dùng công thức cho nhẹ file.
 
Lần chỉnh sửa cuối:
Upvote 0
Em chào các Anh/Chị.

Em là 1 thành viên mới chưa biết tẹo nào về lạp trình VBA.
Em có tìm hiểu trên Youtobe và tự copy các code VBA về tập làm 1 phần mềm excell cho riêng mình
tuy nhiên thì có 1 số điểm chưa hoàn thiện được.
Hôm nay Em gửi File tự làm của em lên diễn đàn nhờ các Anh/ chị chỉ bảo và sửa file cho hoạt động hết các tính năng giúp Em.
File này của Em bị 3 lỗi khi em copy code vào thì không hoạt động được, và có 1 số chỗ em vẫn phải dùng công thức để tính toán dữ liệu
Lỗi 1: khi thực hiện tìm kiếm dữ liệu thì chỉ tìm được đến dòng 427, còn thông tin các dòng tiếp theo thì không tìm được
Lỗi 2: chức năng cập nhật khi sửa dữ liệu không thực hiện
Lỗi 3: chức năng cập xóa dữ liệu không thực hiện
Điểm cuối cùng là có 1 số chỗ em vẫn phải sử dụng công thức excell để tính toán và tìm kiếm điều kiện: VD: hàm Sum, hàm countifs, hàm if..
Vậy Nhờ Anh/chị sửa giúp em ah.
EM chân thành cảm ơn các Anh/chị.
Trong file em có để password đăng nhập: Username: admin và password:123456
Bạn mô tả cụ thể hơn về vấn đề mình cần.
Lỗi 1: Cụ thể bạn muốn tìm cái gì, tìm ở cột nào của sheet nào? Chứ code của bạn theo tôi thấy thì tìm ở sheet1 cột A, nhưng cột A của bạn có cái gì mà tìm?
Lỗi 2: Cập nhật là sao, khi Click vào cập nhật mục đích của bạn muốn là gì?
Lỗi 3: Chức năng cập xóa là thế nào? Mục đích của bạn là xóa dữ liệu ở sheet nào, tiêu chí xóa là gì, khi xóa là xóa luôn hàng hay chỉ xóa dữ liệu...
Nói tóm lại muốn được giúp nhiệt tình thì bạn phải mô tả nhiệt tình, chi tiết. Hãy diễn tả như bạn đang giải thích cho đứa trẻ biết càng tốt, vì không phải ai cũng hiểu vấn đề bạn. Có khi bạn nghĩ nó đơn giản nhưng bạn mô tả chẳng ai hiểu cả (ít nhất là tôi).
 
Upvote 0
File này của Em bị 3 lỗi khi em copy code vào thì không hoạt động được, và có 1 số chỗ em vẫn phải dùng công thức để tính toán dữ liệu
Lỗi 1: khi thực hiện tìm kiếm dữ liệu thì chỉ tìm được đến dòng 427, còn thông tin các dòng tiếp theo thì không tìm được
Nhiều quá nên làm tạm 1 phần.

Dễ hiểu thôi. Nhìn code
For i = 2 To Application.WorksheetFunction.CountA(Sheet1.range("A:A"))
For x = 1 To 15 '122
a = Len(Me.txtSearch.Text)
If Left(Sheet1.Cells(i, x).Value, a) = ... Then
...
End If
Next x
Next i
thì thấy bạn tìm từ dòng 2 tới dòng Application.WorksheetFunction.CountA(Sheet1.range("A:A")). Hiện tại Application.WorksheetFunction.CountA(Sheet1.range("A:A")) trả về 427. Nhưng dòng dữ liệu cuối cùng nằm ở dòng 429. Tức code tìm trong các dòng 2-427, không tìm ở dòng 428 và 429. Code đúng phải là
Mã:
For i = 2 To Application.WorksheetFunction.CountA(Sheet1.range("A:A"))+2

Bạn có thể xác định dòng cuối cùng có dữ liệu bằng cách khác nữa. Vd.
Mã:
Dim i As Long, lastRow As Long
lastRow = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow 
...
Nhưng thôi. Ta xét cách của bạn.
Bạn có code sau khi sửa
Mã:
Private Sub btnSearch_Click() '// tim kiem du lieu
On Error Resume Next
    Me.ListBox1.Clear
    Me.ListBox1.AddItem Sheet1.Cells(3, "A")
    For B = 2 To 122
        Me.ListBox1.List(ListBox1.ListCount - 1, B - 1) = Sheet1.Cells(3, B)
    Next B
    Me.ListBox1.Selected(0) = True
    Dim i As Long
    lastRow = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row
    For i = 2 To Application.WorksheetFunction.CountA(Sheet1.range("A:A")) + 2
        For x = 1 To 15         '122
            a = Len(Me.txtSearch.Text)
            If Left(Sheet1.Cells(i, x).Value, a) = Me.txtSearch.Text And Me.txtSearch.Text <> "" Then
                Me.ListBox1.AddItem Sheet1.Cells(i, 1).Value
                For c = 1 To 122
                    Me.ListBox1.List(ListBox1.ListCount - 1, c) = Sheet1.Cells(i, c + 1).Value
                Next c
            End If
        Next x
    Next i
End Sub
Nếu bạn muốn học viết code thì hãy đọc kỹ những lưu ý sau đâu.
1. Hãy tập khai báo tất cả các biến. Trong code bạn chưa khai báo biến B, x, a và c.

2. Hãy tập viết tường minh. Đừng bắt chước những thói quen xấu của người khác. Không phải là
Mã:
Me.ListBox1.AddItem Sheet1.Cells(3, "A")
mà phải là
Mã:
Me.ListBox1.AddItem Sheet1.Cells(3, "A").Value

3. Những gì chỉ cần làm 1 lần thì chỉ làm 1 lần. Bạn có
Mã:
For i = 2 To Application.WorksheetFunction.CountA(Sheet1.range("A:A")) + 2
        For x = 1 To 122
            a = Len(Me.txtSearch.Text)
Như thế là bạn đã xác định a tổng cộng là 428*122 = 52 216 lần do bạn đặt a = Len(Me.txtSearch.Text) trong 2 vòng lặp FOR. Rất tốn điện nước. Rõ ràng khi nhấn nút "tìm kiếm" giá trị Me.txtSearch.Text đã xác định, vậy chỉ đọc 1 lần trước 2 vòng FOR.

4. Bạn có
Mã:
If Left(Sheet1.Cells(i, x).Value, a) = Me.txtSearch.Text And Me.txtSearch.Text <> "" Then
Như vậy thì khi Me.txtSearch.Text = "" thì cụm IF ... END IF không bao gì được thực hiện. Trong khi đó thì code dò 428*122 = 52 216 ô trên sheet1. Như vậy code dò 52 216 ô trên sheet chỉ để tiêu bớt điện nước vì bạn có chúng quá nhiều? Người khôn ngoan sẽ kiểm tra ngay sau dòng Me.ListBox1.Clear xem có thỏa Me.txtSearch.Text <> "" hay không. Nếu không thỏa thì dọn luôn đồ chơi rồi đi nhậu. Không làm các code tiếp theo vì có làm cũng vô ích.

5. Trên sheet1 bạn chỉ có 15 cột dữ liệu A-O. Vậy tại sao lại For x = 1 To 122 và For c = 1 To 122? Nhiều điện nước nên chạy cho tiêu bớt đi?

6. Bạn có
Mã:
For i = 2 To Application.WorksheetFunction.CountA(Sheet1.range("A:A")) + 2
    For x = 1 To 122
        a = Len(Me.txtSearch.text)
        If Left(Sheet1.Cells(i, x).Value, a) = Me.txtSearch.text And Me.txtSearch.text <> "" Then
            Me.ListBox1.AddItem Sheet1.Cells(i, 1).Value
            For c = 1 To 122
                Me.ListBox1.List(ListBox1.ListCount - 1, c) = Sheet1.Cells(i, c + 1).Value
            Next c
        End If
    Next x
Next i
Bây giờ bạn hãy tưởng tượng là giá trị a xuất hiện ở dòng 3, ở 3 ô G3, O3 và L3.
Như thế khi thực hiện với i = 3 và x = 7 (cột G) điều kiện của IF thỏa nên code thêm dòng 3 vào ListBox. Khi chạy với i = 3 và x = 9 (cột I) thì điều kiện của IF cũng thỏa và code lại thêm dòng 3 vào ListBox. Khi chạy với i = 3 và x = 12 (cột L) thì điều kiện của IF cũng thỏa và code lại thêm dòng 3 vào ListBox. Tổng cộng dòng 3 được thêm vào ListBox 3 lần.

7. Bạn có
Mã:
If Left(Sheet1.Cells(i, x).Value, a) = Me.txtSearch.Text And Me.txtSearch.Text <> "" Then
                Me.ListBox1.AddItem Sheet1.Cells(i, 1).Value
Thế này thì toi rồi. Bạn dò từng ô trong tổng số 52 216 ô trên sheet? Bạn thử nhập vào textbox giá trị 20 rồi nhấn nút "tìm kiếm". Đảm bảo là bạn có thể bỏ đi nhậu, rồi khi về code vẫn chưa chạy xong. Khi dữ liệu nhiều thì phải đọc vào mảng rồi tìm kiếm trong mảng.
Bạn có thể chạy code của mình và chạy code tôi dùng mảng ở dưới để so sánh tốc độ.
Mã:
Private Sub btnSearch_Click() '// tim kiem du lieu
Dim lastRow As Long, i As Long, r As Long, c As Long, total_col As Long, rows_count As Long, text As String, data(), result()
On Error Resume Next
    Me.ListBox1.Clear
    text = txtSearch.text & "*"
    If text = "" Then Exit Sub  ' neu gia tri tim kiem rong thi ket thuc
    With Sheet1
        lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        If lastRow < 4 Then Exit Sub    ' khong co du lieu nen ket thuc
        data = .Range("A4:O" & lastRow).Value
        total_col = UBound(data, 2) ' so cot cua du lieu nguon
        ReDim result(1 To total_col, 1 To 1)
        For i = 1 To total_col
            result(i, 1) = .Cells(3, i).Value
        Next i
        rows_count = 1  ' so dong ket qua tim duoc
    End With
    For r = 1 To UBound(data, 1)
        For i = 1 To total_col
            If data(r, i) Like text Then   ' data(r, i) co doan dau = text
                rows_count = rows_count + 1
                ReDim Preserve result(1 To total_col, 1 To rows_count)   ' mo rong mang result them 1 cot
                For c = 1 To total_col
'                    nhap gia tri o dong r va cot c trong mang data vao dong c cot rows_count (cot cuoi hien hanh) trong mang result
                    result(c, rows_count) = data(r, c)
                Next c
'                 dong r cua mang data da duoc them vao mang result, vay khong xet cac cot tiep theo cua dong r nua
                Exit For    ' ra khoi vong lap i
            End If
        Next i
    Next r
'    nhap mang result vao ListBox. Do tung dong cua result la tung cot cua ListBox, va tung cot cua
'    result la tung dong cua ListBox nen phai dung thuoc tinh Column cua ListBox thay cho thuoc tinh List
    ListBox1.Column = result
End Sub
------------
Về thiết kế nên sửa như sau:
- ListBox: ColumnCount = 15, ColumnWidths = 20 pt;100 pt;80 pt;70 pt;50 pt;60 pt;50 pt;60 pt;80 pt;70 pt;70 pt;60 pt;90 pt;30 pt;90 pt

- Frame1: ScrollBars = fmScrollBarsHorizontal, ScrollWidth = 1000
 
Upvote 0
Vâng. Em gán code của anh/chị batman1 vào thì việc tìm kiếm rất nhanh và tìm được đẩy đủ thông tin
Em cảm ơn Anh hay chị batman1 ah.
Bài phân tích code của anh rất dễ hiểu và code chạy rất chính xác ah.
Em cảm ơn anh/chị batman1 rất nhiều ah.
còn các mục lỗi 2, Lỗi 3 khi em muốn sửa hay xóa dữ liệu qua userform thì nhờ anh/chị batman1 hỗ trợ sửa tiếp giúp em ah.
 
Upvote 0
còn các mục lỗi 2, Lỗi 3 khi em muốn sửa hay xóa dữ liệu qua userform thì nhờ anh/chị batman1 hỗ trợ sửa tiếp giúp em ah.
Muốn làm gì thì trước hết hãy sửa sheet "Dữ liệu Scan" vì nặng quá. Chả lý gì lại có số dòng, cột khủng khi dữ liệu chỉ có vài trăm dòng và 15 cột.
Thêm sheet mới -> vào VBE và copy Worksheet_Change của sheet "Dữ liệu Scan" lưu sang vd. notepad -> chọn A1:O429 trong sheet "Dữ liệu Scan" -> Ctrl + C -> chọn A1 trong sheet mới -> Ctrl + V -> loại bỏ sheet "Dữ liệu Scan" -> đổi tên sheet mới thành "Dữ liệu Scan" -> Alt + F11 -> đổi code name của sheet "Dữ liệu Scan" thành Sheet1 -> trong code của Sheet1 dán nội dung đã lưu trong notepad. Từ lúc này mở tập tin và thao tác không phải đợi lâu.
-----------
Thực ra để viết cho bạn thì tôi phải viết từ A đến z, rất nhiều. Vì thế tôi chỉ gợi ý cho bạn để bạn thử tự viết.
1. Trước khi viết code thì phải vạch ra cách thức hoạt động của nó. Vd. để tìm kiếm thì phải nhập gì, vào đâu, nhấn nút nào. Rồi khi nhấn nút thì tìm gì, ở đâu. Để sửa, xóa, thêm thì nhập gì, ở đâu, và khi nhấn nút nào thì tìm gì, ở đâu. Vân vân và mây mây.
Vd.
Lỗi 2: chức năng cập nhật khi sửa dữ liệu không thực hiện
Ý bạn muốn nói tới btnUpdest_Click?
- dữ liệu có từ dòng 4, vậy tìm từ dòng 4 trở đi. Trong code bạn tìm từ dòng 1 (g = 1). Khi p = txtMaScan.text , tức tìm thấy thì sửa. Theo tôi hiểu thì Mã Scan phải tìm ở cột B. Nếu các mã ở cột B là duy nhất, không lặp lại, thì khi tìm thấy thì sửa (thực hiện cụm IF ... End If) và ra khỏi vòng lặp (Exit Do). Không lý gì khi tìm thấy lại vẫn tìm ở các dòng tiếp theo.
Code sau chỉ là ví dụ
Mã:
Private Sub btnUpdest_Click()
Dim lastRow As Long, r As Long, ma()
    With Sheet1
        lastRow = .Cells(Rows.Count, "B").End(xlUp).Row
        If lastRow < 4 Then Exit Sub    ' khong co du lieu
        ma = .Range("B4:B" & lastRow + 1).Value ' lay du  dong
    End With
    For r = 1 To UBound(ma, 1) - 1 ' khong xet dong lay them o cuoi
        If ma(r, 1) = CDbl(txtMaScan.Value) Then
'            de khong thuc hien Worksheet_Change cua sheet1 khi sua dong thi ...
            Application.EnableEvents = False
'            dong r trong mang ma la dong (r + 3) tren sheet.
            With Sheet1
                .Range("I" & r + 3) = TxtNumber.text
                .Range("H" & r + 3) = TxtDate.text
                .Range("J" & r + 3) = txtCode.text
            End With
            Application.EnableEvents = True
            Exit For
        End If
    Next r
    txtMaScan.SetFocus
    txtMaScan.SetFocus ' Cho con nháy nh?y vŕo txtMaScan
    txtMaScan.SelStart = 0 ' Con nháy n?m d?u txtMaScan
    txtMaScan.SelLength = 14 ' Bôi den 6 ký t? d?u tięn trong txtMaScan
End Sub

Lỗi 3: chức năng cập xóa dữ liệu không thực hiện
Ý bạn nói về btnDelete_Click? Bạn có
Mã:
Private Sub btnDelete_Click()
On Error Resume Next
    g = 0
    Do
    DoEvents
    g = g + 1
    p = Sheet1.Range("a" & g)
    If p = txtMaScan.text Then
        Sheet1.Range("a" & g).Select
        Selection.Delete
        Sheet1.Range("b" & g).Select
...
- Mã Scan có trong cột B, code lại tìm trong cột A (số thứ tự)?
- dữ liệu có từ dòng 4 mà lại tìm từ dòng 1?
- nếu mã scan trong cột B là duy nhất thì khi tìm được (If p = txtMaScan.text Then) thì xóa dòng g và ra khỏi vòng lặp. Chả lý gì lại vẫn xét các dòng tiếp theo.
- có thể xóa dòng g trong 1 nốt nhạc.

Code sau chỉ là ví dụ. Thay cho vòng lặp For có thể dùng phương thức Find của đối tượng Range.
Mã:
Private Sub btnDelete_Click()
Dim lastRow As Long, r As Long, ma()
    With Sheet1
        lastRow = .Cells(Rows.Count, "B").End(xlUp).Row
        If lastRow < 4 Then Exit Sub    ' khong co du lieu
        ma = .Range("B4:B" & lastRow + 1).Value ' lay du  dong
    End With
    For r = 1 To UBound(ma, 1) - 1 ' khong xet dong lay them o cuoi
        If ma(r, 1) = CDbl(txtMaScan.Value) Then
'            de khong thuc hien Worksheet_Change cua sheet1 khi xoa dong thi ...
            Application.EnableEvents = False
'            dong r trong mang ma la dong (r + 3) tren sheet.
            Sheet1.Range("A" & r + 3).Resize(1, 15).Delete
            Application.EnableEvents = True
            Exit For
        End If
    Next r
    txtMaScan.SetFocus
    txtMaScan.SetFocus ' Cho con nháy nh?y vŕo txtMaScan
    txtMaScan.SelStart = 0 ' Con nháy n?m d?u txtMaScan
    txtMaScan.SelLength = 14 ' Bôi den 6 ký t? d?u tięn trong txtMaScan
End Sub
------------
Tóm lại phải phác thảo cách thức hoạt động của Form, từng nút. Và viết code sao cho chúng đồng bộ với nhau, có lôgíc. Những code tôi đưa ra chỉ là để tham khảo.
 
Lần chỉnh sửa cuối:
Upvote 0
Em cảm ơn anh/chị batman1 ah.

Anh chị đã rất nhiệt tình hỗ trợ và giải thích cho em hiểu bài ah.
Các mã code anh chị viết giúp em chạy rất tốt ah.
 
Upvote 0
Web KT

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

Back
Top Bottom