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
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.
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.
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
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.
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).
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
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
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à
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â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.
Ý 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
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