Chú ý: Các thành viên học lớp "Lập trình VBA trong Excel" có thể trao đổi bài ở đây

Liên hệ QC
Em nộp bài MyMaxIf ạ!!!
Mã:
Function MyMaxIf(ByVal rngTest As Range, _
                 ByVal TestValue As Variant, _
                 ByVal rngValue As Range) As Double
    Dim i As Long
    Dim lCountRows As Long
        MyMaxIf = -2147483648#
        lCountRows = rngTest.Rows.Count
    For i = 1 To lCountRows
        If rngTest(i).Value = TestValue Then
            If MyMaxIf < rngValue(i).Value Then
                MyMaxIf = rngValue(i).Value
            End If
        End If
    Next i
End Function
 

File đính kèm

  • MyMaxIf.rar
    11.9 KB · Đọc: 11
Lần chỉnh sửa cuối:
Em nộp bài MyMaxIf ạ!!!
Mã:
Function MyMaxIf(ByVal rngTest As Range, _
                 ByVal TestValue As Variant, _
                 ByVal rngValue As Range) As Double
    Dim i As Long
    Dim lCountRows As Long
        MyMaxIf = -2147483648#
        lCountRows = rngTest.Rows.Count
    For i = 1 To lCountRows
        If rngTest(i).Value = TestValue Then
            If MyMaxIf < rngValue(i).Value Then
                MyMaxIf = rngValue(i).Value
            End If
        End If
    Next i
End Function
Thế hàm này chỉ làm việc được với vùng dữ liệu 1 cột nhiều dòng thôi hả bạn?
Trường hợp dữ liệu của tôi thế này thì sao?

untitled.JPG
 
Thế hàm này chỉ làm việc được với vùng dữ liệu 1 cột nhiều dòng thôi hả bạn?
Trường hợp dữ liệu của tôi thế này thì sao?

View attachment 54430

Thầy ơi, mới học VBA mấy bạn như vậy là cố gắng lắm rồi ạ! Hàm của Thầy em học trên diễn đàn này hơn 3 năm còn chưa hiểu huống chi mấy bạn mới! Thầy làm với Level thấp thôi để cho em và mọi thành viên mới cùng học chứ cao quá hỏng có hiểu!

Cám ơn Thầy!
 
Thầy ơi, mới học VBA mấy bạn như vậy là cố gắng lắm rồi ạ! Hàm của Thầy em học trên diễn đàn này hơn 3 năm còn chưa hiểu huống chi mấy bạn mới! Thầy làm với Level thấp thôi để cho em và mọi thành viên mới cùng học chứ cao quá hỏng có hiểu!

Cám ơn Thầy!
Chính vì mới học nên tôi mong muốn các bạn có hướng suy nghĩ thêm về những khả năng cải tiến của hàm mình viết ra (không phải cứ ra kết quả đúng là tưởng nó ngon rồi nha)
Không bắt các bạn phải 1 bước lên mây ngay, nhưng ít ra cũng đừng tự hài lòng về những gì ta đã làm được! Thế thôi mà...
Ẹc... Ẹc...
-----------------
Có đại ca MOD nào đi ngang qua đây vui lòng "bứng" ông #142 đi giùm cái
 
Lần chỉnh sửa cuối:
Như thế này có được không thầy
Mã:
Function MyMaxIf(ByVal rngTest As Range, _
                 ByVal TestValue As Variant, _
                 ByVal rngValue As Range) As Double
    Dim i As Long
    Dim lCountCells As Long
        MyMaxIf = -2147483648#
        lCountCells = rngTest.Cells.Count
    For i = 1 To lCountCells
        If rngTest(i).Value = TestValue Then
            If MyMaxIf < rngValue(i).Value Then
                MyMaxIf = rngValue(i).Value
            End If
        End If
Next i
End Function
 
Lần chỉnh sửa cuối:
Như thế này có được không thầy
Mã:
Function MyMaxIf(ByVal rngTest As Range, _
                 ByVal TestValue As Variant, _
                 ByVal rngValue As Range) As Double
    Dim i As Long
    Dim lCountCells As Long
        MyMaxIf = -2147483648#
        lCountCells = rngTest.Cells.Count
    For i = 1 To lCountCells
        If rngTest(i).Value = TestValue Then
            If MyMaxIf < rngValue(i).Value Then
                MyMaxIf = rngValue(i).Value
            End If
        End If
Next i
End Function
Rất tốt!
Hàm đã chạy được trên vùng dữ liệu 1 cột nhiều dòng và cả vùng 1 dòng nhiều cột!
Thử nghĩ xem hàm của bạn có thể hoạt động trên vùng nhiều dòng nhiều cột hay không?
Cấu trúc dữ liệu kiểu thế này đây:

untitled.JPG

Ẹc... Ẹc... Cố lên!
 
Lần chỉnh sửa cuối:
Em thử rồi và thấy chạy ngon thầy ạ:D
 

File đính kèm

  • MymaxIf_nhieudongcot.rar
    12.1 KB · Đọc: 8
Lần chỉnh sửa cuối:
Em thử rồi và thấy chạy ngon thầy ạ:D
Ẹc... Ẹc... Đây là món tuyệt chiêu của thuộc tính Range so với Array
Ví dụ:
PHP:
Sub Test()
  Dim Rng As Range
  Set Rng = Range("A1:B10")
  MsgBox Rng(12)
End Sub
Rng(12) sẽ là = giá trị của cell B6, tức nằm tại dòng 6 cột 2 của vùng Rng
Và đây cũng là cái dở của Range so với Array ---> Vì nhìn vào số 12, ta chẳng tài nào đoán được đấy là vị trí nào
Mai này, khi bạn giỏi về VBA 1 chút, bạn sẽ thấy rằng để tăng tốc độ tính toán cho code VBA, không gì bằng đưa mọi thứ về mảng, và việc truy xuất mảng tuy là gần giống với truy xuất Range nhưng cũng sẽ có chổ khác biệt ----> Ví dụ với code trên nếu biến Rng là Array thì câu lệnh MsgBox Rng(12) báo lỗi ngay lập tức
 
Sơ suất quá, em sửa lại ạ

Mình sửa lại chút code của Hưng cho hàm MinIf:
PHP:
Public Function MyMinIf(ByVal rngTest As Range, _
                 ByVal TestValue As Variant, _
                 ByVal rngValue As Range) As Double
    Dim i As Long
    Dim lCountCells As Long
        MyMinIf = 2147483648#
        lCountCells = rngTest.Cells.Count
    For i = 1 To lCountCells
        If rngTest(i).Value = TestValue Then
            If MyMinIf > rngValue(i).Value Then
                MyMinIf = rngValue(i).Value
            End If
        End If
    Next
End Function
 
Mình sửa lại chút code của Hưng cho hàm MinIf:
PHP:
Public Function MyMinIf(ByVal rngTest As Range, _
                 ByVal TestValue As Variant, _
                 ByVal rngValue As Range) As Double
    Dim i As Long
    Dim lCountCells As Long
        MyMinIf = 2147483648#
        lCountCells = rngTest.Cells.Count
    For i = 1 To lCountCells
        If rngTest(i).Value = TestValue Then
            If MyMinIf > rngValue(i).Value Then
                MyMinIf = rngValue(i).Value
            End If
        End If
    Next
End Function
Các bạn lưu ý rằng, trong Excel, số lớn nhất và nhỏ nhất mà nó có thể hiểu được không phải là 2147483648-2147483648 đâu nha, nó chính là số 9.99999999999999E+307-9.99999999999999E+307
Hãy thử hàm của bạn với dữ liệu thế này sẽ thấy kết quả trật lất:

untitled.JPG

Hãy xem bài #140 ---> Nó cho kết quả đúng trong trường hợp này đấy
 
Lần chỉnh sửa cuối:
Các bạn lưu ý rằng, trong Excel, số lớn nhất và nhỏ nhất mà nó có thể hiểu được không phải là 2147483648-2147483648 đâu nha, nó chính là số 9.99999999999999E+307-9.99999999999999E+307
Hãy thử hàm của bạn với dữ liệu thế này sẽ thấy kết quả trật lất:

View attachment 54492

Hãy xem bài #140 ---> Nó cho kết quả đúng trong trường hợp này đấy
NDU làm giúp 1 UDF = array. Mình đang phân vân rngTest là nhiều dòng nhiều cột thì nên dùng mảng 1 hay 2 chiều nào cho tối ưu. Cám ơn.
 
NDU làm giúp 1 UDF = array. Mình đang phân vân rngTest là nhiều dòng nhiều cột thì nên dùng mảng 1 hay 2 chiều nào cho tối ưu. Cám ơn.
Bài #140 là Array rồi đấy ThuNghi ơi ---> Tôi đang dùng mảng 2 chiều
Còn 1 chuyện nữa có thể suy nghĩ nữa (trong tương lai), đó là cải tiến đề hàm làm việc được với 1 vùng dữ liệu tùy ý, tức có thể nhiều dòng nhiều cột, thậm chí là vùng không liên tục
 
If ResRng(i, 1) > TmpMax Then TmpMax = ResRng(i, j).Value
Em không hiểu dòng này lắm, tại sao lại là ResRng(i,1) hả bác. Theo em phải là
If ResRng(i, j).Value> TmpMax Then TmpMax = ResRng(i, j).Value
 
If ResRng(i, 1) > TmpMax Then TmpMax = ResRng(i, j).Value
Em không hiểu dòng này lắm, tại sao lại là ResRng(i,1) hả bác. Theo em phải là
If ResRng(i, j).Value> TmpMax Then TmpMax = ResRng(i, j).Value
Code của anh NDU bị nhầm đấy Bạn. Đúng ra phải như vầy:
Mã:
[COLOR=#000000][COLOR=#007700]If [/COLOR][/COLOR][COLOR=#000000][COLOR=#0000bb]ResRng[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]j[/COLOR][COLOR=#007700]).[/COLOR][COLOR=#0000bb]Value[/COLOR][/COLOR][COLOR=#000000][COLOR=#007700]> [/COLOR][COLOR=#0000bb]TmpMax Then TmpMax [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]ResRng[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]i[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]j[/COLOR][COLOR=#007700]).[/COLOR][COLOR=#0000bb]Value
[/COLOR][/COLOR]
 
Hoá ra em phát hiện đúng khà khà
 
Em muốn hỏi nếu làm hàm MySumIf hay MyCountIf mà điều kiện không phải là một giá trị mà là một khoảng, như tìm tổng của tất cả những số trong vùng có giá trị lớn hơn (hay nhỏ hơn) một số cụ thể thì làm thế nào?
Ví dụ như hàm sẵn có trong excel thì ta có thể viết =SumIf(A1:B5,">10")
 
Em muốn hỏi nếu làm hàm MySumIf hay MyCountIf mà điều kiện không phải là một giá trị mà là một khoảng, như tìm tổng của tất cả những số trong vùng có giá trị lớn hơn (hay nhỏ hơn) một số cụ thể thì làm thế nào?
Ví dụ như hàm sẵn có trong excel thì ta có thể viết =SumIf(A1:B5,">10")

Nếu bạn chưa trãi qua cấu trúc For Each. . . . Next, thì ta lập ra 2 vòng lặp cho 2 cột dữ liệu đó

Sau đó, trong quá trình duyệt 2 vòng lặp, cái nào ưng í thì ta cộng thêm vô MySumIf của bạn

Hứa hẹn 1 thành công mĩ mãn với buổi sáng tốt lành!
 
Nếu bạn chưa trãi qua cấu trúc For Each. . . . Next, thì ta lập ra 2 vòng lặp cho 2 cột dữ liệu đó

Sau đó, trong quá trình duyệt 2 vòng lặp, cái nào ưng í thì ta cộng thêm vô MySumIf của bạn

Hứa hẹn 1 thành công mĩ mãn với buổi sáng tốt lành!

Trong trường hợp tổng quát thì tham số thứ 2 sẽ được người dùng gõ vào, thí dụ ">10", ">=20", "<>100", "<10^5", ...
Không đơn giản dối với trình độ của lớp hiện giờ đâu, kể cả tầm trung bình. (Select Case, InStr tách chuỗi, Replace và Val chẳng hạn)
 
Lần chỉnh sửa cuối:
Web KT
Back
Top Bottom