powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Узнать все доступные значения при установке автофильтра
25 сообщений из 78, страница 2 из 4
Узнать все доступные значения при установке автофильтра
    #35716050
Фотография HandKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот кстати была похожая тема


I Have Nine Lives You Have One Only
THINK!
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35716329
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HandKot,
Ага, и там было условие не изменять порядок следования элементов (нельзя сортировать).
Тогда, если в столбце только числовые значения, то можно сделать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Private Sub CommandButton4_Click()
Dim rng As Range
Dim RngAddr As String, t As Single
Dim arr
t = Timer
Columns( 2 ).ClearContents
With Application
  .ScreenUpdating = False
  Set rng = Range(Cells( 2 ,  1 ), Cells(Rows.Count,  1 ).End(xlUp))
  RngAddr = rng.Address
  arr = Split(.Trim(Join(Evaluate("TRANSPOSE(IF(FREQUENCY(" & RngAddr & "," & RngAddr & ")," & RngAddr & ",""""))"), " ")), " ")
  rng.Offset(,  1 ).Resize(UBound(arr) +  1 ) = .Transpose(arr)
End With
[CalcTime] = Timer - t
End Sub
Если же присутствуют текстовые значения, то наиболее оптимальным получается второй вариант (_slan_ - ANik).
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35716441
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, HandKot, ещё одно и самое главное отличие этих вариантов от тех, что на твоей ссылке в том, что на этих данных (3400 строк) самый быстрый вариант (а это вариант с исп. Application.CountIf() ) оказывается медленнее варианта "_slan_ - ANik" по меньшей мере в 25 раз :-)
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35717391
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
A-Nik, да, согласен, быстро, но...

по мере увеличения масива, разница во времени уменьшается практически до нуля, а так же у способа имеется два больших недостатка:

1 нужно место для сортировки
2 ограничение длиной строки
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35717448
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ps способ, кстате, не мой - подсказал ZVI на planetaexcel - я решал небольшие массивы - с помощью расширенного фильтра, большие - сортировкой, но формулы вставлял на листе..
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35719147
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот пример : здесь методы slan_anik и anik сравнялись, а метод slan-anik 2 работает в полтора раза быстрее(и без ограничений)... но файл не пролезает.. :)

на меньшем массиве метод slan-anik 2 работает чуть быстрее, чем anik. для получения вышеозначенного результата нужно пару-тройку раз скопировать и вставить данные из столбца a , получая таким образом массив, в котором все значения повторяются несколько раз - по-моему вполне рабочая ситуация.. при массиве более 20 000 метод anik перестает работать..
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35720878
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, _slan_, функция Join() , а так же функция рабочего листа Trim не хотят работать с большим текстом (или с большим массивом, не знаю что им не нравится).
Вот сделал вариант Anik', который работает без ограничений ;-) Но на очень больших массивах (напр. 50000 строк) он начинает отставать от slan-ANik2 :-)
Так же по подобию slan-ANik2 сделал вариант slan-ANik', который стал значительно быстрее работать.
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35720886
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
P.S.
Признаю вариант "slan-ANik2" как лучший для поиска уникальнх и, если чуток переделать, повторяющихся значений :-)
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35720934
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
A-Nik,
:)
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35721721
nporaMep
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как быстро сделать массив значений, если range с разрывами?
Вот например у меня
rng.Address = "$A$1:$A$6,$A$195:$A$199,$A$388:$A$392,$A$581:$A$585,$A$774:$A$778,$A$967:$A$971"

соответственно
arr=rng копирует только первую Area $A$1:$A$6
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35721741
nporaMep
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовал копированием rng.copy wstmp.range("A1"), но это всё усложняется там кодом
мне надо копировать много ренжей (около 3 тысяч раз)
set wstmp = worksheets.add
wstmp.UsedRange.Clear
wstmp.Delete
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35721890
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nporaMep,
Сделай так:
Код: plaintext
Range("$A$1:$A$6,$A$195:$A$199,$A$388:$A$392,$A$581:$A$585,$A$774:$A$778,$A$967:$A$971").Copy [EmptyCell]
где "EmptyCell" - имя ячейки из любого незадействованного столбца. Там ты получишь уже непрерывный диапазон :-)
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35721898
nporaMep
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Придумал так:
Dim aCell As Range, area As Range
i = 1
For Each area In rng.Areas
For Each aCell In area
arr(i) = CStr(aCell.Value)
i = i + 1
Next
Next
но кажется криво все равно (
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35721923
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, обнаружил ошибку в файле " выборка уникальных значений_3.11.xls " (это обработчик варианта slan-ANik' ). В процедуре Private Sub CommandButton6_Click() надо вместо arr2(j) = arr( j , 1) написать arr2(j) = arr( i , 1)
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35722064
nporaMep
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Копирование очень долго.
Есть таблица из до 30000-40000 строк.
Столбцы в ней условно говоря
Поставщик (номера от 1 до 100)
Товар (номера от 1 до 240)
+ прочие поля

Надо посчитать сколько различных товаров у каждого поставщика.
То есть например поставщик номер 1, у него 1000 записей с товарами от 1 до 240, надо посчитать в нем уникальные, далее тоже самое для поставщика номер 2.

Это только часть макроса с расчетами, далее там много формул по минимуму, максимуму, среднему и прочим несложным функциям экселя.

Фильтр работает как-то быстрее чем копирование, но range получаются из нескольких area.
Вообще думаю мб быстрее будет сделать какой-нить recordset мб на основе таблицы и select group by вытаскивать оттуда по очереди и считать recordset.count но не очень в курсе как это делать.
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35722082
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тогда воспользуйся расширенным фильтром ;-)
Если не получится - выложи упрощённый файл-пример
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35722283
nporaMep
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот, надо узнать по каждой ProductID сколько разных CompanyID.
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35722320
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
или так:
Dim rng As Range
Set rng = Selection
Dim arr()
Dim n%
n = rng.Areas.Count
ReDim arr(1 To n)
Dim i As Long
For i = 1 To n
arr(i) = rng.Areas(i)
Next
Dim r, e
i = 0
For Each r In arr
For Each e In r
i = i + 1
Next
Next
в обычный одномерный массив можно попробовать с помощью copymemory..
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35722436
nporaMep
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ы, я также сделал в принципе:

Private Function GetCompaniesCount(rng As Range) As String
Dim cl As New Collection, i As Long, j As Long
On Error GoTo erm
Dim arr() As String, arr2() As String
ReDim arr(1 To rng.Count)
ReDim arr2(1 To rng.Count)
Dim aCell As Range, area As Range
i = 1
For Each area In rng.Areas
For Each aCell In area
arr(i) = CStr(aCell.Value)
i = i + 1
Next
Next
For i = 1 To UBound(arr)
cl.Add arr(i), Format(arr(i), "@")
j = j + 1
arr2(j) = arr(i)
erm:
Resume nxt
nxt:
Next
GetCompaniesCount = cl.Count - 1
End Function
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35723188
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nporaMepы, я также сделал в принципе...
Так же, да не так... :-) Сравни по скорости свой вариант и _slan(a)_ ;-) У него будет по шустрее ;-)
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35723339
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если задача только узнать количество уникальных, то лучше так:
Function num_comp(compid As Range, prodid As Range, prodid_sample As Range) As Long
Dim cid

Dim cl As New Collection
Dim arr, arr2, rng As Range
Dim i As Long
On Error Resume Next
arr = compid
arr2 = prodid
cid = prodid_sample.Cells(1).Value
For i = 1 To UBound(arr)
If arr2(i, 1) = cid Then cl.Add arr(i, 1), Format(arr(i, 1), "@")
Next
num_comp = cl.Count
End Function
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35723697
А так?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Private Sub CommandButton4_Click()
Dim arr, arr1, x, i&, j&, c As New Collection, t As Single
t = Timer
On Error Resume Next
Application.ScreenUpdating = False
With Range(Cells(2, 1), Cells(Rows.Count, 1).End(xlUp))
arr = .Value
j = UBound(arr)
For Each x In arr
Err.Clear
c.Add 0, CStr(x)
If Err = 0 Then
i = i + 1
arr(i, 1) = x
End If
Next
While i < j
i = i + 1
arr(i, 1) = Empty
Wend
.Offset(, 1).Value = arr
End With
Range("CalcTime") = Timer - t
End Sub
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35723700
x
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
x
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
Private Sub CommandButton4_Click()
  Dim arr, arr1, x, i&, j&, c As New Collection, t As Single
  t = Timer
  On Error Resume Next
  Application.ScreenUpdating = False
  With Range(Cells( 2 ,  1 ), Cells(Rows.Count,  1 ).End(xlUp))
    arr = .Value
    j = UBound(arr)
    For Each x In arr
      Err.Clear
      c.Add  0 , CStr(x)
      If Err =  0  Then
        i = i +  1 
        arr(i,  1 ) = x
      End If
    Next
    While i < j
      i = i +  1 
      arr(i,  1 ) = Empty
    Wend
    .Offset(,  1 ).Value = arr
  End With
  Range("CalcTime") = Timer - t
End Sub
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35724015
_slan_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
x, лень проверять :) прирост скорости дает?

экономия памяти, по-моему, сейчас не актуальна..

да, если будет не массив, а одно единственное значение, то работать не будет - надо доп проверку вводить.. но это в порядке брюзжания, ибо вручную тогда никто запускать макрос не будет, а вот если автоматически..
...
Рейтинг: 0 / 0
Узнать все доступные значения при установке автофильтра
    #35724287
A-Nik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, прирост в скорости небольшой есть :-) Только заметен на оч. больших массивах.
Вот я ещё немного ускорил.... (заметно, если много повторов).
На 65000 ячейках нижеприведённый вариант аж на 0,08 с. быстрее, чем вар. "_slan_ - ANik 2"
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Private Sub CommandButton8_Click()
  Dim arr, arr1, x, i&, j&, c As New Collection, t As Single
  t = Timer
  On Error Resume Next
  Application.ScreenUpdating = False
  With Range(Cells( 2 ,  1 ), Cells(Rows.Count,  1 ).End(xlUp))
    arr = .Value
    j = UBound(arr)
    ReDim arr1(j,  1  To  1 )
    For Each x In arr
      Err.Clear
      c.Add  0 , CStr(x)
      If Err =  0  Then
        arr1(i,  1 ) = x
        i = i +  1 
      End If
    Next
    .Offset(,  1 ).Value = arr1
  End With
  Range("CalcTime") = Timer - t
End Sub
...
Рейтинг: 0 / 0
25 сообщений из 78, страница 2 из 4
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Узнать все доступные значения при установке автофильтра
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]