Lồng function trong function (2 người xem)

  • Thread starter Thread starter flycat
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

flycat

Thành viên mới
Tham gia
21/8/14
Bài viết
19
Được thích
1
Mã:
Function x1(x) as double
...
End function
Mã:
Function x2(x) as double
...
End function
Muốn sử dụng function x1 bên trong function x2 thì làm sao vậy mấy anh?
Cách Function x2(x1) as double không áp dụng được cho trường hợp của mình.
Cảm ơn mấy anh nhiều
 
Lần chỉnh sửa cuối:
Mã:
Function x1(x) as double
...
End function
Mã:
Function x2(x) as double
...
End function
Muốn sử dụng function x1 bên trong function x2 thì làm sao vậy mấy anh?
Cách Function x2(x1) as double không áp dụng được cho trường hợp của mình.
Cảm ơn mấy anh nhiều
Bạn có thể để 2 hàm riêng biệt như vậy, còn khi nào dùng muốn lồng thì lồng thôi, chẳng hạn trong code chính của bạn có lệnh gán như vầy: a=x2(x1(x)) với a là 1 biến kiểu Double.
 
Lần chỉnh sửa cuối:
Mã:
Function dtt(x1, x2) As Double
    dtt = x1 + x2
End Function
Mã:
Function dsc(x3, x4) As Double
    Dim a As Double
    a = dsc(dtt(x1, x2))
    dsc = a - x3 - x4
End Function

Chạy code báo lỗi anh ơi.
 
Mã:
Function dtt(x1, x2) As Double
    dtt = x1 + x2
End Function
Mã:
Function dsc(x3, x4) As Double
    Dim a As Double
    a = dsc(dtt(x1, x2))
    dsc = a - x3 - x4
End Function

Chạy code báo lỗi anh ơi.
Bạn khai báo hàm dsc có 2 tham số x3, x4 nhưng lệnh a=dsc(dtt(x1,x2)) chỉ có 1 tham số cho hàm dsc là dtt(x1,x2). Nếu cung cấp đủ 2 tham số như a=dsc(dtt(x1,x2),0) thì sẽ hết báo lỗi nhưng đây là kiểu hàm đệ quy, một hàm gọi chính nó, nếu không có điểm dừng trong hàm sẽ làm chương trình chạy mãi.
 
Điều đầu tiên là bạn đang sai ở câu lệnh:
Mã:
    a = dsc(dtt(x1, x2))
Bỡi lẽ hàm DSC cần được cung cấp hai tham biến, nhưng bạn mới cung cấp có 1

Mà gọi kiểu hàm gọi chính nó thế này fải là tay sành sõi mới nên chơi; Dân tay ngang như mình thì ngán là cái chắc!
 
Vậy em hiểu nhầm vấn đề rồi :(
Trường hợp của em là thế này:
ô A1 có giá trị 2
ô A2 có giá trị 3
Mã:
Function dtt(x1, x2) As Double
    dtt = x1 + x2
End Function

ô A3 gõ =dtt(A1,A2) thì ra kết quả =5.

Tiếp tục:
ô C1 có giá trị 4
ô C2 có giá trị 6
ô C3 muốn có giá trị =A3 - C1 - C2 = 5 -4 -6 =-5 thì dòng lệnh như thế nào vậy mấy anh?

Mã:
Function dsc(dtt, x3, x4) As Double
    dsc = dtt - x3 - x4
End Function
Như lúc đầu em đề cập không muốn dùng code trên, mong muốn dòng đầu chỉ có Function dsc(x3, x4) As Double
Lúc đó gõ ô C3 =dsc(C1,C2) sẽ được kết quả =-5

Cái bảng của em số liệu không cố định trong 1 ô cụ thể, lung tung hết, nên dùng được hàm Range không được ạ.
 
Dùng hàm SUM để tính thì không được nha mấy anh. Ví dụ của em là rút gọn cho mấy anh dễ hiểu thôi (code trên là gần sát với bài của em), chứ bên trong là từa lưa.
Các function riêng rẽ thì em giải quyết được. Nhưng trong quá trình viết, ở function thứ y, phải dùng lại function trước nó để tính.
Nghĩ mãi mà chưa biết làm thế nào lồng được 2 function với nhau.
 
Vậy em hiểu nhầm vấn đề rồi :(
Trường hợp của em là thế này:
ô A1 có giá trị 2
ô A2 có giá trị 3
Mã:
Function dtt(x1, x2) As Double
    dtt = x1 + x2
End Function

ô A3 gõ =dtt(A1,A2) thì ra kết quả =5.

Tiếp tục:
ô C1 có giá trị 4
ô C2 có giá trị 6
ô C3 muốn có giá trị =A3 - C1 - C2 = 5 -4 -6 =-5 thì dòng lệnh như thế nào vậy mấy anh?

Mã:
Function dsc(dtt, x3, x4) As Double
    dsc = dtt - x3 - x4
End Function
Như lúc đầu em đề cập không muốn dùng code trên, mong muốn dòng đầu chỉ có Function dsc(x3, x4) As Double
Lúc đó gõ ô C3 =dsc(C1,C2) sẽ được kết quả =-5


Cái bảng của em số liệu không cố định trong 1 ô cụ thể, lung tung hết, nên dùng được hàm Range không được ạ.
Lưu ý chỗ màu đỏ nha: Nếu hàm viết vậy thì biến x1 và x2 biết lấy ở đâu mà tính ra dtt?
Theo tôi thì phải thế này:
Mã:
Function dsc(x1, x2, x3, x4) As Double
  Dim a As Double
  [COLOR=#ff0000]a = dtt(x1, x2)[/COLOR]
  dsc = a - x3 - x4
End Function
và công thức gõ trên bảng tính là: =dsc(A1, A2, C1, C2)
---------------------
Ngoài ra, nếu cảm thấy còn khó khăn gì nữa, tốt nhất cho dữ liệu thật lên đây và nói rõ yêu cầu cụ thể để người ta giúp 1 lần. Đừng tự cho rằng cách tính của mình là hướng đi tốt
 
Lưu ý chỗ màu đỏ nha: Nếu hàm viết vậy thì biến x1 và x2 biết lấy ở đâu mà tính ra dtt?

Lấy x1 và x2 từ hàm dtt đã khai báo trước đó ạ.
Mã:
Function dtt(x1, x2) As Double    
      dtt = x1 + x2
End Function
Function dsc(x3, x4) As Double   
      'lúc này dsc = dtt - x3 -x4
End Function

Bài toán của em: muốn có giá trị ô sau thì phải có kết quả giá trị ô trước. Gần giống bài toán cộng dồn.
Mã:
A1 = 2
A2 = 3
A3 = [COLOR=#0000FF]sum(A1+A2)[/COLOR]
A4 = 5
A5 =[COLOR=#0000CD] sum(A3-A4)[/COLOR] [COLOR=#FF0000]=sum(A1+A2-A4)[/COLOR]
A6 = 7
A7 = [COLOR=#0000FF]sum(A5*A6)[/COLOR] [COLOR=#FF0000]=sum(A1+A2+A4*A6)[/COLOR]
...
Chữ màu đỏ càng lúc càng dài.
Code thì em chưa hoàn thiện, vì phải gọi lại function trước mới tính được. Nhưng không biết code gọi lại như thế nào nên dừng lại.

Lúc đầu em cũng khai báo đơn giản như Function dsc(x3, x4) As Double. Nhưng càng về sau thì càng nhiều x, nhập vào ô bảng tính rất là dài.
Function dscm(x3, x4, x5, x6) As Double
Function dscn(x3, x4, x5, x6, x7, x8) As Double
...
Nội dung của function sau = function trước + thêm tí code

Sử dụng các hàm bên bản tính cũng được (đã ra kết quả mong muốn), nhưng em muốn mày mò + "lạm dụng" bên VBA.
 
Lần chỉnh sửa cuối:
...............

Lúc đầu em cũng khai báo đơn giản như Function dsc(x3, x4) As Double. Nhưng càng về sau thì càng nhiều x, nhập vào ô bảng tính rất là dài.
Function dscm(x3, x4, x5, x6) As Double
Function dscn(x3, x4, x5, x6, x7, x8) As Double
...
Nội dung của function sau = function trước + thêm tí code

Sử dụng các hàm bên bản tính cũng được (đã ra kết quả mong muốn), nhưng em muốn mày mò + "lạm dụng" bên VBA.

Nói chung là bạn nên đưa dữ liệu thật lên đây. Lòng vòng chẳng ai hiểu gì đâu
 
http://www.mediafire.com/download/cz34v6pwkgwbr4o/tinh_thep_dam.xlsm

Bắt đầu gặp rắc rối từ ô I9 đến ô P9

Code dừng lại ở att
Mã:
Function dt(phi1, s1, phi2, s2) As Double        Const pi = 3.14159
        phi1 = pi * phi1 ^ 2 / 4
        phi2 = pi * phi2 ^ 2 / 4
        'tong dien tich tat ca thanh thep
        dt = phi1 * s1 + phi2 * s2
End Function
Function lbv(phi1, phi2) As Byte
        'tinh lop bao ve
        Dim phi3 As Byte
        Dim gtm As Byte
        phi3 = 25
        gtm = WorksheetFunction.Max(phi1, phi2, phi3)
        If gtm > 35 Then
            lbv = 40
        ElseIf gtm > 30 Then
            lbv = 35
        ElseIf gtm > 25 Then
            lbv = 30
        Else
            lbv = 25
        End If
End Function
Function att(phi1, s1, phi2, s2) As Double
        Const pi = 3.14159
        phi1 = pi * phi1 ^ 2 / 4
        phi2 = pi * phi2 ^ 2 / 4
        'att = tong dien tich tung loai thanh thep * (trong tam cot thep + lop vao ve lbv) / tong dien tich _
        tat ca thanh thep dt
End Function
 
http://www.mediafire.com/download/cz34v6pwkgwbr4o/tinh_thep_dam.xlsm

Bắt đầu gặp rắc rối từ ô I9 đến ô P9

Code dừng lại ở att
Mã:
Function dt(phi1, s1, phi2, s2) As Double        Const pi = 3.14159
        phi1 = pi * phi1 ^ 2 / 4
        phi2 = pi * phi2 ^ 2 / 4
        'tong dien tich tat ca thanh thep
        dt = phi1 * s1 + phi2 * s2
End Function
Function lbv(phi1, phi2) As Byte
        'tinh lop bao ve
        Dim phi3 As Byte
        Dim gtm As Byte
        phi3 = 25
        gtm = WorksheetFunction.Max(phi1, phi2, phi3)
        If gtm > 35 Then
            lbv = 40
        ElseIf gtm > 30 Then
            lbv = 35
        ElseIf gtm > 25 Then
            lbv = 30
        Else
            lbv = 25
        End If
End Function
Function att(phi1, s1, phi2, s2) As Double
        Const pi = 3.14159
        phi1 = pi * phi1 ^ 2 / 4
        phi2 = pi * phi2 ^ 2 / 4
        [COLOR=#ff0000]'att = tong dien tich tung loai thanh thep * (trong tam cot thep + lop vao ve lbv) / tong dien tich _
        tat ca thanh thep dt[/COLOR]
End Function
Tóm lại thì chỗ màu đỏ phải tính thế nào là đúng. Và trên bảng tính ta sẽ cộng trừ nhân chia thế nào?
 
Dạ đầy đủ như thế này
Mã:
Function att(phi1, s1, phi2, s2, lbv, dt) As Double
        Const pi = 3.14159
        att = (pi * phi1 ^ 2 / 4 * s1 * (lbv + phi1 / 2) + pi * phi2 ^ 2 / 4 * s2 * (lbv + phi1 + phi2 / 2)) / dt   
End Function
Tại ô L9 nhập =att(G9,H9,G10,H10,J9,I9)

2 hàm được gọi lại là lbv và dt

//Em xin lỗi 2 dòng phi1, phi2 quên để trong dấu ghi chú.
 
Vậy em hiểu nhầm vấn đề rồi :(
Trường hợp của em là thế này:
ô A1 có giá trị 2
ô A2 có giá trị 3
Mã:
Function dtt(x1, x2) As Double
    dtt = x1 + x2
End Function

ô A3 gõ =dtt(A1,A2) thì ra kết quả =5.

Tiếp tục:
ô C1 có giá trị 4
ô C2 có giá trị 6
ô C3 muốn có giá trị =A3 - C1 - C2 = 5 -4 -6 =-5 thì dòng lệnh như thế nào vậy mấy anh?

Mã:
Function dsc(dtt, x3, x4) As Double
    dsc = dtt - x3 - x4
End Function
Như lúc đầu em đề cập không muốn dùng code trên, mong muốn dòng đầu chỉ có Function dsc(x3, x4) As Double
Lúc đó gõ ô C3 =dsc(C1,C2) sẽ được kết quả =-5

Cái bảng của em số liệu không cố định trong 1 ô cụ thể, lung tung hết, nên dùng được hàm Range không được ạ.

Nếu hàm dtt chỉ giản dị cộng 2 số với nhau thì cách lồng functions giản dị thế này:

A3 = A1 + A2; C3 = A3 - C1 - C2 = A1 + A2 - C1 - C2 = ((A1 + A2) + (-C1)) + (-C2)
Tại C3, gõ =dtt( dtt( dtt(A1,A2), -C1), -C2)
Nguyên tắc là dùng tính phân bổ của phép toán cộng
Và cái này gọi là nạp tham số cho hàm bằng trị của hàm; không phải là lồng hàm trong hàm như bạn nghĩ.

Theo thuật ngữ của lập trình lồng hàm trong hàm là khai báo một hàm con bên trong một hàm mẹ, chỉ có hàm mẹ mới gọi được hàm con. Phương pháp này chỉ có một vài ngôn ngữ làm được, bản thân VBA không cho phép làm việc này.

Tuy nhiên, bài của bạn không cần phải làm như vậy.

Dạ đầy đủ như thế này
Mã:
Function att(phi1, s1, phi2, s2, lbv, dt) As Double
        Const pi = 3.14159
        att = (pi * phi1 ^ 2 / 4 * s1 * (lbv + phi1 / 2) + pi * phi2 ^ 2 / 4 * s2 * (lbv + phi1 + phi2 / 2)) / dt   
End Function
Tại ô L9 nhập =att(G9,H9,G10,H10,J9,I9)

2 hàm được gọi lại là lbv và dt

//Em xin lỗi 2 dòng phi1, phi2 quên để trong dấu ghi chú.

Trong công thức của bạn chỉ có 2 loại đường kính thép phải không?

Mã:
Function att(ByVal phi1, ByVal s1, ByVal phi2, ByVal s2) As Double
Const pi = 3.14159
Dim dt1 as Double, dt2 as Double
dt1 = s1 * phi1 * phi1 * pi / 4 [COLOR=#008000]' con toán tín diện tính khá giản dị, lập hàm mất công[/COLOR]
dt2 = s2 * phi2 * phi2 * pi / 4
Dim lbv As Integer
[COLOR=#008000]' hàm Max chọn lựa phi lơn nhất, hạn tối thiểu là 25, hàm Match dò bậc của phi, hàm Choose chuyển lên số chẵn[/COLOR]
lbv = Choose(Application.Match( Application.Max(ph1,ph2,25), _
        [ { 1000, 35, 30, 25, 0 } ], -1), 40, 35, 30, 25, 0)
att = ( dt1 * (lbv + phi1 / 2) + dt2 * (lbv + phi1 + phi2 / 2) ) / (dt1 + dt2)
[COLOR=#008000]' tôi chỉ ghi công thức đúng như bạn ghi thôi, tại sao lại có vế (lbv + phi1 + phi2 / 2) thì tôi không biết
[/COLOR]End Function

Tuy nhiên, nếu tính theo cách của bạn, tức là ghi lbv vào ô J9 và dt vào ô I9 thì là

Mã:
Function lbv(ByVal phi1, ByVal phi2) As Double
lbv = Choose(Application.Match(Application.Max(phi1, phi2, 25), _
        [ { 1000, 35, 30, 25, 0 } ], -1), 40, 35, 30, 25, 0)
End Function

Function dt(ByVal phi, byVal s) As Double
Const pi = 3.14159
dt = s * phi * phi * pi / 4
End Function

Function att(ByVal phi1, ByVal s1, ByVal phi2, ByVal s2) As Double
att = (dt(phi1,s1) * (lbv(phi1,phi2) + phi1 / 2) + dt(phi2,s2) * (lbv(phi1,phi2) + phi1 + phi2 / 2)) / (dt(phi1,s1) + dt(phi2,s2))
End Function

Ở J9 ghi =lbv(G9,G10). ở I9 ghi =dt(G9,H9)+dt(G10,H10)

Lưu ý: trong lập trình, không ai dùng a ^ 2 cả. Con toán a * a chính xác và nhanh hơn. Phép toán nhân luôn luôn chính xác và nhanh hơn phép tính luỹ thừa. Trừ phi a là một hàm. Khi ấy tính a * a thì code phải gọi hàm a 2 lần.
 
Lần chỉnh sửa cuối:
Cảm ơn anh VetMini, code của anh đúng như em mong muốn }}}}}
Công thức đơn giản như vậy mà không nghĩ tới.

Có vài chỗ em không hiểu, mong anh vui lòng giải đáp giúp em.
Mã:
Application.Match(Application.Max(phi1, phi2, 25), _
        [COLOR=#ff0000][ { 1000, 35, 30, 25, 0 } ][/COLOR], -1)
Đoạn màu đỏ nghĩa là gì vậy anh? Phải chăng đó là cách ghi, mảng tìm kiếm của match trong VBA? 2 dấu [ { nghĩa là gì nhỉ?

Mã:
Function att(ByVal phi1, ByVal s1, ByVal phi2, ByVal s2) As Double
att = (dt(phi1,s1) * (lbv(phi1,phi2) + phi1 / 2) + dt(phi2,s2) * (lbv(phi1,phi2) + phi1 + phi2 / 2)) / (dt(phi1,s1) + dt(phi2,s2))
End Function
2 hàm dt và lbv chưa được khai báo, mà vẫn sử dụng được? Không hiểu chỗ này cho lắm. Chắc do từ khóa ByVal thì phải?
Có đọc qua bài này ... không hiểu gì hết.
 
[ ] là ký hiệu tắt của Evaluate, { val1, val2, ... } là cách trình bày một mảng.
 
Web KT

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

Back
Top Bottom