Страницы: 1
RSS
Как эффективно удалить из строк все символы кроме букв?
 
Можно ли как-нибудь получить строки без пробелов, "-", "?", цифр и прочих символов. То есть только буквы.  
 
Например есть список:  
НО отдела АААА123  
НО отдела АААА234  
НО отдела АААА-345  
ЧП, НО отдела ББББ-1  
 
Надо привести к виду:  
НОотделаАААА  
НОотделаАААА  
НОотделаАААА  
ЧПНОотделаБББ  
 
Задача нужна потому что есть исходный список со всякими цифрами и тире и переправленный конечный список без запятых и цифр. Нужно их сопоставить тупо по буквам.
 
думать решительно лень :)  
но могу тыкнуть пальцем в тему, где было решение схожей задачи.  
почитайте, может пригодится  
:)  
 
http://www.planetaexcel.ru/forum.php?thread_id=5628
 
мож просто комбинацию из многих подставить?  
 
подставить(подставить(a1;"1";"");"2";"") и т.д.
 
Мне кажется нужно просто написать пользовательскую функцию, которая бы просматривала каждую букву в ячейке циклом и если это не буква, то игнорировала бы её, а буквы собирала в цепочку.  
 
P.S. Буквы только русские? или попадаются и английские?
 
ps  
для лентяев  
 
можно одну формулу :ПОДСТАВИТЬ(A1;СТОЛБЕЦ(A1)-1;"") растянуть на 10 столбцов, а потом еще добавить для разных знаков..  
 
или записать набор знаков в отдельную ячейку, в формуле в качестве искомого текста использовать ПСТР($A$2;СТОЛБЕЦ();1)  
 
в a2 записан набор удаляемых символов  
 
в n-ом столбце получится результат - минимум затрат :)
 
вот
 
Подумал и написал сам :)  
Кому интересно  
 
Option Explicit  
Option Compare Text  
Sub qq()  
Dim i, iLen, iRow, lastRow As Integer  
Dim txt, mSym As String  
lastRow = Range("A2").End(xlDown).Row  
For iRow = 2 To lastRow  
   txt = Cells(iRow, 1)  
   iLen = Len(txt)  
   If iLen > 0 Then  
       For i = iLen To 1 Step -1  
           mSym = Mid(txt, i, 1)  
           If Not (mSym Like "[A-Z]" Or mSym Like "[А-Я]") Then
               txt = Mid(txt, 1, i - 1) & Mid(txt, i + 1, iLen - i)  
           End If  
       Next  
       Cells(iRow, 1) = txt  
   End If  
Next  
End Sub  
 
Удаляет всё кроме букв A-Z, a-z, А-Я, а-я.
 
Почитабельней  
 
Option Explicit  
Option Compare Text  
 
Sub qq()  
Dim i, iLen, iRow, lastRow As Integer  
Dim txt, mSym As String  
 
lastRow = Range("A2").End(xlDown).Row  
 
For iRow = 2 To lastRow  
   txt = Cells(iRow, 1)  
   iLen = Len(txt)  
     
   If iLen > 0 Then  
     
       For i = iLen To 1 Step -1  
           mSym = Mid(txt, i, 1)  
             
           If Not (mSym Like "[A-Z]" Or mSym Like "[А-Я]") Then
               txt = Mid(txt, 1, i - 1) & Mid(txt, i + 1, iLen - i)  
           End If  
             
       Next  
         
       Cells(iRow, 1) = txt  
         
   End If  
     
Next  
 
End Sub
 
молодца!  
можно прокомментировать? :)  
Option Explicit  
Option Compare Text  
 
Sub qq()  
Dim i, iLen, iRow, lastRow As Integer ' только lastRow  будет типа integer, остальные - variant  
Dim txt, mSym As String ' то же  
 
lastRow = Range("A2").End(xlDown).Row    
For iRow = 2 To lastRow  
   txt = Cells(iRow, 1)  
   iLen = Len(txt)  
     
   If iLen > 0 Then ' лишний оператор, цикл и так не будет выполняться, если ilen=0  
     
       For i = iLen To 1 Step -1  
           mSym = Mid(txt, i, 1)  
             
           If Not (mSym Like "[A-Z]" Or mSym Like "[А-Я]") Then
               txt = Mid(txt, 1, i - 1) & Mid(txt, i + 1, iLen - i)' я б использовал replace(txt,mSym,"",1)  
           End If  
             
       Next  
         
       Cells(iRow, 1) = txt' в данном случае это прокатит, но если будете присваивать ячейке ячейку.. в общем предпочео бы cells().value=txt, а вообще, еще лучше было бы сначала txtarray=range(cells(2,1),cells(lastrow,1)), все операции проделать над массивом, потом массив записать обратно на лист : range().value=txtarray  
 
         
   End If  
     
Next  
 
End Sub
 
{quote}{login=слэн}{date=01.10.2008 03:14}{thema=}{post}молодца!  
можно прокомментировать? :)  
Option Explicit  
Option Compare Text  
 
Sub qq()  
Dim i, iLen, iRow, lastRow As Integer ' только lastRow  будет типа integer, остальные - variant  
Dim txt, mSym As String ' то же  
 
lastRow = Range("A2").End(xlDown).Row    
For iRow = 2 To lastRow  
   txt = Cells(iRow, 1)  
   iLen = Len(txt)  
     
   If iLen > 0 Then ' лишний оператор, цикл и так не будет выполняться, если ilen=0  
     
       For i = iLen To 1 Step -1  
           mSym = Mid(txt, i, 1)  
             
           If Not (mSym Like "[A-Z]" Or mSym Like "[А-Я]") Then
               txt = Mid(txt, 1, i - 1) & Mid(txt, i + 1, iLen - i)' я б использовал replace(txt,mSym,"",1)  
           End If  
             
       Next  
         
       Cells(iRow, 1) = txt' в данном случае это прокатит, но если будете присваивать ячейке ячейку.. в общем предпочео бы cells().value=txt, а вообще, еще лучше было бы сначала txtarray=range(cells(2,1),cells(lastrow,1)), все операции проделать над массивом, потом массив записать обратно на лист : range().value=txtarray  
 
         
   End If  
     
Next  
 
End Sub{/post}{/quote}  
 
Dim i, iLen, iRow, lastRow As Integer ' только lastRow    
А как записать тогда в одну строку, чтобы они все были интегер?  
 
Cells(iRow, 1) = txt' в данном случае это прокатит, но если будете присваивать ячейке ячейку.. в общем предпочео бы cells().value=txt  
А в каком случае это не прокатит?  
 
Про if спорно, если в листе довольно много пустых ячеек, то сравнение будет происходить быстрее имхо, чем запись того же значения в ту же ячейку (Cells(iRow, 1) = txt), которое находится в том же If.
 
Replace(txt, mSym, "", i, 1, vbTextCompare)  
 
Наверно лучше, можно будет убрать option compare text сверху тогда.
 
либо так:  
 
Dim i As Integer , iLen As Integer , iRow As Integer , lastRow As Integer  
 
либо так  
 
Dim i%, iLen%, iRow%, lastRow%  
 
P.S. Но если вы про номера строк, то лучше использовать не Integer, а Long, т.к. строк в файле может быть больше, чем 32536 (Integet)
 
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post  
Dim i, iLen, iRow, lastRow As Integer ' только lastRow    
А как записать тогда в одну строку, чтобы они все были интегер?  
{/post}{/quote}  
 
dim i as integer,j as integer  
 
или    
 
dim i%,j%  
 
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
 
Cells(iRow, 1) = txt' в данном случае это прокатит, но если будете присваивать ячейке ячейку.. в общем предпочео бы cells().value=txt  
А в каком случае это не прокатит?  
 
cells(1,1)=cells(1,2)  
{/post}{/quote}  
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
 
Про if спорно, если в листе довольно много пустых ячеек, то сравнение будет происходить быстрее имхо, чем запись того же значения в ту же ячейку (Cells(iRow, 1) = txt), которое находится в том же If.{/post}{/quote}  
 
да, эт я поторопился, забыл про эту последнюю строчку, но вот если, как я и предложил, сначала весь диапазон в массив загнать, тогда эта строчка уходит за пределы первого цикла(будет относиться ко всему массиву) и оператор сравнения точно становится не нужен..
 
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
Dim i, iLen, iRow, lastRow As Integer ' только lastRow    
А как записать тогда в одну строку, чтобы они все были интегер?  
{/post}{/quote}  
 
dim i as integer,j as integer  
 
или    
 
dim i%,j%  
 
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
 
Cells(iRow, 1) = txt' в данном случае это прокатит, но если будете присваивать ячейке ячейку.. в общем предпочео бы cells().value=txt  
А в каком случае это не прокатит?  
 
cells(1,1)=cells(1,2)  
{/post}{/quote}  
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
 
Про if спорно, если в листе довольно много пустых ячеек, то сравнение будет происходить быстрее имхо, чем запись того же значения в ту же ячейку (Cells(iRow, 1) = txt), которое находится в том же If.{/post}{/quote}  
 
да, эт я поторопился, забыл про эту последнюю строчку, но вот если, как я и предложил, сначала весь диапазон в массив загнать, тогда эта строчка уходит за пределы первого цикла(будет относиться ко всему массиву) и оператор сравнения точно становится не нужен..{/post}{/quote}
 
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
Dim i, iLen, iRow, lastRow As Integer ' только lastRow    
А как записать тогда в одну строку, чтобы они все были интегер?  
{/post}{/quote}  
 
dim i as integer,j as integer  
 
или    
 
dim i%,j%  
 
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
 
Cells(iRow, 1) = txt' в данном случае это прокатит, но если будете присваивать ячейке ячейку.. в общем предпочео бы cells().value=txt  
А в каком случае это не прокатит?  
 
cells(1,1)=cells(1,2)  
{/post}{/quote}  
{quote}{login=Prog}{date=01.10.2008 03:41}{thema=Re: }{post}  
 
Про if спорно, если в листе довольно много пустых ячеек, то сравнение будет происходить быстрее имхо, чем запись того же значения в ту же ячейку (Cells(iRow, 1) = txt), которое находится в том же If.{/post}{/quote}  
 
да, эт я поторопился, забыл про эту последнюю строчку, но вот если, как я и предложил, сначала весь диапазон в массив загнать, тогда эта строчка уходит за пределы первого цикла(будет относиться ко всему массиву) и оператор сравнения точно становится не нужен..{/post}{/quote}{/post}{/quote}
 
Dim i, iLen, iRow, lastRow As Integer ' только lastRow    
А как записать тогда в одну строку, чтобы они все были интегер?  
 
dim i as integer,j as integer  
 
или    
 
dim i%,j%  
 
 
Cells(iRow, 1) = txt' в данном случае это прокатит, но если будете присваивать ячейке ячейку.. в общем предпочео бы cells().value=txt  
А в каком случае это не прокатит?  
 
cells(1,1)=cells(1,2)  
 
 
Про if спорно, если в листе довольно много пустых ячеек, то сравнение будет происходить быстрее имхо, чем запись того же значения в ту же ячейку (Cells(iRow, 1) = txt), которое находится в том же If  
 
 
да, эт я поторопился, забыл про эту последнюю строчку, но вот если, как я и предложил, сначала весь диапазон в массив загнать, тогда эта строчка уходит за пределы первого цикла(будет относиться ко всему массиву) и оператор сравнения точно становится не нужен
Страницы: 1
Читают тему
Наверх