Nhờ khắc phục và giải thích lỗi ByRef argument type mismatch

Liên hệ QC

Nguyen Rem

Tất cả chỉ là đưa ra quyết định đúng đắn
Tham gia
23/2/22
Bài viết
211
Được thích
30
Giới tính
Nữ
Em chào các anh chị trên diễn đàn hí hí ! Lại là em đây.
Hôm nay em đang code thì có một số vấn đề sau mong muốn được các anh chị giúp đỡ. Các anh , chị vào modul6 chạy code giúp em nhé ^^
Ý tưởng của em là : Lập một Function đếm số lần xuất hiện của một chuỗi con trên một chuỗi cho trước
Khi mà em Chạy Sub "Test" thì mọi chuyện khá là êm đẹp nhưng
Khi mà em chạy Sub "Test1" thì nó hiện ra lỗi "ByRef argument type mismatch" . Em thử thay đối số của function từ ByRef thành ByVal thì nó không lỗi nhưng mà kết quả nó lại không được như mong đợi .
Câu hỏi ???
1. Cho em hỏi là tại sao khi em thay đối số của Function như thế thì nó lại hết lỗi , lỗi này sinh ra do đâu , các anh chị có lưu ý gì để cho những lần sau không bị lặp lỗi này nữa không.
2. Tại sao code của em chạy nó không ra kết quả như ý muốn của em mặc dù chạy Sub "Test" đã rất ok rồi

1650946543663.png
 

File đính kèm

  • 19 - Các hàm sử lý String (tiếp).xlsm
    23.8 KB · Đọc: 7

Ăn may thôi.

Trước tiên, bạn cần học cách khai báo biến đúng chuẩn đã.
Bạn đọc tài liệu, làm theo đâu mà khai báo biến kiểu này là dính chưởng ngỏm ngay.
1650948777513.png

Khai báo thế thì chỉ có biến SoLan là integer thôi, còn hai biến K, K1 là variant

KHÔNG TIN THÌ thử:
msgbox typename(K) 'xem ra cái gì '


Bằng chứng DÍNH CHƯỞNG NGAY VÀ LUÔN:

Vì byref chỉ định kiểu dữ liệu nên nếu truyền khác kiểu là ngỏm.
Biến C là variant, mà DemSoS có đối số 1 là String ====> Tắc tử.

Debug nhảy luôn vào biến C đó.



1650948764955.png
 
Upvote 0
Bỏ tham số vào dấu ngoặc để nó tự tính ra thành string trước khi nạp tham số C.
Nguyên tắc 1: dấu ngoặc xác định một biểu thức cần tính trước khi làm chuyện khác.
Nguyên tắc 2 (quan trọng): khi tính xong biểu thức, VBA chứa kết quả vào 1 biến tạm. Vì vậy nạp tham số vào hàm mà chứa trong dấu ngoặc thì tương đương với tạm sửa ByRef thành ByVal.

1650949967666.png
 
Upvote 0
Ăn may thôi.

Trước tiên, bạn cần học cách khai báo biến đúng chuẩn đã.
Bạn đọc tài liệu, làm theo đâu mà khai báo biến kiểu này là dính chưởng ngỏm ngay.
View attachment 275031

Khai báo thế thì chỉ có biến SoLan là integer thôi, còn hai biến K, K1 là variant

KHÔNG TIN THÌ thử:
msgbox typename(K) 'xem ra cái gì '


Bằng chứng DÍNH CHƯỞNG NGAY VÀ LUÔN:

Vì byref chỉ định kiểu dữ liệu nên nếu truyền khác kiểu là ngỏm.
Biến C là variant, mà DemSoS có đối số 1 là String ====> Tắc tử.

Debug nhảy luôn vào biến C đó.



View attachment 275030
Anh ơi ! Anh cho em hỏi . Vậy có cách nào để khai báo nhiều biến cùng một lúc một cách nhanh chóng không ạ ^^
Bài đã được tự động gộp:

Bỏ tham số vào dấu ngoặc để nó tự tính ra thành string trước khi nạp tham số C.
Nguyên tắc 1: dấu ngoặc xác định một biểu thức cần tính trước khi làm chuyện khác.
Nguyên tắc 2 (quan trọng): khi tính xong biểu thức, VBA chứa kết quả vào 1 biến tạm. Vì vậy nạp tham số vào hàm mà chứa trong dấu ngoặc thì tương đương với tạm sửa ByRef thành ByVal.

View attachment 275032
Em đã đọc bài của anh rồi ạ ! Em cảm ơn anh vì đã dành thời gian đọc bài và khắc phục lỗi giúp em ^^
 
Upvote 0
Anh ơi ! Anh cho em hỏi . Vậy có cách nào để khai báo nhiều biến cùng một lúc một cách nhanh chóng không ạ ^^
Tôi không trả lời giùm tác giả bài 2# bởi vì tôi không biết. Tôi chỉ bày cách lười và ưa nhanh như tôi là khai báo tắt:
C as string = C$
C as interger = C%
C as long = C&
 
Upvote 0
Vậy có cách nào để khai báo nhiều biến cùng một lúc một cách nhanh chóng không ạ ^^

Khó thế mà cũng hỏi được.
Con người chỉ có chăm chỉ lao động mới tiến hóa được.
Đến khai báo biến thôi cũng đòi nhanh thì kinh đấy.

Dim ti_tỉ_biến(1 to ti_tỉ) as string

ti_ti_biến(1) = "A"
ti_tỉ_biến(2) = "ti tỉ biến"
 
Upvote 0
Khó thế mà cũng hỏi được.
Con người chỉ có chăm chỉ lao động mới tiến hóa được.
Đến khai báo biến thôi cũng đòi nhanh thì kinh đấy.

Dim ti_tỉ_biến(1 to ti_tỉ) as string

ti_ti_biến(1) = "A"
ti_tỉ_biến(2) = "ti tỉ biến"
^^ Em cảm ơn anh nhiều lắm . Nhưng mà anh ơi đây là mảng mà anh ^^
 
Upvote 0
Trường hợp của bạn không có lý do gì phải dùng ByRef. Nhưng nếu cứ muốn vọc với ByRef thì có nhiều cách. Có thể dùng ép kiểu - không truyền C mà truyền C & "" hoặc CStr(C):

DemSoS(C & "", D)
DemSoS(CStr(C), D)
-------------
Cũng cần giải thích thêm cho bạn hiểu, vì sau này bạn sẽ có thắc mắc.

Nếu bạn truyền ByRef mà trong sub/function bạn thay đổi giá trị của tham số thì sau khi thực hiện sub/function thì giá trị của biến khác với giá trị trước đó. Nhưng trong trường hợp bạn dùng C & "", CStr(C) hay (C) thì giá trị của biến trước và sau khi thực hiện sub/function là như nhau, không thay đổi. Như thế dùng ByRef là vô nghĩa, ước muốn không được thực hiện. Nguyên nhân là nếu truyền C (đã có khai báo C As String) thì ĐỊA CHỈ của biến C trong bộ nhớ được truyền vào hàm DemSoS (ByRef là truyền Reference) nên mọi thay đổi trong hàm là thay đổi ở nơi có ĐỊA CHỈ được truyền vào, vì thế giá trị sau khác giá trị trước. Trong 3 trường hợp ở trên thì cái truyền vào không phải là ĐỊA CHỈ của C, vì thế giá trị của C không bị thay đổi. Thực tế ở đây là "sau cánh gà" có một biến HICHIC được tạo ra tạm thời và có giá trị như (C), C & "" hoặc CStr(C), và chính ĐỊA CHỈ của HICHIC mới được truyền vào hàm. Vì thế mọi thay đổi trong hàm thực ra là thay đổi ở biến tạm HICHIC. Khi xong mọi việc thì HICHIC cũng bay theo chiều gió.

Cũng từ đây thấy nếu không có sự thay đổi giá trị của biến trong hàm thì dùng ByVal (ByVal là truyền Value) chứ dùng ByRef là vô nghĩa. Mà không chỉ vô nghĩa mà còn gây rắc rối.
 
Lần chỉnh sửa cuối:
Upvote 0
Trường hợp của bạn không có lý do gì phải dùng ByRef. Nhưng nếu cứ muốn vọc với ByRef thì có nhiều cách. Có thể dùng ép kiểu - không truyền C mà truyền C & "" hoặc CStr(C):

DemSoS(C & "", D)
DemSoS(CStr(C), D)
-------------
Cũng cần giải thích thêm cho bạn hiểu, vì sau này bạn sẽ có thắc mắc.

Nếu bạn truyền ByRef mà trong sub/function bạn thay đổi giá trị của tham số thì sau khi thực hiện sub/function thì giá trị của biến khác với giá trị trước đó. Nhưng trong trường hợp bạn dùng C & "", CStr(C) hay (C) thì giá trị của biến trước và sau khi thực hiện sub/function là như nhau, không thay đổi. Như thế dùng ByRef là vô nghĩa, ước muốn không được thực hiện. Nguyên nhân là nếu truyền C (đã có khai báo C As String) thì ĐỊA CHỈ của biến C trong bộ nhớ được truyền vào hàm DemSoS (ByRef là truyền Reference) nên mọi thay đổi trong hàm là thay đổi ở nơi có ĐỊA CHỈ được truyền vào, vì thế giá trị sau khác giá trị trước. Trong 3 trường hợp ở trên thì cái truyền vào không phải là ĐỊA CHỈ của C, vì thế giá trị của C không bị thay đổi. Thực tế ở đây là "sau cánh gà" có một biến HICHIC được tạo ra tạm thời và có giá trị như (C), C & "" hoặc CStr(C), và chính ĐỊA CHỈ của HICHIC mới được truyền vào hàm. Vì thế mọi thay đổi trong hàm thực ra là thay đổi ở biến tạm HICHIC. Khi xong mọi việc thì HICHIC cũng bay theo chiều gió.

Cũng từ đây thấy nếu không có sự thay đổi giá trị của biến trong hàm thì dùng ByVal (ByVal là truyền Value) chứ dùng ByRef là vô nghĩa. Mà không chỉ vô nghĩa mà còn gây rắc rối.
Anh ơi ! Không biết anh đọc những kiến thức về ByRef này ở đâu mà hay thế ^^. Em cũng có học cái ByRef với cái ByVal rồi xong cũng chỉ biết cái ByRef với cái ByVal khác nhau thế nào thôi nhưng về vấn đề truyền địa chỉ vào hàm hay tạo một biến tạm và truyền địa chỉ của nó vào hàm thì thực sự bây giờ em mới nghe qua hí hí
 
Upvote 0
Web KT

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

Back
Top Bottom