Sub [parameter-list]

Liên hệ QC

Phương Phương mito

Thành viên thường trực
Tham gia
1/5/19
Bài viết
275
Được thích
65
Kính gửi anh chị,
Trên diễn đàn em tìm kiếm thì khá ít bài viết sub kèm [parameter-list] mà chủ yếu là sub đơn thuần. Em nhận thấy Sub [parameter-list] khá hay như kiểu Function. Có anh chị nào chia sẻ cho em thêm các ví dụ về cách viết sub kiểu này cho em học hỏi và tham khảo với ạ ! em cảm ơn ạ !
 
cái này thì mình không rõ, nhưn theo ý kiến của mình VBA môi trường project của nó còn nhiều hạn chế không tốt như những ngôn ngôn ngữ khác, nên việc viết sub kèm [parameter -list] hạn chế và thường mọi người dùng sub đơn thuần luôn
 
Upvote 0
Kính gửi anh chị,
Trên diễn đàn em tìm kiếm thì khá ít bài viết sub kèm [parameter-list] mà chủ yếu là sub đơn thuần. Em nhận thấy Sub [parameter-list] khá hay như kiểu Function. Có anh chị nào chia sẻ cho em thêm các ví dụ về cách viết sub kiểu này cho em học hỏi và tham khảo với ạ ! em cảm ơn ạ !
Bạn đưa dẫn dụ mấy cái Subs "khá hay" trên. Tôi sẽ chỉ cho bạn biết cách viết. Trước mắt, tôi chỉ thắc mắc là bạn không biết cách viết thì làm sao biết nó "khá hay"?
Cụm từ "như kiểu Function" cũng tối nghĩa. Function chủ yếu chỉ là một Sub có trả về một trị. Và vì function có trả về trị cho nên nó chúng dùng hơi khác.

cái này thì mình không rõ, nhưn theo ý kiến của mình VBA môi trường project của nó còn nhiều hạn chế không tốt như những ngôn ngôn ngữ khác, nên việc viết sub kèm [parameter -list] hạn chế và thường mọi người dùng sub đơn thuần luôn
Dóc tổ. Nói sai bét hết.

Dùng Sub có danh sách tham số (param list) thì mỗi lần gọi nó phải tọng tham số vào. Vì vậy, các Subs có tham số sẽ không được Excel đưa vào danh sách Macros.
 
Upvote 0
cái này thì mình không rõ, nhưn theo ý kiến của mình VBA môi trường project của nó còn nhiều hạn chế không tốt như những ngôn ngôn ngữ khác, nên việc viết sub kèm [parameter -list] hạn chế và thường mọi người dùng sub đơn thuần luôn
Tôi quan niệm khác. Nếu sử dụng nhiều 1 tính năng ở nhiều chỗ khác nhau thì viết 1 sub có tham số thay vì viết nhiều sub. Và tôi không thấy hạn chế gì.
Ví dụ:
Sub Filter(Rng as Range, Col as long, Crit as Variant)

Dùng để lọc 1 vùng dữ liệu bất kỳ theo điều kiện bất kỳ ở 1 cột bất kỳ trong vùng dữ liệu
(Ví dụ đơn giản nhất)
 
Upvote 0
t hiểu ý của bạn, nhưng với project của VBA thì việc các sub nó không cần maker với nhau nên thực tế người dùng họ cũng không cần thiết làm như vậy.
còn đúng tư duy lập trình thì nên viết và khai báo như vậy.
hoặc nếu bạn có thể thử tham khảo class trong VBA xem, khi đi sâu vào hướng đối tượng có thể chương trình sẽ được viết theo đúng chuẩn code.
Bài đã được tự động gộp:

Bạn đưa dẫn dụ mấy cái Subs "khá hay" trên. Tôi sẽ chỉ cho bạn biết cách viết. Trước mắt, tôi chỉ thắc mắc là bạn không biết cách viết thì làm sao biết nó "khá hay"?
Cụm từ "như kiểu Function" cũng tối nghĩa. Function chủ yếu chỉ là một Sub có trả về một trị. Và vì function có trả về trị cho nên nó chúng dùng hơi khác.


Dóc tổ. Nói sai bét hết.

Dùng Sub có danh sách tham số (param list) thì mỗi lần gọi nó phải tọng tham số vào. Vì vậy, các Subs có tham số sẽ không được Excel đưa vào danh sách Macros.
thì t nói là không rõ rồi còn gì. còn với 1 project chuyên nghiệp thì sẽ có 2 phần.
1- Define.
2- Code.
và tất cả các hàm đều được Define để tiện cho việc phát triển chương trình trong tương lại. VBA thì chắc là không rồi.
 
Upvote 0
thực tế người dùng họ cũng không cần thiết làm như vậy.
...
khi đi sâu vào hướng đối tượng có thể chương trình sẽ được viết theo đúng chuẩn code.
Người dùng thì cần gì biết code viết thế nào, trong khi người lập trình cần "tối ưu" công việc của mình, viết có bài bản mà không phải viết lặp đi lặp lại các thủ tục giống nhau
Có những người như tôi, chưa đi sâu đến hướng đối tượng, nhưng không thể nói họ viết code không đúng chuẩn.
 
Upvote 0
với project của VBA thì việc các sub nó không cần maker với nhau nên thực tế người dùng họ cũng không cần thiết làm như vậy
...
VBA thì chắc là không rồi.

Gớm vậy. Cái gì mà ma cơ với ma cô là gì thế.

Ở đâu ra cái lý luận hay vậy chời? Mình đưa bằng chứng "thực tế" lên đây xem nào?
 
Upvote 0
Người dùng thì cần gì biết code viết thế nào, trong khi người lập trình cần "tối ưu" công việc của mình, viết có bài bản mà không phải viết lặp đi lặp lại các thủ tục giống nhau
Có những người như tôi, chưa đi sâu đến hướng đối tượng, nhưng không thể nói họ viết code không đúng chuẩn.
Tôi đã có nói đương sự nói dóc. Hướng đối tượng đặt nặng với thiết kế nhiều hơn code. Lại càng chả liên quan gì đến "chuẩn code".

thì t nói là không rõ rồi còn gì. còn với 1 project chuyên nghiệp thì sẽ có 2 phần.
1- Define.
2- Code.
và tất cả các hàm đều được Define để tiện cho việc phát triển chương trình trong tương lại. VBA thì chắc là không rồi.
Define trong ngữ cảnh nào?

Define của C/C++?
Nhiều ngôn ngữ đời xưa cần biết trước các dạng của hàm, cấu trúc, và biến để compiler có thể "crunch" code.
Nhưng những ngôn ngữ dùng interpreter như Basic đâu có cần.

Define theo ngữ cảnh của Phát Triển Đồ Án Phần Mềm (Software Project Development)?
Nếu bạn làm đến cấp bậc Quản Lý Kế Hoạch (Project Planner) và/hoặc Quản lý Đồ Án (Project Manager) thì cũng biết có hai giai đoạn "define" khác nhau.
Ở giai đoạn đầu (meta structure) người ta chỉ xác định phạm vi công việc cần làm.
Ở giai đoạn sau (cách giai đoạn trên 1 vài giai đoạn) mới là giai đoạn thiết kế. Trogn giai đoạn này người ta phân định rõ từng KFA (Key Functional Areas), tách chúng ra từng phần. Rồi lại tách từng KFA ra thành từng công việc. Sau khi những côngn việc trên được xác định rõ rệt và lên hồ sơ (documented) thì nchungs sẽ được lập trình viên code.

Bạn không đem ba cái project ra hù được tôi đâu. Tô đã làm Project manager nhiều năm trước khi đổi sang việc nhàn hạ hơn vì lý do sức khoẻ.

Gớm vậy. Cái gì mà ma cơ với ma cô là gì thế.

Ở đâu ra cái lý luận hay vậy chời? Mình đưa bằng chứng "thực tế" lên đây xem nào?
Các phần mềm ngày xưa dùng linker để nối các sub/function với nhau sau khi compiler đã dịch code. Nếu linker có nhiều tính năng hơn thì gọi là Builder. Điển hình là nó có thể "build" thành dll hay exe.
Maker chỉ là một loại Builder.
 
Upvote 0
Tôi đã có nói đương sự nói dóc. Hướng đối tượng đặt nặng với thiết kế nhiều hơn code. Lại càng chả liên quan gì đến "chuẩn code".


Define trong ngữ cảnh nào?

Define của C/C++?
Nhiều ngôn ngữ đời xưa cần biết trước các dạng của hàm, cấu trúc, và biến để compiler có thể "crunch" code.
Nhưng những ngôn ngữ dùng interpreter như Basic đâu có cần.

Define theo ngữ cảnh của Phát Triển Đồ Án Phần Mềm (Software Project Development)?
Nếu bạn làm đến cấp bậc Quản Lý Kế Hoạch (Project Planner) và/hoặc Quản lý Đồ Án (Project Manager) thì cũng biết có hai giai đoạn "define" khác nhau.
Ở giai đoạn đầu (meta structure) người ta chỉ xác định phạm vi công việc cần làm.
Ở giai đoạn sau (cách giai đoạn trên 1 vài giai đoạn) mới là giai đoạn thiết kế. Trogn giai đoạn này người ta phân định rõ từng KFA (Key Functional Areas), tách chúng ra từng phần. Rồi lại tách từng KFA ra thành từng công việc. Sau khi những côngn việc trên được xác định rõ rệt và lên hồ sơ (documented) thì nchungs sẽ được lập trình viên code.

Bạn không đem ba cái project ra hù được tôi đâu. Tô đã làm Project manager nhiều năm trước khi đổi sang việc nhàn hạ hơn vì lý do sức khoẻ.


Các phần mềm ngày xưa dùng linker để nối các sub/function với nhau sau khi compiler đã dịch code. Nếu linker có nhiều tính năng hơn thì gọi là Builder. Điển hình là nó có thể "build" thành dll hay exe.
Maker chỉ là một loại Builder.
Em đã tìm nhiều trên các trang web nước ngoài và ở diễn đàn mình không có nhiều ví dụ. Em thấy nó khá hay nếu áp dụng một công việc gì đó lặp lại nhiều lần, mình khỏi phải tạo nhiều sub - tạo nhiều sub cho nhiều công việc tương đồng nó không hay ạ.
 
Upvote 0
Em đã tìm nhiều trên các trang web nước ngoài và ở diễn đàn mình không có nhiều ví dụ. Em thấy nó khá hay nếu áp dụng một công việc gì đó lặp lại nhiều lần, mình khỏi phải tạo nhiều sub - tạo nhiều sub cho nhiều công việc tương đồng nó không hay ạ.
Bạn thử viết code cho việc filter 1 vùng dữ liệu, 1 điều kiện cụ thể, trong 1 cột cụ thể, rồi thử sửa bằng cách truyền 3 tham số như bài #4, ứng dụng cho nhiều bảng dữ liệu ở nhiều sheet khác nhau. Code trên GPE có viết nhưng nằm trong các bài viết trả lời chứ không có chuyên đề.
 
Upvote 0
Em đã tìm nhiều trên các trang web nước ngoài và ở diễn đàn mình không có nhiều ví dụ. Em thấy nó khá hay nếu áp dụng một công việc gì đó lặp lại nhiều lần, mình khỏi phải tạo nhiều sub - tạo nhiều sub cho nhiều công việc tương đồng nó không hay ạ.
Tôi viết 1 ứng dụng trong đó thường xuyên phải điều chỉnh 1 cái nút lệnh in cho phù hợp với biểu mẫu muốn in nên tôi phải viết 1 thủ tục con như sau để có thể gọi và truyền tham số từ 1 thủ tục mẹ:
Rich (BB code):
Sub NutIn(Cao As Double, txt As String, Optional Rong As Double = 83)
    ActiveSheet.Shapes(1).Select
    Selection.ShapeRange.Height = Cao
    Selection.ShapeRange.Width = Rong
    Selection.ShapeRange.TextFrame2.TextRange.Characters.Text = txt
End Sub
 
Upvote 0
Tôi viết 1 ứng dụng trong đó thường xuyên phải điều chỉnh 1 cái nút lệnh in cho phù hợp với biểu mẫu muốn in nên tôi phải viết 1 thủ tục con như sau để có thể gọi và truyền tham số từ 1 thủ tục mẹ:
Rich (BB code):
Sub NutIn(Cao As Double, txt As String, Optional Rong As Double = 83)
    ActiveSheet.Shapes(1).Select
    Selection.ShapeRange.Height = Cao
    Selection.ShapeRange.Width = Rong
    Selection.ShapeRange.TextFrame2.TextRange.Characters.Text = txt
End Sub
Em cảm ơn anh ạ ! ANh chị nào còn nhiều ví dụ, gửi lên cho em và mọi người tham khảo và học tập với ạ. kèm theo File nữa thì càng tốt ạ !
 
Upvote 0
...Code trên GPE có viết nhưng nằm trong các bài viết trả lời chứ không có chuyên đề.
Code của hầu hết bài trên GPE là loại code chữa cháy. Loại code này chỉ viết cho trưởng hợp đặc thù, tức là vấn đề của người hỏi. Những người viết code giúp pử GPE thì cứ chiếu theo chính sách "tuốt tuồn tuột", phăng theo yêu cầu và lô gic mà viết code. Người viết không ngại viết, và người hỏi thoả mãn vì được code đặc thù cho mình (theo tâm lý thì cái "đặc thù" nó làm cho người ta giảm đi mặc cảm "cả bầy vịt con nào cũng như con nấy")
Trên thực tế, hầu hết các mô đen xảy ra giống như chiếc xe tải chở hàng từ A đến B, gồm các công việc lên hàng theo vận đơn lấy hàng, chọn tuyến đường và lái xe theo tuyến đường, đến nơi thì giao hàng theo vận đơn giao hàng. Những yếu tố như trả tiền qua BOT, đổ xăng, ngừng ăn trưa,... là những chuyện phụ, tìm thấy rải rác trong code.
Theo tình trạng lý tưởng thì đáng lẽ những việc phụ như tiền BOT có thể trả khoán (theo biển số xe, cuối kỳ công ty thanh toán một lần, hay qua một cái app trong xe) thì xe không phải ngừng ở trạm, đổ xăng có thể hợp đồng với một vài trạm xăng sẽ được giá tốt hơn.
Đó là một trong những lý do nên viết hàm con. Viết hàm con quen rồi thì sẽ biết cách dùng tham số.

Tham số cho hàm có nhiều dạng, và nhiều lý do. Thớt chỉ nói là thấy nó "hay" thôi chứ đâu có đưa ra ví dụ nào cho nên tôi đâu có giải thích được. Theo tôi thì code kiểu này nọ là do tiện lợi chứ tôi đâu có nề hà cái chuyện "hay dở". Lúc tôi chỉ bà con cách code thì tôi luôn nói "thường thì người ta làm vầy..."

... ANh chị nào còn nhiều ví dụ, gửi lên cho em và mọi người tham khảo và học tập với ạ. kèm theo File nữa thì càng tốt ạ !
Hầu hết các hàm bắt dữ kiện đều có tham số.
Hầu hết các phương thức của các đối tượng trong các referenced library đều có tham số.

Nếu tôi viết code dài khoảng 40 dòng trở lên thì thường do nó làm nhiều hơn một công việc. Nếu tôi thấy những công việc ấy tương đối độc lập nhau thì tôi sẽ tách chúng thành nhiều hàm con. Hàm con kiểu này gần như luôn luôn có param list.
Tìm những bài cũ tôi viết cách đây vài năm sẽ thấy chúng.

Gợi ý: hàm giải phương trình bậc hai là một trong những hàm kinh điển thử thách cách sử dụng param list.
Gợi ý 2: bỏ qua các bài dùng paramarray. Chúng thuộc về phần sau này. Tham học chạy trước khi học đi thì sẽ bị ngã vỡ đầu.
 
Upvote 0
Kính gửi anh chị,
Trên diễn đàn em tìm kiếm thì khá ít bài viết sub kèm [parameter-list] mà chủ yếu là sub đơn thuần. Em nhận thấy Sub [parameter-list] khá hay như kiểu Function. Có anh chị nào chia sẻ cho em thêm các ví dụ về cách viết sub kiểu này cho em học hỏi và tham khảo với ạ ! em cảm ơn ạ !
Cách viết cũng giống Function
từ Function LocMang(ByVal rng As Range, ParamArray crit()) As Variant theo link
chỉnh tí thành
Sub Fileter_CriteriaS(ByRef Res, ByVal rng As Range, ParamArray crit())
Mã:
Sub Main()
  Dim Res
  Call Fileter_CriteriaS(Res, [F5:F19], [B5:B19], [M5], [C5:C19], [N5])
  If IsArray(Res) Then [O18].Resize(UBound(Res), UBound(Res, 2)) = Res
End Sub

Sub Fileter_CriteriaS(ByRef Res, ByVal rng As Range, ParamArray crit())
  Dim aRow(), sRow&, sCol&, i&, k&, j&, c&
  sRow = crit(0).Rows.Count: sCol = rng.Columns.Count
  If sRow <> rng.Rows.Count Then Exit Sub
  ReDim aRow(1 To sRow)
  For j = LBound(crit) To UBound(crit) Step 2
    If sRow <> crit(j).Rows.Count Then Exit Sub
  Next j
  For i = 1 To sRow
    For j = LBound(crit) To UBound(crit) Step 2
      If crit(j)(i, 1) <> crit(j + 1) Then Exit For
    Next j
    If j = UBound(crit) + 1 Then
      k = k + 1
      aRow(k) = i
    End If
  Next i
  If k Then
    ReDim Res(1 To k, 1 To rng.Columns.Count)
    For i = 1 To k
      For j = 1 To sCol
        Res(i, j) = rng(aRow(i), j)
      Next j
    Next i
  End If
End Sub

Function LocMang(ByVal rng As Range, ParamArray crit()) As Variant
  Dim aRow(), Res(), sRow&, sCol&, i&, k&, j&, c&
  sRow = crit(0).Rows.Count: sCol = rng.Columns.Count
  If sRow <> rng.Rows.Count Then LocMang = "#REF!": Exit Function
  ReDim aRow(1 To sRow)
  For j = LBound(crit) To UBound(crit) Step 2
    If sRow <> crit(j).Rows.Count Then LocMang = "#REF!": Exit Function
  Next j
  For i = 1 To sRow
    For j = LBound(crit) To UBound(crit) Step 2
      If crit(j)(i, 1) <> crit(j + 1) Then Exit For
    Next j
    If j = UBound(crit) + 1 Then
      k = k + 1
      aRow(k) = i
    End If
  Next i
  If k Then
    ReDim Res(1 To k, 1 To rng.Columns.Count)
    For i = 1 To k
      For j = 1 To sCol
        Res(i, j) = rng(aRow(i), j)
      Next j
    Next i
    LocMang = Res
  End If
End Function
 

File đính kèm

  • Sổ làm việc1.xlsm
    22.8 KB · Đọc: 8
Upvote 0
Mình cũng lanh cha lanh chanh xin góp 1 file:
PHP:
Sub TinhNgayFepTheoDieuKien()
 Dim Rws As Long, J As Long, W As Integer, MaNV As Double, Tong As Double
 Dim Arr(), Rng As Range, sRng As Range
 Dim LoaiNghi As String, wNo As String
 ReDim aKQ(1 To 99, 5 To 15)
 
 With Sheets("ERP")
    Rws = .[B4].CurrentRegion.Rows.Count
    Arr() = .[A4].Resize(Rws, 25).Value
    For J = 1 To UBound(Arr())
        If Arr(J, 1) <> MaNV Then
            If J > 1 Then
                W = W + 1:                  aKQ(W, 5) = MaNV
                aKQ(W, 15) = Tong:          Tong = 0
                aKQ(W, 6) = Arr(J, 2)       '?'
            Else
            End If
            MaNV = Arr(J, 1)
        End If
        LoaiNghi = Arr(J, 24)
        wNo = Arr(J, 3)
        If LoaiNghi = "RP" Or LoaiNghi = "PB" Then
            If W_No(wNo) And Arr(J, 13) < 7 Then     '**  **  ** '
                Tong = Tong + 8 - Arr(J, 13)
            ElseIf Not W_No(wNo) And Arr(J, 13) < 8 Then
                Tong = Tong + 8 - Arr(J, 13)
            End If
        End If
    Next J
 End With
 If W Then
    Sheets("W1").[E7].Resize(W, 11).Value = aKQ()
 End If
End Sub
Mã:
Function W_No(wNo As String) As Boolean
 Dim Rng As Range, sRng As Range
 
 Set Rng = Sheets("Data").Range("BTr")
 Set sRng = Rng.Find(wNo, , xlFormulas, xlWhole)
 W_No = Not sRng Is Nothing
End Function
PHP:
Sub TinhNghiTheoDanhSachDaCo()
 Dim Rws As Long, lRw As Integer, Dg As Integer, MaNV As Double, J As Long, W As Integer
 Dim Arr(), Tong As Double, MyColor As Byte
 Dim LoaiNghi As String, wNo As String
 
 Sheets("W1").Select
 lRw = [e65500].End(xlUp).Row
 If lRw < 7 Then
    MsgBox "Nothing!", , "GPE.COM"
 Else:                                      Randomize:
 End If
 ReDim aKQ(1 To lRw, 1 To 1) As Double
 
 With Sheets("ERP")
    Rws = .[B4].CurrentRegion.Rows.Count
    Arr() = .[A4].Resize(Rws, 25).Value     '25  '
 End With
 For Dg = 7 To lRw
    MaNV = Cells(Dg, "E").Value
    W = W + 1
    For J = 1 To UBound(Arr())
        If Arr(J, 1) = MaNV Then
            LoaiNghi = Arr(J, 24)
            wNo = Arr(J, 3)
            If LoaiNghi = "RP" Or LoaiNghi = "PB" Then
                If W_No(wNo) And Arr(J, 13) < 7 Then     '**  **  ** '
                    Tong = Tong + 8 - Arr(J, 13)
                ElseIf Not W_No(wNo) And Arr(J, 13) < 8 Then
                    Tong = Tong + 8 - Arr(J, 13)
                End If
            End If
        End If
    Next J
    aKQ(W, 1) = Tong:                   Tong = 0
 Next Dg
 MyColor = 34 + 9 * Rnd() \ 1
 If W Then
    [O7].Resize(W).Value = aKQ():       [E5:F5].Interior.ColorIndex = MyColor
 End If
 MsgBox "Xong Rôi!", , "GPE.COM Xin Chào!"
End Sub
 

File đính kèm

  • Array.rar
    107.2 KB · Đọc: 6
Lần chỉnh sửa cuối:
Upvote 0
Cách viết cũng giống Function
từ Function LocMang(ByVal rng As Range, ParamArray crit()) As Variant theo link
chỉnh tí thành
Sub Fileter_CriteriaS(ByRef Res, ByVal rng As Range, ParamArray crit())
Mã:
Sub Main()
  Dim Res
  Call Fileter_CriteriaS(Res, [F5:F19], [B5:B19], [M5], [C5:C19], [N5])
  If IsArray(Res) Then [O18].Resize(UBound(Res), UBound(Res, 2)) = Res
End Sub

Sub Fileter_CriteriaS(ByRef Res, ByVal rng As Range, ParamArray crit())
  Dim aRow(), sRow&, sCol&, i&, k&, j&, c&
  sRow = crit(0).Rows.Count: sCol = rng.Columns.Count
  If sRow <> rng.Rows.Count Then Exit Sub
  ReDim aRow(1 To sRow)
  For j = LBound(crit) To UBound(crit) Step 2
    If sRow <> crit(j).Rows.Count Then Exit Sub
  Next j
  For i = 1 To sRow
    For j = LBound(crit) To UBound(crit) Step 2
      If crit(j)(i, 1) <> crit(j + 1) Then Exit For
    Next j
    If j = UBound(crit) + 1 Then
      k = k + 1
      aRow(k) = i
    End If
  Next i
  If k Then
    ReDim Res(1 To k, 1 To rng.Columns.Count)
    For i = 1 To k
      For j = 1 To sCol
        Res(i, j) = rng(aRow(i), j)
      Next j
    Next i
  End If
End Sub

Function LocMang(ByVal rng As Range, ParamArray crit()) As Variant
  Dim aRow(), Res(), sRow&, sCol&, i&, k&, j&, c&
  sRow = crit(0).Rows.Count: sCol = rng.Columns.Count
  If sRow <> rng.Rows.Count Then LocMang = "#REF!": Exit Function
  ReDim aRow(1 To sRow)
  For j = LBound(crit) To UBound(crit) Step 2
    If sRow <> crit(j).Rows.Count Then LocMang = "#REF!": Exit Function
  Next j
  For i = 1 To sRow
    For j = LBound(crit) To UBound(crit) Step 2
      If crit(j)(i, 1) <> crit(j + 1) Then Exit For
    Next j
    If j = UBound(crit) + 1 Then
      k = k + 1
      aRow(k) = i
    End If
  Next i
  If k Then
    ReDim Res(1 To k, 1 To rng.Columns.Count)
    For i = 1 To k
      For j = 1 To sCol
        Res(i, j) = rng(aRow(i), j)
      Next j
    Next i
    LocMang = Res
  End If
End Function
Em cảm ơn các anh, toàn người top của diễn đàn. Em sẽ học hỏi thêm ạ !
Bài đã được tự động gộp:

Cách viết cũng giống Function
từ Function LocMang(ByVal rng As Range, ParamArray crit()) As Variant theo link
chỉnh tí thành
Sub Fileter_CriteriaS(ByRef Res, ByVal rng As Range, ParamArray crit())
Mã:
Sub Main()
  Dim Res
  Call Fileter_CriteriaS(Res, [F5:F19], [B5:B19], [M5], [C5:C19], [N5])
  If IsArray(Res) Then [O18].Resize(UBound(Res), UBound(Res, 2)) = Res
End Sub

Sub Fileter_CriteriaS(ByRef Res, ByVal rng As Range, ParamArray crit())
  Dim aRow(), sRow&, sCol&, i&, k&, j&, c&
  sRow = crit(0).Rows.Count: sCol = rng.Columns.Count
  If sRow <> rng.Rows.Count Then Exit Sub
  ReDim aRow(1 To sRow)
  For j = LBound(crit) To UBound(crit) Step 2
    If sRow <> crit(j).Rows.Count Then Exit Sub
  Next j
  For i = 1 To sRow
    For j = LBound(crit) To UBound(crit) Step 2
      If crit(j)(i, 1) <> crit(j + 1) Then Exit For
    Next j
    If j = UBound(crit) + 1 Then
      k = k + 1
      aRow(k) = i
    End If
  Next i
  If k Then
    ReDim Res(1 To k, 1 To rng.Columns.Count)
    For i = 1 To k
      For j = 1 To sCol
        Res(i, j) = rng(aRow(i), j)
      Next j
    Next i
  End If
End Sub

Function LocMang(ByVal rng As Range, ParamArray crit()) As Variant
  Dim aRow(), Res(), sRow&, sCol&, i&, k&, j&, c&
  sRow = crit(0).Rows.Count: sCol = rng.Columns.Count
  If sRow <> rng.Rows.Count Then LocMang = "#REF!": Exit Function
  ReDim aRow(1 To sRow)
  For j = LBound(crit) To UBound(crit) Step 2
    If sRow <> crit(j).Rows.Count Then LocMang = "#REF!": Exit Function
  Next j
  For i = 1 To sRow
    For j = LBound(crit) To UBound(crit) Step 2
      If crit(j)(i, 1) <> crit(j + 1) Then Exit For
    Next j
    If j = UBound(crit) + 1 Then
      k = k + 1
      aRow(k) = i
    End If
  Next i
  If k Then
    ReDim Res(1 To k, 1 To rng.Columns.Count)
    For i = 1 To k
      For j = 1 To sCol
        Res(i, j) = rng(aRow(i), j)
      Next j
    Next i
    LocMang = Res
  End If
End Function
Em cảm ơn các anh, toàn người top của diễn đàn. Em sẽ học hỏi thêm ạ !
Bài đã được tự động gộp:

Mình cũng lanh cha lanh chanh xin góp 1 file:
PHP:
Sub TinhNgayFepTheoDieuKien()
 Dim Rws As Long, J As Long, W As Integer, MaNV As Double, Tong As Double
 Dim Arr(), Rng As Range, sRng As Range
 Dim LoaiNghi As String, wNo As String
 ReDim aKQ(1 To 99, 5 To 15)
 
 With Sheets("ERP")
    Rws = .[B4].CurrentRegion.Rows.Count
    Arr() = .[A4].Resize(Rws, 25).Value
    For J = 1 To UBound(Arr())
        If Arr(J, 1) <> MaNV Then
            If J > 1 Then
                W = W + 1:                  aKQ(W, 5) = MaNV
                aKQ(W, 15) = Tong:          Tong = 0
                aKQ(W, 6) = Arr(J, 2)       '?'
            Else
            End If
            MaNV = Arr(J, 1)
        End If
        LoaiNghi = Arr(J, 24)
        wNo = Arr(J, 3)
        If LoaiNghi = "RP" Or LoaiNghi = "PB" Then
            If W_No(wNo) And Arr(J, 13) < 7 Then     '**  **  ** '
                Tong = Tong + 8 - Arr(J, 13)
            ElseIf Not W_No(wNo) And Arr(J, 13) < 8 Then
                Tong = Tong + 8 - Arr(J, 13)
            End If
        End If
    Next J
 End With
 If W Then
    Sheets("W1").[E7].Resize(W, 11).Value = aKQ()
 End If
End Sub
Mã:
Function W_No(wNo As String) As Boolean
 Dim Rng As Range, sRng As Range
 
 Set Rng = Sheets("Data").Range("BTr")
 Set sRng = Rng.Find(wNo, , xlFormulas, xlWhole)
 W_No = Not sRng Is Nothing
End Function
PHP:
Sub TinhNghiTheoDanhSachDaCo()
 Dim Rws As Long, lRw As Integer, Dg As Integer, MaNV As Double, J As Long, W As Integer
 Dim Arr(), Tong As Double, MyColor As Byte
 Dim LoaiNghi As String, wNo As String
 
 Sheets("W1").Select
 lRw = [e65500].End(xlUp).Row
 If lRw < 7 Then
    MsgBox "Nothing!", , "GPE.COM"
 Else:                                      Randomize:
 End If
 ReDim aKQ(1 To lRw, 1 To 1) As Double
 
 With Sheets("ERP")
    Rws = .[B4].CurrentRegion.Rows.Count
    Arr() = .[A4].Resize(Rws, 25).Value     '25  '
 End With
 For Dg = 7 To lRw
    MaNV = Cells(Dg, "E").Value
    W = W + 1
    For J = 1 To UBound(Arr())
        If Arr(J, 1) = MaNV Then
            LoaiNghi = Arr(J, 24)
            wNo = Arr(J, 3)
            If LoaiNghi = "RP" Or LoaiNghi = "PB" Then
                If W_No(wNo) And Arr(J, 13) < 7 Then     '**  **  ** '
                    Tong = Tong + 8 - Arr(J, 13)
                ElseIf Not W_No(wNo) And Arr(J, 13) < 8 Then
                    Tong = Tong + 8 - Arr(J, 13)
                End If
            End If
        End If
    Next J
    aKQ(W, 1) = Tong:                   Tong = 0
 Next Dg
 MyColor = 34 + 9 * Rnd() \ 1
 If W Then
    [O7].Resize(W).Value = aKQ():       [E5:F5].Interior.ColorIndex = MyColor
 End If
 MsgBox "Xong Rôi!", , "GPE.COM Xin Chào!"
End Sub
Em cảm ơn anh nhiều ạ ! ANh chị nào có thêm gửi cho chúng em học hỏi thêm ạ !
 
Upvote 0
Cô bé thớt này hình như ở một thế giới khác thì phải.
Thi thoảng gặp vài thành viên: Ai nói gì, ai viết gì cũng mặc bay. Rồi viết bài phản hồi đi tận nơi đâu đâu, không ăn nhập tí tẻo tèo teo nào với các bài trước của thành viên khác. Cứ như tâm hồn đang bận dạo chơi nơi đâu ấy.
(Mọi người có thể xem các bài của thớt sẽ thấy).

Cái vụ "khá hay" của thớt chỉ đơn giản là tình cờ mới thấy ở đâu đó, mà mọi khi chưa nhìn thấy.
Để biết làm và vận dụng cái "khá hay" đó cần phải nắm được:
- Tầm vực của biến;
- Cách sử dụng ByVal, ByRef cho các đối số của Function/ Sub;
- Cách phân tích, phân chia thành Function/ Sub con với các đối số để làm phần việc riêng lẻ sao cho hợp lý;

1627007327285.png

Nói về mức độ "khá hay" thì dùng Function hay hơn nhiều. Dùng Sub không hứng được gì cả, nếu muốn phải thêm biến ByRef, hoặc biến toàn cục.
Ví dụ điển hình là mấy cái API có sẵn của MS họ cũng viết ở dạng Function ấy (Function vừa thực hiện nhiệm vụ, vừa có kết quả trả về để kiểm tra, đúng kỹ thuật chuẩn - vừa làm vừa kiểm tra).
 
Upvote 0
Cô bé thớt này hình như ở một thế giới khác thì phải.
Thi thoảng gặp vài thành viên: Ai nói gì, ai viết gì cũng mặc bay. Rồi viết bài phản hồi đi tận nơi đâu đâu, không ăn nhập tí tẻo tèo teo nào với các bài trước của thành viên khác. Cứ như tâm hồn đang bận dạo chơi nơi đâu ấy.
...
Chẳng sao cả. Ở đây thiên hạ hảo ngọt lắm. Cứ lấy cái tên ẻo lả một chút và thêm giỏi nịnh là được tất.

Em cảm ơn các anh, toàn người top của diễn đàn. Em sẽ học hỏi thêm ạ !
...
Top tiếng Anh cũng có nghĩa là con quay (bông vụ theo tiếng Nam)
Như vậy, từ này dùng làm tĩnh từ hay danh từ ở đây đều đúng cả. :p
 
Upvote 0
Web KT
Back
Top Bottom