我需要能够将包含特定字符的单元格从一列复制到另一列。在本例中,它们是^和*字符可以按单元格中的任意顺序排列。
以下是一个例子:
如果我没有弄错的话,我似乎可以使用VBA中的InStr函数来完成这一任务。
为列表中的每一项运行一个循环,并使用如下所示的内容检查它:
IF InStr(1,Range("A" & i), "^") <> 0 AND InStr(1, Range("A" & i), "*") <> 0 THEN
'copy cell to another place
End If
还是有一个更优雅的解决方案?
发布于 2017-10-12 12:56:56
我无法看到您的图像形式,但Like
通常比Instr()
更容易和更快。你可以试试这样的方法:
If Range("A" & i) Like "*[*^]*[*^]*" Then
意思是你寻找一些文本,然后*或^,更多的文本,然后*或*,更多的文本
有关详细语法,请参阅这里。
发布于 2017-10-12 13:05:43
无循环选项-使用Arrays
和Filter
Option Explicit
Sub MatchCharacters()
Dim src As Variant, tmp As Variant
Dim Character As String, Character2 As String
Character = "*"
Character2 = "^"
' Replace with your sheetname
With Sheet1
src = Application.Transpose(Range(.Cells(2, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1)))
tmp = Filter(Filter(src, Character), Character2)
.Range(.Cells(2, 3), .Cells(.Cells(1, 3).End(xlDown).Row, 3)).ClearContents
If UBound(tmp) > -1 Then
With .Cells(2, 3)
Range(.Offset(0, 0), .Offset(UBound(tmp), 0)).Value2 = Application.Transpose(tmp)
End With
End If
End With
End Sub
或用作具有无限字符搜索的函数。
Public Function MatchCharacters(arr As Variant, ParamArray Characters() As Variant) As Variant
Dim i As Long
For i = LBound(Characters) To UBound(Characters)
arr = Filter(arr, Characters(i))
Next i
MatchCharacters = arr
End Function
Sub test()
Dim tmp As Variant
With Sheet1
tmp = Application.Transpose(Range(.Cells(2, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1)))
tmp = MatchCharacters(tmp, "*", "^")
If UBound(tmp) > -1 Then
With .Cells(2, 3)
Range(.Offset(0, 0), .Offset(UBound(tmp), 0)).Value2 = Application.Transpose(tmp)
End With
End If
End With
End Sub
发布于 2017-10-12 13:17:57
编辑
再看看这个,被汤姆关于过滤的答案所启发,它开始思考.AdvancedFilter
可以做你想要做的事情。它是在Excel的电子表格端设计的,但是您可以从VBA中使用它。
如果您只想在VBA之外工作,或者您的过滤器不会经常更改,那么这可能不是您的最佳选择。但是,如果您希望从工作簿方面获得更直观、更灵活的东西,这将是一个很好的选择。
手动运行Advanced Filter
**...**的
示例代码和动态筛选方案.
(请注意,您可以使用它的方程式)
Sub RunCopyFilter()
Dim CriteriaCorner As Integer
CriteriaCorner = Application.WorksheetFunction.Max( _
Range("B11").End(xlUp).Row, _
Range("C11").End(xlUp).Row, _
Range("D11").End(xlUp).Row)
[A4:A10].AdvancedFilter xlFilterCopy, Range("B4:D" & CriteriaCorner), [E4:E10], True
End Sub
命名为Ranges
AdvancedFitler自动为它的标准和输出创建NamedRanges。这很方便,因为您可以将NamedRange引用为Extract
,并且它将动态更新。
原始邮政
下面是一些来自我写的类似的帖子的“容忍”我写的类似的帖子函数的代码..。它不完全适合您的例子,但它得到了基本点的字符逐字分析。
Function InStrTolerant(InputString As String, MatchString As String, Optional CaseInsensitiveChoice = False, Optional Tolerance As Integer = 0) As Integer
'Similar to InStr, but allows for a tolerance in matching
Dim ApxStr As String 'Approximate String to Construct
Dim j As Integer 'Match string index
j = 1
Dim Strikes As Integer
Dim FoundIdx As Integer
For i = 1 To Len(InputString)
'We can exit early if a match has been found
If StringsMatch(ApxStr, MatchString, CaseInsensitiveChoice) Then
InStrTolerant = FoundIdx
Exit Function
End If
If StringsMatch(Mid(InputString, i, 1), Mid(MatchString, j, 1), CaseInsensitiveChoice) Then
'This character matches, continue constructing
ApxStr = ApxStr + Mid(InputString, i, 1)
j = j + 1
FoundIdx = i
Else
'This character doesn't match
'Substitute with matching value and continue constructing
ApxStr = ApxStr + Mid(MatchString, j, 1)
j = j + 1
'Since it didn't match, take a strike
Strikes = Strikes + 1
End If
If Strikes > Tolerance Then
'Strikes exceed tolerance, reset contruction
ApxStr = ""
j = 1
Strikes = 0
i = i - Tolerance
End If
Next
If StringsMatch(ApxStr, MatchString, CaseInsensitiveChoice) Then
InStrTolerant = FoundIdx
Else
InStrTolerant = 0
End If
End Function
而且,在这种情况下,我总是觉得有必要提到Regex
。虽然它不是最容易使用的,特别是在VBA中,但它正是为强大的复杂匹配而设计的。
https://stackoverflow.com/questions/46709788
复制相似问题