Câu lệnh đếm số dòng và số cột khi bôi đen

Liên hệ QC

Pro speed

Thành viên bị đình chỉ hoạt động
Thành viên bị đình chỉ hoạt động
Tham gia
15/9/20
Bài viết
21
Được thích
7
Chào toàn thể lãnh đạo GPE !
Mình cần câu lệnh để đếm số dòng và số cột khi bôi đen
Ví dụ
1605578171602.png
Như vầy là số cột = 3
Số dòng = 7
Xin cảm ơn !
 
Chào toàn thể lãnh đạo GPE !
Mình cần câu lệnh để đếm số dòng và số cột khi bôi đen
Ví dụ
Như vầy là số cột = 3
Số dòng = 7
Xin cảm ơn !
Bạn xem file nhé, số dòng/cột được chọn sẽ hiển thị ở thanh trạng thái góc dưới bên trái
1605591943492.png
 

File đính kèm

  • STATUS.xlsm
    13.2 KB · Đọc: 9
Upvote 0
Bạn xem file nhé, số dòng/cột được chọn sẽ hiển thị ở thanh trạng thái góc dưới bên trái
View attachment 249515
Bạn dùng sự kiện SelectionChange:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
thì Target đã được khai báo là "Range" rồi
Vậy câu lệnh sau đó:
If TypeName(Target) = "Range" Then
có phải là thừa không?
----------------------------------------------------------------------------
Ngoài ra thì dù dùng Target.Rows.Count, Target.Columns.Count hay Selection.Rows.Count. Selection.Columns.Count... cũng sẽ không đúng cho trường hợp Range gồm nhiều vùng không liên tục tạo thành (chẳng hạn quét chọn A1:C5 xong bấm giữ Ctrl rồi quét chọn tiếp F8:G10)
----------------------------------------------------------------------------
Bài này thấy đơn giản vậy chứ làm cho đến nơi đến chốn sẽ rất khó nha
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn dùng sự kiện SelectionChange:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
thì Target đã được khai báo là "Range" rồi
Vậy câu lệnh sau đó:
If TypeName(Target) = "Range" Then
có phải là thừa không?
----------------------------------------------------------------------------
Ngoài ra thì dù dùng Target.Rows.Count, Target.Columns.Count hay Selection.Rows.Count. Selection.Columns.Count... cũng sẽ không đúng cho trường hợp Range gồm nhiều vùng không liên tục tạo thành (chẳng hạn quét chọn A1:C5 xong bấm giữ Ctrl rồi quét chọn tiếp F8:G10)
----------------------------------------------------------------------------
Bài này thấy đơn giản vậy chứ làm cho đến nơi đến chốn sẽ rất khó nha
Cám ơn bạn đã góp ý, câu lệnh If đó đúng là dư thừa thật. Còn làm sao để đếm số dòng/cột khi chọn nhiều range khác nhau thì mình chưa nghĩ ra, bạn có cách gì không?
 
Upvote 0
Cám ơn bạn đã góp ý, câu lệnh If đó đúng là dư thừa thật. Còn làm sao để đếm số dòng/cột khi chọn nhiều range khác nhau thì mình chưa nghĩ ra, bạn có cách gì không?
Gợi ý là: Dùng vòng lập duyệt qua các Areas, ví dụ:
Mã:
For Each rng in Selection.Areas
  lCount = lCount + rng.Rows.Count
Next
Biến lCount của code trên sẽ cho kết quả cuối cùng chính là tổng số dòng cần tìm
Tuy nhiên vẫn còn một vấn đề khiến cho code bị sai, đó là trường hợp range gồm nhiều vùng không liên tục nhưng lại nằm chồng lên nhau. Ví dụ: bạn quét chọn A1:C5 xong bấm giữ Ctrl rồi quét chọn tiếp B2:B4)
-----------------------------------------------------------
Các bạn suy nghĩ tiếp đi
 
Upvote 0
Gợi ý là: Dùng vòng lập duyệt qua các Areas, ví dụ:
Mã:
For Each rng in Selection.Areas
  lCount = lCount + rng.Rows.Count
Next
Biến lCount của code trên sẽ cho kết quả cuối cùng chính là tổng số dòng cần tìm
Tuy nhiên vẫn còn một vấn đề khiến cho code bị sai, đó là trường hợp range gồm nhiều vùng không liên tục nhưng lại nằm chồng lên nhau. Ví dụ: bạn quét chọn A1:C5 xong bấm giữ Ctrl rồi quét chọn tiếp B2:B4)
-----------------------------------------------------------
Các bạn suy nghĩ tiếp đi
Chú cho con hỏi thêm với ạ, nếu bôi cả vùng kiểu crt+A (số dòng số cột rất lớn) thì có đếm được không ạ?
 
Upvote 0
Các bạn suy nghĩ tiếp đi
Nếu có vùng trùng thì trừ số row vùng bị trùng ra
PHP:
    For Each rng In Selection.Areas
        lCount = lCount + rng.Rows.Count
        If giao Is Nothing Then
            Set giao = rng
        Else
            Set giao = Application.Intersect(giao, rng)
            On Error Resume Next
            sotru = sotru + giao.Rows.Count
        End If
    Next
    MsgBox lCount - sotru
 
Upvote 0
Nếu có vùng trùng thì trừ số row vùng bị trùng ra
PHP:
    For Each rng In Selection.Areas
        lCount = lCount + rng.Rows.Count
        If giao Is Nothing Then
            Set giao = rng
        Else
            Set giao = Application.Intersect(giao, rng)
            On Error Resume Next
            sotru = sotru + giao.Rows.Count
        End If
    Next
    MsgBox lCount - sotru
Ví dụ tôi quét chọn A1:C5, sau đó bấm giữ Ctrl rồi quét chọn G3:G4. Trường hợp này bạn nghĩ kết quả là mấy dòng?
 
Upvote 0
Ví dụ tôi quét chọn A1:C5, sau đó bấm giữ Ctrl rồi quét chọn G3:G4. Trường hợp này bạn nghĩ kết quả là mấy dòng?
Hehe, mình cũng thấy sai sai. Tạm thời code kia xử được vụ vùng chọn chồng chéo lên nhau, còn để cho nó "đúng đúng" thì phải cải tiến thêm...
 
Upvote 0
Ví dụ tôi quét chọn A1:C5, sau đó bấm giữ Ctrl rồi quét chọn G3:G4. Trường hợp này bạn nghĩ kết quả là mấy dòng?
Mình sửa lại như này, bạn xem qua rồi góp ý giúp mình nhé

PHP:
    For Each rng In Selection.Areas
        lCount = lCount + rng.Rows.Count
        On Error Resume Next
            If trunggian.Row + trunggian.Rows.Count > rng.Row Then
                lCount = lCount - (trunggian.Row + trunggian.Rows.Count - rng.Row)
                If trunggian.Row + trunggian.Rows.Count > rng.Row + rng.Rows.Count Then lCount = lCount + (trunggian.Row + trunggian.Rows.Count - (rng.Row + rng.Rows.Count))
            End If
        Set trunggian = rng
    Next
 
Upvote 0
Mã:
Sub Test()
  Dim x, tmp
  Dim xRows As New Collection
  Dim xCols As New Collection
  Dim rng As Range
  For Each rng In Selection.Areas
    On Error Resume Next
    For x = 1 To rng.Rows.Count
      tmp = rng.Row + x
      xRows.Add tmp, CStr(tmp)
    Next x
    For x = 1 To rng.Columns.Count
      tmp = rng.Column + x
      xCols.Add tmp, CStr(tmp)
    Next x
  Next rng
  Debug.Print "So dong: " & xRows.Count
  Debug.Print "So cot: " & xCols.Count
End Sub
Thử code này xem sao.
 
Upvote 0
Mã:
Sub Test()
  Dim x, tmp
  Dim xRows As New Collection
  Dim xCols As New Collection
  Dim rng As Range
  For Each rng In Selection.Areas
    On Error Resume Next
    For x = 1 To rng.Rows.Count
      tmp = rng.Row + x
      xRows.Add tmp, CStr(tmp)
    Next x
    For x = 1 To rng.Columns.Count
      tmp = rng.Column + x
      xCols.Add tmp, CStr(tmp)
    Next x
  Next rng
  Debug.Print "So dong: " & xRows.Count
  Debug.Print "So cot: " & xCols.Count
End Sub
Thử code này xem sao.
Ví dụ tôi quét chọn A1:C5, sau đó bấm giữ Ctrl rồi quét chọn G3:G4. Trường hợp này bạn nghĩ kết quả là mấy dòng?

mình thử code cột thì có cộng nhưng dòng thì hình như chưa cộng vào
 
Upvote 0
Mình sửa lại như này, bạn xem qua rồi góp ý giúp mình nhé

PHP:
    For Each rng In Selection.Areas
        lCount = lCount + rng.Rows.Count
        On Error Resume Next
            If trunggian.Row + trunggian.Rows.Count > rng.Row Then
                lCount = lCount - (trunggian.Row + trunggian.Rows.Count - rng.Row)
                If trunggian.Row + trunggian.Rows.Count > rng.Row + rng.Rows.Count Then lCount = lCount + (trunggian.Row + trunggian.Rows.Count - (rng.Row + rng.Rows.Count))
            End If
        Set trunggian = rng
    Next
Chưa bàn chuyện đúng sai, mình chỉ xin góp ý nhỏ: Khi viết code các bạn nhớ khai báo biến đầy đủ và rõ ràng nhé
------------------------------------------------------------------------------------------------------------------
Mã:
Sub Test()
  Dim x, tmp
  Dim xRows As New Collection
  Dim xCols As New Collection
  Dim rng As Range
  For Each rng In Selection.Areas
    On Error Resume Next
    For x = 1 To rng.Rows.Count
      tmp = rng.Row + x
      xRows.Add tmp, CStr(tmp)
    Next x
    For x = 1 To rng.Columns.Count
      tmp = rng.Column + x
      xCols.Add tmp, CStr(tmp)
    Next x
  Next rng
  Debug.Print "So dong: " & xRows.Count
  Debug.Print "So cot: " & xCols.Count
End Sub
Thử code này xem sao.
For Next kiểu này mà duyệt qua 1 triệu dòng chắc.. mệt à nha
 
Upvote 0
mình thử code cột thì có cộng nhưng dòng thì hình như chưa cộng vào
Vì code của mình chỉ lấy dòng và cột duy nhất nên nếu nó nằm cùng dòng hoặc cột thì sẽ không tính.
For Next kiểu này mà duyệt qua 1 triệu dòng chắc.. mệt à nha
Máy nó mệt thôi anh, còn mình chờ lâu quá thì mình đi uống cafe
 
Upvote 0
Biết là vậy nhưng nếu cả 2 code cùng cho kết quả đúng thì ta có nên ưu tiên chọn dùng code chạy nhanh hơn không?
Đếm số dòng như này ổn không anh Ndu:
Mã:
Private Sub a()

    Dim subRange As Range
    Dim r As Range
    For Each subRange In Selection.Areas
        If r Is Nothing Then
            Set r = subRange.EntireRow.Columns(1)
        Else
            Set r = Union(r, subRange.EntireRow.Columns(1))
        End If
    Next

    Debug.Print r.Cells.Count
End Sub
 
Upvote 0
Đếm số dòng như này ổn không anh Ndu:
Mã:
Private Sub a()

    Dim subRange As Range
    Dim r As Range
    For Each subRange In Selection.Areas
        If r Is Nothing Then
            Set r = subRange.EntireRow.Columns(1)
        Else
            Set r = Union(r, subRange.EntireRow.Columns(1))
        End If
    Next

    Debug.Print r.Cells.Count
End Sub
Cách của tôi cũng gần giống vậy:
1> Đếm dòng
Mã:
Function RowsCount(ByVal SourceRange As Range) As Long
  Dim rng       As Range
  Dim lCount    As Long
  For Each rng In Intersect(SourceRange.EntireRow, Columns(1)).Areas
    lCount = lCount + rng.Rows.Count
  Next
  RowsCount = lCount
End Function
2> Đếm cột
Mã:
Function ColumnsCount(ByVal SourceRange As Range) As Long
  Dim rng       As Range
  Dim lCount    As Long
  For Each rng In Intersect(SourceRange.EntireColumn, Rows(1)).Areas
    lCount = lCount + rng.Columns.Count
  Next
  ColumnsCount = lCount
End Function
 
Upvote 0
Web KT
Back
Top Bottom