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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 09.02.2010, 23:37   #1
BRcr
 
Регистрация: 07.02.2010
Сообщений: 5
По умолчанию Запарка со сравнением текста

Здравствуйте, подскажите маленько, кому не лень.
Сами мы не местные и синтаксис VB знаем крайне хреново...
Так вот. В теле функции объявляю массив(или это строка ) следующего вида:
Код:
var = "*[()[]{}]*"
Затем пытаюсь сравнить его со строчкой формата string посредством функции like и ничего не выходит - строчка обрабатывается так, будто бы в ней нет скобок. Пятая точка мне подсказывает, что я неправильно объявляю строчку шаблона, содержащую скобки и что проблема именно в самих скобках, т.к. с другими символами это работает.
Сразу скажу - способ объявления где-то подглядел и на самом деле понятия не имею, как в VB объявляются массивы, а в справке этого найти не смог. В этой идиотской справке вообще фиг чего найдешь в час ночи.
BRcr вне форума Ответить с цитированием
Старый 10.02.2010, 02:31   #2
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Время больше часу ночи
Стив Каммингс
VBA для чайников


Объявление массивов
Как и обычные переменные, массивы должны быть объявленными. При этом объявление
массива по форме отличается от объявления переменной только в одной дополнительной де-
тали. Вот несколько примеров:
' Объявление одномерного массива данных типа Date:
Dim datTimeOfImpact (cdatMaxObservations) As Date
' Объязление массива типа Currency без объявления размера:
Public curPriceQuotes () As Currency
1 Объязление четырехмерного массива типа I n t e g e r :
Dim intArrayOflntegers (34, 13, 29, 4) As Integer
Как видите, разница объявлений для обычных переменных и массивов заключается в том,
что в объявлении массива за именем следуют скобки, в которых может не содержаться ниче-
го, а могут содержаться значения, задающие размеры массива по каждому из его измерений.
(Обратите внимание, что в первом из вышеприведенных примеров размер одномерного мас-
сива задается именованной константой.)
Не забудьте при объявлении массива указать тип данных, включив в объявление
массива As Type с подходящим ключевым словом, задающим тип. Если не ука-
зать тип, VBA создаст массив типа V a r i a n t , в результате чего требования ва-
шей программы к памяти возрастут, а ее выполнение замедлится. Массивы дан-
ных типа V a r i a n t допустимы и в некоторых ситуациях могут быть вполне под-
ходящим решением, но всегда, когда это возможно, лучше назначать массивам
конкретный тип данных.
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 10.02.2010, 02:35   #3
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

Начнём с того что Like не функция а оператор.
Если бы вы навели на него курсор и нажали F1 то узнали бы что он имеет синтаксис:
логический результат = строка Like шаблон
В шаблоне же символы [?#* являются специальными и при употреблении в группе [... ] должны быть заключены в квадратные скобки. Пара квадратных скобок означает что соответствующее знакоместо будет сопоставляться с любым символом
из находящихся внутри скобок [.,;:] сопоставится с любым из перечисленных в скобках символом.
[!.,;:] - c любым символом отличным от . , ; :
[A-Z] - c любым символом от A до Z
### - c любыми тремя цифрами
* - с любым набором символов
[] - cопоставляется с пустой строкой.
Правая квадратная скобка ] не может присутствовать в качестве одного из символов группы.
Если задача состоит в том что бы узнать присутствует ли в строке какая либо скобка - нужно воспользоваться не like а объектом RegExp (примеры есть на этом форуме) или кодом вроде:
Код:
Dim s As String
s = "(a + b) *c[3]"
Debug.Print Instr(s,"[") + Instr(s,"]") > 0 Or  s Like "*[{()}]*"
Можно ограничиться использованием оператора Like
Код:
Debug.Print s Like "*[[]*" Or s Like "*]*" Or s Like "*[{()}]*
Конструкция в шаблоне "*[[]*" означает "что угодно" "левая квадратная скобка (в экранирующих квадратных скобках)" "что угодно"
Правая квадратная скобка во втором шаблоне не начинает группу и поэтому не нуждается в экранировании.
Последний шаблон сопоставится с любой строкой содержащей один из символов: "{", "}", "(", ")".
Однако, приведённый выше код не будет самым эффективным.
К сожалению в чистом VB (VBA) нет функции или оператора проверяющего присутствие любого символа из множества.
Но можно написать:
Код:
Dim i As Long
Dim s As String
Dim res As Boolean
res  = False
For i = 1 to Len(s)
   res =  Instr("([{}])",Mid$(s,i,1)) > 0
   If res exit For
Next i
Но и этот код не слишком эффективен.
Вместо использования функции Instr в цикле можно воспользоваться оператором Select
Код:
Select Case Mid$(s,i,1)
      Case "(",")","{","}","[","]"
            res = True : Exit For
End Select

Последний раз редактировалось Aent; 10.02.2010 в 03:33.
Aent вне форума Ответить с цитированием
Старый 10.02.2010, 11:31   #4
BRcr
 
Регистрация: 07.02.2010
Сообщений: 5
Радость

2doober: спасибо, конечно, но мимо.

2Aent: нда... слышал я звон, да не понял, где он. Хотя сразу, блин, больно странным показалось такое задание строчки шаблона, все в звездах да скобках. Правильно говорила мине мама: "Не пиши на незнакомом языке по ночам, сынок!". Спасибо вам огромное за не менее огромное количество вариантов! Я бы ерундой не маялся, написал бы все на С++ и ходил довольным, но не для себя - для Народа стараюсь. А народ с excel'ем гораздо лучше дружит, нежели с С++.

Эффективности ради, конечно, стоило бы набросать отдельную функцию на проверку "присутствия любого символа из множества", построенную на Case, но скорость значения не имеет, так что instr будет в самый раз, самый очевидный выход.
BRcr вне форума Ответить с цитированием
Старый 10.02.2010, 13:17   #5
BRcr
 
Регистрация: 07.02.2010
Сообщений: 5
По умолчанию

Блин, то ли лыжи не едут, то ли я е####й?!

Почему может не работать вот этот кусок?
(замена Mid на Mid$ ничего не меняет)
Код:
 Public Function FilterTName(str As String, s1 As Boolean, s2 As Boolean, s3 As Boolean)
  Dim signs1 As String
  Dim signs2 As String
  Dim signs3 As String
  Dim text As String
  Dim res As Boolean
  
  signs1 = "-_.,;'"
  signs2 = "[](){}"
  signs3 = "№~!@#$%^&+="
  res = False
  text = str
  
  If s1 Then
    For i = 1 To Len(text) Step 1
     res = InStr(signs1, Mid(text, i, 1)) > 0
     If res Then
      text = Left(text, i - 1) & Right(text, Len(text) - i)
      i = i - 1
     End If
    Next i
  End If
  
  FilterTName = text
  
 End Function
PS. Об ошибке excel дает понять надписью #!ЗНАЧ в ячейке.

Последний раз редактировалось BRcr; 10.02.2010 в 13:23.
BRcr вне форума Ответить с цитированием
Старый 10.02.2010, 13:42   #6
SAS888
Старожил
 
Аватар для SAS888
 
Регистрация: 05.12.2007
Сообщений: 4,180
По умолчанию

Во-первых, ошибка в строке
Код:
res = InStr(signs1, Mid(text, i, 1)) > 0
Во-вторых, если я правильно Вас понимаю, то требуется убирать из строки символы по условиям. Если так, то все можно сделать существенно проще:
Код:
Public Function FilterTName(str As String, s1 As Boolean, s2 As Boolean, s3 As Boolean)
    Dim signs1 As String, signs2 As String, signs3 As String, text As String, i As Integer
    signs1 = "-_.,;'": signs2 = "[](){}": signs3 = "№~!@#$%^&+=": text = str
    If s1 Then
        For i = 1 To Len(signs1): text = Application.Substitute(text, Mid$(signs1, i, 1), ""): Next
    End If
    FilterTName = text
End Function
Пример применения этой функции см. во вложении.
В-третьих, замена Mid на Mid$ увеличивает быстродействие, т.к. в последнем случае функция работает без неявного преобразования аргумента в тип Variant.
Чем шире угол зрения, тем он тупее.

Последний раз редактировалось SAS888; 10.02.2010 в 13:51.
SAS888 вне форума Ответить с цитированием
Старый 10.02.2010, 15:17   #7
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

Вот простая функция для замены группы символов на подстроку (в частном случае на пустую)
Код:
Public Function MultiChrReplace(s As String, f As String, t As String, Optional Inv as Boolean = False ) As String
    Dim i As Long
    Dim j As Long
    Dim ls As Long
    Dim lt As Long

    MultiChrReplace = s
    ls = Len(s)
    if ls = 0 then 
         Exit Function
    end if
    lt = Len(t)
    j = 1
   
    For i = 1 To ls
        If (InStr(f, Mid$(s, i, 1)) > 0) <> Inv Then 'символ подлежит замене ?
            If lt > 0 Then 'длина замещающей подстроки больше 0 ?
                Mid$(MultiChrReplace, j, lt) = t
                j = j + lt
            End If
        Else ' копируем не подлежащий замене символ в результирующую строку
            Mid$(MultiChrReplace, j, 1) = Mid$(s, i, 1)
            j = j + 1
        End If
    Next i
    MultiChrReplace = Left$(MultiChrReplace, j - 1)
End Function
Пример:
Код:
' Удалить из строки s все скобки
s = MultiChrReplace(s, "(){}[]",VbNullString)
' Заменить знаки операций на "&&&"
s = MultiChrReplace(s, "+-*/\^","&&&")
Опциональный параметр Inv служит для инвертирования условия замены
MultiChrReplace("a+b-c*d","+-*","") = "abcd" , но
MultiChrReplace("a+b-c*d","+-*","",True) = "+-*"
MultiChrReplace("a+b-c*d","+-*","_",Inv:=True) = "_+_-_*_"

Последний раз редактировалось Aent; 10.02.2010 в 16:33.
Aent вне форума Ответить с цитированием
Старый 10.02.2010, 15:55   #8
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

To BRcr:
Во первых непонятно зачем у функции лишние аргументы s2 и s3 ведь строки signs2 и signs3 вы в коде не используете.
По существу:
Вы идёте в цикле по i по символам входной строки (кстати копировать её совершенно не обязательно) и в теле цикла меняете длину этой строки и переменную цикла
Если вы хотите получить строку s без i-го символа, то используйте код:
Код:
s = Left$(s,i-1) & Mid$(s,i+1)
Если нужно заменить в строке символ ch на пустую цепочку (т.е. удалить его), воспользуйтесь стандартной функцией Replace
Код:
s = Replace(s,ch,vbNullString)

Последний раз редактировалось Aent; 10.02.2010 в 15:59.
Aent вне форума Ответить с цитированием
Старый 11.02.2010, 07:49   #9
SAS888
Старожил
 
Аватар для SAS888
 
Регистрация: 05.12.2007
Сообщений: 4,180
По умолчанию

To Aent:
1. На сколько я понял, аргументы s2 и s3 содержатся в функции для того, чтобы указывать, какой набор символов (signs1, signs2, signs3, или их комбинацию) требуется заменять. Не случайно в коде есть строка If s1 Then... Естественно, что в функцию требуется добавить If s2 Then... и If s3 Then...
2. Стандартная функция Replace понимает спец. символы. А т.к. в наборе символов для замены они присутствуют, то для того, чтобы не случилось некорректной замены, я предлагаю использовать стандартную функцию рабочего листа Excel Application.Substitute(..., ..., ...)
Чем шире угол зрения, тем он тупее.
SAS888 вне форума Ответить с цитированием
Старый 11.02.2010, 13:37   #10
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

To SAS888:
1. О задумке автора я догадывался Но в приведённом примере функции
FilterTName s2 и s3 не используются...
2. Стандартная функция VBA Replace НЕ понимает спецсимволов. Что очень жаль. Но вы упорствуете в заблуждении
(http://programmersforum.ru/showpost....74&postcount=2)
По всей видимости, вы путаете функцию replace с методом.

Последний раз редактировалось Aent; 11.02.2010 в 13:49.
Aent вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Расшифровка текста. Michelin Gamedev - cоздание игр: Unity, OpenGL, DirectX 6 10.01.2010 21:19
Форматирование текста. Altera Общие вопросы Delphi 3 11.05.2009 23:29
Не могу разобраться с сравнением 2-х двумерных масивов на совпадения текста tj_pablo Общие вопросы C/C++ 0 11.03.2009 22:21
Обработка текста Absent Помощь студентам 2 20.05.2008 23:17
Вставка текста Pedro Общие вопросы Delphi 4 27.01.2008 10:27