Страницы: 1
RSS
vba сортировка двумерного массива по определенному полю
 
есть алгоритм сортировки одномерного массива.  
 
далее вижу такой пордход  
1 берем одномерный столбец( тот, по которому нужно сортировать)(вот тут лучше воспользоваться средствами не совсем VBA - функция copymemory из библиотеки kernel32 с этим справится быстрее)  
 
2 создаем доп массив, равный получившемуся одномерному- он будет считаться заполненным порядковыми номерами элементов первого массива(1,2,3..) - т.е. изначально он упорядочен.  
 
3 сортируем первый массив, одновременно выполняя те же преобразования над вторым  
 
4 переписываем остальные поля двумерного массива в соответствии с порядком, получившимся в нашем дополнит массиве - например получилось 4,2,8,1.. -    
заполняем двумерный массив arr(1 to n,1 to c) из первоначального массива arr_n с помощью нашего доп массива arr_r(1 to n)  
for i=1 to n  
..  
arr(i,c)=arr_n(arr_r(i))  
next  
 
есть ли лучшие предложения? или где почитать?
Живи и дай жить..
 
слэн, про CopyMemory можешь пояснить? Там ведь надо знать объём, как это применить к массиву с произвольными данными? Или я не так понимаю?
 
да, есть проблемы, но в частном случае, допустим, целых чисел это решаемо..
Живи и дай жить..
 
КОПЛЮ НА КОНОПЛЮ,  
КАК НАКОПЛЮ - УЙДУ В САКЛЮ.  
 
В теме сортировки нам и год назад было за Вами не угнаться....
 
привет. помощь всякая нужна.. (хотя бы и просто поднять тему :) )
Живи и дай жить..
 
Для не безразмерных массивов я как-то пытался делать, но не доделал - нужда отпала, с использованием коллекций по такому алгоритму:  
1. Каждая строка 2D-массива в виде 1D-массива заносится в коллекцию. Ключ записи - значение из столбца, по которому нужно сортировать.  
2. С использованием .Add bafore/after записи коллекции сортируются каким-нибудь методом (да хоть простейшим "пузырьком")  
3. Из записей сортированной коллекции "собирается" 2D-массив.  
 
Но "сборка/разборка" массива стандартными средствами VBA, кажется, не слишком быстрый процесс...  
Так что нашему известному "акселератору" слэну такой алгоритм вряд ли по душе.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
К стати, вопрос о сортировке 2D-массивов я здесь не так давно задавал, но все советчики сошлись на варианте с использованием сортировки на временном листе Ёкселя.  
А мне не хотелось бы быть привязанному к приложению, т.к. часть данных у меня в Access'e, часть - в Visio и хотелось бы иметь универсальную процедуру сортировки, которую можно было бы применять везде, где есть VB(A?)  
 
Ещё чуть не в тему вопрос к гуру: коллекции - это объект VB или только некоторых конкретных VBA?  
А словари (Scripting.Dictionary)? Они, я кажется, в любых приложениях должны работать? Но там нет методов .Add bafore/after...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
А зачем что-то изобретать?  
Сильно критична производительность?  
 
Я обычно использую такой вариант: http://excelvba.ru/code/SortArray
 
{quote}{login=The_Prist}{date=22.10.2010 11:39}{thema=Re: }{post}{quote}{login=Hugo}{date=22.10.2010 10:07}{thema=}{post}слэн, про CopyMemory можешь пояснить? Там ведь надо знать объём, как это применить к массиву с произвольными данными? Или я не так понимаю?{/post}{/quote}Ну так ведь границы уже сформированного массива в любом случае известны...{/post}{/quote}  
Как я понял, нкжно знать размер в байтах. Если каждый элемент одинаков по размеру и изначально это известно, то это сделать легко. Ну а если взяли в массив с листа неизвестно что?
 
производительность суперсверхкритична - пузырьком не предлагать.(вообще не понимаю, почему как пример алгоритма пузырек приводят, типа как не надо?)  
 
copymemory все равно  - оно перетащит кусок куда надо. а вот что распознает объект, ссылающийся на этот кусок..
 
Про размер - я как-то давно пробовал. Если мы знаем, что 10 элементов размером по 10 каждый, то переносим 100 байт, и порядок - весь массив перенесли.  
А если переносим 100 байт массива из 10 элементов неизвестно чего, то сколько перенесётся, не известно. У меня перенеслось 6.5 элемента... например.
 
да, надо знать структуру использования памяти.
Живи и дай жить..
 
Sub t()  
Dim s(1 To 3), sr(1 To 3)  
s(1) = "привет"  
s(2) = 1  
s(3) = "123456789123456789123456789"  
Call CopyMemory(sr(1), s(1), 99)  
End Sub  
 
капча: 96999
Живи и дай жить..
 
'Эту строку в область объявлений в СТАНДАРТНЫЙ МОДУЛЬ  
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
 
вот что получилось - см вложение(код)  
 
по моим подсчетам быстрее в два раза чем sort(без учета вывода на лист) - но на больших массивах не тестировал.
Живи и дай жить..
 
сделал по возрастанию и убыванию + сэкономил немного на инициализации вспомогательного массива..
Живи и дай жить..
Страницы: 1
Наверх