Hàm nội suy 1 chiều và 2 chiều

Liên hệ QC
Cám ơn anh keeponlylove rất nhiều, nhờ anh chỉnh lại một chút để khi thay đổi các giá trị trong bảng tra thì hàm vẫn có thể chạy bình thường được
 
bác cho em hỏi la hàm ngoại suy thì như thế nào?
Em có một bản cel này, trong sheet bản tra. Chỉ khi nào x,y tăng thì mới làm được vậy; có cách giải quyết khác khi không phải lập bảng cho x, y tăng không? và em còn có 1 ô không có x mà vẫn có y thì giải quyết ra sao?
 
Mình là dân kỹ thật nên sử dụng nội suy từ rất lâu (từ năm 1998) nên cũng đã viết ra hàm nội suy để dùng riêng. Cũng phải qua thực tế sử dụng rất nhiều lần mới viết được một hàm ưng ý (vì trong lĩnh vực kỹ thuật rất cần sự chính xác và tin cậy), tiện đây xin giới thiệu để các bạn tham khảo:
' One Directions Interpolate Function
' Author : Dang Vu Tuan
'
Function NS(table_array, Lookup_value)
Dim NumRows As Integer, i As Integer
Dim Max, Min
Dim Range1 As Range, Range2 As Range

NumRows = table_array.Rows.Count
Set Range1 = table_array.Columns(1)
Set Range2 = table_array.Columns(2)
' check for case if val = last value in range1
If Lookup_value = Range1.Cells(NumRows) Then
NS = Range2.Cells(NumRows)
Exit Function
End If
' Get Max and Min
Max = Range1.Cells(1)
Min = Range1.Cells(1)
For i = 1 To NumRows
If Max <= Range1.Cells(i) Then Max = Range1.Cells(i)
If Min >= Range1.Cells(i) Then Min = Range1.Cells(i)
Next i
' Return an error if lookup_value is not within range1
If Lookup_value > Max Or Lookup_value < Min Then
NS = "Out of range" 'Evaluate("NA()")
Exit Function
End If
' Do linear interpolation
For i = 1 To NumRows - 1
If (Lookup_value >= Range1.Cells(i) And Lookup_value <= Range1.Cells(i + 1)) Or (Lookup_value <= Range1.Cells(i) And Lookup_value >= Range1.Cells(i + 1)) Then
If (Range1.Cells(i) - Range1.Cells(i + 1)) <> 0 Then
NS = (Range2.Cells(i + 1) + (Range2.Cells(i) - Range2.Cells(i + 1)) * (Lookup_value - Range1.Cells(i + 1)) / (Range1.Cells(i) - Range1.Cells(i + 1)))
Else
NS = Range2.Cells(i)
End If
Exit Function
End If
Next i
End Function



Và đây là hàm nội suy hai chiều:

' Two Directions Interpolate Function
' Author : Dang Vu Tuan
'
Function NS2(Data_Range As Range, x, y)
Dim A(), xMax, yMax, xMin, yMin
Dim Nx, Ny, i, J, k1, k2, k3, k4, k12, k34
'Get the data
Nx = Data_Range.Columns.Count
Ny = Data_Range.Rows.Count
ReDim A(Nx, Ny)
For i = 1 To Nx
For J = 1 To Ny
A(i, J) = Data_Range(J, i)
Next J
Next i
'Check data
xMax = A(2, 1)
xMin = A(2, 1)
For i = 2 To Nx
If xMax < A(i, 1) Then xMax = A(i, 1)
If xMin > A(i, 1) Then xMin = A(i, 1)
Next i
yMax = A(1, 2)
yMin = A(1, 2)
For J = 2 To Ny
If yMax < A(1, J) Then yMax = A(1, J)
If yMin > A(1, J) Then yMin = A(1, J)
Next J
If x < xMin Or x > xMax Or y < yMin Or y > yMax Then
NS2 = "Out of range"
Exit Function
End If
'Do linear interpolation
For i = 2 To Nx - 1
If (A(i, 1) <= x And x <= A(i + 1, 1)) Or (A(i, 1) >= x And x >= A(i + 1, 1)) Then
For J = 2 To Ny - 1
If (A(1, J) <= y And y <= A(1, J + 1)) Or (A(1, J) >= y And y >= A(1, J + 1)) Then
k1 = A(i, J)
k2 = A(i + 1, J)
k3 = A(i, J + 1)
k4 = A(i + 1, J + 1)
If (A(i + 1, 1) - A(i, 1)) = 0 Then
k12 = k1
k34 = k3
Else
k12 = k1 + (k2 - k1) * (x - A(i, 1)) / (A(i + 1, 1) - A(i, 1))
k34 = k3 + (k4 - k3) * (x - A(i, 1)) / (A(i + 1, 1) - A(i, 1))
End If
If (A(1, J + 1) - A(1, J)) = 0 Then
NS2 = k12
Else
NS2 = k12 + (k34 - k12) * (y - A(1, J)) / (A(1, J + 1) - A(1, J))
End If
Exit Function
End If
Next J
End If
Next i
End Function



Hai hàm trên mình viết để dễ theo dõi nên thực sự còn có thể compact được hơn nữa.
bác ơi sao em copy về dùng mà giá trị trả lại hết =0 vậy bác
thông não em với
 
Web KT
Back
Top Bottom