Tìm số ô cách nhau lớn nhất và nhỏ nhất trong dòng giữa 2 số liệu khác nhau.

Liên hệ QC

hcl_pt

Thành viên thường trực
Tham gia
21/10/10
Bài viết
208
Được thích
11
Mình có vấn đề sau mong được GPE giúp đỡ: muốn kiểm tra xem dữ liệu a cách dữ liệu b bao nhiêu ô trong dòng: lấy kết quả số ô cách nhau lớn nhất và số ô cách nhau ít nhất.
- Ví dụ :
+ Ở dòng 5: dữ liệu a cách dữ liệu b số ô lớn nhất là 6, và số ô cách ít nhất là 0.
+ Ở dòng 6: dữ liệu a cách dữ liệu b số ô lớn nhất là 4 và số ô cách ít nhất cũng là 4 (trường hợp này số ô cách nhiều nhất và ít nhất là như nhau).
+ v..v...
- Rất mong sự giúp đỡ của GPE. Xin chân thành cảm ơn rất nhiều!
 

File đính kèm

  • SO_O_MAX_MIN.xlsx
    65 KB · Đọc: 33
Mình có vấn đề sau mong được GPE giúp đỡ: muốn kiểm tra xem dữ liệu a cách dữ liệu b bao nhiêu ô trong dòng: lấy kết quả số ô cách nhau lớn nhất và số ô cách nhau ít nhất.
- Ví dụ :
+ Ở dòng 5: dữ liệu a cách dữ liệu b số ô lớn nhất là 6, và số ô cách ít nhất là 0.
+ Ở dòng 6: dữ liệu a cách dữ liệu b số ô lớn nhất là 4 và số ô cách ít nhất cũng là 4 (trường hợp này số ô cách nhiều nhất và ít nhất là như nhau).
+ v..v...
- Rất mong sự giúp đỡ của GPE. Xin chân thành cảm ơn rất nhiều!
Mã:
Sub minmax()
Dim min As Integer, max As Integer, i, j As Integer
    For i = 5 To 102
        max = 0: min = 150
        For j = 5 To 153
            If Cells(i, j) = "a" Then
                For k = j + 1 To 153
                    If Cells(i, k) <> "" Then
                        If Cells(i, k) = "b" Then
                            If min >= k - j - 1 Then min = k - j - 1
                            If max <= k - j - 1 Then max = k - j - 1
                            j = k - 1
                            Exit For
                        Else
                            j = k - 1
                            Exit For
                        End If
                    End If
                Next
            End If
        Next
        If min <> 150 Then
            Cells(i, 2) = max: Cells(i, 3) = min
        End If
    Next
End Sub
 
Mình có vấn đề sau mong được GPE giúp đỡ: muốn kiểm tra xem dữ liệu a cách dữ liệu b bao nhiêu ô trong dòng: lấy kết quả số ô cách nhau lớn nhất và số ô cách nhau ít nhất.
- Ví dụ :
+ Ở dòng 5: dữ liệu a cách dữ liệu b số ô lớn nhất là 6, và số ô cách ít nhất là 0.
+ Ở dòng 6: dữ liệu a cách dữ liệu b số ô lớn nhất là 4 và số ô cách ít nhất cũng là 4 (trường hợp này số ô cách nhiều nhất và ít nhất là như nhau).
+ v..v...
- Rất mong sự giúp đỡ của GPE. Xin chân thành cảm ơn rất nhiều!

Xin hỏi:
(1) Cách nhau được định nghĩa là: Không có dữ liệu gì (rỗng) giữa a và b HAY có dữ liệu khác a và khác b?
(2) Cách nhau chỉ tính chiều từ trái sang phải hay tính cả chiều ngược lại?
 
Mình có vấn đề sau mong được GPE giúp đỡ: muốn kiểm tra xem dữ liệu a cách dữ liệu b bao nhiêu ô trong dòng: lấy kết quả số ô cách nhau lớn nhất và số ô cách nhau ít nhất.
- Ví dụ :
+ Ở dòng 5: dữ liệu a cách dữ liệu b số ô lớn nhất là 6, và số ô cách ít nhất là 0.
+ Ở dòng 6: dữ liệu a cách dữ liệu b số ô lớn nhất là 4 và số ô cách ít nhất cũng là 4 (trường hợp này số ô cách nhiều nhất và ít nhất là như nhau).
+ v..v...
- Rất mong sự giúp đỡ của GPE. Xin chân thành cảm ơn rất nhiều!
sử dung hàm tự tạo
Mã:
Function CachKhoang(Rng As Range, Str1 As String, Str2 As String, Optional MM As Boolean)
Dim Arr(), j As Integer, k As Integer, dMax As Integer, dMin As Integer, tmp As Byte
Arr = Rng.Value
dMin = UBound(Arr, 2)
For j = 1 To UBound(Arr, 2) - 1
    If Arr(1, j) = Str1 Then
        For k = j + 1 To UBound(Arr, 2)
            If Arr(1, k) = Str1 Then j = k
            If Arr(1, k) = Str2 Then
                If MM = False And k - j - 1 > dMax Then dMax = k - j - 1
                If MM = True And k - j - 1 < dMin Then dMin = k - j - 1
                j = k:  tmp = 1: Exit For
            End If
        Next k
    End If
Next j
If tmp = 0 Then
    CachKhoang = "Không có DL"
Else
    If MM = False Then CachKhoang = dMax
    If MM = True Then CachKhoang = dMin
End If
Erase Arr
End Function
 

File đính kèm

  • SO_O_MAX_MIN.xlsb
    37.5 KB · Đọc: 9
Lần chỉnh sửa cuối:
Mình có vấn đề sau mong được GPE giúp đỡ: muốn kiểm tra xem dữ liệu a cách dữ liệu b bao nhiêu ô trong dòng: lấy kết quả số ô cách nhau lớn nhất và số ô cách nhau ít nhất.
- Ví dụ :
+ Ở dòng 5: dữ liệu a cách dữ liệu b số ô lớn nhất là 6, và số ô cách ít nhất là 0.
+ Ở dòng 6: dữ liệu a cách dữ liệu b số ô lớn nhất là 4 và số ô cách ít nhất cũng là 4 (trường hợp này số ô cách nhiều nhất và ít nhất là như nhau).
+ v..v...
- Rất mong sự giúp đỡ của GPE. Xin chân thành cảm ơn rất nhiều!
Mình dùng Ct cho bài này:
Tính Max, CT tại B5:
Mã:
B5=MAX(MAX(IFERROR((COLUMN(A:ES)/(E5:EW5="b")-LOOKUP(COLUMN(A:ES)/(E5:EW5="b"),COLUMN(A:ES)/(E5:EW5="a")))/(--TRANSPOSE(FREQUENCY(COLUMN(A:ES)*(E5:EW5="a"),COLUMN(A:ES)*(E5:EW5="b"))>0)),""))-1,0)
Tính Min, CT tại C5:
Mã:
=MAX(MIN(IFERROR((COLUMN(A:ES)/(E5:EW5="b")-LOOKUP(COLUMN(A:ES)/(E5:EW5="b"),COLUMN(A:ES)/(E5:EW5="a")))/(--TRANSPOSE(FREQUENCY(COLUMN(A:ES)*(E5:EW5="a"),COLUMN(A:ES)*(E5:EW5="b"))>0)),""))-1,0)
CTrl+Shift+Enter rồi fill xuông!!!
 

File đính kèm

  • SO_O_MAX_MIN.xlsx
    63.3 KB · Đọc: 6
Lần chỉnh sửa cuối:
Bài này code VBA thì trả về luôn 2 trị một lúc: array(1 to 2), khoẻ hơn.
 
Lần chỉnh sửa cuối:
Bài này code VBA thì trả về luôn 2 trị một lúc: array(1 to 2), khoẻ hơn.
bạn góp ý dùm, cám ơn
Mã:
Function CachKh(Rng As Range, Str1 As String, Str2 As String)
Dim Arr(), j As Integer, k As Integer, dMax As Integer, dMin As Integer, tmp As Byte, kq(1 To 1, 1 To 2)
Arr = Rng.Value
dMin = UBound(Arr, 2)
For j = 1 To UBound(Arr, 2) - 1
    If Arr(1, j) = Str1 Then
        For k = j + 1 To UBound(Arr, 2)
            If Arr(1, k) = Str1 Then j = k
            If Arr(1, k) = Str2 Then
                If k - j - 1 > dMax Then dMax = k - j - 1
                If k - j - 1 < dMin Then dMin = k - j - 1
                j = k:  tmp = 1: Exit For
            End If
        Next k
    End If
Next j
If tmp = 0 Then
    kq(1, 1) = "Không có DL": kq(1, 2) = "Không có DL"
Else
    kq(1, 1) = dMax:    kq(1, 2) = dMin
End If
CachKh = kq
Erase Arr:  Erase kq
End Function
chọn 2 ô nhập công thức và nhấn Ctrl+Shift+Enter
 

File đính kèm

  • SO_O_MAX_MIN.xlsb
    38.7 KB · Đọc: 8
Lần chỉnh sửa cuối:
Cảm ơn các bạn và GPE rất nhiều. Xin cảm ơn ạ!
 
Mã:
Dim kq(1 To 1, 1 To 2)...
chọn 2 ô nhập công thức và nhấn Ctrl+Shift+Enter
Anh khai báo là kq(1 to 2) cũng được.
Công thức ở bảng tính có thể dùng:
Mã:
B5=INDEX(CachKh($E5:$EW5,"a","b"),1,1)
C5=INDEX(CachKh($E5:$EW5,"a","b"),1,2)
 
Code bài này hình như dùng 1 vòng lặp vẫn giải quyết được hay sao í
 
Anh khai báo là kq(1 to 2) cũng được.
Công thức ở bảng tính có thể dùng:
Mã:
B5=INDEX(CachKh($E5:$EW5,"a","b"),1,1)
C5=INDEX(CachKh($E5:$EW5,"a","b"),1,2)
cám ơn bạn, mình viết lại code để nhập công thức theo nhiều cách
Mã:
Function CachKh(Rng As Range, Str1 As String, Str2 As String, Optional MM As Boolean)
Dim Arr(), j As Integer, k As Integer, dMax As Integer, dMin As Integer, tmp As Byte, kq(1 To 2)
Arr = Rng.Value
dMin = UBound(Arr, 2)
For j = 1 To UBound(Arr, 2) - 1
    If Arr(1, j) = Str1 Then
        For k = j + 1 To UBound(Arr, 2)
            If Arr(1, k) = Str1 Then j = k
            If Arr(1, k) = Str2 Then
                If k - j - 1 > dMax Then dMax = k - j - 1
                If k - j - 1 < dMin Then dMin = k - j - 1
                j = k:  tmp = 1: Exit For
            End If
        Next k
    End If
Next j
If tmp = 0 Then
    kq(1) = "Không có DL": kq(2) = "Không có DL"
Else
    kq(1) = dMax:    kq(2) = dMin
End If
CachKh = kq
If MM = True Then CachKh = kq(2)
Erase Arr:  Erase kq
End Function
- chọn 2 ô nhập công thức và nhấn Ctrl+Shift+Enter ra kết quả cả Max và Min
- chọn ô B5 =CachKh($E5:$EW5,"a","b") kết quả Max
- chọn ô C6 =CachKh($E5:$EW5,"a","b",1) kết quả Min
 

File đính kèm

  • SO_O_MAX_MIN.xlsb
    38.6 KB · Đọc: 2
Code bài này hình như dùng 1 vòng lặp vẫn giải quyết được hay sao í

Đây nè. Mấy code dùng nhiều vòng lặp không hẳn đã không hiệu quả, bởi vì chúng có cách nhảy khoảng. Chỉ là phương pháp nhảy khoảng thì trông code khó hiểu 1 chút thôi.

Mã:
Function MXMN_Khoang(ByVal rg As Range, ByVal s1 As String, ByVal s2 As String) As Variant

[COLOR=#008000]' đếm số ô trống giúa 2 giá trị s1 và s2, trả về một mảng gồm số max và số min
' giải thuật là lần lượt tìm những khoảng có dang (a)(n ô trống)(b)
' mỗi khi tìm được 1 a thì bắt đầu đếm ô trống cho đến khi gặp b.[/COLOR]

Dim r(1 To 2) As Integer [COLOR=#008000]' mảng kết quả[/COLOR]
If (rg.Rows.Count = 1) Then
Dim dat() As Variant, i As Integer, dem As Integer, sDem As Boolean
dat = rg.Value2
r(1) = -1: r(2) = 100000 [COLOR=#008000]' trị tạm khởi đầu[/COLOR]
sDem = False [COLOR=#008000]' flag: chưa bắt đầu đếm[/COLOR]
For i = 1 To UBound(dat, 2) [COLOR=#008000]' duyệt từng trị trong range[/COLOR]
  Select Case dat(1, i)
    Case s1
      sDem = True [COLOR=#008000]' flag: đã gặp trị a, bắt đầu đếm số ô trống[/COLOR]
      dem = 0
    Case s2
      If sDem Then [COLOR=#008000]' khi flag on có nghĩa là ta có một trị a đi trước trị b, cách nhau n (dem) ô trống[/COLOR]
        If dem > r(1) Then r(1) = dem
        If dem < r(2) Then r(2) = dem
        sDem = False [COLOR=#008000]' flag: ngưng đếm[/COLOR]
      End If
    Case vbNullString
      If sDem Then dem = dem + 1[COLOR=#008000] ' tiếp tục đếm số ô trống[/COLOR]
    Case Else
      sDem = False [COLOR=#008000]' không phải dang a và b cách nhau n ô trống, ngưng đếm[/COLOR]
  End Select
Next i
End If
If r(2) > r(1) Then r(2) = r(1) [COLOR=#008000]' không có s1 hoặc s2 trong range[/COLOR]
MXMN_Khoang = r
End Function
 
Lần chỉnh sửa cuối:
Code bài này hình như dùng 1 vòng lặp vẫn giải quyết được hay sao í
cám ơn bạn, code mới chỉ dùng 1 vòng lập gọn hơn
Mã:
Function CachKhoang(Rng As Range, Str1 As String, Str2 As String, Optional MM As Boolean)
Dim Arr(), j As Integer, ja As Integer, dMax As Integer, dMin As Integer, tmp As Byte, kq(1 To 2)
Arr = Rng.Value
dMin = UBound(Arr, 2):  ja = 0
For j = 1 To UBound(Arr, 2)
    If Arr(1, j) = Str1 Then ja = j
    If Arr(1, j) = Str2 And ja > 0 Then
        If j - ja - 1 > dMax Then dMax = j - ja - 1
        If j - ja - 1 < dMin Then dMin = j - ja - 1
        ja = 0:  tmp = 1
    End If
Next j
If tmp = 0 Then
    kq(1) = "Không có DL": kq(2) = "Không có DL"
Else
    kq(1) = dMax:    kq(2) = dMin
End If
CachKhoang = kq
If MM = True Then CachKhoang = kq(2)
Erase Arr:  Erase kq
End Function
 
Mình dùng Ct cho bài này:
Tính Max, CT tại B5:
Mã:
B5=MAX(MAX(IFERROR((COLUMN(A:ES)/(E5:EW5="b")-LOOKUP(COLUMN(A:ES)/(E5:EW5="b"),COLUMN(A:ES)/(E5:EW5="a")))/(--TRANSPOSE(FREQUENCY(COLUMN(A:ES)*(E5:EW5="a"),COLUMN(A:ES)*(E5:EW5="b"))>0)),""))-1,0)
Tính Min, CT tại C5:
Mã:
=MAX(MIN(IFERROR((COLUMN(A:ES)/(E5:EW5="b")-LOOKUP(COLUMN(A:ES)/(E5:EW5="b"),COLUMN(A:ES)/(E5:EW5="a")))/(--TRANSPOSE(FREQUENCY(COLUMN(A:ES)*(E5:EW5="a"),COLUMN(A:ES)*(E5:EW5="b"))>0)),""))-1,0)
CTrl+Shift+Enter rồi fill xuông!!!

công thức hay mà sao không ai để ý ta !$@!!!$@!! . Bài này mà anh leo xài được công thức thì đáng gọi là sư phụ của doveandrose rồi chứ chả chơi !$@!!!$@!!
Chỉ tiếc là bài này không thích hợp dùng công thức nhỉ ? hi hi .
Tôi không rõ thớt này lập file dữ liệu có liên quan gì đến cờ bạc số đề gì không nên cũng ngại tham gia , theo dự đoán của tôi thì đề bài không chỉ dừng ở đây đâu , hình như điều kiện đề bài còn thiếu : liền trước ô có giá trị "a" và liền sau ô có giá trị "b" cũng phải là ô trắng , và sau này có thể giá trị "a" (hoặc "b") không phải 1 kí tự đơn nữa .
 
Tôi không rõ thớt này lập file dữ liệu có liên quan gì đến cờ bạc số đề gì không nên cũng ngại tham gia , theo dự đoán của tôi thì đề bài không chỉ dừng ở đây đâu , hình như điều kiện đề bài còn thiếu : liền trước ô có giá trị "a" và liền sau ô có giá trị "b" cũng phải là ô trắng , và sau này có thể giá trị "a" (hoặc "b") không phải 1 kí tự đơn nữa .

1. Nhìn điều kiện là biết mục đích khó mà minh bạch rồi. Tuy nhiên ở đây mình nói chuyện về giải thuật thôi ở 2 vấn đề ít khi gặp thôi:
(a) Hàm tự tạo trả về nhiều giá trị bằng 1 mảng
(b) Dùng flag để đánh dấu mẫu pattern

2. Nếu có thêm điều kiện thì có thể phải thêm code "dòm trước ngó sau". Đại khái bắt chước nguyên tắc duyệt chuỗi của RegExp vậy.
 
công thức hay mà sao không ai để ý ta !$@!!!$@!! . Bài này mà anh leo xài được công thức thì đáng gọi là sư phụ của doveandrose rồi chứ chả chơi !$@!!!$@!!
Chỉ tiếc là bài này không thích hợp dùng công thức nhỉ ? hi hi .
Tôi không rõ thớt này lập file dữ liệu có liên quan gì đến cờ bạc số đề gì không nên cũng ngại tham gia , theo dự đoán của tôi thì đề bài không chỉ dừng ở đây đâu , hình như điều kiện đề bài còn thiếu : liền trước ô có giá trị "a" và liền sau ô có giá trị "b" cũng phải là ô trắng , và sau này có thể giá trị "a" (hoặc "b") không phải 1 kí tự đơn nữa .
liền trước ô có giá trị "a" và liền sau ô có giá trị "b" cũng phải là ô trắng=>Tức là khoảng cách từ "aa"->"b" đúng không anh, nếu vậy thì giống đề bài của bạn chủ topic đưa ra, chỉ cần kết hợp 2 mảng rồi thay "a" thành "aa" la được!!!
Sau này có thể giá trị "a" (hoặc "b") không phải 1 kí tự đơn nữa,thực ra hôm qua khi làm bài này em làm 2 chiều luôn, tức là a->b và b->a, nhưng coi kĩ lại thì đề bài lại chỉ có 1 chiều,
CT 2 chiều và không phân biệt biệt kí tự đầu cuối, chỉ cần khác nhau là được:
tính Max tại B5:
Mã:
=MAX(MAX(IFERROR(IF(T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($1:$149))))<>T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($2:$150)))),SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($2:$150))-SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($1:$149))),""))-1,0)

Tính Min tại C5:
Mã:
=MAX(MIN(IFERROR(IF(T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($1:$149))))<>T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($2:$150)))),SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($2:$150))-SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW($1:$149))),""))-1,0)

Ctrl+Shift+Enter!!


 
Lần chỉnh sửa cuối:
liền trước ô có giá trị "a" và liền sau ô có giá trị "b" cũng phải là ô trắng=>Tức là khoảng cách từ "aa"->"b" đúng không anh, nếu vậy thì giống đề bài của bạn chủ topic đưa ra, chỉ cần kết hợp 2 mảng rồi thay "a" thành "aa" la được!!!
Sau này có thể giá trị "a" (hoặc "b") không phải 1 kí tự đơn nữa,thực ra hôm qua khi làm bài này em làm 2 chiều luôn, tức là a->b và b->a, nhưng coi kĩ lại thì đề bài lại chỉ có 1 chiều,
CT 2 chiều và không phân biệt biệt kí tự đầu cuối, chỉ cần khác nhau là được:
tính Max tại B5:
Mã:
=MAX(MAX(IFERROR(IF(T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(1:149))))<>T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(2:150)))),SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(2:150))-SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(1:149))),""))-1,0)

Tính Min tại C5:
Mã:
=MAX(MIN(IFERROR(IF(T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(1:149))))<>T(OFFSET(D5,,SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(2:150)))),SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(2:150))-SMALL(IF(E5:EW5<>"",COLUMN(A:ES)),ROW(1:149))),""))-1,0)

Ctrl+Shift+Enter!!

công thức tính hai chiều a->b và b->a phải không bạn?
Chép vào rồi kéo công thức xuống thôi phải không ?
Bạn xem lại công thức xem sao !
Mình mới thử thấy min ở C11 không đúng.(kết quả là 5 , trong khi a cách b có 2 ô)
cả ở B13 và C13 kết quả là 0 và 0 trong khi b đến a là 9 và từ a lại đến b là 3
Không biết mình có thực hiện sai gì không.



 
công thức tính hai chiều a->b và b->a phải không bạn?
Chép vào rồi kéo công thức xuống thôi phải không ?
Bạn xem lại công thức xem sao !
Mình mới thử thấy min ở C11 không đúng.(kết quả là 5 , trong khi a cách b có 2 ô)
cả ở B13 và C13 kết quả là 0 và 0 trong khi b đến a là 9 và từ a lại đến b là 3
Không biết mình có thực hiện sai gì không.



[/COLOR]
Ah, nó bị chạy CT chỗ Row(1:149) và row(2:150), em quên cố định lại!!!
p/s: em đã sữa lại rồi!!!
 
Web KT

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

Back
Top Bottom