Viếtt giúp em hàm nội suy

Liên hệ QC

AGi

Thành viên mới
Tham gia
21/4/10
Bài viết
5
Được thích
0
Chào các anh/chị. Em nhờ mọi người viết dùm em cái hàm nội suy để tình mật độ (MĐ) xây dựng từ diện tích (DT) đất (QCVN : 01/2008/BXD) như sau:
DT -> MĐXD
=< 50 -> 100
75 -> 90
100 -> 80
200 -> 70
300 -> 60
500 -> 50
>= 1000 -> 40
Cám ơn mọi người!
 
Lần chỉnh sửa cuối:
Bạn dùng hàm IF() là được mà;

Nếu muốn viết hàm tự tạo thì có thể vầy:

PHP:
 Function MatDoXD( Rng As Range) As Long
  Dim DTich As Double
  
  DTich = Rng.Value
     MatDoXD = Switch( DTich <=50, 100,  DTich <=75, 90, DTich <=100, 80, DTich <=200, 70  _
                    , DTich <=300, 60, DTich <=500, 50, DTich <=1000, 40, DTich >1000, 30) 
 End Fuction
=< 50 -> 100
75 -> 90
100 -> 80
. . .
500 -> 50
?
>= 1000 -> 40
 
Nếu muốn viết hàm tự tạo thì có thể vầy:

PHP:
 Function MatDoXD( Rng As Range) As Long
  Dim DTich As Double
  
  DTich = Rng.Value
     MatDoXD = Switch( DTich <=50, 100,  DTich <=75, 90, DTich <=100, 80, DTich <=200, 70  _
                    , DTich <=300, 60, DTich <=500, 50, DTich <=1000, 40, DTich >1000, 30) 
 End Fuction
Thanks bạn! Hình như cái này ko có nội suy hả bạn? Có lẽ đề bài mình ko nói rõ lắm nên khiến bạn hiểu nhầm. VD: với lô đất có diện tích là 150m2 thì mình fai3 nội suy từ MĐXD của 2 lô có dt 100m2 vá 200m2. Nếu dùng hàm If() thì cũng đc nhưng chắc sẽ dài lắm ^_^
 
Chào các anh/chị. Em nhờ mọi người viết dùm em cái hàm nội suy để tình mật độ (MĐ) xây dựng từ diện tích (DT) đất (QCVN : 01/2008/BXD) như sau:
DT -> MĐXD
=< 50 -> 100
75 -> 90
100 -> 80
200 -> 70
300 -> 60
500 -> 50
>= 1000 -> 40
Cám ơn mọi người!
Bạn phải nói rõ công thức nội suy như thế nào thì mới tính được chứ. Ví dụ: DT = 169 thì MĐXD là bao nhiêu?
 
Bạn phải nói rõ công thức nội suy như thế nào thì mới tính được chứ. Ví dụ: DT = 169 thì MĐXD là bao nhiêu?
DT(S) -> MĐXD(M)
=< 50 -> 100
75 -> 90
100 -> 80
200 -> 70
300 -> 60
500 -> 50
>= 1000 -> 40
Hihihi. Công thức nội suy như sau: Mi = Ma - (Si - Sa)x(Ma-Mb)/(Sb-Sa)
Trong đó:
Si : diện tích lô đất (i) (lô đất cần tính mđxd)
Sa: diện tích của lô đất (a) (diện tích giới hạn dưới so với i)
Sa: diện tích của lô đất (b) (diện tích giới hạn trên so với i)
Mi: mật độ xây dựng tối đa cho phép của lô đất (i)
Ma: mật độ xây dựng tối đa cho phép của lô đất (a)
Mb: mật độ xây dựng tối đa cho phép của lô đất (b)
VD: nếu Si = 169(m2) thì theo bảng ở trên : Sa = 100(m2), Sb = 200(m2), Ma = 80(%), Mb = 70(%), Mi = kết quả cần tìm
 
Lần chỉnh sửa cuối:
Hàm của bạn đây, xin mời

PHP:
Function NoiSuy1Chieu(LookUpRange As Range, DTich As Double)
  Dim Clls As Range
  Dim Sa As Double, Sb As Double, Ma As Long, Mb As Long
 
  For Each Clls In LookUpRange.Cells(1,1).Resize(LookUpRange.Rows.Count)
   If Clls.Value > DTich Then
      With Clls
         Sa = .Offset(-1).Value:             Sb = .Value
         Ma = .Offset(-1, 1).Value:          Mb = .Offset(, 1).Value
         NoiSuy1Chieu = Ma - (DTich - Sa) * (Ma - Mb) / (Sb - Sa)
9        Exit Function
      End With
   End If
  Next Clls
End Function
Lưu í: Bạn vẫn còn sai chổ này:
 
Lần chỉnh sửa cuối:
DT(S) -> MĐXD(M)
=< 50 -> 100
75 -> 90
100 -> 80
200 -> 70
300 -> 60
500 -> 50
>= 1000 -> 40
Hihihi. Công thức nội suy như sau: Mi = Ma - (Si - Sa)x(Ma-Mb)/(Sb-Sa)
Trong đó:
Si : diện tích lô đất (i) (lô đất cần tính mđxd)
Sa: diện tích của lô đất (a) (diện tích giới hạn dưới so với i)
Sa: diện tích của lô đất (b) (diện tích giới hạn trên so với i)
Mi: mật độ xây dựng tối đa cho phép của lô đất (i)
Ma: mật độ xây dựng tối đa cho phép của lô đất (a)
Mb: mật độ xây dựng tối đa cho phép của lô đất (b)
VD: nếu Si = 169(m2) thì theo bảng ở trên : Sa = 100(m2), Sb = 200(m2), Ma = 80(%), Mb = 70(%), Mi = kết quả cần tìm
Tôi cũng có một hàm cho bạn đây. Test xem có sai chỗ nào không.
PHP:
Function MDXD(Si As Single) As Single
Dim S As Variant, i As Long
    If Si <= 50 Or Si >= 1000 Then
        MDXD = IIf(Si <= 50, 100, 40)
        Exit Function
    End If
S = Array(50, 75, 100, 200, 300, 500, 1000)
For i = 0 To 6
    If Si <= S(i) Then Exit For
Next
MDXD = 110 - 10 * i - (Si - S(i - 1)) * 10 / (S(i) - S(i - 1))
End Function
 

File đính kèm

  • GPE.xls
    30 KB · Đọc: 227
PHP:
Function NoiSuy1Chieu(LookUpRange As  Range, DTich As Double)
  Dim Clls As Range
  Dim Sa As Double, Sb  As Double, Ma As Long, Mb As Long
 
  For Each Clls In  LookUpRange.Cells(1,1).Resize(LookUpRange.Rows.Count)
   If  Clls.Value > DTich Then
      With Clls
         Sa =  .Offset(-1).Value:             Sb = .Value
         Ma = .Offset(-1,  1).Value:          Mb = .Offset(, 1).Value
         NoiSuy1Chieu = Ma  - (DTich - Sa) * (Ma - Mb) / (Sb - Sa)
      End With
   End If
   Next Clls
End Function
Lưu í: Bạn vẫn còn sai chổ này:
Hình như UDF này có vấn đề, không biết Bác test chưa. Xem qua thấy một số chỗ thế này:
- Dùng For... Next duyệt qua các diện tích trong bảng dò nhưng không có dòng lệnh thoát vòng lặp, vòng lặp sẽ duyệt đến ô cuối cùng.
- Nếu diện tích cần tính ngoài vùng giá trị của bảng dò thì sao???
 
Nói mọi người đừng cười em chứ mấy cái này dùng ntn vây? Em gà excel lắm !
 
Hình như UDF này có vấn đề, không biết Bác test chưa. Xem qua thấy một số chỗ thế này:
- Dùng For... Next duyệt qua các diện tích trong bảng dò nhưng không có dòng lệnh thoát vòng lặp, vòng lặp sẽ duyệt đến ô cuối cùng.
- Nếu diện tích cần tính ngoài vùng giá trị của bảng dò thì sao???

Nếu diện tích ngoài vùng giá trị vd: 35m2 (<50m2) => Mđxd = 100%, 1500m2 (>1000m2) => Mđxd = 40%
Xem trong files đính kèm của bác "huuthang_bd" thấy kết qua trongc các ô là đúng rồi. Nhưng mỗi tội là em ko biết dùng nó ntn? Nhập diện tích cần tra mđxd ở đâu?
 
Lần chỉnh sửa cuối:
Hình như UDF này có vấn đề, không biết Bác test chưa. Xem qua thấy một số chỗ thế này:
(1) - Dùng For... Next duyệt qua các diện tích trong bảng dò nhưng không có dòng lệnh thoát vòng lặp, vòng lặp sẽ duyệt đến ô cuối cùng.

(2) - Nếu diện tích cần tính ngoài vùng giá trị của bảng dò thì sao???
(1) Mình đã thêm dòng lệnh để thoát; Rất xin lỗi vì đã làm fiền các bạn

(2) Thì hàm sẽ có giá trị 0
 
Em thấy file anh chi viết rất hay và đúng. Em gà về excel. Nếu giờ em muốn thay tỷ lệ % trong công thức thì em làm thế nào
 
Vì dự liệu X được cho theo dạng tăng dần nên có thể bỏ hai dãy số vào mảng rồi dùng Match mà tìm vị trí để nội suy.

Function NoiSuyTungPhan(x As Double) As Double
' hàm nội suy từng phần theo hai dãy số
' cụm từ "từng phần" có nghĩa là trị Y(i) sẽ nội suy theo từng khoảng X(i)-X(i+1)
' trái với nội suy tuyến tính, làm việc theo phương trình thẳng, suy từ cả dãy
' lưu ý: bài này dùng hàm Estimate để dựng mảng, chỉ số sẽ bắt đầu từ 1
' nếu dùng hàm Array để dựng mảng thì chỉ số có thể bắt đầu bằng 0
mgX = [ { 0, 50, 75, 100, 200, 300, 500, 1000, 999999999 } ] ' 7+2 = 9 phần tử (thêm 2 trị bao ở cạnh biên)
mgY = [ { 100, 100, 90, 80, 70, 60, 50, 40, 40 } ]
viTri = Application.Match(x, mgX, 1)
NoiSuyTungPhan = mgY(viTri) + (x - mgX(viTri))*(mgY(viTri+1)-mgY(viTri))/(mgX(viTri+1)-mgX(viTri))
End Function

Dựa trên nguyên tắc này, có thể viết công thức trên bảng tính nếu cần.
 
Web KT
Back
Top Bottom