wsConfig
не требуется. Дайте этому листу кодовое имя например ConfigSheet
, а затем используйте это имя идентификатора в своем коде всякий раз, когда вам нужно обратиться к этому указанному c листу. Обратите внимание, что вы можете сделать это только с листами, которые существуют в ThisWorkbook
во время компиляции; см. мою статью CodeName: Sheet1 для получения дополнительной информации.
Проблема One заключается во вложении квалифицированных и неквалифицированных вызовов Worksheet
членов; вызовы квалифицированных членов выполняются для квалифицируемого объекта Worksheet
, но вложенные неквалифицированные ссылаются на независимо от того, что ActiveSheet в это время происходит , и если это не объект Worksheet
, который квалифицируется вызов внешнего члена, тогда вы можете ожидать ошибку 1004. Инструмент анализа кода stati c от Rubberduck помечает эти неквалифицированные вызовы члена как неявные ссылки ActiveSheet .
wb.Worksheets("Roster").Range(Cells(wsConfig.Range("B4")), _
............................................................................
^ workbook qualifier ^ Worksheet member call (unqualified)
^ Workbook member call ^ worksheet qualifier
^ Worksheet member call
Неквалифицированные Cells
вызовы участников не обязательно идут вразрез с листом wb.Worksheets("Roster")
, , но они явно означают . Это следует сделать явным.
Блок With
может решить эту проблему:
With wb.Worksheets("Roster")
.Range(.Cells(ConfigSheet.Range("B4").Value, ConfigSheet.Range("B2".Value)) ...
End With
... но это не идеально, потому что теперь все неявно связано с поздним связыванием, потому что Worksheets
возвращает Object
и теперь мы теряем проверку во время компиляции.
Лучше всего объявить для нее локальную переменную ... и теперь компилятор начнет жаловаться на вызов Worksheet.Range
, который имеет 3 аргумента, вместо закрывать глаза (благодаря неявному позднему связыванию) и взрываться только во время выполнения:
Dim rosterSheet As Worksheet
Set rosterSheet = wb.Worksheets("Roster")
Dim idSheet As Worksheet
Set idSheet = wb.Worksheets("Sharepoint IDs")
With rosterSheet
.Range(.Cells(ConfigSheet.Range("B4").Value, _
.Cells(ConfigSheet.Range("B2").Value), _
.Cells(lastRow, .Cells(ConfigSheet.Range("B2").Value) _
.Copy Destination:=idSheet.Cells(1, 1)
End With
Worksheet.Range
принимает 1 или 2 аргумента: при наличии двух аргументов ожидается, что первая - это верхняя левая ячейка, а вторая - нижняя правая ячейка нужного прямоугольника angular, непрерывный диапазон ячеек.
Я не могу угадать, какой диапазон c вы указали пытаюсь скопировать, но это то, что происходит. В вашем сообщении недостаточно информации, чтобы найти действующий рабочий код; Я предполагаю, что lastrow
это то, что B4 говорит в листе конфигурации. Если это так, то может быть таким:
Dim configColumn As Long
configColumn = ConfigSheet.Range("B2").Value
Debug.Assert configColumn > 0
Dim configRow As Long
configRow = ConfigSheet.Range("B4").Value
Debug.Assert configRow > 0
With rosterSheet
.Range(.Cells(2, configColumn), .Cells(configRow, configColumn)) _
.Copy Destination:=idSheet.Cells(1, 1)
End With
Избегать ненужного вложения вызовов Range
и Cells
и всегда явно указывать их с помощью ссылки на объект Worksheet
; также избегайте продолжения строки, которая не является полным, полным, допустимым утверждением - спасибо за то, что не разбил именованный аргумент Destination:=
на несколько строк.