基于当前单元格上方的第一特定文本字符串查找另一单元格的内容

时间:2012-09-28 20:11:31

标签: excel excel-formula

我正在尝试提出一个可以在不同的工作表中运行的公式,并引用下面的数据。

基本上对于D中的每个单元格,我想向上检查,当我找到字符串“Invoice”时,我选择上面的下一行和B列。基本上我每次都会找到公司名称。如您所见,每家公司的记录行数可能会有所不同。

更简单地说,公式可以只对B列起作用,并将字符串直接返回到第一次出现的字符串“Status”上方。

我不喜欢这有多复杂,但我无法控制我收到的数据格式,而且来源拒绝改变它。

原始数据

    A               B               C               D
1                   ABC Widgets, Inc.
2   Account         Status          Date            Invoice
3   1423            Open            4/25/2011       123748
4   1423            Closed          5/1/2011        432741
5   1423            Open            5/2/2011        522211
6 
7                   XYZ Sprockets, Inc.
8   Account         Status          Date            Invoice
9   3222            Open            5/3/2011        529999
10

已完成数据

    A               B               C               D            E
2   Account         Status          Date            Invoice      Client
3   1423            Open            4/25/2011       123748       ABC Widgets, Inc.
4   1423            Closed          5/1/2011        432741       ABC Widgets, Inc.
5   1423            Open            5/2/2011        522211       ABC Widgets, Inc.
9   3222            Open            5/3/2011        529999       XYZ Sprockets, Inc.

Nutch的,

虽然我无法让您的VBA代码正常工作(请参阅注释),但它确实允许我提供此代码,该代码首先发现“状态”,然后抵消上面的1个单元格。这基本上是我想要的,但是在公式格式中。

Sub findFirstStringAbove()
'
Cells.Find(What:="Status", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
    :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase _
    :=False).Offset(-1, 0).Select
End Sub

4 个答案:

答案 0 :(得分:2)

尝试此公式,作为数组公式输入,即使用 Ctrl + Shift + 输入,然后向下复制。

=INDEX(B:B,IF(ROW()>COUNTIF(B:B,"Status"),"",SMALL(IF($B:$B="Status",ROW($B:$B),2000000000),ROW()))-1)

要从其他工作表中运行剪切并将其从原始工作表中粘贴,它会自动调整参考。

答案 1 :(得分:1)

VBA会为你提供比公式快得多的答案,尽管不是动态的。运行附加的代码,过滤,偏移和复制结果:

Dim lLastRow As Long, rgResult As Range


lLastRow = Cells(Rows.Count, 2).End(xlUp).Row


With Range("B1:B" & lLastRow)
    .AutoFilter field:=1, Criteria1:="Status"
    Set rgResult = .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
    .AutoFilter
End With

Sheets.Add

rgResult.Offset(-1).Copy ActiveSheet.Cells(1, 1)

答案 2 :(得分:0)

我讨厌谜题。至少,这是我告诉别人的。

确定。我将第一列作为标题。

A1 =    Account
B1 =    Status
C1 =    Date
D1 =    Invoice
E1 =    Client
F1 =    Index
G1 =    Client Index
H1 =    Client Cnt

第2行将是您数据的开头。

A2 =    =INDEX(Sheet1!A$1:A$1000,$F2)
B2 =    =INDEX(Sheet1!B$1:B$1000,$F2)
C2 =    =INDEX(Sheet1!C$1:C$1000,$F2)
D2 =    =INDEX(Sheet1!D$1:D$1000,$F2)
E2 =    =INDEX(Sheet1!B$1:B$1000,$G2)
F2 =    =IF(ISNUMBER(F1),IF(INDEX(Sheet1!B$1:B$1000,$F1+1)="",G2+2,F1+1),G2+2)
G2 =    {=IF(H2=H1,G1,SMALL(IF(Sheet1!$B$1:$B$1000="Status",ROW(Sheet1!$B$1:$B$1000),2000),H2)-1)}
H2 =    =IF(ISNUMBER(H1),IF(INDEX(Sheet1!B$1:B$1000,$F1+1)="",H1+1,H1),1)

粘贴,直到收到#REF错误。

Excel正在对$ B:$ B语法产生一些问题。它想要一个真正的范围。此外,您可能想要一个比1000美元更大的数字。

毕竟,宏更直接,更适合这个要求,但那将是多么有趣。

享受!

答案 3 :(得分:0)

行。这是VBA。

Public Sub test()
Dim rngStCol As Range
Dim rngSt As Range
Dim lastRow As Integer
Dim rngDB As Range
Dim currRow As Integer

Set rngStCol = Sheet1.UsedRange.Columns(2)
Set rngSt = rngStCol.Find("Status")
Do While rngSt.Row > lastRow
    Set rngDB = rngSt.CurrentRegion
    Set rngDB = rngDB.Offset(2, 0).Resize(rngDB.Rows.Count - 2)

    If currRow = 0 Then
        Sheet3.Range(Sheet3.Cells(1, 1), Sheet3.Cells(1, rngDB.Columns.Count)).Value = rngDB.Offset(-1, 0).Resize(1).Value
        Sheet3.Cells(1, rngDB.Columns.Count + 1).Value = "Client"
        currRow = 2
    End If

    Sheet3.Range(Sheet3.Cells(currRow, 1), Sheet3.Cells(currRow + rngDB.Rows.Count - 1, rngDB.Columns.Count)).Value = rngDB.Value
    Sheet3.Range(Sheet3.Cells(currRow, rngDB.Columns.Count + 1), Sheet3.Cells(currRow + rngDB.Rows.Count - 1, rngDB.Columns.Count + 1)).Value = rngDB.Cells(-1, 2)

    currRow = currRow + rngDB.Rows.Count

    lastRow = rngSt.Row
    Set rngSt = rngStCol.FindNext(rngSt)
Loop


End Sub