Могу ли я вкладывать букву «С» в букву «С», когда оба обозначают разные листы в одной и той же книге?VBA - PullRequest
2 голосов
/ 26 сентября 2019

По сути, у меня есть книга, которая импортирует значения из одного листа, затем позволяет выбрать некоторые, добавить дополнительные данные, затем перенести выбранные элементы, добавленные значения и дополнительную информацию, содержащуюся на листе, значения которого извлекаютсяИзначально в другую рабочую книгу.Мне нужно иметь возможность сопоставить значения внутри исходного листа с соответствующей информацией на другом листе (в той же книге), чтобы я мог взять данные из обоих и зациклить их. Я беспокоюсь, что мне не разрешено вложитьМои С, когда они оба обозначают рабочие листы в одной и той же книге, потому что я продолжаю получать сообщение об ошибке 91 (переменная объекта или переменная блока не установлены).Это правда?

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

Ответы [ 3 ]

1 голос
/ 26 сентября 2019

В вашем коде много проблем, ни одна из которых не имеет ничего общего с блоками 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
1 голос
/ 26 сентября 2019

Если вы находитесь в блоке With и ваш код вводит секунду With (без первого попадания End With), тогда область действия, определенная вторым With, становится активной областью, пока вы не нажметеEnd With (или другое With)

With A
   'scope here is A
   With B
       'scope here is B
   End with
   'scope here is A
End With
0 голосов
/ 26 сентября 2019

Более правильный ответ на этот вопрос заключается в том, что конструкция With должна быть направлена ​​на простую последовательность методов получения и установки объекта.

Хорошим примером этого является объект Word Find, где приведенный ниже код является общим

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

Использование

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
...