VBA — объявление и настройка диапазона с вложенными предварительно объявленными переменными (ошибка времени выполнения ’91’:)

#excel #vba #runtime-error

#excel #vba #время выполнения-ошибка

Вопрос:

Первый запрос здесь!

Я хочу определить свой фрейм данных на листе Excel. Однако, когда я пытаюсь установить диапазон, я получаю ошибку 91 во время выполнения.

 Dim i As Long
Dim WSCount As Long
WSCount = Application.ActiveWorkbook.Worksheets.Count

For i = 1 To WSCount Step 1

Select Case Worksheets(i).Name

Case "Page1_1", "Page2_2", "Written", "Waived", "Earned"

Dim LR As Long
LR = Worksheets(i).Cells(Rows.Count, 1).End(xlUp).Row   1
Dim LC As Long
LC = Worksheets(i).Cells(1, Columns.Count).End(xlToLeft).Column
Dim DataFrame As Range
**DataFrame = Worksheets(i).Range("A2").Resize(LR, LC)**

DataFrame.ClearContents


End Select

Next i
  

Оба LR и LC генерируют правильный ответ.

Однако, когда я пытаюсь объявить Dataframe как диапазон, а затем установить Dataframe, как указано ниже, я получаю ошибку, которую я не могу понять…

«Ошибка времени выполнения ’91’: переменная объекта или переменная блока не установлена»

Кто-нибудь знает, в чем проблема?

Заранее благодарен!

Артур

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

1. Предполагая, что вы хотите начать с A1 простого использования Set Dataframe = Range("A1").Resive(LR, LC) — ничего плохого в вашем методе, это просто кажется проще. У вас также есть неквалифицированные объекты, и вы полагаетесь на Active объекты, которые иногда могут быть грязными. Лучше быть явным.

2. @urdearboy Относительно неквалифицированного объекта; Я хочу Dataframe.clearcontents, а затем перебирать листы с выбором регистра на основе имени листа. Таким образом, я думаю, что мне нужно будет сохранить объекты activeworkbook и activesheet

3. Устанавливайте рабочие листы по ходу работы

4. Какая строка выдает ошибку? Я подозреваю, что проблема связана с вашим неквалифицированным Cells объектом. Однако кода, который у вас здесь, недостаточно, чтобы знать. Предоставьте больше соответствующего кода…

5. Почему вы используете Row 1 and Cells(2, LC) ? Я имею в виду 1 и 2 ?

Ответ №1:

Фрейм данных

  • Чтобы полностью определить диапазон так, как вы его «создаете», вам необходимо выполнить следующее:

     Set DataFrame = ThisWorkbook.Worksheets("Sheet1").Range(ThisWorkbook.Worksheets("Sheet1").Cells(2, 1), ThisWorkbook.Worksheets("Sheet1").Cells(LR, LC))
      
  • Чтобы избежать предыдущего, вы можете использовать With инструкцию, которая также позволяет вам легко изменять рабочий лист только в одном месте.

  • Обратите внимание на точки (.) перед Range , Cells , Rows и Columns .

Код

 Option Explicit

Sub df()
    
    Dim LR As Long
    Dim LC As Long
    Dim Dataframe As Range
    
    With ActiveWorkbook.ActiveSheet
        LR = .Cells(.Rows.Count, 1).End(xlUp).Row
        LC = .Cells(1, .Columns.Count).End(xlToLeft).Column
        ' Explicitly: note the '2'.
        Set Dataframe = .Range(.Cells(2, 1), .Cells(LR, LC))
        ' Implicitly i.e. you have the full range incl. the headers:
        ' Define 'full' range.
        'Dim rng As Range
        'Set rng = .Range(.Cells(1, 1), .Cells(LR, LC))
        ' Resize and offset to exclude the headers.
        'Set Dataframe = rng.Resize(rng.Rows.Count - 1).Offset(1)
    End With
    
    Dataframe.Select

End Sub
  

Редактировать:

  • Вот как я бы написал ваш код, используя For Each Next цикл и Application.Match массив имен рабочих листов.
  • Это не чувствительно к регистру, как ваша Select Case версия, поэтому я могу иметь, например WriTTeN , и рабочий лист все равно будет найден.
  • Dataframe Переменная не нужна.
  • Это 2 указывает на то, что диапазон будет начинаться со второй строки, сохраняющей заголовки.

Код

 Sub df2()
        
    Dim wsNames As Variant
    wsNames = Array("Page1_1", "Page2_2", "Written", "Waived", "Earned")
    
    Dim ws As Worksheet
    Dim LR As Long
    Dim LC As Long
    
    For Each ws In ActiveWorkbook.Worksheets
        If Not IsError(Application.Match(ws.Name, wsNames, 0)) Then
            LR = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
            LC = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
            ws.Range(ws.Cells(2, 1), ws.Cells(LR, LC)).ClearContents
        End If
    Next ws

End Sub
  

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

1. Большое вам спасибо. Это работает как шарм. Очень признателен, я многому научился из этого!