Giúp mình lỗi đếm số thứ tự trong đoạn code này với.

Liên hệ QC

qtm1987

Thành viên thường trực
Tham gia
15/9/09
Bài viết
311
Được thích
215
Nghề nghiệp
Kế toán tổng hợp
Mình viết code đếm số thự tự, nếu bên cột Tên có sẵn tên rồi thì code chạy bình thường, khi mình test thử xóa 1 tên, rồi xóa 2 tên thì code vẫn chạy bình thường, nhưng nếu xóa 3 tên còn lại 1 tên thì code báo lỗi, lẽ ra còn 1 tên thì code vẫn phải đếm là số 1 chứ, mình ko hiểu tại sao lại báo lỗi
Nếu xóa hết tất cả tên thì stt lại đếm 1, lẽ ra dữ liệu Tên ko có, ko thỏa điều kiện để đếm stt thì stt tại A5 phải là 0 chứ nhỉ.
Code mình viết sai chỗ nào mong các bạn giải đáp giúp mình với.
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
If Mid(Target.Address, 2, 1) = "B" Then STT
End Sub

Sub STT()
Dim i As Long, sArray, Arr()
With ActiveSheet
    .Range("A5:A65536").ClearContents
    sArray = .Range(.[B5], .[B65536].End(xlUp)).Value
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
For i = 1 To UBound(sArray, 1)
    If Not IsEmpty(sArray(i, 1)) Then
        n = n + 1
        Arr(i, 1) = n
    End If
Next
.Range("A5").Resize(i - 1, 1).Value = Arr
End With
End Sub
 

File đính kèm

  • Test.rar
    7.6 KB · Đọc: 11
Mình viết code đếm số thự tự, nếu bên cột Tên có sẵn tên rồi thì code chạy bình thường, khi mình test thử xóa 1 tên, rồi xóa 2 tên thì code vẫn chạy bình thường, nhưng nếu xóa 3 tên còn lại 1 tên thì code báo lỗi, lẽ ra còn 1 tên thì code vẫn phải đếm là số 1 chứ, mình ko hiểu tại sao lại báo lỗi
Nếu xóa hết tất cả tên thì stt lại đếm 1, lẽ ra dữ liệu Tên ko có, ko thỏa điều kiện để đếm stt thì stt tại A5 phải là 0 chứ nhỉ.
Code mình viết sai chỗ nào mong các bạn giải đáp giúp mình với.
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
If Mid(Target.Address, 2, 1) = "B" Then STT
End Sub

Sub STT()
Dim i As Long, sArray, Arr()
With ActiveSheet
    .Range("A5:A65536").ClearContents
    sArray = .Range(.[B5], .[B65536].End(xlUp)).Value
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
For i = 1 To UBound(sArray, 1)
    If Not IsEmpty(sArray(i, 1)) Then
        n = n + 1
        Arr(i, 1) = n
    End If
Next
.Range("A5").Resize(i - 1, 1).Value = Arr
End With
End Sub
1. Khi còn xóa hết để lại 1 lại hàng 5 thì mới bị lỗi (các hàng khác vẫn bình thường) nguyên nhân .[B65536].End(xlUp) ~ .[B5]
nghĩa là sArray chỉ có 1 phần tử duy nhất (mình không chắc do 1 phần tử máy có xem là mãng không? các anh chị giải thích tiếp cho bạn)
2. Khi xóa hết thì .[B65536].End(xlUp) ~ B4 nghĩa là sArray=Range("B4:B5").Value nên có 1 phần tử B4 (not Empty)
Vậy bạn nên đặt sArray = .Range(.[B4], .[B65536].End(xlUp)).Value -> Sửa code
 
Upvote 0
Khi bạn xóa hết dữ liệu thì mảng sArray tự động lấy ngược lên dòng tiêu đề, do đó nó đưa ra giá trị 1; khi chỉ còn 1 dòng thì sArray tự chuyển thành 1 giá trị nên hàm uBound báo lỗi cú pháp. Để tránh 2 tình huống này, có thể xử lý bằng cách cài bẫy lỗi như dưới đây:

PHP:
Sub STT()
Dim i As Long, Arr(), rData As Range, rc As Long
With ActiveSheet
    .Range(.[A5], .[A65536]).ClearContents
    Set rData = .Range(.[A4], .[B65536].End(xlUp))
    rc = rData.Rows.Count
    If rc = 1 Then
        rData.Cells(2, 1) = ""
    ElseIf rc = 2 Then rData.Cells(2, 1) = 1
    Else
        rc = rc - 1
        ReDim Arr(1 To rc, 1 To 1)
        Set rData = rData.Offset(1).Resize(rc)
        Arr = rData
        For i = 1 To rc
            If Not IsEmpty(Arr(i, 2)) Then
                n = n + 1
                Arr(i, 1) = n
            End If
        Next
        .Range("A5").Resize(i - 1, 1).Value = Arr
    End If
End With
End Sub

Hy vọng giải quyết được vấn đề của bạn!
 
Upvote 0
Khi bạn xóa hết dữ liệu thì mảng sArray tự động lấy ngược lên dòng tiêu đề...
Phải chăng do code của mình lúc nạp range vào mảng mình để .end(xlUp) nên lúc xóa hết dữ liệu thì mảng lấy dòng tiêu đề. Vậy nếu mình thay bằng .end(xlDown) thì sẽ ko bị lỗi đúng ko nhỉ?
...khi chỉ còn 1 dòng thì sArray tự chuyển thành 1 giá trị nên hàm uBound báo lỗi cú pháp.
Còn hàm ubound bị lỗi cú pháp là sao bạn, mình chưa hiểu lắm về lỗi này của ubound.
 
Upvote 0
Như trên đã nói, với 1 phần tử thì biến sArray không còn là biến mảng, mà cú pháp của hàm uBound đòi hỏi tham số mảng nên nó báo lỗi!
 
Upvote 0
Chỉ cần sửa sơ thế này là đủ:
PHP:
Sub STT()
  Dim i As Long, j As Long, n As Long, sArray, Arr()
  On Error Resume Next
  With ActiveSheet
    .Range("A5:A65536").ClearContents
    sArray = .Range("B5:B10000").Value
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
    For i = 1 To UBound(sArray, 1)
      If Not IsEmpty(sArray(i, 1)) Then
        n = n + 1: j = i
        Arr(i, 1) = n
      End If
    Next
    If n Then .Range("A5").Resize(j).Value = Arr
  End With
End Sub
Mảng cho tốc độ rất cao, khai báo luôn 10000 dòng cũng chẳng thấm thía gì (khỏi cần phải xlUp, xlDown gì ráo)
 
Upvote 0
Chỉ cần sửa sơ thế này là đủ:
Mảng cho tốc độ rất cao, khai báo luôn 10000 dòng cũng chẳng thấm thía gì (khỏi cần phải xlUp, xlDown gì ráo)

Thầy giúp giùm em cách đánh số thứ tự này, trường hợp của em nó phức tạp hơn nên em không thể áp dụng bài trên vào bài của em được ạ!
Vì mỗi lần em thêm bớt dòng thí nó thương hay báo lỗi.
Câu hỏi ở trong File đính kèm. xin cảm ơn Quý thầy cô và anh chị.
 

File đính kèm

  • Book2.xls
    38 KB · Đọc: 7
Lần chỉnh sửa cuối:
Upvote 0
nếu bỏ qua xlUp hoặc xlDown có phải vòng for sẽ đếm tới 10000 lun phải hok anh NDU?
Đúng như viethoai đã nói về mặt tốc độ ta không phải lo, vì xử lý mảng cho tốc độ rất nhanh. Ngoài ra, nếu bạn dùng xlUp sẽ có nguy cơ bị sai nếu 1 ngày nào đó trong bảng tính của bạn có dùng đến chức năng AutoFilter
Vậy nên: Đã dùng đến mảng thì cứ yên tâm mà... "phung phí"
Ẹc... Ẹc...
(đương nhiên là đừng vung tay quá trán)
 
Upvote 0
Thầy ndu giúp em bài số #7 với, vì thực tế mỗi lần thêm bớt dòng em lại phải kéo cái công thức, nếu nó báo lỗi thì em còn thấy, nhiều lúc nó tính sai thì em không để ý hết.
Xin cảm ơn thầy trước!
 
Upvote 0
Web KT
Back
Top Bottom