Excel 当两者在同一工作簿中指定不同的工作表时,是否可以将a嵌套在a中?VBA

Excel 当两者在同一工作簿中指定不同的工作表时,是否可以将a嵌套在a中?VBA,excel,vba,nested,with-statement,Excel,Vba,Nested,With Statement,基本上,我有一个工作簿,它从一个工作表中导入值,然后允许您选择一些值,添加额外的数据,然后将所选项目、您添加的值以及工作表中包含的其他信息传输到另一个工作簿中,这些值最初从工作表中提取。我需要能够将初始工作表中的值与另一个工作表(在同一工作簿中)中的相应信息相匹配,以便从这两个工作表中获取数据并将其循环。我担心在同一工作簿中同时指定工作表时,不允许我嵌套我的With,因为我不断收到错误91(对象变量或With block变量未设置)。这是真的吗 Dim RMs As Worksheet Dim

基本上,我有一个工作簿,它从一个工作表中导入值,然后允许您选择一些值,添加额外的数据,然后将所选项目、您添加的值以及工作表中包含的其他信息传输到另一个工作簿中,这些值最初从工作表中提取。我需要能够将初始工作表中的值与另一个工作表(在同一工作簿中)中的相应信息相匹配,以便从这两个工作表中获取数据并将其循环。我担心在同一工作簿中同时指定工作表时,不允许我嵌套我的With,因为我不断收到错误91(对象变量或With block变量未设置)。这是真的吗

Dim RMs As Worksheet
Dim FLF As Worksheet
Set RMs = Workbooks("FLF Coding Trials.xlsm").Worksheets("Program")
Set FLF = Workbooks("FLF Template.xlsx").Worksheets("FLF Sheet")

Dim lng As Long
Dim cnt As Long
Dim check As Long
Dim length As Long

Dim namecheck As Range
Dim vencheck As Range

With ThisWorkbook.Sheets("Program")
lng = Me.Cells(.Rows.Count, "N").End(xlUp).Row
For cnt = 1 To lng - 1 Step 1
    'The two below lines work reliably
    FLF.Range("B" & cnt + 23).Value = Me.Range("N" & cnt + 1).Value
    FLF.Range("N" & cnt + 23).Value = Me.Range("P" & cnt + 1).Value

    'Adding the following variable designations and the With gives me the error. If I change the below two variables to strings I get a compile error
    namecheck.Value = Range("N" & cnt + 1).Value
    vencheck.Value = Range("P" & cnt + 1).Value

        With ThisWorkbook.Sheets("Names and Vendors")
        length = Me.Cells(.Rows.Count, "B").End(xlUp).Row
        check = ThisWorkbook.Sheets("Names and Vendors").Evaluate("MATCH(1,(B1:B" & length & "=""" & namecheck.Value & """)*(C1:C" & length & "=""" & vencheck.Value & """),0)")
        'more commands will go here
        End With
    Next cnt
End With

如果您处于带的
块中,并且您的代码输入了带
的第二个
(没有先命中带
结束),则第二个带
定义的范围将成为活动范围,直到您命中带
结束(或另一个带
结束)


代码中有许多问题,这些问题都与
块无关

根据一条注释,我假设Me使用
Me指定了作用域中的对象。
应替换为

请参见下面代码中标有
“~~~

Dim RMs As Worksheet
Dim FLF As Worksheet
Set RMs = Workbooks("FLF Coding Trials.xlsm").Worksheets("Program")
Set FLF = Workbooks("FLF Template.xlsx").Worksheets("FLF Sheet")

Dim lng As Long
Dim cnt As Long
Dim check As Long
Dim length As Long

Dim namecheck As Range
Dim vencheck As Range

With ThisWorkbook.Sheets("Program")
    '~~~ .Rows refers to ThisWorkbook.Sheets("Program").Rows
    lng = .Cells(.Rows.Count, "N").End(xlUp).Row '~~~ drop the Me
    For cnt = 1 To lng - 1 Step 1
        'The two below lines work reliably
        '~~~ Me implies this code is in a Worksheet code behind module, and refers to that sheet.  Is this what you intend?
        FLF.Range("B" & cnt + 23).Value = .Range("N" & cnt + 1).Value '~~~ drop the Me
        FLF.Range("N" & cnt + 23).Value = .Range("P" & cnt + 1).Value '~~~ drop the Me

        'Adding the following variable designations and the With gives me the error. If I change the below two variables to strings I get a compile error
        '~~~ there is no reference to the With block in these 2 lines of code
        '~~~ And you havn't Set namecheck or vencheck. Add
        Set namecheck = FLF.Range("B" & cnt + 23) '~~~ or whatever range you actually meant
        Set vencheck = FLF.Range("N" & cnt + 23)
        namecheck.Value = Range("N" & cnt + 1).Value '~~~ the unqualified Range(...) refers to the ActiveSheet.  Maybe should be .Range? 
        vencheck.Value = Range("P" & cnt + 1).Value

        With ThisWorkbook.Sheets("Names and Vendors")
            '~~~ .Rows now refers to ThisWorkbook.Sheets("Names and Vendors").Rows
            length = .Cells(.Rows.Count, "B").End(xlUp).Row '~~~ drop the Me
            '~~~ you can leave out ThisWorkbook.Sheets("Names and Vendors") as this is in the With block for that sheet
            check = .Evaluate("MATCH(1,(B1:B" & length & "=""" & namecheck.Value & """)*(C1:C" & length & "=""" & vencheck.Value & """),0)")
            'more commands will go here
        End With
        '~~~ .Anything now refers to ThisWorkbook.Sheets("Program").Anything again
    Next cnt
End With

对这个问题更正确的答案是With构造应该被重新构造为对象的一个简单的getter和setter序列

一个很好的例子是单词Find object,下面的代码很常见

With ActiveDocument.Content.Find
     .Text = "FindText"
     .Replacement.Text = "ReplaceText"
     .Forward = True
     .Wrap = wdFindStop
     Do While .Execute() = True
         .TypeParagraph
         .MoveLeft Unit:=wdWord, Count:=2, Extend:=wdExtend
         .Find.Replacement.Font.Italic = True
         .Font.Bold = True
         .Collapse Direction:=wdCollapseEnd
     Loop
 End With
解决您提出的问题的更正确方法是使用具有本地范围的适当对象来提供您需要的快捷方式,例如

而不是

With ThisWorkbook.Sheets("Program")

    'Do xyz

End With
使用


既然你实际上没有将第二个
用于
(用于“名称和供应商”),为什么不删除它呢?我会的。我将在其中放置一个循环,以循环其中包含的所有额外数据,如“more commands will go here”(更多命令将转到此处)注释所指定。是的,您可以使用块嵌套,但只能有一个作用范围-这将是与
最接近的
的范围对不起,但是您能详细说明吗?我假设With中包含的内容只能通过End With命令或嵌套另一个With命令来完成(正如我在这里尝试的那样)。以上代码是试用版、模板版还是其他版本?它是在工作表模块中还是在类模块中?上面的代码是如何执行的?上述代码是子代码还是函数?以确定哪一行代码失败。非常感谢。正如你所知道的,我坐在这里,手里拿着一本我朋友借给我的VBA教科书,并使用谷歌尝试将这种语言与我的目的结合起来。我不明白你说“我”是什么意思。我基本上一直用它来指代活动表。我假设我在作用域中指定了对象。我假设我在作用域中指定了对象,但没有。在对Q的评论中,您说代码在一个专用子模块下试用,如果此代码在试用模块中(在VBA编辑器的“Microsoft Excel对象”下列出),则Me指的是试用表。with block对象由一个前导的
(正如您在
Me.Cells(.Rows.Count,“B”).End(xlUp)。Row
)中对
行所做的那样)引用。我能让您为我澄清最后一件事吗?我得到的类型与check=.Evaluate不匹配。。。。。在测试之后,它以namecheck.Value和vencheck.Value为中心。我在其他地方也使用过类似的代码,但由于某些原因,这里没有。尝试重写它,使我的代码使用变体,但这不起作用。这是一行已经可以使用的代码:rw=thispoolk.Sheets(“名称和供应商”)。评估(“匹配(1,(B1:B“&lr&=”&arr(0)&“*(C1:C“&lr&=”&arr(1)&“0)”)此时变量的值是多少?它们是否生成有效的公式字符串?
With ThisWorkbook.Sheets("Program")

    'Do xyz

End With
Dim mySourceWb  as excel.Worksheet
Set mySOurceWb = ThisWorkbook.Sheets("Program")
Dim myDestWb as Excel.Worksheet
Set myDestWB = ADifferentWb.Sheets("YetAnotherSpreadsheet")

'Do xyz

set mySourceWb=nothing
set myDestWb=nothing