Вопрос или проблема
Я выбрал все используемые диапазоны в своем рабочем листе, используя UsedRange.Select
, и хотел исключить только два верхних диапазона. Есть ли способ сделать это?
Предполагая, что выбор был сделан вручную. Если выбор был сделан программно, не делайте это. Вместо этого просто не выделяйте диапазоны, которые не хотите выделять с самого начала.
Нет способа «исключить» диапазон. Что-то должно быть выделено, так что способ сделать это – выбрать диапазон, с которым вы хотите остаться.
Если выбрано несколько ячеек, то объект Selection
содержит ссылку на Range
, которая включает несколько Areas
; вы можете перебирать Areas
и определять, является ли область одной из двух областей в «верхних двух диапазонах», которые вы не хотите оставлять; если это не так, добавьте их в новый объект Range
с помощью Union
, и Select
объединенный диапазон после того, как вы перебрали все области – на относительно высоком уровне абстракции это может выглядеть так:
Public Sub DeselectUpperAreas()
Dim initialSelection As Range
Set initialSelection = Application.Selection
Dim finalSelection As Range
Dim currentArea As Range
For Each currentArea In initialSelection.Areas
If Not IsUnwantedRange(currentArea) Then
Set finalSelection = AppendRange(currentArea, finalSelection)
End If
Next
If Not finalSelection Is Nothing Then finalSelection.Select
End Sub
Private Function IsUnwantedRange(ByVal target As Range) As Boolean
'TODO оценить, является ли target желаемым или нет;
'возвращать True, если target нежелателен в финальном выборе
'IsUnwantedRange = (логическое выражение)
End Function
Private Function AppendRange(ByVal target As Range, ByVal merged As Range) As Range
If merged Is Nothing Then
Set AppendRange = target
Else
Set AppendRange = Union(target, merged)
End If
End Function
Как вы реализуете функцию IsUnwantedRange
, неясно из вопроса, но один из способов может быть такой: Intersect
указанного target
с ячейкой, о которой вы знаете, что она находится внутри диапазона, который вы не хотите выделять, и возвращать False
, если пересечение равно Nothing
.
Еще один способ может заключаться в том, чтобы передать весь initialSelection
, вместе с currentArea
, определить, какие две области являются «верхними двумя диапазонами» (сравнив их свойство Row
, я бы предположил), и возвращать True
, если target
является одним из двух диапазонов, которые вы не хотите включать.
Еще один способ может заключаться в том, чтобы заполнить массив значением Row
каждой области, использовать WorksheetFunction.Small
(один раз с k=1
, один раз с k=2
), чтобы найти два номера строк, которые вы не хотите (это будут два меньших значения), а затем возвращать True
, если target.Row
является одним из этих двух значений.
Обратите внимание, что законные случаи использования Selection
в VBA для Excel очень редки; в зависимости от того, что вы намерены делать с этим выбором, этот пост может помочь избежать полной работы с Select
и Activate
.
Ответ или решение
Как отменить выделение определенных данных в Excel VBA
Вопрос, который мы рассматриваем сегодня, заключается в том, как отменить выделение верхних двух диапазонов данных в уже выбранной области на листе Excel. Важно помнить, что в VBA нет прямого способа «разделить» выделенную область: всегда нужно осуществлять новое выделение. Однако, используя объект Selection
, мы можем создать логику, которая позволит выбрать только те диапазоны, которые нам необходимы.
Шаги для реализации решения
-
Используйте объект Selection для начала: Нам сначала нужно получить текущее выделение, используя объект
Selection
. Это позволит нам в дальнейшем работать только с текущими выбранными диапазонами. -
Итерация по областям выделения: Так как при выделении может существовать несколько областей, следует использовать цикл для обработки каждого диапазона отдельно.
-
Функция для проверки нежелательных диапазонов: Необходимо создать функцию, которая будет проверять, является ли данный диапазон одним из тех, которые мы хотим отменить. Функция должна возвращать
True
, если диапазон нежелателен, иFalse
, если он необходим. -
Объединение нужных диапазонов: Если текущий диапазон не является нежелательным, мы будем добавлять его в новый диапазон, используя метод
Union
. -
Выбор нового диапазона: По завершении обработки всех областей мы можем выбрать объединенный диапазон.
Пример кода
В приведенном ниже коде реализуется описанная выше логика:
Public Sub DeselectUpperAreas()
Dim initialSelection As Range
Set initialSelection = Application.Selection
Dim finalSelection As Range
Dim currentArea As Range
For Each currentArea In initialSelection.Areas
If Not IsUnwantedRange(currentArea) Then
Set finalSelection = AppendRange(currentArea, finalSelection)
End If
Next
If Not finalSelection Is Nothing Then finalSelection.Select
End Sub
Private Function IsUnwantedRange(ByVal target As Range) As Boolean
' Проверяем, является ли целевой диапазон нежелательным
' Например, если необходимо исключить первые две области
Static unwantedRows As Variant
If IsEmpty(unwantedRows) Then
unwantedRows = Array(1, 2) ' Исключаем строки 1 и 2
End If
Dim rowNum As Long
rowNum = target.Row
IsUnwantedRange = (UBound(Filter(unwantedRows, rowNum)) >= 0)
End Function
Private Function AppendRange(ByVal target As Range, ByVal merged As Range) As Range
If merged Is Nothing Then
Set AppendRange = target
Else
Set AppendRange = Union(target, merged)
End If
End Function
Пояснение кода
- Основная процедура
DeselectUpperAreas
: Она извлекает текущее выделение и инициализирует новый диапазон для выделения оставшихся областей. - Функция
IsUnwantedRange
: В этой функции проверяем, попадает ли строка текущего диапазона в исключаемые строки. Вы можете легко адаптировать эту функцию под ваши нужды, например, добавляя другие диапазоны или изменяя условия. - Функция
AppendRange
: Проводит соединение диапазонов, обрабатывая состояние, когда новый диапазон может быть пустым.
Заключение
Используя указанные шаги, вы сможете эффективно отменить выделение только определенных диапазонов в Excel с помощью VBA, избегая прямого выделения нежелательных областей. Помните, что работа с Selection
не является лучшей практикой, и, когда это возможно, следует избегать ситуации, в которых необходимо использовать выделение. Это позволит сделать ваш код более эффективным и чистым.
Если у вас остались вопросы или вы хотите обсудить конкретные сценарии использования этой методики, пожалуйста, дайте знать, и я буду рад помочь!