Испугал ты меня, Серёга, про Areas. Я код-то подправил, но старый не стёр. Сравнил работу "в разных позах". Никакой разницы. Посмотрел внимательно и понял, что т.к. у меня идёт цикл по каждой ячейке, а не применение трима сразу к диапазону, то ареасами можно не париться.
Испугал ты меня, Серёга, про Areas. Я код-то подправил, но старый не стёр. Сравнил работу "в разных позах". Никакой разницы. Посмотрел внимательно и понял, что т.к. у меня идёт цикл по каждой ячейке, а не применение трима сразу к диапазону, то ареасами можно не париться.Alex_ST
Леш, я не поленился и выполнил свой совет: cells: 88,625s areas: 1,578125s разница не очевидна? Код был такой:
[vba]
Code
Sub TrimSpaces1() Dim a As Range, t! t = Timer For Each a In ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).Cells a = Application.Trim(a) Next Debug.Print Timer - t End Sub
[/vba]
[vba]
Code
Sub TrimSpaces() Dim a As Range, t! t = Timer For Each a In ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).Areas a = Application.Trim(a) Next Debug.Print Timer - t End Sub
[/vba] Саня, тут: [vba]
Code
.Global = True: .MultiLine = True .Pattern = "^[ " & Chr(160) & "]+": txt = .Replace(txt, "") 'с начала каждой строки .Pattern = "\s+$": txt = .Replace(txt, "")' в конце каждой строки
[/vba] Ниже показал, как у меня выглядит мой код.
Леш, я не поленился и выполнил свой совет: cells: 88,625s areas: 1,578125s разница не очевидна? Код был такой:
[vba]
Code
Sub TrimSpaces1() Dim a As Range, t! t = Timer For Each a In ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).Cells a = Application.Trim(a) Next Debug.Print Timer - t End Sub
[/vba]
[vba]
Code
Sub TrimSpaces() Dim a As Range, t! t = Timer For Each a In ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).Areas a = Application.Trim(a) Next Debug.Print Timer - t End Sub
[/vba] Саня, тут: [vba]
Code
.Global = True: .MultiLine = True .Pattern = "^[ " & Chr(160) & "]+": txt = .Replace(txt, "") 'с начала каждой строки .Pattern = "\s+$": txt = .Replace(txt, "")' в конце каждой строки
[/vba] Ниже показал, как у меня выглядит мой код.KuklP
Серёга, ну я же не дебил совсем чтобы утверждать, что перебор ячеек по одной не намного дольше "массивных" операций. Я просто совсем забыл, что Replace можно применять к диапазону точно так же, как и Application.Trim Тогда, конечно, получится намного быстрее.
Только мне бы по окончанию работы макроса хотелось бы выделить обработанные им ячейки (так нагляднее). А как просто сделать Select для всех диапазонов, входящих в Area я что-то не соображу с ходу
Серёга, ну я же не дебил совсем чтобы утверждать, что перебор ячеек по одной не намного дольше "массивных" операций. Я просто совсем забыл, что Replace можно применять к диапазону точно так же, как и Application.Trim Тогда, конечно, получится намного быстрее.
Только мне бы по окончанию работы макроса хотелось бы выделить обработанные им ячейки (так нагляднее). А как просто сделать Select для всех диапазонов, входящих в Area я что-то не соображу с ходу Alex_ST
Леш, я ничего и не имел ввиду такого:-) Просто подумал, что ты поленишься.
Quote
А как просто сделать Select для всех диапазонов, входящих в Area
- наверное наоборот - для всех area входящих в диапазон:-) А выделить обработанные areas можно с помощью Union. Или сразу одним махом присвоить set r=....specialcells(2), а потом r.select. Саня, я мож и дебил, но см. скрин другого моего поста в этой теме. Так может быть, если жаба отключена?
Леш, я ничего и не имел ввиду такого:-) Просто подумал, что ты поленишься.
Quote
А как просто сделать Select для всех диапазонов, входящих в Area
- наверное наоборот - для всех area входящих в диапазон:-) А выделить обработанные areas можно с помощью Union. Или сразу одним махом присвоить set r=....specialcells(2), а потом r.select. Саня, я мож и дебил, но см. скрин другого моего поста в этой теме. Так может быть, если жаба отключена?KuklP
1. Убедись, что js включен в найстроках. 2. Перезагрузи страницу 3. Скинь код "нормального" поста в txt 4. Скинь код "зеленого" поста в txt 5. Почисти куки / кеш 6. Приберись в квартире (optional)
p.s.: чтобы скинуть код поста, надо зайти в режим редактирования поста
1. Убедись, что js включен в найстроках. 2. Перезагрузи страницу 3. Скинь код "нормального" поста в txt 4. Скинь код "зеленого" поста в txt 5. Почисти куки / кеш 6. Приберись в квартире (optional)
p.s.: чтобы скинуть код поста, надо зайти в режим редактирования постаnerv
Чебурашка стал символом олимпийских игр. А чего достиг ты? Тишина - самый громкий звук
наверное наоборот - для всех area входящих в диапазон:-)
ну, вообще-то вхождение тут "друг в друга" (не пойми превратно ) Range -> Areas -> Range F1: Areas Collection - a collection of the areas, or contiguous blocks of cells, within a selection. There’s no singular Area object; individual members of the Areas collection are Range objects. The Areas collection contains one Range object for each discrete, contiguous range of cells within the selection. If the selection contains only one area, the Areas collection contains a single Range object that corresponds to that selection. А вот так, похоже, получилось совсем не плохо:[vba]
Code
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона If TypeName(Selection) <> "Range" Then Exit Sub 'If Not TypeOf Selection Is Range Then Exit Sub Dim rRange As Range, rAreas As Areas With ActiveSheet.UsedRange Set rAreas = Intersect(Selection, .SpecialCells(xlCellTypeVisible), .SpecialCells(xlCellTypeConstants)).Areas End With If rAreas Is Nothing Then Exit Sub Application.ScreenUpdating = False For Each rRange In rAreas With rRange .Value = Replace(.Value, Chr(160), " ") ' Chr(160) - неразрывный пробел .Value = Application.WorksheetFunction.Trim(.Value) ' СЖПРОБЕЛЫ .Value = Replace(.Value, " " & Chr(10), Chr(10)) ' пробел перед LF .Value = Replace(.Value, Chr(10) & " ", Chr(10)) ' пробел после LF End With Next rRange Application.ScreenUpdating = True rAreas.Parent.Select End Sub
[/vba]
Quote (KuklP)
наверное наоборот - для всех area входящих в диапазон:-)
ну, вообще-то вхождение тут "друг в друга" (не пойми превратно ) Range -> Areas -> Range F1: Areas Collection - a collection of the areas, or contiguous blocks of cells, within a selection. There’s no singular Area object; individual members of the Areas collection are Range objects. The Areas collection contains one Range object for each discrete, contiguous range of cells within the selection. If the selection contains only one area, the Areas collection contains a single Range object that corresponds to that selection. А вот так, похоже, получилось совсем не плохо:[vba]
Code
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона If TypeName(Selection) <> "Range" Then Exit Sub 'If Not TypeOf Selection Is Range Then Exit Sub Dim rRange As Range, rAreas As Areas With ActiveSheet.UsedRange Set rAreas = Intersect(Selection, .SpecialCells(xlCellTypeVisible), .SpecialCells(xlCellTypeConstants)).Areas End With If rAreas Is Nothing Then Exit Sub Application.ScreenUpdating = False For Each rRange In rAreas With rRange .Value = Replace(.Value, Chr(160), " ") ' Chr(160) - неразрывный пробел .Value = Application.WorksheetFunction.Trim(.Value) ' СЖПРОБЕЛЫ .Value = Replace(.Value, " " & Chr(10), Chr(10)) ' пробел перед LF .Value = Replace(.Value, Chr(10) & " ", Chr(10)) ' пробел после LF End With Next rRange Application.ScreenUpdating = True rAreas.Parent.Select End Sub
Да Саш, потестил твой код на том же примере, что предлагал Алексею. Твой короче, но по времени немного проигрывает моему. Тестил только на скорость, не на качество. И в таком контексте его вообще(ни твой, ни мой) использовать не стоит. Он с треском проигрывает даже коду Леши. С areas не работает. Но как пример использования regexp, очень даже подходяще.
Да Саш, потестил твой код на том же примере, что предлагал Алексею. Твой короче, но по времени немного проигрывает моему. Тестил только на скорость, не на качество. И в таком контексте его вообще(ни твой, ни мой) использовать не стоит. Он с треском проигрывает даже коду Леши. С areas не работает. Но как пример использования regexp, очень даже подходяще.KuklP
Ну с НДС и мы чего-то стoим! kuklp60@gmail.com WM Z206653985942, R334086032478, U238399322728
ну, вообще-то вхождение тут "друг в друга" (не пойми превратно )
Леш, давай вместе:-) У меня твой код спотыкается на каждой строке в предложенном тебе примере. Вариант(дешево и сердито): [vba]
Code
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона If TypeName(Selection) <> "Range" Then Exit Sub 'If Not TypeOf Selection Is Range Then Exit Sub Dim rRange As Range, r As Range With ActiveSheet.UsedRange Set r = Intersect(Selection, .SpecialCells(xlCellTypeVisible), .SpecialCells(xlCellTypeConstants)) End With Application.ScreenUpdating = False With r .Replace Chr(160), " ", xlPart' Нефиг это в цикле делать! For Each rRange In .Areas rRange.Value = Application.Trim(rRange.Value) ' СЖПРОБЕЛЫ Next .Replace " " & Chr(10), Chr(10), xlPart ' пробел перед LF .Replace Chr(10) & " ", Chr(10), xlPart ' пробел после LF .Select End With Application.ScreenUpdating = True End Sub
[/vba] Леш, так это отработало на моем примере(10000*30) за 3,453125 сек. Это не 88(причем без замены начальных и конечных пробелов).
Quote (Alex_ST)
ну, вообще-то вхождение тут "друг в друга" (не пойми превратно )
Леш, давай вместе:-) У меня твой код спотыкается на каждой строке в предложенном тебе примере. Вариант(дешево и сердито): [vba]
Code
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона If TypeName(Selection) <> "Range" Then Exit Sub 'If Not TypeOf Selection Is Range Then Exit Sub Dim rRange As Range, r As Range With ActiveSheet.UsedRange Set r = Intersect(Selection, .SpecialCells(xlCellTypeVisible), .SpecialCells(xlCellTypeConstants)) End With Application.ScreenUpdating = False With r .Replace Chr(160), " ", xlPart' Нефиг это в цикле делать! For Each rRange In .Areas rRange.Value = Application.Trim(rRange.Value) ' СЖПРОБЕЛЫ Next .Replace " " & Chr(10), Chr(10), xlPart ' пробел перед LF .Replace Chr(10) & " ", Chr(10), xlPart ' пробел после LF .Select End With Application.ScreenUpdating = True End Sub
[/vba] Леш, так это отработало на моем примере(10000*30) за 3,453125 сек. Это не 88(причем без замены начальных и конечных пробелов).KuklP
Ну с НДС и мы чего-то стoим! kuklp60@gmail.com WM Z206653985942, R334086032478, U238399322728
Сообщение отредактировал KuklP - Среда, 15.08.2012, 18:44
Странно... У меня всё работает. Правда, я обычно применяю не сокращённую запись Application.Trim , а полную: Application.WorksheetFunction.Trim, т.к. у меня самого при сокращенной форме иногда начинает спотыкаться. Завтра на работе помучаю в разных позах твой пример (дома не могу).
Quote (KuklP)
У меня твой код спотыкается на каждой строке
Странно... У меня всё работает. Правда, я обычно применяю не сокращённую запись Application.Trim , а полную: Application.WorksheetFunction.Trim, т.к. у меня самого при сокращенной форме иногда начинает спотыкаться. Завтра на работе помучаю в разных позах твой пример (дома не могу).Alex_ST
Да, Серёга, ты абсолютно прав! Я упёрся в функцию VBA Replace , а про метод диапазона Replace совсем забыл
В итоге у тебя получилась процедура вполне компактная и шустрая. Спасибо, Серёга! Кладу её к себе в Personal в замен старой.
Только я у себя ещё добавил отключение/включение событий чтобы другие макросы не реагировали на замены:[vba]
Code
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона If TypeName(Selection) <> "Range" Then Exit Sub 'If Not TypeOf Selection Is Range Then Exit Sub Dim rRng As Range, rSubRng As Range With ActiveSheet.UsedRange Set rRng = Intersect(Selection, .SpecialCells(xlCellTypeVisible), .SpecialCells(xlCellTypeConstants)) End With Application.ScreenUpdating = False: Application.EnableEvents = False With rRng .Replace Chr(160), " ", xlPart ' Chr(160) - неразрывный пробел For Each rSubRng In .Areas rSubRng.Value = Application.Trim(rSubRng.Value) ' СЖПРОБЕЛЫ Next .Replace " " & Chr(10), Chr(10), xlPart ' пробел перед LF .Replace Chr(10) & " ", Chr(10), xlPart ' пробел после LF .Select End With Application.ScreenUpdating = True: Application.EnableEvents = True End Sub
[/vba]
Да, Серёга, ты абсолютно прав! Я упёрся в функцию VBA Replace , а про метод диапазона Replace совсем забыл
В итоге у тебя получилась процедура вполне компактная и шустрая. Спасибо, Серёга! Кладу её к себе в Personal в замен старой.
Только я у себя ещё добавил отключение/включение событий чтобы другие макросы не реагировали на замены:[vba]
Code
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона If TypeName(Selection) <> "Range" Then Exit Sub 'If Not TypeOf Selection Is Range Then Exit Sub Dim rRng As Range, rSubRng As Range With ActiveSheet.UsedRange Set rRng = Intersect(Selection, .SpecialCells(xlCellTypeVisible), .SpecialCells(xlCellTypeConstants)) End With Application.ScreenUpdating = False: Application.EnableEvents = False With rRng .Replace Chr(160), " ", xlPart ' Chr(160) - неразрывный пробел For Each rSubRng In .Areas rSubRng.Value = Application.Trim(rSubRng.Value) ' СЖПРОБЕЛЫ Next .Replace " " & Chr(10), Chr(10), xlPart ' пробел перед LF .Replace Chr(10) & " ", Chr(10), xlPart ' пробел после LF .Select End With Application.ScreenUpdating = True: Application.EnableEvents = True End Sub
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона Dim rRng As Range, rSubRng As Range Set rRng = Intersect(ActiveWindow.RangeSelection.SpecialCells(xlCellTypeVisible), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants)) If rRng Is Nothing Then Exit Sub Application.ScreenUpdating = False: Application.EnableEvents = False With rRng .Replace Chr(160), " ", xlPart ' Chr(160) - неразрывный пробел For Each rSubRng In .Areas rSubRng.Value = Application.Trim(rSubRng) ' СЖПРОБЕЛЫ Next .Replace " " & Chr(10), Chr(10), xlPart ' пробел перед LF .Replace Chr(10) & " ", Chr(10), xlPart ' пробел после LF .Select End With Application.ScreenUpdating = True: Application.EnableEvents = True End Sub
[/vba]
Ещё чуть навёл красоты:[vba]
Код
Sub Trim_By_Formula() ' применить функцию СЖПРОБЕЛЫ к видимым ячейкам выделенного диапазона Dim rRng As Range, rSubRng As Range Set rRng = Intersect(ActiveWindow.RangeSelection.SpecialCells(xlCellTypeVisible), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants)) If rRng Is Nothing Then Exit Sub Application.ScreenUpdating = False: Application.EnableEvents = False With rRng .Replace Chr(160), " ", xlPart ' Chr(160) - неразрывный пробел For Each rSubRng In .Areas rSubRng.Value = Application.Trim(rSubRng) ' СЖПРОБЕЛЫ Next .Replace " " & Chr(10), Chr(10), xlPart ' пробел перед LF .Replace Chr(10) & " ", Chr(10), xlPart ' пробел после LF .Select End With Application.ScreenUpdating = True: Application.EnableEvents = True End Sub