Nhờ các thày giúp cho vài ví dụ về truyền tham số cho thủ tục Sub (hoặc hàm Function)

Liên hệ QC

Dauthivan

Thành viên tiêu biểu
Tham gia
15/8/08
Bài viết
565
Được thích
327
Em đang nghiên cứu về truyền tham số bằng giá trị (byVal tức Byvalue), em có tìm đọc trên diễn đàn thì hầu hết nói rất nhanh vấn đề này, chính vì vậy em nhờ mọi người giúp em:

- Tại sao lại phải cần thiết truyền tham số.

- Giúp em một vài ví dụ để em hiểu về "cách truyền" của nó

Xin đa tạ các thày
 
Em đang nghiên cứu về truyền tham số bằng giá trị (byVal tức Byvalue), em có tìm đọc trên diễn đàn thì hầu hết nói rất nhanh vấn đề này, chính vì vậy em nhờ mọi người giúp em:

- Tại sao lại phải cần thiết truyền tham số.

- Giúp em một vài ví dụ để em hiểu về "cách truyền" của nó

Xin đa tạ các thày

Truyền tham số như một cách làm giúp tận dụng ưu điểm của việc chia thành nhiều sub hay function. Cụ thể
PHP:
Sub tong(a as integer)
dim tong as integer
tong=a+5
msgbox tong
End Sub

Sub thunghiem()
Call tong(5)
Call tong(6)
Call tong(7)
End Sub

Giả sử như bạn không truyền tham số, bạn sẽ phải làm thế này
PHP:
Public a as integer
Sub tong()
dim tong as integer, a as integer
tong=a+5
msgbox tong
End Sub

Sub thunghiem()
a=5
Call tong
a=6
Call tong
a=7
Call tong
End Sub

Với chương trình đơn giản như trên thì có lẽ sẽ không có nhiều khác biệt nhưng với chương trình phức tạp hơn thì có lẽ sẽ là một cách biệt vô cùng lớn đấy.

Tương tự với function, còn sự khác biệt giữa sub với function chắc bạn biết nhỉ (thấy bạn không có hỏi).
 
Lần chỉnh sửa cuối:
Upvote 0
Anh kyo ơi, anh giúp em lấy một ví dụ truyền tham số trong trường hợp tham số truyền là vùng lựa chọn trên màn hình (ví dụ ta dùng chuột lựa chọn vùng A1:A10 chẳng hạn), nó sẽ chuyển vào Sub tổng, tức là vai trò của vùng lựa chọn như là vai trò của a trong VD của anh vậy
 
Upvote 0
Anh kyo ơi, anh giúp em lấy một ví dụ truyền tham số trong trường hợp tham số truyền là vùng lựa chọn trên màn hình (ví dụ ta dùng chuột lựa chọn vùng A1:A10 chẳng hạn), nó sẽ chuyển vào Sub tổng, tức là vai trò của vùng lựa chọn như là vai trò của a trong VD của anh vậy
Làm đơn giản thì thế này
PHP:
Sub tong(diachi As Range)
MsgBox WorksheetFunction.Sum(diachi)
End Sub

PHP:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Call tong(Target)
End Sub

Tức là khi chọn một vùng range trên màn hình thì nó sẽ gọi sub Tong với tham số truyền là địa chỉ vùng đó, sau đó trong sub Tong nó sẽ lấy cái địa chỉ vùng (tức là biến diachi) vào trong hàm Sum để tính toán. Đây chỉ là một ví dụ để giúp bạn hiểu rõ hơn về tham số truyền thôi chứ thực chất cái ví dụ này gộp thành một sub cho nó lẹ.
 
Upvote 0
Tức là khi chọn một vùng range trên màn hình thì nó sẽ gọi sub Tong với tham số truyền là địa chỉ vùng đó, sau đó trong sub Tong nó sẽ lấy cái địa chỉ vùng (tức là biến diachi) vào trong hàm Sum để tính toán. Đây chỉ là một ví dụ để giúp bạn hiểu rõ hơn về tham số truyền thôi chứ thực chất cái ví dụ này gộp thành một sub cho nó lẹ.

Cũng thí dụ đó, viết thế này cho rộng hiểu:

PHP:
Sub tong(Rng As Range)
  MsgBox WorksheetFunction.Sum(Rng)
End Sub

PHP:
Sub TongSelection()
Call Tong(Selection)
End Sub

Ghi chú:
- Đặt tên biến cho 1 Range đừng đặt diachi As Range, sẽ nhầm lẫn với Range.Address (String)
- Đưa vào sự kiện Selection_Change, hễ rục rịch nhúc nhích gì đều tính tổng!
 
Upvote 0
Em nghĩ ra một cái, nhưng sao nó không chạy được
PHP:
Sub Tinhs()
    A = InputBox("Vao gia tri A", , 4)
    B = InputBox("Vao gia tri B", , 5)
    C = InputBox("Vao gia tri C", , 6)
    Giatri = A ^ 2 + B - C
    MsgBox "Ham Giatri =" & Giatri(A, B, C)
End Sub
 
Upvote 0
Em nghĩ ra một cái, nhưng sao nó không chạy được
PHP:
Sub Tinhs()
    A = InputBox("Vao gia tri A", , 4)
    B = InputBox("Vao gia tri B", , 5)
    C = InputBox("Vao gia tri C", , 6)
    Giatri = A ^ 2 + B - C
    MsgBox "Ham Giatri =" & Giatri(A, B, C)
End Sub

Thế cái Sub Giatri(byVal A, byVal B, byVal C) của bạn đâu?
Có tính toán gì cũng sẽ tính trong sub này chứ không phải trong Sub Tinhs đâu nha
Ít nhất cũng phải vầy:
PHP:
Sub Giatri(A, B, C)
  Dim tmp
  tmp = A ^ 2 + B - C
  MsgBox "Ham Giatri =" & tmp
End Sub
PHP:
Sub Tinhs()
  Dim A, B, C
  A = InputBox("Vao gia tri A", , 4)
  B = InputBox("Vao gia tri B", , 5)
  C = InputBox("Vao gia tri C", , 6)
  Call Giatri(A, B, C)
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Em nghĩ ra một cái, nhưng sao nó không chạy được
PHP:
Sub Tinhs()
    A = InputBox("Vao gia tri A", , 4)
    B = InputBox("Vao gia tri B", , 5)
    C = InputBox("Vao gia tri C", , 6)
    Giatri = A ^ 2 + B - C
    MsgBox "Ham Giatri =" & Giatri(A, B, C)
End Sub

PHP:
Sub Tinhs()
Dim i As Integer, j As Integer, k As Integer
    i = InputBox("Vao gia tri A", , 4)
    j = InputBox("Vao gia tri B", , 5)
    k = InputBox("Vao gia tri C", , 6)
    MsgBox "Ham Giatri =" & Giatri(i, j, k)
End Sub

Function Giatri(a As Integer, b As Integer, c As Integer)
Giatri = a ^ 2 + b - c
End Function

Thế này mới đúng vì bạn gọi Giatri tức là bạn phải gọi là một Sub hoặc một Function chứ sao bạn lại làm như thế kia, bạn nhìn các ví dụ trên thì bạn sẽ thấy, muốn sử dụng tham số truyền thì phải qua một Sub hoặc một Function. Mình làm lại cho bạn thế này nhưng mà sẽ có xảy ra lỗi nếu không nhập số đấy nhé, chỉ là một ví dụ cho bạn hiểu thôi.
 
Upvote 0
Vâng, em đang tù mù về cái này, đang tưởng tượng ra cái Sub này tại sao lại phải gọi từ cái Sub (hoặc Funtion) khác mà sao không tính luôn trong nó? Sao phức tạp quá vậy
 
Upvote 0
Trong tất cả thí dụ trên, đều có 2 Sub, 1 sub A có tham số và 1 sub gọi B. Sub gọi B phải truyền tham số cho Sub A, nếu không Sub A cũng không chạy.

Thế mà đọc xong mấy thí dụ vẫn đành đoạn viết mỗi 1 sub.
 
Upvote 0
Vâng, em đang tù mù về cái này, đang tưởng tượng ra cái Sub này tại sao lại phải gọi từ cái Sub (hoặc Funtion) khác mà sao không tính luôn trong nó? Sao phức tạp quá vậy

Bạn cứ hiểu là xài Sub hay Function như một cách để bạn xài dần lâu ngày, giả sử bạn muốn xài Sub Tong 10 lần với những biến khác nhau thì thay vì bạn phải copy paste cả đoạn code của bạn rồi đổi biến thì bạn đã có sẵn một cái khuôn, chỉ việc truyền tham số biến khác vào thôi. Còn vấn đề bạn thắc mắc tại sao không tính luôn thì cũng có cách cho bạn làm mà, chỉ vì bạn sai cú pháp thôi. Nhưng làm thế này, giả sử bạn lại muốn tính Giatri nhưng trong một Sub khác thì bạn làm thế nào, chẳng lẽ lại phải copy paste toàn bộ những gì trong đây ra để làm lại sao?
PHP:
Sub Tinhs() 
    A = InputBox("Vao gia tri A", , 4) 
    B = InputBox("Vao gia tri B", , 5) 
    C = InputBox("Vao gia tri C", , 6) 
    Giatri = A ^ 2 + B - C 
    MsgBox "Ham Giatri =" & Giatri
End Sub
 
Upvote 0
Vâng, em đang tù mù về cái này, đang tưởng tượng ra cái Sub này tại sao lại phải gọi từ cái Sub (hoặc Funtion) khác mà sao không tính luôn trong nó? Sao phức tạp quá vậy
Thì tùy bạn thôi... Bạn cảm thấy tính luôn là thuận tiện thì cứ làm
Có trường hợp thế này:
- Ta thực hiện tính toán gì đó trên bảng tính của ta, đương nhiên code chỉ đúng với dữ liệu của riêng ta
- Ta nghĩ đến việc "tổng quát hóa" để sang máy tính khác, dữ liệu khác cũng sẽ dùng được
- Vậy là ta buộc phải viết code thành 1 Function hoặc Sub có tham số truyền để khi người ta áp dụng trên dữ liệu khác, tự người ta truyền vào giá trị tùy ý
Ví dụ:
- Code bạn viết thực thi tính toán trên vùng A1:A100
- Sang máy khác, người ta muốn tính trên vùng C1:C100
- Vậy phải sửa lại toàn bộ, chổ nào có A1:A100 thì phải thay thế thành C1:C100 ---> Điều này không phải không làm được nhưng có khi thay thế nhiều quá khiến ta nhầm lẫn
- Với Sub có tham số truyền hoặc Function, ta chỉ cần cho nó thành 1 biến Range nào đó (SrcRng as Range chẳng hạn) ---> Ai muốn SrcRng là vùng nào, cứ việc điền vào là xong
 
Upvote 0
Vì em đang tìm hiểu cái thực chất tại sao phải tách làm hai Sub, nó có tác dụng gì hơn so với làm trực tiếp 1 Sub, em "cố tình" so sánh giữa 2 cái đó với nhau
Tại sao người ta không dùng
PHP:
Sub Tinhs()
    A = InputBox("Vao gia tri A", , 4)
    B = InputBox("Vao gia tri B", , 5)
    C = InputBox("Vao gia tri C", , 6)
    Giatri = A ^ 2 + B - C
    MsgBox "Giatri =" & Giatri
End Sub

mà cứ khoái kết hợp thế này
PHP:
Sub Tinhs()
Dim i As Integer, j As Integer, k As Integer
    i = InputBox("Vao gia tri A", , 4)
    j = InputBox("Vao gia tri B", , 5)
    k = InputBox("Vao gia tri C", , 6)
    MsgBox "Ham Giatri =" & Giatri(i, j, k)
End Sub

Function Giatri(a As Integer, b As Integer, c As Integer)
Giatri = a ^ 2 + b - c
End Function

Xin sư phụ chỉ cho
 
Upvote 0
Ví dụ:
- Code bạn viết thực thi tính toán trên vùng A1:A100
- Sang máy khác, người ta muốn tính trên vùng C1:C100
- Vậy phải sửa lại toàn bộ, chổ nào có A1:A100 thì phải thay thế thành C1:C100 ---> Điều này không phải không làm được nhưng có khi thay thế nhiều quá khiến ta nhầm lẫn

Em đã hiểu được mục đích của nó sau khi đọc xong bài của sư phụ Ndu, anh Kyo, em đang rất cần một ví dụ đơn giản cụ thể hoá những cái trên để em đỡ phải hình dung.

Mong nhận được sự quan tâm, giúp đỡ của các sư phụ
-----------------
Em chưa hiểu được
PHP:
Sub Tinhs()
Dim i As Integer, j As Integer, k As Integer
    i = InputBox("Vao gia tri i", , 4)
    j = InputBox("Vao gia tri j", , 5)
    k = InputBox("Vao gia tri k", , 6)
    MsgBox "Ham Giatri =" & Giatri(i, j, k)
End Sub

Function Giatri(a As Integer, b As Integer, c As Integer)
Giatri = a ^ 2 + b - c
End Function
thì Sub làm gì có a,b,c đâu mà Funtion vẫn tính được nhỉ.
Vì Funtion là a,b,c còn Sub là i,j,k cơ mà
 
Lần chỉnh sửa cuối:
Upvote 0
Vì em đang tìm hiểu cái thực chất tại sao phải tách làm hai Sub, nó có tác dụng gì hơn so với làm trực tiếp 1 Sub, em "cố tình" so sánh giữa 2 cái đó với nhau
Tại sao người ta không dùng
PHP:
Sub Tinhs()
    A = InputBox("Vao gia tri A", , 4)
    B = InputBox("Vao gia tri B", , 5)
    C = InputBox("Vao gia tri C", , 6)
    Giatri = A ^ 2 + B - C
    MsgBox "Giatri =" & Giatri
End Sub

mà cứ khoái kết hợp thế này
PHP:
Sub Tinhs()
Dim i As Integer, j As Integer, k As Integer
    i = InputBox("Vao gia tri A", , 4)
    j = InputBox("Vao gia tri B", , 5)
    k = InputBox("Vao gia tri C", , 6)
    MsgBox "Ham Giatri =" & Giatri(i, j, k)
End Sub

Function Giatri(a As Integer, b As Integer, c As Integer)
Giatri = a ^ 2 + b - c
End Function

Xin sư phụ chỉ cho
Mấy ví dụ trên thuộc dạng đơn giản nên cũng cảm thấy việc chia ra 2 Sub chẳng ngon lành gì so với gộp chung lại
Giờ bạn hãy xem bài này:
http://www.giaiphapexcel.com/forum/showthread.php?29665-Dò-tìm-và-tô-màu-ký-tự
và cho biết nếu không viết thành Sub có tham số truyền riêng thì bạn sẽ làm sao để ai mang về cũng xài được với dữ liệu riêng của mình?
- Nếu viết theo kiểu gộp chung lại, mang sang file khác để dùng, buộc bạn phải sửa lại toàn bộ các tham chiếu cho phù hợp (với dữ liệu mới) ---> Điều này không phải không làm được nhưng sẽ khá rắc rối với những ai mới tiếp cần VBA vì biết chổ nào đâu mà sửa
- Trong khi nếu tôi viết thành 1 Sub có tham số truyền thi mọi chuyện trở nên đơn giản hơn... Người dùng thậm chí không cần quan tâm đến code trong Sub chính viết gì, chỉ cần biết cú pháp là dùng được
- Như code trong bài trên có Sub chính là:
PHP:
Private Sub Character_Color(Rng As Range, ByVal Text As String, ByVal MCase As Boolean)
.....
....
End Sub
Bên trong nó viết gì tôi không cần quan tâm, chỉ cần biết khi muốn dùng thì tôi sẽ viết 1 sub để gọi như thế này:
PHP:
Sub Chay
  Character_Color Range("gì gì đó"), Chuổi tìm kiếm, TRUE
End Sub
Gọi đúng theo cú pháp mà Sub Character_Color đưa ra:
- Vùng cần tô màu là vùng nào ---> truyền vào biến Rng
- Chuổi tìm kiếm vào chuổi nào ---> Cho vào biến Text
- Tìm kiếm có phân biệt HOA thường không ---> Cho vao biến MCase (là TRUE hoặc FALSE)
Vậy là xong
Nói thêm: Cái sự "đơn giản hóa" ở đây là dành cho người dùng, giúp họ thuận tiên khi dùng 1 code... Ta "đóng gói" mọi thứ vào 1 Sub (có tham số truyền), khi người ta xài, chỉ cần cho biết các tham số ấy là những gì, thế là chạy mà không cần quan tâm đến Sub chính viết những gì trong đó
 
Lần chỉnh sửa cuối:
Upvote 0
Mình nghĩ việc này cũng dễ hiểu thôi:
- Nếu bạn chỉ muốn thực hiện một dãy lệnh trên một vùng cụ thể chỉ 1 lần (hoặc rất ít lần) thì bạn chẳng cần phải dùng đến Sub hay Function thứ 2 mà chỉ cần đưa dãy lệnh này vào vị trí cần thiết.
- Nếu bạn muốn thực hiện dãy lệnh này nhiều lần và áp dụng với nhiều dữ liệu đầu vào khác nhau (chẳng hạn: trên nhiều vùng khác nhau, số liệu khác nhau,...) thì bạn hãy nghĩ đến việc tách dãy lệnh này ra thành 1 Sub hoặc 1 Function riêng cho gọn. Mỗi lần cần thực hiện dãy lệnh này thì thay vì phải gõ cả dãy lệnh, bạn chỉ cần gọi tên Sub hoặc Function tương ứng là xong. Cái này có thể xem như là việc chuyên môn hóa trong phân công nhiệm vụ đó mà.
 
Upvote 0
Mình nghĩ việc này cũng dễ hiểu thôi:
- Nếu bạn chỉ muốn thực hiện một dãy lệnh trên một vùng cụ thể chỉ 1 lần (hoặc rất ít lần) thì bạn chẳng cần phải dùng đến Sub hay Function thứ 2 mà chỉ cần đưa dãy lệnh này vào vị trí cần thiết.
- Nếu bạn muốn thực hiện dãy lệnh này nhiều lần và áp dụng với nhiều dữ liệu đầu vào khác nhau (chẳng hạn: trên nhiều vùng khác nhau, số liệu khác nhau,...) thì bạn hãy nghĩ đến việc tách dãy lệnh này ra thành 1 Sub hoặc 1 Function riêng cho gọn. Mỗi lần cần thực hiện dãy lệnh này thì thay vì phải gõ cả dãy lệnh, bạn chỉ cần gọi tên Sub hoặc Function tương ứng là xong. Cái này có thể xem như là việc chuyên môn hóa trong phân công nhiệm vụ đó mà.
Thật ra rút gọn code không phải là ý nghĩa chính của việc dùng Sub có tham số truyền... Ý nghĩa lớn nhất của nó là "đơn giản hóa" giúp người dùng thuận tiện hơn khi sử dụng (chỉ cần làm theo cú pháp, không quan tâm nội dung viết gì)
Một ví dụ thực tế minh họa tốt nhất cho Sub có tham số truyền đó là con IC trong vi mạch ----> Chỉ cần mua con IC về, biết được mỗi 1 chân của nó có công dụng gì là xài được rồi (không cần quan tâm đến các mạch trong ruột con IC được tạo ra như thế nào)
 
Upvote 0
Em chưa hiểu được
PHP Code:
Sub Tinhs()
Dim i As Integer, j As Integer, k As Integer
i
= InputBox("Vao gia tri i", , 4)
j = InputBox("Vao gia tri j", , 5)
k = InputBox("Vao gia tri k", , 6)
MsgBox "Ham Giatri =" & Giatri(i, j, k)
End Sub

Function Giatri(a As Integer, b As Integer, c As Integer)
Giatri = a ^ 2 + b - c
End
Function


thì Sub làm gì có a,b,c đâu mà Funtion vẫn tính được nhỉ.
Vì Funtion là a,b,c còn Sub là i,j,k cơ mà
Em hiểu thế này thì có đúng không ah: nhờ Sub có cái thành phần Giatri(i, j, k) mà Funtion nó hiểu thứ tự gán như sau: a=i, b=j, c=k nghĩa là a, b,c là biến tổng quát, còn i,j,k là cụ thể hóa trong từng trường hợp phải không ah?
 
Lần chỉnh sửa cuối:
Upvote 0
Em hiểu thế này thì có đúng không ah: nhờ Sub có cái thành phần Giatri(i, j, k) mà Funtion nó hiểu thứ tự gán như sau: a=i, b=j, c=k nghĩa là a, b,c là biến tổng quát, còn i,j,k là cụ thể hóa trong từng trường hợp phải không ah?
Đúng là vậy!
Tuy nhiên phải phân biết Function và Sub nha
- Function: Cho kết quả là 1 giá trị nào đó sau quá trình tính toán... Vì thế code trong Function luôn có dang
Mã:
Function Gì gì đó (biến 1, biến 2,....) [B][COLOR=#ff0000]as Kiểu dữ liệu[/COLOR][/B]
  'Tính toan
  [COLOR=#ff0000][B]Gì gì đó[/B][/COLOR] = Giá trị nào đó ''<--- Kết quả của Function
End Function
Chú ý chổ màu đó
- Sub có tham số: Làm 1 công việc gì đó theo các tham số... Nó không có kiểu dữ liệu cũng như không cần kết quả.. Nó có dạng thế này
Mã:
Sub Gì gì đó (biến 1, biến 2,....)
  'Tính toán và làm việc theo các biến 1, biến 2...
End Sub
 
Upvote 0
Web KT

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

Đếm ngược thời gian

000
Ngày
00
Giờ
00
phút
00
giây
Back
Top Bottom