Как я могу ссылаться на имя листа в vba, где имя имеет другой номер

#excel #vba #range

Вопрос:

Я пытаюсь ссылаться на диапазон листов с общим именем и уникальным номером, используя vba, чтобы указать диапазон на каждом листе. Но я получаю ошибку 1004.

 For lngWeek = 1 To 53
    strSheet = "Week" amp; Trim(Str(lngWeek))
    strRange = strSheet amp; "!B5:H7"
    Range(strRange).Activate
Next
 

Листы-Неделя 1, Неделя 2 и т. Д., И мне нужно очистить диапазоны B5:H7 на каждом листе. Весь путь от недели 1 до недели 53.

Почему такой диапазон.Активировать не удается выбрать каждую страницу?

Комментарии:

1. Тебе это и не нужно Activate . ThisWorkbook.Worksheets("Week" amp; lngWeek).Range("B5:H7").ClearContents .

2. Используйте CStr, а не Str. Прочитайте документы, чтобы узнать, почему.

3. Тебе это даже не нужно CStr . amp; принудительное объединение строк .

4. Нет необходимости CStr , @BigBen, но «говорите то, что вы имеете в виду, и подразумевайте то, что вы говорите» для большей ясности в коде

5. @FreeMan amp; делает то, что он говорит.

Ответ №1:

Здесь вы получаете ошибку 1004:

 Range(strRange).Activate
 

Потому strRange что имеет квалификацию листа, но Range это не так; это неявная ссылка на таблицу активов, которая означает Range.Activate , что вызов члена может работать только тогда, когда strRange ссылается на ячейку, которая уже находится в списке ActiveSheet . Предложение: переименовать strRange в cellAddress или во что-то действительно значимое. «str»-для-строки бесполезно; «о, это адрес»; -)

Чтобы иметь возможность выбрать конкретный Range , вы должны сначала разыменовать Worksheet объект, с которым вы собираетесь работать, — где sheetName содержится имя рабочего листа:

 Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(sheetName)
 

И тогда strRange адрес больше не нуждается в WeekXX! части:

 ws.Activate
ws.Range("B5:H7").Select
 

Обратите внимание, что если это не для удобства пользователя, существует, как правило, практически нет причин когда-нибудь Select или Activate что-нибудь в VBA: когда вы правильно квалифицировать все объекты, с которыми вы работаете вы не будете получать ошибку 1004 при этом ActiveSheet не окрашенный код предполагает активное, потому что код больше не будет, при условии, что лист является активным.

Комментарии:

1. Спасибо тебе, Матье. Я человек старой закалки, и для меня тип переменной также полезен: «О, это и адрес» бесполезно, так как это может быть длинное число, короткое число, двойное число, строка или многие другие типы переменных. Я поставил str впереди, чтобы показать, что переменная диапазона является строкой. Но спасибо за разъяснение причины ошибки 1004.

2. @tmd63, если ты так говоришь. К вашему сведению, венгерская нотация повсеместно отбрасывается и сильно не поощряется в каждом отдельном типизированном языке программирования, и ее упрямое глубоко укоренившееся использование в VBA и VB6 во многом способствует тому, что VBA и VB6 являются самыми страшными языками из существующих. Я бы настоятельно рекомендовал прочитать, чтобы Неправильный код выглядел неправильно , что объясняет, как и почему появилась венгерская нотация, и как и почему венгерская нотация, сделанная правильно , вообще не является «str-для-строки» или «lng-для-long». Ваше здоровье!

3. Также Ctrl i дает вам тип данных всего, на чем находится курсор, FWIW, и ни одна переменная не должна быть объявлена вне поля зрения из-за ее использования.

4. Как неутомимый и почти миссионерский коммуникатор базового понимания часто игнорируемых или даже игнорируемых основ кода, вы заслуживаете un grand merci ! — Я искренне надеюсь, что суть ваших ценных комментариев и статей — может найти выражение на официальных сайтах справки , где поколения пользователей потенциально вводят в заблуждение, потому что ссылки на полный спектр, по-видимому, широко неизвестны. @MathieuGuindon

Ответ №2:

Если вы хотите очистить один и тот же диапазон на любом листе с именем формы «Неделя#», вы можете просмотреть все листы и действовать только на тех, имя которых соответствует правильному формату.

 Sub ClearSpecial()
Dim ASheet As Worksheet
Dim ToClear As Boolean

For Each ASheet In ActiveWorkbook.Worksheets
    ToClear = Left(ASheet.Name, 4) = "Week" ' add more conditions if needed
    If ToClear Then
        ASheet.Range("B5:H7").ClearContents
    End If
Next ASheet

End Sub
 

Если, например, есть также рабочий лист под названием «Еженедельное резюме», вы можете расширить свой тест, чтобы исключить и это.

Комментарии:

1. Спасибо. Я использовал это в коде кнопки, это занимает некоторое время, но работает прекрасно (есть страницы за 52 недели и 12 месяцев плюс несколько других).