Страницы: 1
RSS
Формирование списка с уникальными значениями
 

Требуется периодически рассылать данные по соответствующим адресам электронной почты. Сейчас эта задача вручную решается пользователями так – копируется столбец с e-mail в Word, делается замена разделителя ";" на абзац, увеличившийся список в Excel через "Удалить дубликаты" делается уникальным, и затем снова в Word делается замена абзаца на ";" и итоговый список используется для отправки письма в Outlook адресатам без дублей.

А как правильнее решить эту задачу в VBA?

 
Здравствуйте
Код
Sub enstaraldsfg()
Dim Rg1 As Range, col1 As New Collection, Txt$, i&, j&, Tp1, Arr1
Set Rg1 = ActiveWorkbook.ActiveSheet.Cells(1).CurrentRegion
Arr1 = Rg1.Value
On Error Resume Next
For i = 2 To UBound(Arr1)
    Tp1 = VBA.Split(Arr1(i, 1), ";")
        For j = 0 To UBound(Tp1)
            col1.Add VBA.Trim(Tp1(j)), VBA.Trim(VBA.CStr(Tp1(j)))
         Next j, i
On Error GoTo 0
For i = 1 To col1.Count
If i = 1 Then Txt = col1(i) Else Txt = Txt & "; " & col1(i)
Next i
Rg1.Parent.Range("C1") = Txt
End Sub
Изменено: Евгений Смирнов - 05.05.2024 12:28:49
 
Вариант для 21го:
=LET(_о;"; "&ОБЪЕДИНИТЬ("; ";1;Таблица1[e-mail])&"; ";_п;ПОСЛЕД((ДЛСТР(_о)-ДЛСТР(ПОДСТАВИТЬ(_о;"; "; )))/2-1);_н;ПОИСК("|";ПОДСТАВИТЬ(_о;"; ";"|";_п))+2;_д;ПОИСК("|";ПОДСТАВИТЬ(_о;"; ";"|";_п+1))-_н;_ф;ОБЪЕДИНИТЬ("; ";1;УНИК(ПСТР(_о;_н;_д)));_ф)
 
Евгений Смирнов,
Благодарю! Только немного подправил под себя - т.к. используется умная таблица, то объявил диапазон как ListObjects("Таблица1").ListColumns("e-mail").DataBodyRange, чтобы счётчик - с единицы

Уточнение по коду - вызов функции удаления пробелов VBA.Trim обязательно делать с полным указанием (Application.Trim/Application.WorksheetFunction.Trim)? Вроде и без них - работает?

Павел \Ʌ/,
С новыми функциями - здорово, но в использовании - только 16й

Однако, как выясняется, в новых версиях Excel и команды соответствующее в VBA ещё появляются: https://stackoverflow.com/a/67053675
 
LKN
Цитата
Уточнение по коду - вызов функции удаления пробелов VBA.Trim обязательно делать с полным указанием (Application.Trim/Application.WorksheetFunction.Trim)? Вроде и без них - работает?
Application.Trim/ и Application.WorksheetFunction.Trim это одно и тоже функция СЖПРОБЕЛЫ рабочего листа.  Для функции рабочего листа обязательно писать  Application.
VBA.Trim это функция  VBA удаление пробелов слева и справа здесь не обязательно писать VBA впереди.
По результату работы они немного различны.  
 
LKN, это не в VBA, а в Экселе новая функция появилась.
 
Цитата
Евгений Смирнов: Для функции рабочего листа обязательно писать  Application.
неправда.
Для функции листа обязательно писать ФункцияЛиста (WorksheetFunction).
Application ВМЕСТО WorksheetFunction может изменить результат.

VBA.Trim удаляет только ведущие и хвостовые пробелы.
Аналог с листа — и двойные.
Application.Trim, КАЖЕТСЯ (не точно), позволяет обрабатывать сразу диапазоны, но быстрее цикла не будет. И там ещё какие-то нюансы, и я вообще не советую.
Изменено: Jack Famous - 06.05.2024 11:41:23
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous Что то я не догоняю какая разница.. Недели две назад сравнивал работу, сейчас еще раз проверил. Никакой разницы нет в работе в трех вариантах записи Application.WorksheetFunction.Trim, WorksheetFunction.Trim, Application.Trim не нашел. Во всех случаях получается функция рабочего листа. Видимо эксель как то определяет, что это функция рабочего листа. Ведь эксель как то различает функцию Mid и оператор Mid, хотя у них 3 аргумента и все одинаковые. Хотя в принципе конечно лучше писать полностью Application.WorksheetFunction.Trim, но это на уровне подсознания не понятно почему. Вот с Range и Cells понимаю, где надо писать объекты перед ними.
 
По-моему, "WorksheetFunction." излишество, можно использовать "Application.":
Код
Debug.Print "[" & Application.WorksheetFunction.Trim(" 12    345 ") & "]"    '[12 345]
Debug.Print "[" & Application.Trim(" 12    345 ") & "]"                      '[12 345]
Debug.Print "[" & Trim(" 12    345 ") & "]"                                  '[12    345]
Поправлюсь: после "WorksheetFunction." появляется список всех функций, поэтому его использование удобнее.
Но можно без "Application.":
Код
Debug.Print "[" & WorksheetFunction.Trim(" 12    345 ") & "]" '[12 345]
Изменено: andypetr - 07.05.2024 08:12:25
 
Здравствуйте!
LKN, Вариант PQ
С наступающим праздником!  
 
Цитата
Евгений Смирнов: Недели две назад сравнивал работу, сейчас еще раз проверил. Никакой разницы нет в работе в трех вариантах записи Application.WorksheetFunction.Trim, WorksheetFunction.Trim, Application.Trim не нашел.
что не означает, что разницы нет. Лень искать (не так просто), но давно ещё вместе с ZVI обсуждали и тестировали.

Цитата
Евгений Смирнов: Во всех случаях получается функция рабочего листа
это не так

Цитата
Евгений Смирнов: Ведь эксель как то различает функцию Mid и оператор Mid, хотя у них 3 аргумента и все одинаковые.
очень просто — по положению. x = Mid(s, 1, 1) <> Mid(s, 1, 1) = x

Цитата
Евгений Смирнов: лучше писать полностью Application.WorksheetFunction.Trim
если нужна функция листа, то только её и нужно писать. Если работаете с разными приложениями (Applications), то, для однозначности можно указывать соответствующее, но не как Application, а как ApXl (Dim ApXl As New Excel.Application  или как-то так)

Цитата
andypetr: По-моему, "WorksheetFunction." излишество, можно использовать "Application.":
вы удивитесь, насколько вы не правы


UPD:
1. нашёл один пример у себя, но это не тот, о котором я говорил
2. рядом пост от New (но тоже не то)
Изменено: Jack Famous - 08.05.2024 17:22:32
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
написал:
вы удивитесь, насколько вы не правы
Жду примера-сюрприза с нетерпением!  ;)
С наступающим Праздником!  
 
Цитата
andypetr: Жду примера-сюрприза с нетерпением!
я вам его не обещал, так что ждать, возможно, придётся долго  ;)
С праздником и вас  :)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх