#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
andCells(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. Большое вам спасибо. Это работает как шарм. Очень признателен, я многому научился из этого!