Страницы: 1
RSS
Проверка на допустимые символы
 
Всем добрый день!

Возникла такая задача, у меня есть набор допустимых символов: "M", "T", "W", "R", "F", "S", "U". (дни недели)
Нужно проверить примерно 10 тыс строк на то чтобы в ней содержались только допустимые символы (Файл во вложении). Я написал пользовательскую фугкцию под это дело, но к сожалению она работает медленно на таком количестве строк. Возможно ли её как-то оптимизировать?

Вариант с формулами тоже подойдёт.
В дальнейшем хочу использовать решение в составе макроса.

Ни кто не сталкивался с подобным?
Код
Option Explicit

Public Function Day_Correct(Day As String) As Boolean
Dim i As Byte
Dim dictDays
Day_Correct = True

Set dictDays = CreateObject("Scripting.Dictionary")
dictDays.Add "M", 0
dictDays.Add "T", 0
dictDays.Add "W", 0
dictDays.Add "R", 0
dictDays.Add "F", 0
dictDays.Add "S", 0
dictDays.Add "U", 0

For i = 1 To Len(Day)
    If Not dictDays.Exists(Mid(Day, i, 1)) Then
       Day_Correct = False
       Exit For
    End If
Next i

End Function
 
 
скорость мерить не умею мож подойдет
Код
=СУММПРОИЗВ(--ЕЧИСЛО(ПОИСКПОЗ(ПСТР(A2;СТРОКА($1:$3);1);{"M":"T":"W":"R":"F":"S":"U"};0)))=ДЛСТР(A2)
Лень двигатель прогресса, доказано!!!
 
У меня практически мгновенно конвертирует 10 тысяч строк по 180 символов. Простой код PQ по фильтрации вcего лишнего:
Код
List.Transform
 (
  List.Buffer(Excel.CurrentWorkbook(){[Name="Table1"]}[Content][Column1]),
  each Text.Select(_, {"M", "T", "W", "R", "F", "S", "U"})
 )
Вариант с проверкой (true/false) на левые символы и выводом признака в новую колонку:
Код
Table.AddColumn
 (
  Table.Buffer(Excel.CurrentWorkbook(){[Name="Table1"]}[Content]),
  "Bad name",
  each Text.Select([Column1], {"M", "T", "W", "R", "F", "S", "U"}) <> [Column1]
 )
Работает так же почти мгновенно.
Изменено: Alexey_Spb - 01.02.2019 17:04:41
 
=SUM((LEN(A2)-LEN(SUBSTITUTE(A2;{"M";"T";"W";"R";"F";"S";"U"};""))))=LEN(A2)
или по мотивам
=SUM(1-LEN(SUBSTITUTE(A2;{"M";"T";"W";"R";"F";"S";"U"};""))/LEN(A2))=1
Изменено: БМВ - 01.02.2019 16:03:09
По вопросам из тем форума, личку не читаю.
 
Alexey_Spb, PQ не подходит. Но спасибо за решение, как раз изучаю PQ и обязательно проанализирую ваше решение.
 
Сергей, БМВ, Думаю подойдёт попробую засунуть в макрос. Работает точно быстрее чем мой макрос. Большое спасибо.
Изменено: IADmitriy - 01.02.2019 16:06:34
 
Цитата
IADmitriy написал: PQ не подходит.
Почему PQ не подходит для той задачи, в которой он оптимален?
 
Alexey_Spb, потому что
Цитата
IADmitriy написал:
В дальнейшем хочу использовать решение в составе макроса.
Вот еще вариант на PQ:
Код
let
    Источник = Excel.CurrentWorkbook(){[Name="Таблица1_2"]}[Content],
    ТолькоДень = Table.SelectColumns(Источник,{"Day"}),
    ДобПроверка = Table.AddColumn(ТолькоДень, "Проверка", each List.Contains({"M","T","W","R","F","S","U"}, [Day]))
in
    ДобПроверка

IADmitriy, вы уверены в корректности вашей UDF?
Изменено: PooHkrd - 01.02.2019 17:12:07 (код запроса не корректный)
Вот горшок пустой, он предмет простой...
 
Alexey_Spb, данное решение мне нужно, в составе другого более сложного макроса. Также аналитическая часть информации у меня грузится на юзерформу. В случае с PQ мне кажется надо сделать запрос к своей таблице в рамках текущей рабочей книги (для этого преобразовать её в умную таблицу) и после этого выгрузить её на другой лист, либо захватить макросом. Мне кажется это не совсем логичным путём, хотя могу ошибаться. Мне сейчас проще в код встроить функцию.  
 
А возможно ли как как-то оптимизировать мою функцию?
 
PooHkrd, А что не так с ней? Возможно.
 
IADmitriy, если вы проверяете точное соответствие, то все двухбуквенные значения должны в результате давать ЛОЖЬ. У вас есть много значений, где функция показывает истина.
Если же вы проверяете имеется ли в тексте один из 7 символов, то тоже все не гут, ибо для "MV" формула выдает ЛОЖЬ, хотя там присутствует "M".
Странно она у вас работает, или я не так понял условие задачи?
Вот горшок пустой, он предмет простой...
 
PooHkrd, всё верно допустимо только символы: "M", "T", "W", "R", "F", "S", "U". А там есть "V" это недопустимый символ, поэтому FALSE.
 
IADmitriy, ага, т.е. нужно чтобы все буквы в строке пересекались со списком?
Тогда я не так понял. Правильный вариант у Alexey_Spb в посте №3. Мой не корректный.
Вот горшок пустой, он предмет простой...
 
IADmitriy, свои сообщения можно дополнять
 
Цитата
IADmitriy написал:
А возможно ли как как-то оптимизировать мою функцию?
все зависит от данных
например, при длинных строках
Код
Public Function Day_Correct(ByRef Day As String) As Boolean
Dim dictDays
Dim i As Integer
dictDays = Array("M", "T", "W", "R", "F", "S", "U")
Day_Correct = True
For i = 0 To UBound(dictDays)
    Day = Replace(Day, dictDays(i), "")
Next i
Day_Correct = (Len(Day) = 0)
End Function
По вопросам из тем форума, личку не читаю.
Страницы: 1
Наверх