tìm SỐ Ô LIÊN TIẾP NHIỀU NHẤT CÓ DỮ LIỆU TRONG DÒNG

Liên hệ QC

pt_hcl

Thành viên hoạt động
Tham gia
15/2/11
Bài viết
138
Được thích
2
Mong GPE giúp đỡ mình trường hợp này, mình có bảng dữ liệu cần tìm SỐ Ô LIÊN TIẾP NHIỀU NHẤT CÓ DỮ LIỆU MÀ ĐỨNG TRƯỚC NÓ LÀ CÓ ÍT NHẤT 1 Ô TRỐNG KHÔNG CÓ DỮ LIỆU đối với từng dòng. Mình có gửi file minh hoạ. Kết quả đếm số cột liên tiếp có dữ liệu nhiều nhất được ghi vào cột 4. File thực tế có vùng dữ liệu rất lớn: (D4: DB966748). Rất mong GPE giúp đỡ. Xin cảm ơn!
 

File đính kèm

  • SOOCODULIEUMAX.xlsx
    16.3 KB · Đọc: 33
Mong GPE giúp đỡ mình trường hợp này, mình có bảng dữ liệu cần tìm SỐ Ô LIÊN TIẾP NHIỀU NHẤT CÓ DỮ LIỆU MÀ ĐỨNG TRƯỚC NÓ LÀ CÓ ÍT NHẤT 1 Ô TRỐNG KHÔNG CÓ DỮ LIỆU đối với từng dòng. Mình có gửi file minh hoạ. Kết quả đếm số cột liên tiếp có dữ liệu nhiều nhất được ghi vào cột 4. File thực tế có vùng dữ liệu rất lớn: (D4: DB966748). Rất mong GPE giúp đỡ. Xin cảm ơn!

nếu số liệu lớn thì phải xài vba, tôi thấy dạng này trên diễn đàn cũng nhiêu
với file hiện tại thì thử cthuc này
Mã:
D4=LARGE(FREQUENCY(IF(G4:DB4<>"",COLUMN(G4:DB4)-6),IF(G4:DB4="",COLUMN(G4:DB4)-6)),IF(G4="",1,2))

nhấn Ctrl shift enter để kết thúc
 
nếu số liệu lớn thì phải xài vba, tôi thấy dạng này trên diễn đàn cũng nhiêu
với file hiện tại thì thử cthuc này
Mã:
D4=LARGE(FREQUENCY(IF(G4:DB4<>"",COLUMN(G4:DB4)-6),IF(G4:DB4="",COLUMN(G4:DB4)-6)),IF(G4="",1,2))

nhấn Ctrl shift enter để kết thúc

Với dữ liệu: "File thực tế có vùng dữ liệu rất lớn: (D4: DB966748)" 100 cột 966748 nghìn dòng thì không công thức nào chịu nổi đâu bạn. Tốt nhất là dùng VBA thôi.
 
nếu số liệu lớn thì phải xài vba, tôi thấy dạng này trên diễn đàn cũng nhiêu
với file hiện tại thì thử cthuc này
Mã:
D4=LARGE(FREQUENCY(IF(G4:DB4<>"",COLUMN(G4:DB4)-6),IF(G4:DB4="",COLUMN(G4:DB4)-6)),IF(G4="",1,2))

nhấn Ctrl shift enter để kết thúc
Vâng ạ, cảm ơn thầy rất nhiều! Nếu thầy giúp được VBA thì hay quá!
 
nếu số liệu lớn thì phải xài vba, tôi thấy dạng này trên diễn đàn cũng nhiêu
với file hiện tại thì thử cthuc này
Mã:
D4=LARGE(FREQUENCY(IF(G4:DB4<>"",COLUMN(G4:DB4)-6),IF(G4:DB4="",COLUMN(G4:DB4)-6)),IF(G4="",1,2))

nhấn Ctrl shift enter để kết thúc
Không dễ ăn đâu bạn hiền ơi, thử nhập 1 số vào G4 sẽ thấy công thức "tèo"
 
VBA thì càng không cần phải lo . đã có Let' Gâu Gâu bảo kê hết
Vâng ạ! Mà em xin lỗi một chút ạ, trong file thì ô có chứa số 0 vẫn tính là có dữ liệu ạ, trong file minh hoạ em chưa có trường hợp này! Rất mong sự giúp đỡ của GPE!
 
Lần chỉnh sửa cuối:
vâng, rất mong thầy và các bạn trong GPE giúp đỡ về VBA ạ!

trong khi đợi cao thủ ra tay, xem thử
à quên, đừng kêu bằng thầy, tôi không thể đạt được đẳng cấp đó
==========
VBA thì càng không cần phải lo . đã có Let' Gâu Gâu bảo kê hết

chỉ là múa rìu qua mắt thợ thui........chơi vui cho qua ngày đoạn tháng mà.......hehehehehh
 

File đính kèm

  • SOOCODULIEUMAX.rar
    17.4 KB · Đọc: 17
trong khi đợi cao thủ ra tay, xem thử
à quên, đừng kêu bằng thầy, tôi không thể đạt được đẳng cấp đó
==========


chỉ là múa rìu qua mắt thợ thui........chơi vui cho qua ngày đoạn tháng mà.......hehehehehh

trùi ui thầy khiêm tốn quá . cách làm của thầy rất hay ạ . em học hỏi được rất nhiều từ thầy ạ . hi hi hi --=0--=0--=0
 
trong khi đợi cao thủ ra tay, xem thử
à quên, đừng kêu bằng thầy, tôi không thể đạt được đẳng cấp đó
chỉ là múa rìu qua mắt thợ thui........chơi vui cho qua ngày đoạn tháng mà.......hehehehehh
Ké theo 1 hàm, giải trí chơi:
Mã:
Public Function LienTiep(Vung As Range) As Long
Dim i As Long, Tam As Long, HeSo As Byte
For i = 1 To Vung.Columns.Count
If Vung(i).Value <> "" Then
    Tam = Tam + 1
    If LienTiep < Tam * HeSo Then LienTiep = Tam
Else
    Tam = 0
    HeSo = 1
End If
Next
End Function
 
trùi ui thầy khiêm tốn quá . cách làm của thầy rất hay ạ . em học hỏi được rất nhiều từ thầy ạ . hi hi hi --=0--=0--=0

đừng chơi quê nha...............quê là khó "quề" đó.....hihihiih
==========
hỏi cái nì một tí
"Chim Hạc & Hồng Hoa" có cách nào làm cho các vòng lặp chỉ chạy một lần ko
tức là như vậy, hiện nay mỗi dòng phải xài một vòng lặp
bi giờ tôi muốn nó chỉ chạy một lần thôi
quét qua từng dòng, rồi quét từ trên xuống
công thức từ B4:B13 thì dùng dạng mảng hay sao đó
có thấy sư phụ HYen làm một lần, mà quên mất, kiếm lại cũng ko ra............hichic
 
đừng chơi quê nha...............quê là khó "quề" đó.....hihihiih
==========
hỏi cái nì một tí
"Chim Hạc & Hồng Hoa" có cách nào làm cho các vòng lặp chỉ chạy một lần ko
tức là như vậy, hiện nay mỗi dòng phải xài một vòng lặp
bi giờ tôi muốn nó chỉ chạy một lần thôi
quét qua từng dòng, rồi quét từ trên xuống
công thức từ B4:B13 thì dùng dạng mảng hay sao đó
có thấy sư phụ HYen làm một lần, mà quên mất, kiếm lại cũng ko ra............hichic

cứ yên tâm là dữ liệu bài này xài ít nhất 2 vòng lặp nếu là viết SUB (dữ liệu mà 1 000 000 dòng thì phải dùng 3 vòng )
anh cứ chuẩn bị tinh thần người ta sắp la làng lên là function chạy không nổi đi nha . hí hí
em đang để đầu óc đi ĐÚ với thầy ĐU bên topic tập giải nén file xlsx nên chưa coi kỹ được bài này . nhờ anh vậy
 
Mong GPE giúp đỡ mình trường hợp này, mình có bảng dữ liệu cần tìm SỐ Ô LIÊN TIẾP NHIỀU NHẤT CÓ DỮ LIỆU MÀ ĐỨNG TRƯỚC NÓ LÀ CÓ ÍT NHẤT 1 Ô TRỐNG KHÔNG CÓ DỮ LIỆU đối với từng dòng. Mình có gửi file minh hoạ. Kết quả đếm số cột liên tiếp có dữ liệu nhiều nhất được ghi vào cột 4. File thực tế có vùng dữ liệu rất lớn: (D4: DB966748). Rất mong GPE giúp đỡ. Xin cảm ơn!

Vậy là file đính kèm khác file thực?

Bài này 1 vòng lặp vẫn được, thời gian hơi bị lâu ~ 300s
 
vâng, rất mong thầy và các bạn trong GPE giúp đỡ về VBA ạ!

Bạn thử với đoạn code này xem.
Do file nặng quá nên mình chỉ upload code lên thôi. Mình đã thử với 1012503 dòng và 100 cột (với dữ liệu giống của bạn) mất khoảng 40s.

Mã:
Option Explicit
Declare Function GetTickCount Lib "kernel32" () As Long

Sub test()
   Dim rngNguon As Range, rngDong As Range
   Dim lngRNguon As Long
   Dim arrKetQua(), t As Double
   t = GetTickCount
   Set rngNguon = Sheet1.Range("G4:DB1012503")
   ReDim arrKetQua(1 To rngNguon.Rows.Count, 1 To 1)
   For lngRNguon = 1 To rngNguon.Rows.Count
      Set rngDong = Sheet1.Range("G" & lngRNguon + 3 & ":DB" & lngRNguon + 3)
      arrKetQua(lngRNguon, 1) = DemFREQUENCY(rngDong)
   Next lngRNguon
   Sheet1.Range("D4").Resize(lngRNguon - 1, 1).Value = arrKetQua
   MsgBox GetTickCount - t
End Sub


Function DemFREQUENCY(rngRng As Range) As Long
   Dim arrNguon()
   Dim lngCNguon As Long, lngDemPT As Long
   arrNguon = rngRng.Value2
   For lngCNguon = 1 To UBound(arrNguon, 2)
      If Len((arrNguon(1, lngCNguon))) Then
      lngDemPT = lngDemPT + 1
         If DemFREQUENCY < lngDemPT Then DemFREQUENCY = lngDemPT
      Else
         lngDemPT = 0
      End If
   Next lngCNguon
End Function
 
Bạn thử với đoạn code này xem.
Do file nặng quá nên mình chỉ upload code lên thôi. Mình đã thử với 1012503 dòng và 100 cột (với dữ liệu giống của bạn) mất khoảng 40s.

Mã:
Option Explicit
Declare Function GetTickCount Lib "kernel32" () As Long

Sub test()
   Dim rngNguon As Range, rngDong As Range
   Dim lngRNguon As Long
   Dim arrKetQua(), t As Double
   t = GetTickCount
   Set rngNguon = Sheet1.Range("G4:DB1012503")
   ReDim arrKetQua(1 To rngNguon.Rows.Count, 1 To 1)
   For lngRNguon = 1 To rngNguon.Rows.Count
      Set rngDong = Sheet1.Range("G" & lngRNguon + 3 & ":DB" & lngRNguon + 3)
      arrKetQua(lngRNguon, 1) = DemFREQUENCY(rngDong)
   Next lngRNguon
   Sheet1.Range("D4").Resize(lngRNguon - 1, 1).Value = arrKetQua
   MsgBox GetTickCount - t
End Sub


Function DemFREQUENCY(rngRng As Range) As Long
   Dim arrNguon()
   Dim lngCNguon As Long, lngDemPT As Long
   arrNguon = rngRng.Value2
   For lngCNguon = 1 To UBound(arrNguon, 2)
      If Len((arrNguon(1, lngCNguon))) Then
      lngDemPT = lngDemPT + 1
         If DemFREQUENCY < lngDemPT Then DemFREQUENCY = lngDemPT
      Else
         lngDemPT = 0
      End If
   Next lngCNguon
End Function
Vâng cảm ơn bạn! Bạn ơi mong bạn xem giúp lại một chút chỗ điều kiện là số ô có dữ liệu liên tiếp nhiều nhất mà trước đó phải có ô trống ạ! Một lần nữa xin cảm ơn bạn và GPE!
 
Vâng cảm ơn bạn! Bạn ơi mong bạn xem giúp lại một chút chỗ điều kiện là số ô có dữ liệu liên tiếp nhiều nhất mà trước đó phải có ô trống ạ! Một lần nữa xin cảm ơn bạn và GPE!

tất cả những người ở trên đều viết theo ý tưởng màu đỏ . cho nên nếu bạn cảm thấy sai thì bạn up file khác lên đây và chỉ rõ đã sai ở dòng nào ? và dòng đó phải là bao nhiêu mới đúng ? giải thích lý do .
 
tất cả những người ở trên đều viết theo ý tưởng màu đỏ . cho nên nếu bạn cảm thấy sai thì bạn up file khác lên đây và chỉ rõ đã sai ở dòng nào ? và dòng đó phải là bao nhiêu mới đúng ? giải thích lý do .
Dạ vâng, em chạy thử với code của bài #15 thì kết quả đếm số ô nhiều nhất là không có ô trống ban đầu ạ! Em xin gửi file minh hoạ! Xin cảm ơn GPE!
 

File đính kèm

  • SOOCODULIEUMAX.xlsm
    23.1 KB · Đọc: 9
Dạ vâng, em chạy thử với code của bài #15 thì kết quả đếm số ô nhiều nhất là không có ô trống ban đầu ạ! Em xin gửi file minh hoạ! Xin cảm ơn GPE!

Mã:
Public Sub hello()
Dim lr As Long, lc As Long, arr As Variant, r As Long, dArr As Variant, tCount As Double, validSpace As Boolean
Dim c As Long, maxCount As Long, tempCount As Long, tempUbound As Long, curRow As Long, k As Long, uc As Long
tCount = Timer
Application.ScreenUpdating = False
With Sheet1
    lr = .UsedRange.SpecialCells(xlCellTypeLastCell).Row
    lc = .UsedRange.SpecialCells(xlCellTypeLastCell).Column - 6
    ReDim dArr(1 To .Rows.Count, 1 To 1)
    curRow = 4
    Do While tempUbound < lr
        tempUbound = tempUbound + 50000
        arr = .Range("G" & curRow & ":G" & WorksheetFunction.Min(tempUbound, lr)).Resize(, lc).Value
        uc = UBound(arr, 2)
        For r = 1 To UBound(arr) Step 1
            maxCount = 0: tempCount = 0: validSpace = False
            For c = 1 To uc Step 1
                If Not arr(r, c) = Empty Then
                    If validSpace Then tempCount = tempCount + 1
                Else
                    If tempCount > maxCount Then maxCount = tempCount
                    tempCount = 0: validSpace = True
                End If
            Next
            k = k + 1
            dArr(k, 1) = maxCount
        Next
        curRow = curRow + UBound(arr)
    Loop
    .Range("D4").Resize(k).Value = dArr
End With
Application.ScreenUpdating = True
MsgBox Timer - tCount
End Sub
 
Lần chỉnh sửa cuối:
Mã:
Public Sub hello()
Dim lr As Long, lc As Long, arr As Variant, r As Long, dArr As Variant, tCount As Double, validSpace As Boolean
Dim c As Long, maxCount As Long, tempCount As Long, tempUbound As Long, curRow As Long, k As Long, uc As Long
tCount = Timer
Application.ScreenUpdating = False
With Sheet1
    lr = .UsedRange.SpecialCells(xlCellTypeLastCell).Row
    lc = .UsedRange.SpecialCells(xlCellTypeLastCell).Column - 6
    ReDim dArr(1 To .Rows.Count, 1 To 1)
    curRow = 4
    Do While tempUbound < lr
        tempUbound = tempUbound + 50000
        arr = .Range("G" & curRow & ":G" & WorksheetFunction.Min(tempUbound, lr)).Resize(, lc).Value
        uc = UBound(arr, 2)
        For r = 1 To UBound(arr) Step 1
            maxCount = 0: tempCount = 0: validSpace = False
            For c = 1 To uc Step 1
                If Not arr(r, c) = Empty Then
                    If validSpace Then tempCount = tempCount + 1
                Else
                    If tempCount > maxCount Then maxCount = tempCount
                    tempCount = 0: validSpace = True
                End If
            Next
            k = k + 1
            dArr(k, 1) = maxCount
        Next
        curRow = curRow + UBound(arr)
    Loop
    .Range("D4").Resize(k).Value = dArr
End With
Application.ScreenUpdating = True
MsgBox Timer - tCount
End Sub
Vâng cảm ơn bạn, bạn ơi những ô có chứa dữ liệu là số 0 thì vẫn được tính ạ, trong code của bạn mình chạy thì không đếm dữ liệu là số 0. Bạn xem giúp ạ! Xin cảm ơn bạn1
 
Web KT

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

Back
Top Bottom