Можно регулярками. Если нужно макросом, то см. код ниже. Работает на активном листе и вытаскивает нужное во второй столбец (предполагается, что столбец у Вас один и он 1)
Код
Sub test()
Dim s as string
Dim arr
Dim i as long
With ActiveSheet
arr = .cells(1,1).CurrentRegion
for i = Lbound(arr, 1) to Ubound(arr, 1)
.cells(i,2) = split(arr(i,1), "_")(1)
next i
End With
End Sub
capybarasan, добрый вечер! Если вопрос потерпит до завтра, то смогу с утра посмотреть и выслать Вам свои предложения и черновой вариант работы. Если нет, то заказ не занимаю. Спасибо!
asesja, здравствуйте! Как вариант, если используете Windows, то пользоваться встроенным антивирусом от Microsoft, а файлы проверять на сервисе VirusTotal
Обернуть в пользовательскую функцию и вытаскивать 1 захватывающую группу (которая в скобках) Выражение означает: взять все символы до конца строки и уступить с конца строки все символы до 2 слешей, включая их, запомнить все, что совпало, кроме слешей в регулярном выражении, в группу 1 код:
Код
Function regex_execute(what, pattern) As String
'regex_execute -- функция для извлечения текста
'what - ячейка с исходным текстом
'pattern - паттерн - строка для регулярного выражения
With CreateObject("VBScript.Regexp")
.Global = False
.MultiLine = False
.Ignorecase = True
.pattern = pattern
If .test(what) Then regex_execute = .Execute(what).Item(0).submatches.Item(0): Exit Function
End With
regex_execute = "нет совпадений"
End Function
Hugo, большое спасибо! Внес правки в код (ниже). Михаил Л, второй вариант (теперь порядок слов в массиве исключений и регистр не имеет значения)
Скрытый текст
Код
Sub подсветить_дубликаты()
Dim dict As Object, arr As Variant, exception_arr As Variant, exception_dict As Object, item As Variant
Dim i As Variant, data_range As Range
exception_arr = Array("картошка", "огурцы") ' в этот массив ИСКЛЮЧЕНИЙ (регистр и порядок не имеет значения)
Set exception_dict = CreateObject("Scripting.Dictionary") ' создаем словарь исключений
' загружаем исключения в словарь исключений
For i = LBound(exception_arr) To UBound(exception_arr)
exception_dict.Add LCase(Trim(exception_arr(i))), 0 ' загоняем слова из масиива исключений в словарь exception_dict
Next i
Set data_range = Application.InputBox("выберите диапазон для выделения дубликатов", , , , , , , 8) ' выбор диапазона (тип 8 == объекту диапазон)
arr = data_range ' загоняем выделенный диапазон в массив
Set dict = CreateObject("Scripting.Dictionary") ' создаем словарь
' ниже цикл для поиска дубликатов в выделенном дипазоне (уже помещенном в массив)
For i = LBound(arr, 1) To UBound(arr, 1)
If Not dict.exists(arr(i, 1)) Then ' если нет такого в словаре, то
dict.Add (LCase(Trim(arr(i, 1)))), 1 ' ключ словаря == значение, значение словаря == 1 (т.е количество повторов)
Else ' иначе
dict(arr(i, 1)) = dict(arr(i, 1)) + 1 ' прибавляем 1 к значению словаря ( то есть этот участовк кода отрабатывает, когда найден первый и последующий дубликаты)
End If
Next i
'---------------------------------------------------------------------------
' ОБРАБАТЫВАЕМ ИСКЛЮЧЕНИЯ
For Each item In dict.keys() ' цикл по ключам словаря для удаления исключений
If exception_dict.exists(item) Then dict(item) = 0 ' если значение item присутствует в словаре исключений exception_dict, то сбрасываем счетчик количества этого значения _
в словаре dict с ключем item
Next item
'---------------------------------------------------------------------------
'ОКРАСКА ЯЧЕЕК
For i = LBound(arr, 1) To UBound(arr, 1) ' цикл по массиву
If dict(arr(i, 1)) > 1 Then data_range(i, 1).Interior.Color = RGB(255, 242, 204) ' если есть дубликаты, то красим
Next i
'----------------------------------------------------------------------------
End Sub
Sub очистка_формата()
' очистка форматов для выделенного участка листа
With Selection
.ClearFormats
End With
End Sub
Михаил Л, только сейчас посмотрел свое предыдущее сообщение (#14) Нюанс: предполагается, что значения в массиве исключений - exception_arr заносятся в алфавитном порядке (в комментариях в коде это прописал, так как функция бинарного поиска (использованнная в моём коде) работает только с отсортированным массивом), то есть:
Sub подсветить_дубликаты()
Dim dict As Object, arr As Variant, exception_arr As Variant, item As Variant
Dim i As Variant, data_range As Range
exception_arr = Array("картошка", "огурцы") ' в этот массив ИСКЛЮЧЕНИЙ заносим значения в алфавитном порядке, так как для поиску по нему используется БИНАРНЫЙ ПОИСК
Set data_range = Application.InputBox("выберите диапазон для выделения дубликатов", , , , , , , 8) ' выбор диапазона (тип 8 == объекту диапазон)
arr = data_range ' загоняем выделенный диапазон в массив
Set dict = CreateObject("Scripting.Dictionary") ' создаем словарь
' ниже цикл для поиска дубликатов в выделенном дипазоне (уже помещенном в массив)
For i = LBound(arr, 1) To UBound(arr, 1)
If Not dict.exists(arr(i, 1)) Then ' если нет такого в словаре, то
dict.Add (arr(i, 1)), 1 ' ключ словаря == значение, значение словаря == 1 (т.е количество повторов)
Else ' иначе
dict(arr(i, 1)) = dict(arr(i, 1)) + 1 ' прибавляем 1 к значению словаря ( то есть этот участовк кода отрабатывает, когда найден первый и последующий дубликаты)
End If
Next i
For Each item In dict.keys() ' цикл по ключам словаря для удаления исключений
If binary_search(exception_arr, item) <> -1 Then dict(item) = 0 ' если значение item присутствует в массиве исключений, то сбрасываем счетчик количества этого значения
Next item
For i = LBound(arr, 1) To UBound(arr, 1) ' цикл по массиву
If dict(arr(i, 1)) > 1 Then data_range(i, 1).Interior.Color = RGB(255, 242, 204) ' если есть дубликаты, то красим
Next i
End Sub
Sub очистка_формата()
' очистка форматов для выделенного участка листа
With Selection
.ClearFormats
End With
End Sub
Private Function binary_search(arr, what) As Long
'функция поиска значения what в одномерном массиве arr
Dim p, q, r
p = 0: r = UBound(arr)
While p <= r
q = Int((p + r) / 2)
If LCase(Trim(arr(q))) = LCase(Trim(what)) Then binary_search = q: Exit Function
If LCase(Trim(arr(q))) > LCase(Trim(what)) Then
r = q - 1
Else
p = q + 1
End If
Wend
binary_search = -1
End Function
Hugo, спасибо большое за code review, внес правки в свой код! Михаил Л, добавил функцию бинарного поиска и массив для исключений (в коде добавил соответствующие строки и комментарии). Предполагается, что значения в массиве исключений - exception_arr заносятся в алфавитном порядке, то есть, например:
Sub подсветить_дубликаты()
Dim dict As Object, arr As Variant, exception_arr As Variant
Dim i As Variant, data_range As Range
exception_arr = Array("картошка", "огурцы") ' в этот массив ИСКЛЮЧЕНИЙ заносим значения в алфавитном порядке, так как для поиску по нему используется БИНАРНЫЙ ПОИСК
With ActiveSheet
Set data_range = Application.InputBox("выберите диапазон для выделения дубликатов", , , , , , , 8) ' выбор диапазона (тип 8 == объекту диапазон)
arr = data_range ' загоняем выделенный диапазон в массив
Set dict = CreateObject("Scripting.Dictionary") ' создаем словарь
' ниже цикл для поиска дубликатов в выделенном дипазоне (уже помещенном в массив)
For i = LBound(arr, 1) To UBound(arr, 1)
If binary_search(exception_arr, arr(i, 1)) = -1 Then
If Not dict.exists(arr(i, 1)) Then ' если нет такого в словаре, то
dict.Add (arr(i, 1)), 1 ' ключ словаря == значение, значение словаря == 1 (т.е количество повторов)
Else ' иначе
dict(arr(i, 1)) = dict(arr(i, 1)) + 1 ' прибавляем 1 к значению словаря ( то есть этот участовк кода отрабатывает, когда найден первый и последующий дубликаты)
End If
End If
Next i
For i = LBound(arr, 1) To UBound(arr, 1) ' цикл по массиву
If dict(arr(i, 1)) > 1 Then data_range(i, 1).Interior.Color = RGB(255, 242, 204) ' если есть дубликаты, то красим
Next i
End With
End Sub
Sub очистка_формата()
' очистка форматов для выделенного участка листа
With Selection
.ClearFormats
End With
End Sub
Private Function binary_search(arr, what) As Long
'функция поиска значения what в одномерном массиве arr
Dim p, q, r
p = 0: r = UBound(arr)
While p <= r
q = Int((p + r) / 2)
If LCase(Trim(arr(q))) = LCase(Trim(what)) Then binary_search = q: Exit Function
If LCase(Trim(arr(q))) > LCase(Trim(what)) Then
r = q - 1
Else
p = q + 1
End If
Wend
binary_search = -1
End Function
Михаил Л, все таки выложу тут код с комментариями, вдруг пригодится Вам (запускаете макрос, выбираете диапазон (только с наименованием для поиска дубликатов)):
Скрытый текст
Код
Sub подсветить_дубликаты()
Dim dict As Object, arr As Variant, item As Variant, data_range As Range
Dim i As Long, nextRow As Long, next_range As Range
With ActiveSheet
Set data_range = Application.InputBox("выберите диапазон для выделения дубликатов", , , , , , , 8) ' выбор диапазона (тип 8 == объекту диапазон)
arr = data_range ' загоняем выделенный диапазон в массив
Set dict = CreateObject("Scripting.Dictionary") ' создаем словарь
' ниже цикл для поиска дубликатов в выделенном дипазоне (уже помещенном в массив)
For i = LBound(arr, 1) To UBound(arr, 1)
If Not dict.exists(arr(i, 1)) Then ' если нет такого в словаре, то
dict.Add (arr(i, 1)), 1 ' ключ словаря == значение, значение словаря == 1 (т.е количество повторов)
Else ' иначе
dict(arr(i, 1)) = dict(arr(i, 1)) + 1 ' прибавляем 1 к значению словаря ( то есть этот участовк кода отрабатывает, когда найден первый и последующий дубликаты)
End If
Next i
For Each item In dict.keys() ' цикл по клюючам словаря
If dict(item) > 1 Then ' если есть дубликаты, то
Set next_range = data_range.Find(item) ' ищем 1 дубликат в диапазоне (котрый выбрали в начале кода)
nextRow = next_range.Row ' запоминаем строку с дубликатом
Do ' пока
next_range.Interior.Color = RGB(255, 242, 204) ' красим дубликат
Set next_range = data_range.FindNext(next_range) ' ищем дальше дубликаты
Loop While nextRow <> next_range.Row ' первая строка с дубликатом не равна строке найденного совпадения
End If
Next item
End With
End Sub
Sub очистка_формата()
' очистка форматов для выделенного участка листа
With Selection
.ClearFormats
End With
End Sub
Михаил Л, здравствуйте! Можно, например, использовать код с такой логикой: 1.загоняем всю таблицу в массив 2.создаем словарь типа - ключ=наименование, значение=количество повторов (при помощи цикла по массиву) 3. проходим циклом по словарю и, где количество значений больше 1, используя метод find в диапазоне значений для выделения, выделяем нужное.
Arteeck, с таким файлом можно работать. У меня сайт немного лагает, поэтому решение выложу чуть позже. Может быть другие коллеги помогут быстрее. Спасибо!
Arteeck, позвольте описать мое виденье (возможного) решения Вашей проблемы. Чтобы корректно сформировать файл с результатом, нужно писать код, опираясь на исходные данные, а не на выгрузку. Так же нужно знать диапазоны чисел, которые могут быть, а именно, количество чисел до запятой (от какого и до какого) и после запятой.
Очевидно (на мой взгляд), что 0,1200 должно быть: 0 - отдельно, а 1200,05760276493 - отдельно. Но для этого нужно знать хотя бы примерно формат исходных данных, как я писал выше в этом сообщении.Но все равно 100% результат и в случае такого преобразования будет (на мой взгляд) не гарантирован.
Ivan Ivanov, я использовал регулярные выражения в несколько проходов. Во втором файле (result2) кое-что съехало. Лучше использовать первый файл (из моего первого сообщения в этой теме). Но в нем некорректно отображаются нули, как уже писал коллега постом выше (то есть 0.0 вместо 0,0)
voler83, да уж, прошу прощения, уже посмотрел, что Вы не автор темы и более подробно её прочитал. Прикладываю файл, посмотрите (и Вы и автор ), если результат норм, то перепишу на макросы. Файл во вложении