これを試すことができますか?
Sub RemoveLinearlyDependentPoints()
Dim rngX As Range, rngY As Range, rngData As Range, rngRemove As Range
Dim lCount As Long, dSlope1 As Double, dSlope2 As Double
Dim varX As Variant, varY As Variant
Const EPSILON = 0.0001
' Change ranges as needed
Set rngX = Range("A1:A5")
Set rngY = Range("B1:B5")
Set rngData = Union(rngX, rngY)
rngData.Sort key1:=rngX, Order1:=xlAscending
' Working with arrays instead of ranges is faster,
' can make a big different for large datasets
varX = rngX.Value
varY = rngY.Value
With WorksheetFunction
For lCount = 1 To rngX.Count - 2
dSlope1 = .Slope(Array(varX(lCount, 1), varX(lCount + 1, 1)), Array(varY(lCount, 1), varY(lCount + 1, 1)))
dSlope2 = .Slope(Array(varX(lCount + 1, 1), varX(lCount + 2, 1)), Array(varY(lCount + 1, 1), varY(lCount + 2, 1)))
' If slopes are the same, point in row lCount+1 can be removed
If Abs(dSlope1 - dSlope2) < EPSILON Then
If Not rngRemove Is Nothing Then
Set rngRemove = Union(rngRemove, .Index(rngData, lCount + 1, 0))
Else
Set rngRemove = .Index(rngData, lCount + 1, 0)
End If
End If
Next lCount
End With
' Mark the cells red for checking
rngRemove.Cells.Interior.Color = vbRed
' Uncomment the below to delete the cells
'rngRemove.EntireRow.Delete (xlUp)
End Sub
アイデアは、データが座標でソートされている場合x
、勾配が変化するポイントのみを保持する必要があるということです。したがって、傾きが 2 つの連続するペアで変化しない場合はいつでも(A,B)
と(B,C)
をB
削除できます。これは、 と同じ行にあるため(A,C)
です。データが に関してソートされているため、勾配のみを確認する必要がありx
ますx_A <= x_B <= x_C
。
与えられた例では、
入力:

出力:

これが役立つことを願っています!