#excel #vba
#excel #vba
Вопрос:
Проблема: нужно иметь возможность проверять диапазон или отдельную ячейку, чтобы увидеть, пуста ли она.
Мой код для замены любого текста флажком выглядит следующим образом:
Private Sub Worksheet_Change(ByVal Target As Range)
' If the range (as defined in the next line) is changed to anything but a blank, replace it with a check mark.
If Not Intersect(Range(Target.Address), Range("C6:C60")) Is Nothing Then
On Error GoTo ErrorOut
Application.EnableEvents = False
If Application.WorksheetFunction.IsText(Range(Target.Address)) Then
Range(Target.Address).Value = "P"
Range(Target.Address).Font.Name = "Wingdings 2"
End If
Application.EnableEvents = True
End If
Exit Sub
ErrorOut:
Debug.Print "Error"
Application.EnableEvents = True
End Sub
Это работает. Но, если пользователь выбирает более одной ячейки и удаляет их, обработка ошибок вступает во владение. Не проблема, потому что это работает, но должен быть способ получше.
Я успешно делал это, когда хотел проверить наличие чисел с помощью If IsNumeric(Range(Target.Address)) Then
. Это работает правильно, если сразу удаляется несколько ячеек. Но IsText
or IsEmpty
, похоже, ведет себя не совсем так, IsNumeric
и одновременное удаление нескольких ячеек приводит к ошибке.
Комментарии:
1. Вы можете выполнить цикл через Target или выйти из sub, если Target. Количество> 1.
2. FWIW
Range(Target.Address)
выдает вам точно такой жеRange
объект, которыйTarget
выполняется в одиночку, предполагая, чтоTarget
он находится в activesheet (в противном случае у вашего кода возникает ряд проблем из-за всех этих неквалифицированныхRange
вызовов элементов)3.
IsEmpty
используется для оценки того,Variant
являетсяvbEmpty
ли a, т. е. является ли его подтипVariant/Empty
. Это будет толькоTrue
для одной ячейки, которая.Value
не содержит буквально ничего (ни формулы, ни значения, ни пустой строки, вообще ничего ) — в терминах Excel, это и есть «пустая» ячейка.4. @MathieuGuindon Спасибо за совет по
Target
, очень приятно знать. И ваше объяснение поIsEmpty
тоже хорошее.
Ответ №1:
Рассмотрим:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range, r As Range, rIntersect As Range
Dim wf As WorksheetFunction
Set rng = Range("C6:C60")
Set rIntersect = Intersect(Target, rng)
Set wf = Application.WorksheetFunction
If rIntersect Is Nothing Then Exit Sub
Application.EnableEvents = False
For Each r In rIntersect
If wf.CountA(r) = 1 Then
r.Value = "p"
r.Font.Name = "Wingdings 2"
End If
Next r
Application.EnableEvents = True
End Sub
Мы перебираем Intersection
по одной ячейке за раз. Кстати, я использую:
r.Value = "a"
r.Font.Name = "Marlett"
Комментарии:
1. И хороший совет по шрифту Marlett. Для Wingdings 2 необходима заглавная буква P.
2. @Donovan Использование разумных имен переменных облегчает понимание логики.