【问题标题】:Two criteria checking in VBAVBA中的两个标准检查
【发布时间】:2017-11-21 11:00:48
【问题描述】:

我有这个 VBA 宏,它在一个范围内搜索“SV”并用某个值(“PEL-SVFC”)更新另一个单元格。我想要扩展它,所以它只在它本身包含另一个值(PEL-CD)的情况下更新该单元格,然后再更改它,但我收到类型不匹配错误。

以下是宏、当前的工作版本以及引发类型不匹配错误的版本:

Sub Update3011()
'Update various values in the 3011

'Define some variables
Dim PromoNameColumn As Range
Dim PromoNameColumnAsArray As Variant

Dim AccountNameColumn As Range
Dim AccountNameColumnAsArray As Variant

Dim i As Long

'First action: search cells in column W for text containing "SV". Of those matches, if the cell in column D of that row matches "PEL-CD", replace it with "PEL-SVFC".

Set PromoNameColumn = Range("W2:W" & ThisWorkbook.Worksheets("3011").UsedRange.Rows.Count)
PromoNameColumnAsArray = PromoNameColumn  ' PromoNameColumnAsArray is now array

Set AccountNameColumn = Range("D2:D" & ThisWorkbook.Worksheets("3011").UsedRange.Rows.Count)
AccountNameColumnAsArray = AccountNameColumn  ' AccountNameColumnAsArray is now array

For i = LBound(PromoNameColumnAsArray, 1) To UBound(PromoNameColumnAsArray, 1)

    If InStr(1, PromoNameColumnAsArray(i, 1), "SV") Then 'If the range "W2:2" contains SV and the range "D2:D" contains "PEL-CD", continue
        AccountNameColumnAsArray(i, 1) = "PEL-SVFC"
    End If

Next

AccountNameColumn = AccountNameColumnAsArray

MsgBox ("3011 updated.")

End Sub

还有不工作的:

Sub Update3011()
'Update various values in the 3011

'Define some variables
Dim PromoNameColumn As Range
Dim PromoNameColumnAsArray As Variant

Dim AccountNameColumn As Range
Dim AccountNameColumnAsArray As Variant

Dim i As Long

'First action: search cells in column W for text containing "SV". Of those matches, if the cell in column D of that row matches "PEL-CD", replace it with "PEL-SVFC".

Set PromoNameColumn = Range("W2:W" & ThisWorkbook.Worksheets("3011").UsedRange.Rows.Count)
PromoNameColumnAsArray = PromoNameColumn  ' PromoNameColumnAsArray is now array

Set AccountNameColumn = Range("D2:D" & ThisWorkbook.Worksheets("3011").UsedRange.Rows.Count)
AccountNameColumnAsArray = AccountNameColumn  ' AccountNameColumnAsArray is now array

For i = LBound(PromoNameColumnAsArray, 1) To UBound(PromoNameColumnAsArray, 1)

    If InStr(1, PromoNameColumnAsArray(i, 1), "SV") And InStr(1, AccountNameColumnAsArray(i, 1), "PEL-CD") Then 'If the range "W2:2" contains SV and the range "D2:D" contains "PEL-CD", continue
        AccountNameColumnAsArray(i, 1) = "PEL-SVFC"
    End If

Next

AccountNameColumn = AccountNameColumnAsArray

MsgBox ("3011 updated.")

End Sub

因此,导致错误的位是if 语句中的And InStr(1, AccountNameColumnAsArray(i, 1), "PEL-CD"),这是代码块之间唯一不同的地方。

如何在更新单元格之前修改此代码以添加额外的逻辑检查?

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    您的代码应该可以工作。如果 D 或 W 列中的任何单元格包含错误值,则它不会仅在一种情况下起作用。你的数据是这样的吗?

    如果是,您可以添加另一个条件来检查这两列中的值是否不是错误值。

    For i = LBound(PromoNameColumnAsArray, 1) To UBound(PromoNameColumnAsArray, 1)
    
        If Not IsError(PromoNameColumnAsArray(i, 1)) And Not IsError(AccountNameColumnAsArray(i, 1)) Then
            If InStr(1, PromoNameColumnAsArray(i, 1), "SV") > 0 And InStr(1, AccountNameColumnAsArray(i, 1), "PEL-CD") > 0 Then 'If the range "W2:2" contains SV and the range "D2:D" contains "PEL-CD", continue
                AccountNameColumnAsArray(i, 1) = "PEL-SVFC"
            End If
        End If
    Next
    

    【讨论】:

    • @YowE3K Instr 不需要 >0 来检查 True。如果它找到正在搜索的字符串,它将被评估为 True,否则为 False。
    • 啊……这很有道理。现在我明白你在说什么了。接得好。 :)
    【解决方案2】:

    InStr 返回找到您要搜索的字符串的索引,例如

    InStr(1, "_PEL-CD_", "PEL-CD")
    

    将返回 2。

    在您的第一个代码中,您真的很幸运,它在索引 1 处找到“SV”,幸运的是,VBA 将 1 理解为 True,因此当您要求 VBA 将 1 和 2 评估为布尔值时,它将返回一个错误。

    只需将第二个宏中的代码更改为

    If InStr(1, PromoNameColumnAsArray(i, 1), "SV") > 0 And InStr(1, AccountNameColumnAsArray(i, 1), "PEL-CD") < 0 Then
    

    会解决的。

    【讨论】:

    • FWIW - 1 And 2 不会产生错误 - 它将返回 0,相当于 False。虽然True 在转换为数字类型时会转换为-1,但任何非零值在转换为布尔值时都会转换为True
    • 这样就解释了当我将非零数传递给 IF 时的行为。谢谢你的澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 2016-07-01
    • 1970-01-01
    相关资源
    最近更新 更多