首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用VBA在包含特定字符的范围内复制单元格。

使用VBA在包含特定字符的范围内复制单元格。
EN

Stack Overflow用户
提问于 2017-10-12 12:36:54
回答 3查看 1K关注 0票数 0

我需要能够将包含特定字符的单元格从一列复制到另一列。在本例中,它们是^和*字符可以按单元格中的任意顺序排列。

以下是一个例子:

如果我没有弄错的话,我似乎可以使用VBA中的InStr函数来完成这一任务。

为列表中的每一项运行一个循环,并使用如下所示的内容检查它:

代码语言:javascript
运行
复制
IF InStr(1,Range("A" & i), "^") <> 0 AND InStr(1, Range("A" & i), "*") <> 0 THEN

'copy cell to another place

End If

还是有一个更优雅的解决方案?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-10-12 12:56:56

我无法看到您的图像形式,但Like通常比Instr()更容易和更快。你可以试试这样的方法:

代码语言:javascript
运行
复制
If Range("A" & i) Like "*[*^]*[*^]*" Then

意思是你寻找一些文本,然后*或^,更多的文本,然后*或*,更多的文本

有关详细语法,请参阅这里

票数 4
EN

Stack Overflow用户

发布于 2017-10-12 13:05:43

无循环选项-使用ArraysFilter

代码语言:javascript
运行
复制
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

或用作具有无限字符搜索的函数。

代码语言:javascript
运行
复制
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
代码语言:javascript
运行
复制
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
票数 2
EN

Stack Overflow用户

发布于 2017-10-12 13:17:57

编辑

再看看这个,被汤姆关于过滤的答案所启发,它开始思考.AdvancedFilter可以做你想要做的事情。它是在Excel的电子表格端设计的,但是您可以从VBA中使用它。

如果您只想在VBA之外工作,或者您的过滤器不会经常更改,那么这可能不是您的最佳选择。但是,如果您希望从工作簿方面获得更直观、更灵活的东西,这将是一个很好的选择。

手动运行Advanced Filter**...**的

示例代码和动态筛选方案.

(请注意,您可以使用它的方程式)

代码语言:javascript
运行
复制
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,并且它将动态更新。

原始邮政

下面是一些来自我写的类似的帖子的“容忍”我写的类似的帖子函数的代码..。它不完全适合您的例子,但它得到了基本点的字符逐字分析。

代码语言:javascript
运行
复制
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中,但它正是为强大的复杂匹配而设计的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46709788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档