使用Excel 2010&有一个零件清单,其中一些可以更改其零件号。如果某个部件已更改,则它将位于一个工作表(A列)中,以及其新值(B列)。更改时还有一个日期时间戳。
在我的所有部件号列表中,我需要
“ last one ”可能意味着
通过添加将其重定向到上一个(正确)版本的行来输入对列表的更正。一个例子:
oldVal A更改为newVal B 2016-04-08 11:39:04.765
oldVal B更改为newVal C 2016-04-08 12:21:39.801
我知道vLookup不会这样做。我认为SUMPRODUCT可以解决第一部分,但我不确定如何进行递归(或者如果可能的话)的时间部分。
任何想法,想法,解决方案将不胜感激。
修改
其他信息 -
我想在 NewPartNo 列中显示的是该部件号链中的最后一个值。如果部件号来自A - > B - > C - > D,我希望在A列的 PartNo 的 NewPartNo 列中看到D.
你有一个1960-1,其newVal为25-1960。问题是25-1960然后有一个新的OBB1960。有多少级递归错位的val?
这就是问题 - 在某些地方,部分可能(最初)被命名为A列中的任何一个。至少有多少级别 - 我不知道。可能是5-10,也许?我完全不知道。
编辑2
@ TMDean的解决方案大部分都有效,除了我有下面的数据。
如果从A001开始,它将映射到B001。 B001的最新(最近的日期)映射是C001。 C001的映射(自身)与另一个映射具有相同的日期时间戳,因此A001应映射到C001。
在单步执行该功能时,它会找到第一个(A001 - > B001),但在尝试查找第二个(B001 - > C001)时会抛出错误。
在上文中,查找的正确结果应为A001 - > C001。
答案 0 :(得分:3)
以下是两个用于检索递归 newVal 的UDF以及它的关联日期。
Option Explicit
Function newestVal(lu As Range, rng As Range)
Dim val As Variant
Static app As New Application
'truncate the rng down to the used range
Set rng = Intersect(rng, rng.Parent.UsedRange)
val = lu.Value2
With rng
If IsError(app.Match(lu.Value2, .Columns(1), 0)) Then
val = app.Index(.Columns(2), app.Match(val, .Columns(2), 0), 1)
Else
Do While Not IsError(app.Match(val, .Columns(1), 0))
val = app.Index(.Columns(2), app.Match(val, .Columns(1), 0), 1)
Loop
End If
End With
newestVal = val
End Function
Function latestValDate(lu As Range, rng As Range)
Dim d As Long, val As Variant, dbl As Double
Static app As New Application
'truncate the rng down to the used range
Set rng = Intersect(rng, rng.Parent.UsedRange)
val = lu.Value2
With rng
If IsError(app.Match(lu.Value2, .Columns(1), 0)) Then
val = app.Index(.Columns(2), app.Match(val, .Columns(2), 0), 1)
Else
Do While Not IsError(app.Match(val, .Columns(1), 0))
val = app.Index(.Columns(2), app.Match(val, .Columns(1), 0), 1)
Loop
End If
For d = app.Match(val, .Columns(2), 0) To rng.Rows.Count
If .Cells(d, 2).Value2 = val Then
If .Cells(d, 3).Value2 > dbl Then
dbl = .Cells(d, 3).Value2
End If
End If
Next d
End With
latestValDate = dbl
End Function
在F2:G2中,
=newestVal(E2,A:C )
=latestValDate(E2,A:C )
¹用户定义函数(又名UDF)被放入标准模块代码表中。点击 Alt + F11 ,当VBE打开时,立即使用下拉菜单插入►模块( Alt + 我,中号)。将功能代码粘贴到标题为 Book1 - Module1(Code)的新模块代码表中。点击 Alt + Q 返回工作表。
答案 1 :(得分:1)
这是所有的伪代码,但它应该让你正确的方向。给我几个小时,我可以为你做,但尝试弄清楚它可能会很有趣。
If Selection Offset Column + 1 <> vbNullString then
newvalue = Selection Offset Column + 1.value
for i = 1 to 100
If newvalue Offset Column + 1 = vbNullString then
Display (i)a,b,c
Exit For
ElseIf newvalue Offset Column + 1 <> vbNullString then
newvalue = newvalue Offset Column + 1.value
Next i
答案 2 :(得分:1)
受Jeeped解决方案的启发,我想知道它是否可以更通用,并编写了一个递归版VLOOKUP
的UDF实现。
此函数的工作方式与VLOOKUP
类似,不同之处在于它将跟随查找值链,直到它到达表的末尾,如问题中所述。
Option Explicit
Function VLOOKUPR(LookupValue As Variant, _
TableArray As Range, _
ColIndexNum As Long, _
RangeLookup As Boolean)
Dim LookupIndex
Set TableArray = Intersect(TableArray, TableArray.Parent.UsedRange)
VLOOKUPR = CVErr(xlErrNA)
Do
LookupIndex = Application.Match(LookupValue, TableArray.Columns(1), _
IIf(RangeLookup, 1, 0))
If IsError(LookupIndex) Then Exit Do
VLOOKUPR = TableArray(LookupIndex, ColIndexNum)
If LookupValue <> TableArray(LookupIndex, 1) Then Exit Do
LookupValue = TableArray(LookupIndex, ColIndexNum)
Set TableArray = Intersect(TableArray, TableArray.Offset(LookupIndex))
Loop Until TableArray Is Nothing
End Function
由于我希望它是通用的,所以我没有要求它返回查找值而不是#N/A
如果它存在于列B中。您可以在您使用的单元格公式中包含此逻辑致电VLOOKUPR
。 =IFERROR(VLOOKUPR($E2,$A$2:$A$100,2,FALSE),VLOOKUP($E2,$B$2:$B$100,1,FALSE))