Sub InvertSelection() Dim rBig As Range, rSmall As Range, iCell As Range, rNew As Range If Not TypeName(Selection) = "Range" Then Exit Sub Set rSmall = Selection 'Set rBig = ActiveSheet.Cells ' все ячейки листа 'Set rBig = ActiveSheet.UsedRange ' ячейки листа в UsedRange Set rBig = Selection.Parent.UsedRange ' ячейки листа в UsedRange For Each iCell In rBig.Cells ' цикл по всем ячейкам rBig If Intersect(iCell, rSmall) Is Nothing Then If rNew Is Nothing Then Set rNew = iCell Else Set rNew = Union(rNew, iCell) End If End If Next iCell If rNew Is Nothing Then Exit Sub rNew.Select End Sub
работает не со всем листом, а только с UsedRange.
Если же вместо Set rBig = Selection.Parent.UsedRange сделать Set rBig = ActiveSheet.Cells то Ёксель задумывается очень надолго, т.к. там будет цикл по всем ячейкам листа...
И это в 2003-ем, а что будет в 2007-ом? Неужели кроме цикла по всем ячейкам никак нельзя выделить ячейки, не входящие в Selection ?
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
В той теме шёл разговор про расформатирование всего, что вне Selection И насколько я понял, вы как таковой диапазон вне Selection целиком не определяете, а вычисляете по очереди диапазоны столбцов и строк, лежащих вне Selection и расформатируете каждый из них. А как такового диапазона "Outside_Selection" в вашем примере не формируется... Или я не так понял?
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
The_Prist честно говоря, на последних строках кода вашего макроса по расформатированию: Union(Range(Cells(1, lClearCols), Cells(1, lClearEndCol)).EntireColumn, Range(Cells(lClearRows, 1), Cells(lClearEndRow, 1)).EntireRow).ClearFormats Range(Cells(1, lClearStartCol), Cells(1, lClearCol)).EntireColumn.ClearFormats Range(Cells(lClearStartRow, 1), Cells(lClearRow, 1)).EntireRow.ClearFormats у меня при попытке разобраться чуть не "съехала крыша" и поэтому с не смог сформировать целиком диапазон вне выделения и выделить его... Вас не очень затруднит модифицировать свой макрос '--------------------------------------------------------------------------------------- ' Procedure : UnFormat_Invert_Selecton ' Author : The_Prist ' URL : http://www.planetaexcel.ru/forum.php?thread_id=13916, post_104142.xls ' DateTime : 27.02.2010 16:31 ' Purpose : сброс форматирования ячеек вне области выделения '--------------------------------------------------------------------------------------- в макрос Select_Outside?
А новая тема потому, что та расширилась и стала не совсем соответствовать её названию. А название темы к сожалению движок форума не позволяет менять даже её топик-стартеру. А это не только затрудняет поиск, но и приводит к обидам знатоков типа "Я сделал точно то что просили, а вы теперь оказывается хотите другого". К стати, а индексация поиска что-то не идёт или идёт с большим запозданием? Позавчерашние темы ещё некоторые не проиндексированы, что вызывает дублирование вопросов.
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
{quote}{login=Alex_ST}{date=02.03.2010 03:41}{thema=Как без цикла инвертировать выделение?}{post}В топике "Как расформатировать весь лист кроме выделенного диапазона?" ... приведённый по ссылке макрос: Sub InvertSelection() ... End Sub работает не со всем листом, а только с UsedRange.{/post}{/quote} Alex_ST, не имеет смысла очищать форматы вне диапазона UsedRange, потому что там нет никаких форматов. Может, уточните с какой целью Вам требуется выделять ячейки и вне диапазона UsedRange, вдруг это тоже не имеет смысла? :)
Ну, например, я всем ячейкам листа, кроме выделенных, хочу задать какой-нибудь хитро-выпендренный формат... А в общем случае, если процедура "выбора не выбранного" будет отработана, то её можно будет применить в том числе и для расформатирования всех ячеек вне выделения
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
к стати, некто :), UsedRange почему-то не всегда корректно обрабатывает ячейки на краях диапазона если они пустые, но имеют какое-нибудь отличное от стандартного форматирование. Это проявляется обычно не сразу, а после нескольких операций удаления/добавления крайних ячеек UsedRange
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Уж не помню, на каком форуме (пришел туда по ссылке из одной из тем Планеты), но там сравнивались достоинства и недостатки различных методов определения последней ячейки листа (UsedRange, xlLastCells и т.д., точно не помню...). И там как раз и писАлось про такой недостаток UsedRange
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
{quote}{login=Alex_ST}{date=02.03.2010 11:07}{thema=}{post}Уж не помню, на каком форуме...{/post}{/quote} Даю гарантию на $100, что вне диапазона UsedRange нет ни одной ячейки с форматом. Недостатки UsedRange в данном случае являются преимуществом. Если Вы захватите еще и ячейки вне пределов UsedRange, то время обработки увеличится значительно, особенно в Excel 2007.
Ну, может быть оно и так, но всё равно, даже UsedRange может быть очень большим. Поэтому вопрос про инверсию селекции БЕЗ ЦИКЛА всё равно остаётся открытым.
Ведь есть же такая удобная команда Intersect ... Эх! Была бы в VBA команда, обратная Intersect (NonIntersect :-), возвращающая диапазон, состоящий из непересекающихся частей диапазонов-аргументов, проблем бы не было во многих случаях... Но мечтать не вредно.
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Sub InverseSelection1() Dim a As String Application.ScreenUpdating = False Application.EnableEvents = False ActiveSheet.Copy With ActiveSheet .UsedRange.Value = 1 Selection.Formula = "=0" a = .UsedRange.SpecialCells(xlCellTypeConstants).Address(0, 0) .Parent.Close False End With Range(a).Select Application.EnableEvents = True Application.ScreenUpdating = True End Sub
Sub InverseSelection2() Dim a As String, Sh As Worksheet Set Sh = ActiveSheet With Application .ScreenUpdating = False .EnableEvents = False .DisplayAlerts = False ActiveSheet.Copy Before:=Sheets(1) With ActiveSheet .UsedRange.Value = 1 Selection.Formula = "=0" a = .UsedRange.SpecialCells(xlCellTypeConstants).Address(0, 0) .Delete End With Sh.Activate Range(a).Select .DisplayAlerts = True .EnableEvents = True .ScreenUpdating = True End With End Sub
Попробуйте на листе проставить границы ВСЕХ ячеек и увидите, что с UsedRange всё-таки глючит... Я сегодня попробовал собирать диапазоны выше, ниже, правее и левее Selection при помощи Union: Sub FastInvertSelection() Dim rAbove As Range, rBelow As Range, rLeft As Range, rRight As Range ' диапазоны выше, ниже, правее и левее Selection Dim rOutside As Range ' диапазон "вне Selection" Dim selLeft As Long, selTop As Long, selRight As Long, selBottom As Long ' границы Selection Dim iLastRow As Long, iLastClm As Long ' последние ряд и столбец листа ' определяем границы iLastRow = ActiveSheet.Rows.Count iLastClm = ActiveSheet.Columns.Count With Selection selLeft = .Column: selRight = .Column + .Columns.Count selTop = .Row: selBottom = .Row + .Rows.Count End With ' устанавливаем диапазоны выше, ниже, правее и левее Selection If selLeft > 1 Then ' если Selection не "прижато" к левой границе ActiveSheet Set rLeft = Range(Cells(1, 1), Cells(iLastRow, selLeft - 1)) End If If selTop > 1 Then ' если Selection не "прижато" к верхней границе ActiveSheet Set rAbove = Range(Cells(1, 1), Cells(selTop - 1, iLastClm)) End If If selRight < ActiveSheet.Columns.Count Then ' если Selection не "прижато" к правой границе ActiveSheet Set rRight = Range(Cells(1, selRight), Cells(iLastRow, iLastClm)) End If If selBottom < ActiveSheet.Rows.Count Then ' если Selection не "прижато" к нижней границе ActiveSheet Set rBelow = Range(Cells(selBottom, 1), Cells(iLastRow, iLastClm)) End If ' собираем из кусочков диапазон "вне Selection" Set rOutside = Union(rAbove, rLeft, rBelow, rRight)
rOutside.Select End Sub
Проблема встала, что если Selection "прижато" хотя бы к одной из границ листа, соответствуюший диапазон = Nothing и Union с ним работать отказывается... Ну не перебирать же 16 комбинаций из 4-х диапазонов, любой из которых может быть Nothing ... А как применить обработчик ошибок, что-то никак не соображу....
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
{quote}{login=The_Prist}{date=03.03.2010 05:40}{thema=}{post}Применительно к моему примеру - см.вложение.
В результате работы макроса создается обратный веделению диапазон. Для просмотра раскомментируйте необходимые строки.{/post}{/quote} Не знаю важно ли это, но в приведенных мною вариантах изначально могут быть выделены сразу несколько несмежных диапазонов. Вообще интересно было бы услышать от Alex_ST пример какого-нибудь практического применения данной задачи, или просто познаем мир?
Гарантия истекла - снимаю :) Взамен - 2 варианта инвертирования выделения. Работают быстро, со всеми ячейками листа, поддерживается выделение нескольких несмежных диапазонов. Первый вариант предпочтительнее, так как работает и при защищенной структуре книги.
Sub InverseSelection1() Dim a As String a = Selection.Address With ActiveSheet With Workbooks.Add With ActiveSheet .Cells.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, Formula1:="0" .Range(a).ClearFormats a = .Cells.SpecialCells(xlCellTypeAllFormatConditions).Address End With .Close False End With .Range(a).Select End With End Sub
Sub InverseSelection2() Dim a As String a = Selection.Address With ActiveSheet With Worksheets.Add Application.DisplayAlerts = False .Cells.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, Formula1:="0" .Range(a).ClearFormats a = .Cells.SpecialCells(xlCellTypeAllFormatConditions).Address .Delete Application.DisplayAlerts = True End With .Range(a).Select End With End Sub
:) вот теперь всё отлично работает. Спасибо большое. А о применимости - так это просто общий случай частной задачи "Расформатировать всё вне выделенного", которая иногда встаёт необходимости "окультуривания" файлов, получаемых иногда от "знатоков", которые спокойно могут вместо ограниченного диапазона (просто из лени лишних "мышкодвижений") выделить и залить цветом или проставить все границы в целом столбце или строке. А при использовании предложенного вами макроса можно просто выделить всё что тебе нужно, запустить макрос и спокойно делать с выделившимся диапазоном всё что угодно, а не только расформатировать как было в частном случае.
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
Алекс, в который раз перечитываю ветку и не могу понять - зачем выделять (инверсно) весь лист? Ведь за пределами UsedRange ЧИСТО! Что там расформатировать?
Я уже отвечал: Попробуйте на листе проставить границы ВСЕХ ячеек или дайте заливку ВСЕМ ячейкам листа и увидите, что с использованием UsedRange макрос всё-таки глючит... А что там есть добавление временного листа я практически сразу заметил, но только сейчас вернулся к рабочему месту: на совещание выдёргивали...
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)
The_Prist, к сожалению ваш пример не учитывает возможности примыкания Selection к последней строке или столбцу (при выделении целиком столбца или строки), поэтому при таких условиях даёт ошибку... Я это пытался исправить сам ещё вчера (см. мой пост от 03.03.2010, 17:27 ) но так и не смог разобраться, как командой Union можно объединить 4 диапазона, любой из которых модет оказаться = Nothing (как раз если Selection - целиком строка или столбец)? НаписАл пока Select Case True с 15-ю вариантами выбора диапазонов, которые можно объединять т.к. они не равны Nothing ... работает, конечно, но уж больно громоздко. А подправить ваш метод объединения с использованием объекта Err мне не по зубам.
А в самом начале макроса, наверное, на всякий случай вставить: If Not TypeName(Selection) = "Range" Then Exit Sub
С уважением, Алексей(ИМХО: Excel-2003 - THE BEST!!!)