【问题标题】:Left Function Compile Error: Argument not optional (VBA)左函数编译错误:参数不是可选的(VBA)
【发布时间】:2020-02-19 02:53:18
【问题描述】:

我正在尝试用这个子程序做一些事情。 首先我需要在每 18 行之后插入一行 然后我需要根据上一行中的字符串(即第一次迭代中的第 17 行)在 A 列中插入一个字符串。 最后我需要根据之前建立的字符串在第i行的B列再次插入一个字符串。

所以用外行的话来说,第 17 行会说 120F_CASH 我想找到“_”并从“_”左侧获取字符串中的字符,然后在第 18 行中,我想将 120F 和“_MULTI_STRAT”放入 A 列 在第 18 行的 B 列中,我想插入 "SSELECT PERF.IMST.INDEX WITH ENTITY = " & "120F" & "AND WITH CATEGORY1 = ""01"""

这是我的代码:

Option Explicit

Sub InsertRowEveryXrows()
Dim r As Long, lr As Long
Dim code As String

lr = Range("A" & Rows.Count).End(xlUp).Row
    For r = 18 To lr Step 18
        Rows(r).Insert Shift:=xlDown
        Set code = Left(Range(Cells(r - 1, "A"), InStr(1, "_", Cells(r, "A")) - 1))
        Cells(r, "A") = code & "_MULTI_STRAT"
        Cells(r, "B") = "SSELECT PERF.IMST.INDEX WITH ENTITY = " & code & "AND WITH CATEGORY1 = ""01"""
    Next r
End Sub

我收到一个编译错误:此行上的参数数量错误或属性分配无效:

设置代码 = Left(Range(Cells(r - 1, "A"), InStr(1, "_", Cells(r, "A")) - 1))

字符串的位置在 A 列的第 17 行 (r-1) 中,通过查找“_”找到字符数

我错过了什么? *仅供参考,我必须在下划线后添加一个空格才能在此处正确显示,但是,下划线后不应有空格。

【问题讨论】:

  • 删除集。 Set 仅在分配给引用变量(例如对象)时使用。字符串不是引用变量。
  • 我认为你的括号也是错误的 Range(Cells(r - 1, "A") 需要是 Cells(r - 1, "A") 或只是 split(Cells(r - 1, "A"),"_")(0)

标签: excel vba


【解决方案1】:
Set code = Left(Range(Cells(r - 1, "A"), InStr(1, "_", Cells(r, "A")) - 1))

Left 函数需要一个字符串和一个整数,但您没有提供整数。这是相同的表达式,没有外部 Left 函数调用:

Set code = Range(Cells(r - 1, "A"), InStr(1, "_", Cells(r, "A")) - 1)

注意到什么了吗? InStr 的结果作为第二个参数传递给(不合格的)Range 属性,这不是您想要的。

事实上,您根本不需要Range 调用。这应该更接近您的意图:

Set code = Left(Cells(r - 1, "A"), InStr(1, "_", Cells(r, "A")) - 1)

请注意,这里有相当多的隐式代码;明确表示,如下所示:

Set code = Left(ActiveSheet.Cells(r - 1, "A").Value, InStr(1, "_", ActiveSheet.Cells(r, "A").Value) - 1)

您是否真的打算只使用恰好处于活动状态的任何工作表?很可能不会,但如果是这样,请考虑使用ActiveSheet 明确限定这些Cells 调用。如果您打算使用特定工作表,请改用该工作表对象作为限定符。

现在,您使用 Set 进行此分配,但 code 不是对象引用,这是另一个问题。

字符串不是 VBA 中的对象,它们使用常规的赋值语法进行赋值。也就是说,没有 Set 关键字(如果需要,您可以在其中使用旧的 Let 关键字,但它不是必需的):

code = Left(ActiveSheet.Cells(r - 1, "A").Value, InStr(1, "_", ActiveSheet.Cells(r, "A").Value) - 1)

现在,Range.Value(此处显式,代码中隐式)将是 Variant,而不是 String。在大多数情况下,这无关紧要。

直到一个单元格具有Variant/Error 子类型(想想#N/A#VALUE! 工作表错误);然后一切都因 type mismatch 错误而崩溃。为避免这种情况,您可以使用单元格的Text 而不是其Value,或者您可以将该值拉入其自己的本地Variant 变量中,并且仅在IsError 返回时将其视为字符串False 为它。

【讨论】:

    【解决方案2】:

    你可以使用类似的东西

    Function Pop_String(strInput As String, strDelim As String, Optional lngInstance = 1)
    
    Dim aTemp() As String
    
    aTemp = Split(strInput, strDelim, lngInstance + 1)
    
    Pop_String = aTemp(lngInstance - 1)
    
    End Function
    

    这样叫

    Pop_String("a-b-c-d-e-f","-",4) 返回 d Pop_String("a-b-c-d-e-f","-",2) 返回 b

    我也会添加一些错误检查,默认(没有第三个参数)是第一部分,所以

    Pop_String("test-string","-") 将返回测试和 Pop_String("test-string","-",2) 将返回字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多