Excel 匹配范围内所有字符串的最后一个单词...VBA
Excel Match last Word in all Strings in a Range...VBA
我正在创建一个帮助分析歌曲创作技巧的小工具。
我有一个数据库,里面有今年 Col. A 的歌词。
歌词一行行往下走(例)
1. You’re so indecisive of what I’m saying
1. Tryna catch the beat, make up your heart
1. Don't know if you're happy or complaining
1. Don't want for us to end, where do I start?
1. First you wanna go to the left then you wanna turn right
1. Wanna argue all day, making love all night
1. First you're up then you’re down and in between*
我想创建一个 vba 调用用户输入单词...例如
"Start" 在这种情况下。
该代码将匹配每个句子的最后一个词,return 包含搜索词的列作为句子中的最后一个词。
然后它需要向用户显示一条消息,包括整个句子,以及上面的两个句子和下面的两个句子。
在我们的示例中,它将把下面的句子带回给用户:
1. Tryna catch the beat, make up your heart
1. Don't know if you're happy or complaining
1. Don't want for us to end, where do I start?
1. First you wanna go to the left then you wanna turn right
1. Wanna argue all day, making love all night
我在 V-Lookups 和 Index-Match 之间挣扎,但找不到一个好的起点。
有谁能指点我正确的道路吗?
更新:
我还没有工作代码。我有的是工作表中的公式
在 B 列中,
我有公式
=IF(ISERR(FIND(" ",A4)),"",RIGHT(A4,LEN(A4)-FIND("*",SUBSTITUTE(A4," ","*",LEN(A4)-LEN(SUBSTITUTE(A4," ",""))))))
其中记录了每个句子的最后一个作品
在 D 列中,
我有一个公式可以将输入的单词与 B 列进行比较,然后返回 A 列
=IF($D=B4,A4,"NO MATCH")
我相信我可以写一个 VBA 来用搜索词替换 "D2",但后来我不知道如何从那里开始
一般方法
您需要将问题分解为可组合的步骤:
- 问题1.获取要分析的值(字符串)
- 问题 2. 查找列中出现的所有单个值
- 问题 3. 对于给定的一行,显示相邻的两行(上下)
如果您可以单独解决每个问题,则只需以某种方式组合解决方案即可获得您最终要寻找的内容。
VBA 与普通 excel 公式
如果您对人体工程学没有严格的要求,您可以使用 excel 公式来做很多您想做的事情。但是如果你 have/need 一个用户界面,VBA 是最好的选择。因此,如果你的 VBA 技能很好,甚至一般,那么就走那条路,因为公式之路需要 excel 大量 excel 公式的知识。
解决问题
一旦你有了这个故障,你就可以 google 它(或者 post 它在 SO - 如果你有一个容易理解的小问题,你会得到更多的答案)。
例如,我 google 第 2 期,我发现(除其他外):
这是一个解决问题2的正则excel公式(具体看步骤3,这是问题3需要的,求值的索引)。它还详细解释了公式的工作原理。即使您采用 VBA 路线,您仍然可以在 VBA 代码中重复使用该公式,所以一切都很好。
现在您希望找到的值是您句子中的最后一个词。所以添加一个列来保存你句子的最后一个词,并将解决方案 2 应用到该列。
问题 3 也可以通过公式解决,只要您有索引作为起点。您可能必须使用以下函数 OFFSET
和数组公式。数组公式见:http://www.excel-easy.com/functions/array-formulas.html。如果我刚才说的对你来说是中文,走VBA这条路,会更容易。
我不会给你一个解决方案(抱歉我有点忙)但我希望至少这可以帮助你思考问题并找到组成你正在寻找的更小步骤的解决方案。
[更新]:
经过一番谷歌搜索后,这里有一些您可以改进的解决方案:
- 将以下用户定义的函数添加到您的 excel sheet
`
Function concatFormat(Delimiter As Variant, ParamArray CellRanges() As Variant) As String
Dim Index As Long, Rw As Long, Col As Long, Down As Boolean, Rng As Range, Cell As Range
If IsMissing(Delimiter) Then Delimiter = ""
Index = LBound(CellRanges)
Do While Index <= UBound(CellRanges)
If TypeName(CellRanges(Index)) = "Range" Then
Set Rng = CellRanges(Index)
If Index < UBound(CellRanges) Then
If TypeName(CellRanges(Index + 1)) <> "Range" Then Down = CellRanges(Index + 1) = "|"
End If
If Down Then
For Col = 0 To Rng.Columns.Count - 1
For Rw = 0 To Rng.Rows.Count - 1
If Len(Rng(1).Offset(Rw, Col).Value) Then concatFormat = concatFormat & Delimiter & Rng(1).Offset(Rw, Col).Text
Next
Next
Index = Index + 1
Else
For Each Cell In Intersect(Rng, Rng.Parent.UsedRange)
If Len(Cell.Value) Then concatFormat = concatFormat & Delimiter & Cell.Text
Next
End If
Else
If CellRanges(Index) = "||" Then
concatFormat = concatFormat & Delimiter & "|"
Else
concatFormat = concatFormat & Delimiter & CellRanges(Index).Text
End If
End If
Index = Index + 1
Loop
concatFormat = Mid(concatFormat, Len(Delimiter) + 1)
End Function
Function UStrip(sWord As String) As String
Dim x As Long
Dim sCharacter As String
'This function takes a string outputs an uppercase equivalent with
' all characters stripped but numbers and letters
'Uppercase is used since it is a better function with "Find" since case becomes immaterial
sWord = UCase(sWord) 'Convert to Uppercase
UStrip = "" 'Set originall as null
For x = 1 To Len(sWord) 'Act on each letter
sCharacter = Mid(sWord, x, 1)
If Asc(sCharacter) >= 65 And _
Asc(sCharacter) <= 90 Then '65-90 are ASCII "A"-"Z"
'sCharacter is a LETTER
UStrip = UStrip & sCharacter
ElseIf sCharacter = " " Then
'sCharacter is a space
UStrip = UStrip & sCharacter
ElseIf Asc(sCharacter) >= 48 And _
Asc(sCharacter) <= 57 Then '48-57 are ASCII "0"-"9"
'sCharacter is a "text-NUMBER"
UStrip = UStrip & sCharacter
End If
Next x
End Function
`
这些函数几乎完全是从以下位置复制粘贴的:
http://windowssecrets.com/forums/showthread.php/139774-Strip-out-punctuation-Excel-2003
http://www.excelfox.com/forum/f22/formatted-flexible-concatenation-function-582/
这些是我在 google 搜索后找到的。
那么你的 excel sheet 必须这样组织:
- A列:原句
- B 列:A 列的最后一个字
- C 列:B 列没有标点符号,即公式
=+ustrip(B2)
- D 列:要查找的词的索引:
=IF(C2=$B,ROW(),"")
。请注意,$B$10 是您要查找的词,即您示例中的 start
- E 列:您想要的串联行:
=concatFormat(CHAR(10),OFFSET($A:$A,IF(D2-4<0,0,D2-4),0,5))
- F 列:消除错误值:
=+IF(ISERROR(E2),"",E2)
请注意,在我的示例中,句子从第 2 行开始(第 1 行是字段名称)。因此,如果您不从第 2 行开始,请相应地调整公式。
从那里你可以做 VBA 部分,要求用户输入一个词,然后写 VBA 来读取和显示 F 列中的值。
我正在创建一个帮助分析歌曲创作技巧的小工具。 我有一个数据库,里面有今年 Col. A 的歌词。 歌词一行行往下走(例)
1. You’re so indecisive of what I’m saying
1. Tryna catch the beat, make up your heart
1. Don't know if you're happy or complaining
1. Don't want for us to end, where do I start?
1. First you wanna go to the left then you wanna turn right
1. Wanna argue all day, making love all night
1. First you're up then you’re down and in between*
我想创建一个 vba 调用用户输入单词...例如 "Start" 在这种情况下。 该代码将匹配每个句子的最后一个词,return 包含搜索词的列作为句子中的最后一个词。
然后它需要向用户显示一条消息,包括整个句子,以及上面的两个句子和下面的两个句子。
在我们的示例中,它将把下面的句子带回给用户:
1. Tryna catch the beat, make up your heart
1. Don't know if you're happy or complaining
1. Don't want for us to end, where do I start?
1. First you wanna go to the left then you wanna turn right
1. Wanna argue all day, making love all night
我在 V-Lookups 和 Index-Match 之间挣扎,但找不到一个好的起点。
有谁能指点我正确的道路吗?
更新:
我还没有工作代码。我有的是工作表中的公式
在 B 列中,
我有公式
=IF(ISERR(FIND(" ",A4)),"",RIGHT(A4,LEN(A4)-FIND("*",SUBSTITUTE(A4," ","*",LEN(A4)-LEN(SUBSTITUTE(A4," ",""))))))
其中记录了每个句子的最后一个作品
在 D 列中,
我有一个公式可以将输入的单词与 B 列进行比较,然后返回 A 列
=IF($D=B4,A4,"NO MATCH")
我相信我可以写一个 VBA 来用搜索词替换 "D2",但后来我不知道如何从那里开始
一般方法
您需要将问题分解为可组合的步骤:
- 问题1.获取要分析的值(字符串)
- 问题 2. 查找列中出现的所有单个值
- 问题 3. 对于给定的一行,显示相邻的两行(上下)
如果您可以单独解决每个问题,则只需以某种方式组合解决方案即可获得您最终要寻找的内容。
VBA 与普通 excel 公式
如果您对人体工程学没有严格的要求,您可以使用 excel 公式来做很多您想做的事情。但是如果你 have/need 一个用户界面,VBA 是最好的选择。因此,如果你的 VBA 技能很好,甚至一般,那么就走那条路,因为公式之路需要 excel 大量 excel 公式的知识。
解决问题
一旦你有了这个故障,你就可以 google 它(或者 post 它在 SO - 如果你有一个容易理解的小问题,你会得到更多的答案)。
例如,我 google 第 2 期,我发现(除其他外):
这是一个解决问题2的正则excel公式(具体看步骤3,这是问题3需要的,求值的索引)。它还详细解释了公式的工作原理。即使您采用 VBA 路线,您仍然可以在 VBA 代码中重复使用该公式,所以一切都很好。
现在您希望找到的值是您句子中的最后一个词。所以添加一个列来保存你句子的最后一个词,并将解决方案 2 应用到该列。
问题 3 也可以通过公式解决,只要您有索引作为起点。您可能必须使用以下函数 OFFSET
和数组公式。数组公式见:http://www.excel-easy.com/functions/array-formulas.html。如果我刚才说的对你来说是中文,走VBA这条路,会更容易。
我不会给你一个解决方案(抱歉我有点忙)但我希望至少这可以帮助你思考问题并找到组成你正在寻找的更小步骤的解决方案。
[更新]: 经过一番谷歌搜索后,这里有一些您可以改进的解决方案:
- 将以下用户定义的函数添加到您的 excel sheet
`
Function concatFormat(Delimiter As Variant, ParamArray CellRanges() As Variant) As String
Dim Index As Long, Rw As Long, Col As Long, Down As Boolean, Rng As Range, Cell As Range
If IsMissing(Delimiter) Then Delimiter = ""
Index = LBound(CellRanges)
Do While Index <= UBound(CellRanges)
If TypeName(CellRanges(Index)) = "Range" Then
Set Rng = CellRanges(Index)
If Index < UBound(CellRanges) Then
If TypeName(CellRanges(Index + 1)) <> "Range" Then Down = CellRanges(Index + 1) = "|"
End If
If Down Then
For Col = 0 To Rng.Columns.Count - 1
For Rw = 0 To Rng.Rows.Count - 1
If Len(Rng(1).Offset(Rw, Col).Value) Then concatFormat = concatFormat & Delimiter & Rng(1).Offset(Rw, Col).Text
Next
Next
Index = Index + 1
Else
For Each Cell In Intersect(Rng, Rng.Parent.UsedRange)
If Len(Cell.Value) Then concatFormat = concatFormat & Delimiter & Cell.Text
Next
End If
Else
If CellRanges(Index) = "||" Then
concatFormat = concatFormat & Delimiter & "|"
Else
concatFormat = concatFormat & Delimiter & CellRanges(Index).Text
End If
End If
Index = Index + 1
Loop
concatFormat = Mid(concatFormat, Len(Delimiter) + 1)
End Function
Function UStrip(sWord As String) As String
Dim x As Long
Dim sCharacter As String
'This function takes a string outputs an uppercase equivalent with
' all characters stripped but numbers and letters
'Uppercase is used since it is a better function with "Find" since case becomes immaterial
sWord = UCase(sWord) 'Convert to Uppercase
UStrip = "" 'Set originall as null
For x = 1 To Len(sWord) 'Act on each letter
sCharacter = Mid(sWord, x, 1)
If Asc(sCharacter) >= 65 And _
Asc(sCharacter) <= 90 Then '65-90 are ASCII "A"-"Z"
'sCharacter is a LETTER
UStrip = UStrip & sCharacter
ElseIf sCharacter = " " Then
'sCharacter is a space
UStrip = UStrip & sCharacter
ElseIf Asc(sCharacter) >= 48 And _
Asc(sCharacter) <= 57 Then '48-57 are ASCII "0"-"9"
'sCharacter is a "text-NUMBER"
UStrip = UStrip & sCharacter
End If
Next x
End Function
`
这些函数几乎完全是从以下位置复制粘贴的: http://windowssecrets.com/forums/showthread.php/139774-Strip-out-punctuation-Excel-2003 http://www.excelfox.com/forum/f22/formatted-flexible-concatenation-function-582/ 这些是我在 google 搜索后找到的。
那么你的 excel sheet 必须这样组织:
- A列:原句
- B 列:A 列的最后一个字
- C 列:B 列没有标点符号,即公式
=+ustrip(B2)
- D 列:要查找的词的索引:
=IF(C2=$B,ROW(),"")
。请注意,$B$10 是您要查找的词,即您示例中的start
- E 列:您想要的串联行:
=concatFormat(CHAR(10),OFFSET($A:$A,IF(D2-4<0,0,D2-4),0,5))
- F 列:消除错误值:
=+IF(ISERROR(E2),"",E2)
请注意,在我的示例中,句子从第 2 行开始
从那里你可以做 VBA 部分,要求用户输入一个词,然后写 VBA 来读取和显示 F 列中的值。