简体   繁体   English

循环VBA中的调用功能

[英]Call function in Loop VBA

My problem is simple for VBA pro. 我的问题很简单,对于VBA pro。 if you can help me to understand please. 如果你能帮我理解的话。 I am trying to call a function which keep only caps in a cell and past the result in the next column by looping all the rows. 我试图调用一个函数,它只保留一个单元格中的上限,并通过循环所有行超过下一列中的结果。 Please take a look at the code below. 请看下面的代码。 Thank you. 谢谢。

Option Explicit
Sub LLOP()
Dim i As Integer
i = 1
Do While Cells(i, 10).Value <> ""
Cells(i, 11).Value = Cells(i, 10).Value = ExtractCap
i = i + 1
Loop

End Sub


Option Explicit

Function ExtractCap(Txt As String) As String

Application.Volatile
Dim xRegEx As Object
Set xRegEx = CreateObject("VBSCRIPT.REGEXP")
xRegEx.Pattern = "[^A-Z]"
xRegEx.Global = True
ExtractCap = xRegEx.Replace(Txt, "")
Set xRegEx = Nothing

End Function

Try something like as follows. 尝试如下的内容。 Notes to follow. 要注意的事项。

1) Extract cap requires an argument which is the string you want to replace. 1)Extract cap需要一个参数,该参数是您要替换的字符串。 I have used the value in the adjacent column 我使用了相邻列中的值

2) Option Explicit should only occur once at the top of the module 2)Option Explicit只应出现在模块顶部一次

3) As you are looping rows uses Long not Integer to avoid potential overflow 3)当您循环行时,使用Long not Integer来避免潜在的溢出

4) Comparison with vbNullString is faster than empty string literal "" 4)与vbNullString的比较比空字符串文字“”快

Edit: 编辑:

5) See @Jeeped's comment re Static xRegEx As Object followed by if xregex is nothing then Set xRegEx = CreateObject("VBSCRIPT.REGEXP") which significantly improves performance when called in a loop as the regex object only gets created once 5)请参阅@ Jeeped的评论re静态xRegEx As Object后跟if xregex什么都没有,然后设置xRegEx = CreateObject(“VBSCRIPT.REGEXP”),这在循环中调用时显着提高了性能,因为正则表达式对象只被创建一次

Option Explicit
Sub LLOP()

    Dim i As Long
    i = 1

    With ThisWorkbook.Worksheets("Sheet1") 'change as appropriate

    Do While .Cells(i, 10).Value <> vbNullString 'column J
        .Cells(i, 11).Value = ExtractCap(.Cells(i, 10).Text) 'column K
        i = i + 1
    Loop

    End With

End Sub


Public Function ExtractCap(Txt As String) As String

    Application.Volatile
    Dim xRegEx As Object
    Set xRegEx = CreateObject("VBSCRIPT.REGEXP")
    xRegEx.Pattern = "[^A-Z]"
    xRegEx.Global = True
    ExtractCap = xRegEx.Replace(Txt, vbNullString)

End Function

Assuming that you want to enter a custom =ExtractCap() formula in the 11. column, with a parameter of the 10. column, this is a possible solution: 假设您要在11.列中输入custom =ExtractCap()公式,并使用10.列的参数,这是一个可能的解决方案:

Option Explicit

Sub LLOP()

    Dim i As Long: i = 1
    Do While Cells(i, 10).Value <> ""
        Cells(i, 11).Formula = "=ExtractCap(""" & Cells(i, 10) & """)"
        i = i + 1
    Loop
End Sub

Function ExtractCap(Txt As String) As String

    Application.Volatile
    Static xRegEx As Object
    If xRegEx Is Nothing Then Set xRegEx = CreateObject("VBSCRIPT.REGEXP")
    xRegEx.Pattern = "[^A-Z]"
    xRegEx.Global = True
    ExtractCap = xRegEx.Replace(Txt, "")

End Function

The .Formula passes the function ExtractCap as a formula with its parameter of Cells(i, 10) . .Formula将函数ExtractCap作为公式传递,其参数为Cells(i, 10)

Try below alternative code. 请尝试以下替代代码。 Your method is complicated and uses regular expressions (which is nice, but in your case, ineffective). 你的方法很复杂,并使用正则表达式(这很好,但在你的情况下,无效)。

The code: 编码:

Option Explicit
Sub LLOP()
Dim i As Integer
i = 1

'indentation! in your original code, you didn't have proper indentation
'I know that VBA editor don't indent code automatically, but it's worth the effort
Do While Cells(i, 10).Value <> ""
    ' invalid syntax!
    ' first, this is kind of multiple assignment (I don't know what are you trying to do)
    ' secondly, you call your function without arguments
    ' Cells(i, 11).Value = Cells(i, 10).Value = ExtractCap
    ' I guess you wanted something like this
    Cells(i, 11).Value = ExtractCap(Cells(i, 10).Value)
    'or using my function:
    Cells(i, 11).Value = SimpleExtractCap(Cells(i, 10).Value)
    i = i + 1
Loop

End Sub

'THIS IS YOUR FUNCTION, which is complicated (unnecessarily)
Function ExtractCap(Txt As String) As String

Application.Volatile
Dim xRegEx As Object
Set xRegEx = CreateObject("VBSCRIPT.REGEXP")
xRegEx.Pattern = "[^A-Z]"
xRegEx.Global = True
ExtractCap = xRegEx.Replace(Txt, "")
Set xRegEx = Nothing

End Function

'this is my alternative to your function, which is very simple and basic
Function SimpleExtractCap(Txt As String) As String
SimpleExtractCap = ""
Dim i As Long, char As String
For i = 1 To Len(Txt)
    char = Mid(Txt, i, 1)
    'if we have upper-case letter, then append it to the result
    If isLetter(char) And char = UCase(char) Then
        SimpleExtractCap = SimpleExtractCap & char
    End If
Next
End Function

Edit: 编辑:

In order to check if given character is letter, you'll need additional function: 为了检查给定的字符是否为字母,您需要额外的功能:

Function isLetter(letter As String) As Boolean
Dim upper As String
upper = UCase(letter)
isletter = Asc(upper) > 64 And Asc(upper) < 91
End Function

Now, I added this function to code, to check if character is letter. 现在,我将此函数添加到代码中,以检查字符是否为字母。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM