Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.11.2010, 16:39   #1
Meta2
Пользователь
 
Регистрация: 28.10.2009
Сообщений: 38
По умолчанию Excel, заменить "неразрывный пробел" на обычный

Всем доброго дня!

У меня есть задача следующего характера - имеется большая таблица (4000 строк) вида "артикул | описание" и надо перенести описания в другую книгу Excel по совпадающему артикулу.

Описание - это довольно длинная последовательность символов, среди которых встречаются т.н. "неразрывные пробелы" (CHAR(160))
Эти "неразрывные пробелы" сильно портят мне жизнь, когда я переношу в другую таблицу описание к данному артикулу, т.к. вставляется не всё описание, а лишь его часть до "неразрывного пробела".

Я борюсь с этим так:
- копирую таблицу описаний в Блокнот, чтобы удалить форматирование текста.
- из блокнота я копирую текст в Microsoft Word, в котором делаю операцию "поиск и замена" для символа "^s" (неразрывный пробел) на символ " " (пробел) По итогам получается в среднем 7000 замен.
- исправленный текст снова копирую в Блокнот, а потом уже вставляю в Excel на место предыдущей таблицы.

Неприятность состоит в том, что после операции копирования туда-сюда продолжить скриптовую обработку, поэтому вместо одного скрипта, который делает всё сразу, у меня их два и промежуточная ручная операция. Можно ли как-нибудь автоматизировать операцию поиска и замены "неразрывного пробела" на обычный?

Описания, которые я обрабатываю, попадают в результирующую таблицу из множества файлов *.xls. В принципе, я могу вычищать из них "неразрывные пробелы" на этапе загрузки данных, только я не знаю, как заменить отдельный символ в строке.

Помогите, пожалуйста!
Meta2 вне форума Ответить с цитированием
Старый 03.11.2010, 16:53   #2
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Код:
Sub tt()
For Each cc In Selection.Cells
cc.Value = Replace(cc.Value, Chr(160), " ")
Next
End Sub
Это?
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 03.11.2010, 17:11   #3
Meta2
Пользователь
 
Регистрация: 28.10.2009
Сообщений: 38
По умолчанию

Да, оно, спасибо!

А почему, когда я попытался переписать код в такой манере, Excel ругнулся в цикле на "Object required"?

Код:
Sub УдалитьПробелы()
    Dim sh As Worksheet: Set sh = ActiveSheet

    Dim i As Integer

    i = 2

    Do While sh.Cells(i, 5) <> ""
        sh.Cells(i, 5).Value = Replace(cc.Value, Chr(160), " ")
        i = i + 1
    Loop

End Sub
Meta2 вне форума Ответить с цитированием
Старый 03.11.2010, 17:15   #4
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

cc.Value - это что здесь?
нужно sh.Cells(i, 5).Value
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 03.11.2010, 17:17   #5
Meta2
Пользователь
 
Регистрация: 28.10.2009
Сообщений: 38
По умолчанию

Чёрт, спать надо больше.
Спасибо ещё раз.

Такими темпами, глядишь, я научусь программировать на VBA
Meta2 вне форума Ответить с цитированием
Старый 03.11.2010, 17:26   #6
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Только тут Integer не годится - вдруг строк больше чем 35000 (точно не помню) будет?
Пишите Long.
Ну и такой перебор небыстрый, быстрее For Each должно быть.
Или брать в массив, в нём заменять, выгружать назад.

Вот, с замером времени:
Код:
Sub УдалитьПробелы()
Dim sh As Worksheet: Set sh = ActiveSheet
Dim tm As Single
tm = Timer
Dim i As Long
Dim a
a = sh.Range("E2:E" & sh.Range("E" & Rows.Count).End(xlUp).Row)
For i = 1 To UBound(a)
a(i, 1) = Replace(a(i, 1), Chr(160), " ")
Next
sh.Range("E2:E" & sh.Range("E" & Rows.Count).End(xlUp).Row) = a
MsgBox Timer - tm
End Sub
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 03.11.2010 в 17:38.
Hugo121 вне форума Ответить с цитированием
Старый 03.11.2010, 17:47   #7
Meta2
Пользователь
 
Регистрация: 28.10.2009
Сообщений: 38
По умолчанию

Ага, понял!

А могли бы вы мне посоветовать, как сделать прогресс-бар или некий, подобный ему индикатор выполнения скрипта? Дело в том, что мне сейчас приходится исполнять скрипты, которые обрабатывают файлы по 4000 - 25000 строк и дело это не быстрое, особенно, если приходится искать в этих файлах. И я слежу за ходом исполнения программы по загруженности процессора. может быыть, можно пихать в какую-нибудь сервисную консоль сообщения в духе "обрабатываю строку %d", strnum?

Было бы полезно. Я, как правило, знаю, сколько строк в файле и могу понять, скоро ли закончится обработка. Что посоветуете?
Meta2 вне форума Ответить с цитированием
Старый 03.11.2010, 18:00   #8
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,170
По умолчанию

Если делать на массивах, то сам прогрессбар отнимет времени больше, чем обработка массива.
А так я обычно Application.StatusBar использую, вот нашёл в записках примеры:

Код:
Sub test()
For i = 1 To 10000
p = i \ 100
Application.StatusBar = "Выполнено: " & p & "% " & String(p \ 10 + 1, ChrW(8700))
DoEvents
Next
Application.StatusBar = False
End Sub

Кстати, вместо квадратиков можно использовать всякие другие прикольные символы.

К примеру, попробуйте такой вариант макроса:

Sub test()
For i = 1 To 10000
p = i \ 100
Application.StatusBar = "Выполнено: " & p & "% " & String(p \ 10 + 1, ChrW(10000 + p \ 2))
DoEvents
Next
Application.StatusBar = False
End Sub

Вот ещё пара вариаций на ту же тему: (обязательно попробуйте - вдруг понравится)

Sub test()
For i = 1 To 10000
p = i \ 100: s = "": For j = 10102 To 10102 + p \ 10: s = s & ChrW(j): Next
Application.StatusBar = "Выполнено: " & p & "% " & s: DoEvents
Next
Application.StatusBar = False
End Sub


Sub test2()
For i = 1 To 10000
p = i \ 100: s = String(p \ 10, ChrW(10152)) & String(11 - p \ 10, ChrW(8700))
Application.StatusBar = "Выполнено: " & p & "% " & s: DoEvents
Next
Application.StatusBar = False
End Sub
_
очень круто) 
Sub test()
For i = 1 To 100000
p = i \ 1000
s = String(p \ 10, ChrW(9632)) & String(10 - p \ 10, ChrW(9633))
Application.StatusBar = "Выполнено: " & p & "% " & s
DoEvents
Next
Application.StatusBar = False
End Sub
Ещё поищите по форуму, был пример с формой, но имхо это только тормозит.

И да, писать сообщения в духе "обрабатываю строку %d", strnum можно, только тогда не каждую, а например 33-ю или 100-ю - меньше тормозить будет, и читать будете успевать.
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 03.11.2010 в 18:03.
Hugo121 вне форума Ответить с цитированием
Старый 03.11.2010, 21:08   #9
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

На самом деле для замены неразрывного пробела на обычный на листе никакие циклы не нужны.
Код:
ActiveSheet.Cells.Replace What:=ChrW(160), Replacement:=" ", LookAt:=xlPart, SearchOrder:=xlByRows,MatchCase:=True, SearchFormat:=False, ReplaceFormat:=False
Aent вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как заменить обычний пробел на неразрывный пробел Jaroslav Microsoft Office Excel 2 05.05.2010 11:57
настроить при открытии Excel 2003 в окошке "Тип файлов" вывод пункта "Все файлы (*.*)" по умолчанию? Unior Microsoft Office Excel 2 01.03.2009 02:42
Excel файл открывается не "до конца" (странички "не показываются" только серое поле) Dorvir Microsoft Office Excel 2 28.03.2008 10:03
Чем отличаются обычный программист и "игровой" ?? aVague Gamedev - cоздание игр: Unity, OpenGL, DirectX 22 11.11.2007 23:41