UDF với tham số là mảng trong dấu ngoặc nhọn {}

Liên hệ QC

Nhattanktnn

Thành viên gắn bó
Tham gia
11/11/16
Bài viết
3,154
Được thích
4,124
Donate (Momo)
Donate
Giới tính
Nam
Em đang viết UDF tạo mảng mới từ một mảng có sẵn chỉ lấy một vài cột chỉ định.
Ví dụ mảng cũ có 20 cột, nhưng mảng mới chỉ cần lấy 3 cột chỉ định (để đưa xuống sheet)
Em đã tạo hàm như này:
Mã:
Function ChooseCol2D_Array(ArrCols As Variant, InputArr As Variant) As Variant
    Dim ResArr As Variant
    Dim Rws_InputArr As Long
    Dim i As Long, x As Long
    Rws_InputArr = UBound(InputArr)
    ReDim ResArr(1 To Rws_InputArr, 1 To UBound(ArrCols))
    For i = 1 To UBound(ArrCols)
        For x = 1 To Rws_InputArr
            ResArr(x, i) = InputArr(x, ArrCols(i))
        Next x
    Next i
    ChooseCol2D_Array = ResArr
End Function

Nói chung là cũng chạy được nếu em truyền vào ArrCols là một Array
Nhưng nếu để ... = ChooseCol2D_Array( {1,2,3} , Arr ) thì báo lỗi cú pháp
Chưa viết kiểu này bao giờ nên cứ loay hoay. Mong mọi người hướng dẫn
 
Em đang viết UDF tạo mảng mới từ một mảng có sẵn chỉ lấy một vài cột chỉ định.
Ví dụ mảng cũ có 20 cột, nhưng mảng mới chỉ cần lấy 3 cột chỉ định (để đưa xuống sheet)
Em đã tạo hàm như này:
Mã:
Function ChooseCol2D_Array(ArrCols As Variant, InputArr As Variant) As Variant
    Dim ResArr As Variant
    Dim Rws_InputArr As Long
    Dim i As Long, x As Long
    Rws_InputArr = UBound(InputArr)
    ReDim ResArr(1 To Rws_InputArr, 1 To UBound(ArrCols))
    For i = 1 To UBound(ArrCols)
        For x = 1 To Rws_InputArr
            ResArr(x, i) = InputArr(x, ArrCols(i))
        Next x
    Next i
    ChooseCol2D_Array = ResArr
End Function

Nói chung là cũng chạy được nếu em truyền vào ArrCols là một Array
Nhưng nếu để ... = ChooseCol2D_Array( {1,2,3} , Arr ) thì báo lỗi cú pháp
Chưa viết kiểu này bao giờ nên cứ loay hoay. Mong mọi người hướng dẫn
Bạn thử từ khóa ParamArray thử nhé.
 
Upvote 0
Bạn thử từ khóa ParamArray thử nhé.
Viết ParamArray thì em biết viết rồi anh, Nhưng theo em biết thì ParamArray đứng cuối function.
Em muốn biết vấn đề viết trong ngoặc nhọn này là để áp dụng cho sau này, có đôi khi đối số mong muốn không đứng cuối mà đứng giữa, đứng đầu chẳng hạn. Với cũng là mong muốn học hỏi thêm thôi anh
 
Upvote 0
Nếu nhập trên bảng tính.
PHP:
Function getItemInList(ByVal listItems As Variant, ByVal index As Long)
    'listItems format: {"string", 10, 2, ...,}'
    'index of first item is 1'
    getItemInList = listItems(index)
End Function
Công thức như sau:
=getItemInList({"item_1",2,3},1)
 
Upvote 0
Em đang viết UDF tạo mảng mới từ một mảng có sẵn chỉ lấy một vài cột chỉ định.
Ví dụ mảng cũ có 20 cột, nhưng mảng mới chỉ cần lấy 3 cột chỉ định (để đưa xuống sheet)
Em đã tạo hàm như này:
Mã:
Function ChooseCol2D_Array(ArrCols As Variant, InputArr As Variant) As Variant
    Dim ResArr As Variant
    Dim Rws_InputArr As Long
    Dim i As Long, x As Long
    Rws_InputArr = UBound(InputArr)
    ReDim ResArr(1 To Rws_InputArr, 1 To UBound(ArrCols))
    For i = 1 To UBound(ArrCols)
        For x = 1 To Rws_InputArr
            ResArr(x, i) = InputArr(x, ArrCols(i))
        Next x
    Next i
    ChooseCol2D_Array = ResArr
End Function

Nói chung là cũng chạy được nếu em truyền vào ArrCols là một Array
Nhưng nếu để ... = ChooseCol2D_Array( {1,2,3} , Arr ) thì báo lỗi cú pháp
Chưa viết kiểu này bao giờ nên cứ loay hoay. Mong mọi người hướng dẫn
Thử code
Mã:
Function ChooseCol2D_Array(ArrCols As Variant, InputArr As Variant) As Variant
    Dim ResArr As Variant
    Dim Rws_InputArr As Long
    Dim i As Long, x As Long
    Rws_InputArr = UBound(InputArr)
    ReDim ResArr(LBound(InputArr) To Rws_InputArr, 1 To UBound(ArrCols)+1)
    For i = 0 To UBound(ArrCols)
        For x = LBound(InputArr) To Rws_InputArr
            ResArr(x, i+1) = InputArr(x, ArrCols(i))
        Next x
    Next i
    ChooseCol2D_Array = ResArr
End Function
Trong code: ... = ChooseCol2D_Array( array(1,2,3), Arr )
Ngoài sheet: ... = ChooseCol2D_Array( {1,2,3} , Arr )
 
Upvote 0
Anh @Hai Lúa Miền Tây : Sao trang web mình vào chậm lắm á, em ấn đăng bài chờ mấy phút liền.
---

Tiếp bài 4:
Nếu trong VBA
=getItemInList([{"item_1",2,3}],1)
 
Upvote 0
Anh @Hai Lúa Miền Tây : Sao trang web mình vào chậm lắm á, em ấn đăng bài chờ mấy phút liền.
---

Tiếp bài 4:
Nếu trong VBA
=getItemInList([{"item_1",2,3}],1)
Ý em là trong vba như vậy đó anh. Ồ chiêu này Lbound mảng đó là 1 luôn, em đỡ mất công phải sửa code ChooseCol2D_Array nè anh. Hay quá!
Thử code
Mã:
Function ChooseCol2D_Array(ArrCols As Variant, InputArr As Variant) As Variant
    Dim ResArr As Variant
    Dim Rws_InputArr As Long
    Dim i As Long, x As Long
    Rws_InputArr = UBound(InputArr)
    ReDim ResArr(LBound(InputArr) To Rws_InputArr, 1 To UBound(ArrCols)+1)
    For i = 0 To UBound(ArrCols)
        For x = LBound(InputArr) To Rws_InputArr
            ResArr(x, i+1) = InputArr(x, ArrCols(i))
        Next x
    Next i
    ChooseCol2D_Array = ResArr
End Function
Trong code: ... = ChooseCol2D_Array( array(1,2,3), Arr )
Ngoài sheet: ... = ChooseCol2D_Array( {1,2,3} , Arr )
Cảm ơn bác Hiếu, mục đích em hỏi là trong vba thôi. Ấy mà bác nói sử dụng cả ngoài sheet. Em thử ngoài sheet sao không được nhỉ

Bạn dùng hàm trong vba hay sheet.
Mình dùng trong vba bạn ạ
 
Upvote 0
Vba nó không hiểu {} nên bị lỗi, sài [{1,2,3}] hoặc array(1,2,3)
 
Upvote 0
Vba nó không hiểu {} nên bị lỗi, sài [{1,2,3}] hoặc array(1,2,3)
Vậy mà 2 kiểu này khác nhau ấy nhỉ
Mã:
Sub test()
Dim arr
'arr = Array(1, 2, 3)
arr = [{1,2,3}]
Debug.Print LBound(arr); UBound(arr)
End Sub
[{1,2,3}] thì nó đồng bộ Lbound(arr)=1 với UDF bài #1 của mình.
Còn array(1,2,3) thì Lbound=0, phải chỉnh lại code như bác Hiếu đã làm
 
Upvote 0
Ý em là trong vba như vậy đó anh. Ồ chiêu này Lbound mảng đó là 1 luôn, em đỡ mất công phải sửa code ChooseCol2D_Array nè anh. Hay quá!

Dùng Array tốt hơn đó. Cái [ list ] có vài bài được anh nhiều chữ viết rồi á. Chờ anh ấy vào giải thích thêm. :)
 
Upvote 0
Ý em là trong vba như vậy đó anh. Ồ chiêu này Lbound mảng đó là 1 luôn, em đỡ mất công phải sửa code ChooseCol2D_Array nè anh. Hay quá!

Cảm ơn bác Hiếu, mục đích em hỏi là trong vba thôi. Ấy mà bác nói sử dụng cả ngoài sheet. Em thử ngoài sheet sao không được nhỉ


Mình dùng trong vba bạn ạ
{ } là ký hiệu mảng của bảng tính, không phải của VBA.
Để VBA hiểu thì phải dùng hàm Evaluate.
Trong VBA [ ] là ký hiệu viết tắt của Evaluate (*1). [ { 1, 2, 3 } ] có nghĩa là bảo tính ra mảng 1,2,3.

(*1) thực sự không hoàn toàn 100%. Evaluate có thể nhận tham số là biến. [ ] luôn luôn nhận hằng.
a = [ { 1, 2, 3 } ] được nhưng
x = 1 : y = 2 : z = 3
a = [ { x, y, z } ] không được.

...[{1,2,3}] thì nó đồng bộ Lbound(arr)=1 với UDF bài #1 của mình.
Còn array(1,2,3) thì Lbound=0, phải chỉnh lại code như bác Hiếu đã làm
Bạn cần phân biệt mảng của worksheet và mảng của VBA.
Mảng của worksheet luôn luôn bắt đầu chỉ số 1.
Mảng của VBA mặc định là bắt đầu chỉ số 0. Mặc định này có thể thay đổi bằng lệnh Option Base 1 (*2). Tức là nếu mô đun có caius option này thì hàm Array sẽ cho ra mảng bắt đầu chỉ số 1.

Điều quan trọng cần nhớ:
Evaluate và [ ] là hàm của worksheet cho nên mảng kết qủa của chúng có chỉ số bắt đầu là 1.

Vụ chỉ số mảng này tôi đã từng đề cập rõ ràng hơn ở một thớt khác.

(*2) Chú ý: để tránh ảnh hưởng của option, gọi hàm Array với tiền tố VBA
a = VBA.Array( x, y, z ) luôn luôn có chỉ số đầu là 0, bất kể Option.

Dùng Array tốt hơn đó. Cái [ list ] có vài bài được anh nhiều chữ viết rồi á. Chờ anh ấy vào giải thích thêm. :)
2 điểm:
- Hàm Array chạy nhanh hơn Evaluate. Nếu code phải làm công việc này nhiều thì nên tránh [ ]. Nếu chỉ làm 1 vài lượt thì ketiano, vài phần triệu giây chả chết ai.
- Hàm Array nhận biến, [ ] chỉ nhận hằng (xem ở trên). Trường hợp này thì không có chọn lựa.
 
Upvote 0
{ } là ký hiệu mảng của bảng tính, không phải của VBA.
Để VBA hiểu thì phải dùng hàm Evaluate.
Trong VBA [ ] là ký hiệu viết tắt của Evaluate (*1). [ { 1, 2, 3 } ] có nghĩa là bảo tính ra mảng 1,2,3.

(*1) thực sự không hoàn toàn 100%. Evaluate có thể nhận tham số là biến. [ ] luôn luôn nhận hằng.
a = [ { 1, 2, 3 } ] được nhưng
x = 1 : y = 2 : z = 3
a = [ { x, y, z } ] không được.


Bạn cần phân biệt mảng của worksheet và mảng của VBA.
Mảng của worksheet luôn luôn bắt đầu chỉ số 1.
Mảng của VBA mặc định là bắt đầu chỉ số 0. Mặc định này có thể thay đổi bằng lệnh Option Base 1 (*2). Tức là nếu mô đun có caius option này thì hàm Array sẽ cho ra mảng bắt đầu chỉ số 1.

Điều quan trọng cần nhớ:
Evaluate và [ ] là hàm của worksheet cho nên mảng kết qủa của chúng có chỉ số bắt đầu là 1.

Vụ chỉ số mảng này tôi đã từng đề cập rõ ràng hơn ở một thớt khác.

(*2) Chú ý: để tránh ảnh hưởng của option, gọi hàm Array với tiền tố VBA
a = VBA.Array( x, y, z ) luôn luôn có chỉ số đầu là 0, bất kể Option.


2 điểm:
- Hàm Array chạy nhanh hơn Evaluate. Nếu code phải làm công việc này nhiều thì nên tránh [ ]. Nếu chỉ làm 1 vài lượt thì ketiano, vài phần triệu giây chả chết ai.
- Hàm Array nhận biến, [ ] chỉ nhận hằng (xem ở trên). Trường hợp này thì không có chọn lựa.
Rất rõ ràng và chi tiết. Em cảm ơn bác nhé
 
Upvote 0
Hihi sao mình thấy giống mình quá, có thời gian mình cũng phải mò và debug biết bao nhiêu mới nghiệm ra chút ít.
 
Upvote 0
Hihi sao mình thấy giống mình quá, có thời gian mình cũng phải mò và debug biết bao nhiêu mới nghiệm ra chút ít.
Lúc đầu em còn phải kiểm tra xem cái mớ trong ngoặc vuông đó là mảng 1D hay 2D nữa kìa chị :D,
Đúng là càng học càng nhiều cái chưa biết
 
Upvote 0
Lúc đầu em còn phải kiểm tra xem cái mớ trong ngoặc vuông đó là mảng 1D hay 2D nữa kìa chị :D,
Đúng là càng học càng nhiều cái chưa biết
Lâu nay Nhattanktnn ít lên sóng he!

Bữa nào tôi cũng thử dùng mấy kiến thức trong thớt này viết 1 thứ gì đó.
 
Upvote 0
Lâu nay Nhattanktnn ít lên sóng he!

Bữa nào tôi cũng thử dùng mấy kiến thức trong thớt này viết 1 thứ gì đó.
Không phải không lên, vẫn theo dõi đó bác à. Nhưng mà công việc nhiều nên không có thời gian chém gió hihi. Bác Maika bữa nay có nhiều bài chia sẻ hay quá. Bác nói viết gì đó là viết gì bật mí tí
 
Upvote 0
Không phải không lên, vẫn theo dõi đó bác à. Nhưng mà công việc nhiều nên không có thời gian chém gió hihi. Bác Maika bữa nay có nhiều bài chia sẻ hay quá. Bác nói viết gì đó là viết gì bật mí tí
Chừ chưa nghĩ ra viết gì bạn à! Sau này ngồi nghĩ vẩn vơ thì lại bật ra ý tưởng.
 
Upvote 0
Web KT

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

Back
Top Bottom