Страницы: 1 2 След.
RSS
замена разделяющей точки на запятую
 
при замене на экране все нормально, макросом - просто убирает точки, запятые не вставляет.  
формат стоит текстовый, но пробовал и с другими.  
нашел два способа:    
1 поставить впереди апостроф - потом все меняет, но слишком муторно.  
 
2 более красиво :) ставлю автозамену точки на запятую..  
 потом меняю макросом в нужном диапазоне.. точку на точку - получается запятая :)  
 
как еще?
 
Меняем числа в текстовом формате с не тем разделителем дробной части на числовой формат? Или я не так понял?
 
да! правда и я мог не так понять .. :)
 
вот файл.  
 
поменяйте мне точки на запятые
 
Ctrl+H, "." на ",". Лист NEW.
 
а первый мой пост читали?  
 
макросом мне надо!
 
{quote}{login=слэн}{date=27.05.2008 03:25}{thema=}{post}вот файл.  
 
поменяйте мне точки на запятые{/post}{/quote}В результате должны получится числа или должен остаться текст?  
И решение зависит от используемого разделителя дробной части.  
Поменять на запятую потому что запятая Application.DecimalSeparator?
 
три раза да!
 
нужно макросом и с наибольшей скоростью ибо данных может быть много
 
На первый вопрос, содержащий "или", ответ "да" непонятен.  
Может так пойдет?  
   Selection.Replace What:=".", Replacement:=Application.DecimalSeparator, LookAt:=xlPart, _  
       SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _  
       ReplaceFormat:=False
 
на самом деле ответ совершенно верен :)  
 
уж из текста числа я сделаю..  
 
но, подчиняясь , в конечном виде нужны числа, и, значит, будем считать это ответом на первую часть вопроса, после получения которого, ответ на вторую часть будет очевиден :)
 
{quote}{login=Лузер™}{date=27.05.2008 04:03}{thema=}{post}На первый вопрос, содержащий "или", ответ "да" непонятен.  
Может так пойдет?  
   Selection.Replace What:=".", Replacement:=Application.DecimalSeparator, LookAt:=xlPart, _  
       SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _  
       ReplaceFormat:=False{/post}{/quote}  
 
врят ли - но щас попробуююю
 
снимаю шляпу - работает.  
 
теперь объясните разницу..    
пожалста-а-а
 
Вариант:  
'Sub Макрос1()  
   With Range("A1:D2")  
       .Replace What:=",", Replacement:=".", LookAt:=xlPart  
   End With  
End Sub
 
{quote}{login=слэн}{date=27.05.2008 04:18}{thema=}{post}снимаю шляпу - работает.  
 
теперь объясните разницу..    
пожалста-а-а{/post}{/quote}А фиг его знает. Я точно знаю, что DecimalSeparator в VBA "."  
Думаю, что VBA меняет точку на точку, имея в виду DecimalSeparator, а эксель меняет вбашный DecimalSeparator на свой.  
Плюс этого кода в независимости от региональных настроек юзера.
 
да, возможно.  
 
еще раз спасибо
 
---  
Application.DecimalSeparator всегда возвращает тот разделитель, который прописан в Сервис – Параметры – Международные – Разделитель целой и дробной части, даже если выбран флажок "Использовать системные разделители".  
 
А символ десятичного разделителя чисел Excel зависит еще и от того, использованы ли системные разделители через меню: Сервис – Параметры – Международные - Использовать системные разделители.  
 
Если не учитывать этот факт, то возможны ошибки в определении правильного знака десятичного разделителя для числовых ячеек.    
 
Например:  
- системный десятичный знак – запятая;  
- в меню: Сервис – Параметры – Международные – Разделитель целой и дробной части указана точка, и при этом установлен флаг "Использовать системные разделители".  
 
При этом Application.DecimalSeparator выдаст точку, а Excel-ю для числовых ячеек нужна запятая.  
 
Чтобы не зависеть от подобных накладок я использую такую функцию:  
 
' Символ десятичного разделителя  
Function DecSep() As String  
With Application  
If .UseSystemSeparators Then  
DecSep = Mid$(CStr(0.1), 2, 1)  
Else  
DecSep = .International(xlDecimalSeparator)  
End If  
End With  
End Function  
 
---  
ZVI
 
zvi, больше интересовала другая особенность:  
 
при непосредственном указании             Range(Cells(2, 4), Cells(i, 7)).Replace What:=".", Replacement:=",", LookAt:=xlPart, _  
 
точки убираются, но запятые не появляются  
 
при             Range(Cells(2, 4), Cells(i, 7)).Replace What:=".", Replacement:=Application.DecimalSeparator, LookAt:=xlPart, _  
 
 
все нормально, точки меняются на запятые
 
{quote}{login=ZVI}{date=28.05.2008 01:37}{thema=Re:}{post}---  
Application.DecimalSeparator всегда возвращает тот разделитель, который прописан в Сервис – Параметры – Международные – Разделитель целой и дробной части, даже если выбран флажок "Использовать системные разделители".  
 
А символ десятичного разделителя чисел Excel зависит еще и от того, использованы ли системные разделители через меню: Сервис – Параметры – Международные - Использовать системные разделители.  
 
Если не учитывать этот факт, то возможны ошибки в определении правильного знака десятичного разделителя для числовых ячеек.    
 
Например:  
- системный десятичный знак – запятая;  
- в меню: Сервис – Параметры – Международные – Разделитель целой и дробной части указана точка, и при этом установлен флаг "Использовать системные разделители".  
 
При этом Application.DecimalSeparator выдаст точку, а Excel-ю для числовых ячеек нужна запятая.  
 
Чтобы не зависеть от подобных накладок я использую такую функцию:  
 
' Символ десятичного разделителя  
Function DecSep() As String  
With Application  
If .UseSystemSeparators Then  
DecSep = Mid$(CStr(0.1), 2, 1)  
Else  
DecSep = .International(xlDecimalSeparator)  
End If  
End With  
End Function  
 
---  
ZVI{/post}{/quote}Да. По поводу DecimalSeparator  
я ошибался.  
Сейчас провел небольшие изыскания и выяснил, что  
1. VBA всегда использует системный DecimalSeparator, хотя в коде употребляется только точка. Это понятно, т.к. запятая испоьзуется для других известных целей.  
2. Конструкция Application.International(xlDecimalSeparator) всегда корректно возвращает DecimalSeparator используемый в экселе, вне зависимости стоит галка UseSystemSeparators или нет  
3. Конструкция Mid$(CStr(0.1), 2, 1)  
всегда возвращает системый DecimalSeparator    
В приложении пример для опытов с услов. форматированием точка - красный, запятая - желтый.  
А также в модуле 2 нарытая аццкая функция для возврата системного DecimalSeparator :)  
2 слэн. Теперь думаю так: у Вас DecimalSeparator стоял точкой потому и прошло :)  
Можно тупо менять точку на точку, при этом ячейка переписывается заново, но уже с DecimalSeparator в понимании VBA  
Что характерно: Код типа Cells.Replace What:=".", Replacement:=Application.International(xlDecimalSeparator), LookAt:=xlPart, SearchOrder _  
       :=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False  
работает, но корежит числа делая их текстом с "правильным" разделителем.  
Резьюм: меняем что-то на точку.
 
Файл забыл :)
 
{quote}{login=слэн}{date=28.05.2008 09:47}{thema=}{post}zvi, больше интересовала другая особенность:  
 
при непосредственном указании             Range(Cells(2, 4), Cells(i, 7)).Replace What:=".", Replacement:=",", LookAt:=xlPart, _  
 
точки убираются, но запятые не появляются  
 
при             Range(Cells(2, 4), Cells(i, 7)).Replace What:=".", Replacement:=Application.DecimalSeparator, LookAt:=xlPart, _  
 
 
все нормально, точки меняются на запятые{/post}{/quote}  
---  
Метод .Replace хоть и со странностями, но с ним то все понятно.  
 
Функция DecSep() мною была приведена в развитие темы, так как звучало "и с наибольшей скоростью ибо данных может быть много". С этой функцией замена текстовых ячеек на числовые работает в 2-3 раза быстрее, чем Replace. На моем компе - примерно в 2.9 раза быстрее.  
 
Для того, чтобы сравнить эффективность 2-х методов замены прилагаю файл небольшой тест-системы с подробными комментариями.  
---  
ZVI
 
ZVI, безусловно, Вы нам уже не раз доказывали, что считать массив, обработать, записать гораздо быстрее, чем непосредственная обработка экселем.  
У меня показывает преимущество метода 2 в 1.89 раза.  
Но, с учетом моего предыдущего поста, я решил проэксперементировать и закоментировал следующий код  
'    ds = DecSep()  
'    For Each v In x  
'      i = InStr(1, v, ".", 0)  
'      If i > 0 Then Mid$(v, i, 1) = ds  
'    Next  
Т.е. реально осталось:  
   x = .Value  
   .NumberFormat = "General"  
   .Value = x  
Работает, даже если поставить разделитель дробной части "%" :)  
Можно даже так:  
   .NumberFormat = "General"  
   .Value = .Value  
Но все это работает в отношении текста с точкой.
 
ZVI, простите, но я нашел у Вас ошибку.  
Mid$(v, i, 1) = ds меняет символ только для переменной v  
массив х остается без изменений. Т.е. работает так:  
x = .Value  
.NumberFormat = "General"  
.Value = x  
А "фор ич в ин х" пустая трата времени.  
Попробуйте с    
TestString = "1,5518"  
и    
i = InStr(1, v, ",", 0)  
В результате получаем числа, но такие: 15518. Без разделителя.
 
Придумал метод 3  
Идея такая:    
Пусть TestString = "1,5518", т.е. у нас некий текст с разделителем "запятая"  
Запоминаем текущие настройки .UseSystemSeparators и .DecimalSeparator  
меняем .DecimalSeparator на запятую или тот разделитель, который был в TestString    
копируем пустую ячейку, вставляем значения со сложением.  
Возвращаем настройки на место.  
Скорость приятно удивляет даже без оптимизации кода (см. файл)  
Поправил метод 2 немного.
 
{quote}{login=Лузер™}{date=29.05.2008 09:21}{thema=}{post}ZVI, простите, но я нашел у Вас ошибку.  
Mid$(v, i, 1) = ds меняет символ только для переменной v  
массив х остается без изменений. Т.е. работает так:  
x = .Value  
.NumberFormat = "General"  
.Value = x  
А "фор ич в ин х" пустая трата времени.  
Попробуйте с    
TestString = "1,5518"  
и    
i = InStr(1, v, ",", 0)  
В результате получаем числа, но такие: 15518. Без разделителя.{/post}{/quote}  
---  
Да, Вы абсолютно правы!  
Действительно, у меня получился частный случай с лишним For Next.  
 
Ваша идея с манипуляцией .UseSystemSeparators и .DecimalSeparator замечательная!  
Но только и она пока, к сожалению, является частным случаем, т.к. не работает, если системный разделитель запятая - выдает 15518.  
Возможно, нужно манипулировать системым разделителем вместо Excel-ного.  
 
Смогу подключиться к проблеме уже на выходных.  
---  
ZVI
 
Она не совсем не работает. Я эксперементировал с запятой и получил работающий код. На радостях выложил. Продолжил эксперименты с разделителем "%" - не работает. Вернулся к запятой, снова не работает.  
Но работает с любым разделителем, если операцию спец вставки выполнять вручную. Даже записав их макрорекордером, я получаю 15518. Хотя еще один раз у меня сработал код, но отследить и повторить не удалось. :(
 
{quote}{login=Лузер™}{date=30.05.2008 10:24}{thema=}{post}Она не совсем не работает. Я эксперементировал с запятой и получил работающий код. На радостях выложил. Продолжил эксперименты с разделителем "%" - не работает. Вернулся к запятой, снова не работает.  
Но работает с любым разделителем, если операцию спец вставки выполнять вручную. Даже записав их макрорекордером, я получаю 15518. Хотя еще один раз у меня сработал код, но отследить и повторить не удалось. :({/post}{/quote}  
 
вот-вот :)  
 
но ваш первый код работает(у меня) без проблем.(это с replace и decimalseparator)  
 
вообще мне нужно было:  
разархивировать файл  
получившийся текстовый файл загрузить в иксель(я загружаю с установкой столбцов в тесктовый формат, хотя тут и можно поиграть с сепаратором)  
вырезать из этого массива нужные данные(по двум параметрам)  
заменить точку на запятую  
преобразовать в числовой формат  
вставить в таблицу  
 
файлов может быть до 1000  
строк в каждом до 20000  
 
в конечной таблице строк до 800 000  
 
сейчас работаю с 60 000 строк основной таблицы - для этого требуется обработать около 40 файлов - на генерацию таблицы уходит 27сек
 
Если есть возможность занести значения в эксель как текст с точкой (если установленный разделитель запятая то любые цифры разделённые точкой воспринимаются общим форматом как текст)  
для активного листа  
Sub USNumbers()  
  Application.ScreenUpdating = False  
  Application.Calculation = xlCalculationManual  
  Dim cell As Range  
  On Error Resume Next  
  For Each cell In ActiveSheet.Cells.SpecialCells(xlConstants, xlTextValues)  
     On Error Resume Next  
     cell.Value = Val(cell.Value)  
     On Error GoTo 0  
  Next cell  
  Application.Calculation = xlCalculationAutomatic  
  Application.ScreenUpdating = True  
End Sub  
 
'функция вал работает только с us-строками  
'aeyrwbz свид, тьфу cdbl работает с региональными стандартами, то бишь запятой
 
{quote}{login=dl}{date=02.06.2008 08:40}{thema=val  и cdbl}{post}Если есть возможность занести значения в эксель как текст с точкой (если установленный разделитель запятая то любые цифры разделённые точкой воспринимаются общим форматом как текст)  
для активного листа  
Sub USNumbers()  
  Application.ScreenUpdating = False  
  Application.Calculation = xlCalculationManual  
  Dim cell As Range  
  On Error Resume Next  
  For Each cell In ActiveSheet.Cells.SpecialCells(xlConstants, xlTextValues)  
     On Error Resume Next  
     cell.Value = Val(cell.Value)  
     On Error GoTo 0  
  Next cell  
  Application.Calculation = xlCalculationAutomatic  
  Application.ScreenUpdating = True  
End Sub  
 
'функция вал работает только с us-строками  
'aeyrwbz свид, тьфу cdbl работает с региональными стандартами, то бишь запятой{/post}{/quote}  
---  
Верно, но это в 4 раза медленнее, чем модифицированный Лузером™ вариант 2.  
С учетом уточненой Слэном задачи (наверное, уже и выполненной), эффективнее, пожалуй, было бы считать весь текстовый файл в переменную, произвести в этой переменной замену точки на запятую, и затем с помощью .TextToColumns скопировать в ячейки как числа.  
Или, не мудрствуя, использовать исходный вариант 2 без For Next, так как речь идет о преобразовании точки в запятую, а не наоборот  
---  
ZVI
 
"спешу" предоставить уважаемому сообществу третий способ преобразования, еще более быстрый..  
благодаря предоставленному ZVI тесту, мне не пришлось себя утруждать :)  
см вложение  
 
ps мне этот способ не понадобился  - я обошелся вообще без преобразования(вернее оно выполняется встроенными средствами иксель при открытии текстового файла). Надо конечно попробовать упомянутый ZVI способ чтения файла в переменную..
Страницы: 1 2 След.
Читают тему
Наверх