Добрый день! Помогите пожалуйста автоматизировать процесс выборки и подсчета количества уникальных значений из двухмерного массива. Интересует вариант с формулами. Нужно, что бы подсчет велся динамически по мере изменения содержимого массива, а не через интерфейс сводной таблицы. Примерно в каком виде мне это нужно см.в приложенном файле. За ранее спасибо!
Добрый день! Помогите пожалуйста автоматизировать процесс выборки и подсчета количества уникальных значений из двухмерного массива. Интересует вариант с формулами. Нужно, что бы подсчет велся динамически по мере изменения содержимого массива, а не через интерфейс сводной таблицы. Примерно в каком виде мне это нужно см.в приложенном файле. За ранее спасибо!DStuart
По поводу формул я имел ввиду без макросов, т.к я в них не силен. Я хочу понимать что я делаю) По поводу "динамически" я имею ввиду если меняется изменяется содержимое массива, то итоги подсчитываются автоматически (кол-во совпадений в массиве), а не путем ручных манипуляций например через "сводную таблицу".
По поводу формул я имел ввиду без макросов, т.к я в них не силен. Я хочу понимать что я делаю) По поводу "динамически" я имею ввиду если меняется изменяется содержимое массива, то итоги подсчитываются автоматически (кол-во совпадений в массиве), а не путем ручных манипуляций например через "сводную таблицу".DStuart
на всякий случай - макрос готов (запускается не по кнопке, а автоматически при изменении данных), но выкладывать пока не буду. пс. "двумерный", "чтобы", "в виду"... что там ещё у вас в загашнике?
на всякий случай - макрос готов (запускается не по кнопке, а автоматически при изменении данных), но выкладывать пока не буду. пс. "двумерный", "чтобы", "в виду"... что там ещё у вас в загашнике? ikki
помощь по Excel и VBA ikki@fxmail.ru, icq 592842413, skype alex.ikki
Сообщение отредактировал ikki - Четверг, 24.01.2013, 15:35
Доб столбцы как вариант можно (потом спрячу), макросы в крайнем случае. Диапазон 256x256 ячеек. Могу собственно приложить вырезку того, что нужно свести. Это расчет решетки Пеннета (расчет генотипов).
Доб столбцы как вариант можно (потом спрячу), макросы в крайнем случае. Диапазон 256x256 ячеек. Могу собственно приложить вырезку того, что нужно свести. Это расчет решетки Пеннета (расчет генотипов).DStuart
каюсь - был неправ. макрос может понадобиться к.-нибудь другому. выкладываю (хотя он очень простой): [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim d As Object, arr, el, i&, j&, n& If Intersect(Target, [диапазон]) Is Nothing Then Exit Sub Set d = CreateObject("scripting.dictionary") d.CompareMode = 0 arr = [диапазон].Value For Each el In arr If Not IsEmpty(el) Then d.Item(el) = d.Item(el) + 1 Next n = Application.Min(Rows.Count - [результат].Rows(1).Row + 1, UBound(arr) * UBound(arr, 2)) Application.ScreenUpdating = False With [результат].Resize(n, 2) .ClearContents .Columns(1).Resize(d.Count) = Application.Transpose(d.Keys) .Columns(2).Resize(d.Count) = Application.Transpose(d.Items) End With End Sub
[/vba]
макрос должен быть размещен в модуле листа (того, где находится исх. диапазон с именем "диапазон") результирующий список может находиться на любом листе. верхняя левая ячейка списка должна иметь имя "результат".
Цитата (ikki)
макрос готов, но выкладывать пока не буду.
каюсь - был неправ. макрос может понадобиться к.-нибудь другому. выкладываю (хотя он очень простой): [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim d As Object, arr, el, i&, j&, n& If Intersect(Target, [диапазон]) Is Nothing Then Exit Sub Set d = CreateObject("scripting.dictionary") d.CompareMode = 0 arr = [диапазон].Value For Each el In arr If Not IsEmpty(el) Then d.Item(el) = d.Item(el) + 1 Next n = Application.Min(Rows.Count - [результат].Rows(1).Row + 1, UBound(arr) * UBound(arr, 2)) Application.ScreenUpdating = False With [результат].Resize(n, 2) .ClearContents .Columns(1).Resize(d.Count) = Application.Transpose(d.Keys) .Columns(2).Resize(d.Count) = Application.Transpose(d.Items) End With End Sub
[/vba]
макрос должен быть размещен в модуле листа (того, где находится исх. диапазон с именем "диапазон") результирующий список может находиться на любом листе. верхняя левая ячейка списка должна иметь имя "результат".ikki
Я бы вместо макроса на событие применял массивную UDF. Алгоритм на словаре, как у ikki. Правда в исходной задаче пришлось бы забивать её на весь лист (одну), и при худшем раскладе места на заголовки нет - т.е. если забить под заголовки, то при всех уникальных будет ошибка... Но ошибка будет и в этом макросе при таком раскладе. Но если диапазоны поменьше, то вполне применимо. Сколько диапазонов - столько применяем UDF.
Я бы вместо макроса на событие применял массивную UDF. Алгоритм на словаре, как у ikki. Правда в исходной задаче пришлось бы забивать её на весь лист (одну), и при худшем раскладе места на заголовки нет - т.е. если забить под заголовки, то при всех уникальных будет ошибка... Но ошибка будет и в этом макросе при таком раскладе. Но если диапазоны поменьше, то вполне применимо. Сколько диапазонов - столько применяем UDF.Hugo
Хорошо конечно применять массивную UDF, но теряется права на редактирования результата =(
может кто поможет разобраться, как макрос сделать на много диапазонов, вот, ято я сделал, но не работает =(((( HELP!!!!
[vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim d As Object, arr, el, n& Dim f As Object, arw, em, k&
If Not Intersect(Target, [диапазон1]) Is Nothing Then Exit Sub Set d = CreateObject("scripting.dictionary") d.CompareMode = 0 arr = [диапазон1].Value For Each el In arr If Not IsEmpty(el) Then d.Item(el) = d.Item(el) + 1 Next n = Application.Min(Rows.Count - [результат1].Rows(1).Row + 1, UBound(arr) * UBound(arr, 2)) Application.ScreenUpdating = False With [результат1].Resize(n, 2) .ClearContents .Columns(1).Resize(d.Count) = Application.Transpose(d.Keys) .Columns(2).Resize(d.Count) = Application.Transpose(d.Items) End With
If Not Intersect(Target, [диапазон2]) Is Nothing Then Exit Sub Set f = CreateObject("scripting.dictionary") f.CompareMode = 0 arr = [диапазон2].Value For Each em In arw If Not IsEmpty(em) Then f.Item(em) = f.Item(em) + 1 Next k = Application.Min(Rows.Count - [результат2].Rows(1).Row + 1, UBound(arw) * UBound(arw, 2)) Application.ScreenUpdating = False With [результат2].Resize(k, 2) .ClearContents .Columns(1).Resize(f.Count) = Application.Transpose(f.Keys) .Columns(2).Resize(f.Count) = Application.Transpose(f.Items) End With
End Sub
[/vba]
[admin]Оформляйте коды тегами![/admin]
Хорошо конечно применять массивную UDF, но теряется права на редактирования результата =(
может кто поможет разобраться, как макрос сделать на много диапазонов, вот, ято я сделал, но не работает =(((( HELP!!!!
[vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim d As Object, arr, el, n& Dim f As Object, arw, em, k&
If Not Intersect(Target, [диапазон1]) Is Nothing Then Exit Sub Set d = CreateObject("scripting.dictionary") d.CompareMode = 0 arr = [диапазон1].Value For Each el In arr If Not IsEmpty(el) Then d.Item(el) = d.Item(el) + 1 Next n = Application.Min(Rows.Count - [результат1].Rows(1).Row + 1, UBound(arr) * UBound(arr, 2)) Application.ScreenUpdating = False With [результат1].Resize(n, 2) .ClearContents .Columns(1).Resize(d.Count) = Application.Transpose(d.Keys) .Columns(2).Resize(d.Count) = Application.Transpose(d.Items) End With
If Not Intersect(Target, [диапазон2]) Is Nothing Then Exit Sub Set f = CreateObject("scripting.dictionary") f.CompareMode = 0 arr = [диапазон2].Value For Each em In arw If Not IsEmpty(em) Then f.Item(em) = f.Item(em) + 1 Next k = Application.Min(Rows.Count - [результат2].Rows(1).Row + 1, UBound(arw) * UBound(arw, 2)) Application.ScreenUpdating = False With [результат2].Resize(k, 2) .ClearContents .Columns(1).Resize(f.Count) = Application.Transpose(f.Keys) .Columns(2).Resize(f.Count) = Application.Transpose(f.Items) End With