Řazení polí podle uživatelského seznamu ve VBA
V podstatě máme tyto možnosti;
- zapsat data z pole na list, seřadit je a nahrát zpět do pole tzv. Worksheet - sort metoda
- použít Bubble-sort - metoda řazení ve VBA (použitelná do 5 000 položek)
- použít Quick-sort - metoda řazení ve VBA (velice rychlá)
- použít Counting-sort - metoda řazení ve VBA (extrémně rychlá)
ActiveWorkbook.Worksheets(1).Sort.SortFields.Clear
ActiveWorkbook.Worksheets(1).Sort.SortFields.Add
Key:=Range("A1:A8"), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
CustomOrder:="Po,Út,St,Čt,Pá,So,Ne", _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets(1).Sort
.SetRange Range("A1:C8")
.Header = xlGuess
.MatchCase = False
.Apply
End With
Office 2003 a nižší
Selection.Sort Key1:=Range("A1"), _
Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=2, MatchCase:=False
Jaké jsou nevýhody tohoto řešení?
-
1, převod dat z pole na list a pak zpět do pole
-
2, v nižších verzích, musíte nejprve kódem zajistit nahrání Vašeho seznamu do Excelu
zjištěni jeho pořadového čísla a poté toto číslo použit v argumentu OrderCustom:=
Ve verzi 2007 můžete použit přímo pole s uživatelským pořadím.
Dim arrCustomOrder As String
arrCustomOrder = "zluta,cervena,zelena,modra,hneda,cerna"
ActiveWorkbook.Worksheets(1).Sort.SortFields.Clear
ActiveWorkbook.Worksheets(1).Sort.SortFields.Add Key:=Range("A1:A8"), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
CustomOrder:=CStr(arrCustomOrder), _
DataOption:=xlSortNormal
-
3, Nelze řadit podle čísel
Pro správnou funkci je zapotřebí následující
-
a, Hlavní pole - arrMain - které obsahuje neseřazené položky
b, Uživatelské pole - arrCustomOrder - které obsahuje uživatelský seznam
řazení
c, pomocné pole pro řazení - arrTemp - které bude obsahovat seřazené pole
- tedy tu nejpomalejší - protože nelze rozdělit položky na menší a větší a
na těch provést seřazení jako to dělá metoda Quick-sort.
2, jelikož pole dat může obsahovat více položek než je v uživatelském seznamu,
musím zjišťovat jestli všechny záznamy byly seřazeny a pokud ne, procházím pole
dat položku po položce a kontroluji jestli je obsažena v poli uživatelského seznamu.
Pokud aktuální položka není obsažena v tomto seznamu, bude přeřazena nakonec
pomocného pole.
3, na konci řazení jsou seřazené data uložená v pomocném poli - arrTemp. Vzhledem
k tomu, že jsem nechtěl použít API funkce - CopyMemory, rozhodl jsem pro
klasické překlopení pomocného pole do hlavního pole pomocí cyklu For - Next.
Výhody tohoto řešení
-
1, použitelné na všech dostupných verzích Office
2, není třeba data přenášet na list a zpět
3, v nižších verzích Office (2003 a nižší) nemusíte přidávat data do
uživatelského seznamu, zjišťovat číslo a pak seznam zase mazat.
4, řadí podle čísel (odzkoušeny čísla s dvěmi desetinými místy)
5, poměrně rychle řešení pro položky do 5 000 položek
-
1, nad 5 000 položek může zpomalovat celý kód.
Všimněte si, že položka barvy "oranžová", kterou obsahuje hlavní pole, tedy neseřazené, není obsažená v uživatelském řazení a proto bude tato barva vždy řazena nakonci seřazeného pole.
Sub TestArray_2D_CustomSort()
Dim arrMain(1 To 7, 1 To 3) As Variant ' obsahuje neserazene data
Dim arrCustomOrder(1 To 6) As Variant ' uzivatelské pole
Dim byteColumnSort As Byte ' urcuje index pole, podle ktereho se radi
' vlozeni ukazkovych dat do pole s neserazenymi daty
arrMain(1, 1) = "blue" ' EN
arrMain(1, 2) = "blau" ' DE
arrMain(1, 3) = "modra" ' CZ
arrMain(2, 1) = "black" 'EN
arrMain(2, 2) = "schwarz" ' DE
arrMain(2, 3) = "cerna" ' CZ
arrMain(3, 1) = "orange" 'EN
arrMain(3, 2) = "orange" ' DE
arrMain(3, 3) = "oranzova" ' CZ
arrMain(4, 1) = "yellow" 'EN
arrMain(4, 2) = "gelb" ' DE
arrMain(4, 3) = "zluta" ' CZ
arrMain(5, 1) = "green" 'EN
arrMain(5, 2) = "grune" ' DE
arrMain(5, 3) = "zelena" ' CZ
arrMain(6, 1) = "brown" 'EN
arrMain(6, 2) = "braune" ' DE
arrMain(6, 3) = "hneda" ' CZ
arrMain(7, 1) = "red" ' EN
arrMain(7, 2) = "rot" ' DE
arrMain(7, 3) = "cervena" ' CZ
' vlozeni dat do pole - Custom Order (od nejsvetlejsi k nejtmavsi)
' pro priklad zvoleno Ceske razeni
arrCustomOrder(1) = "zluta"
arrCustomOrder(2) = "cervena"
arrCustomOrder(3) = "zelena"
arrCustomOrder(4) = "modra"
arrCustomOrder(5) = "hneda"
arrCustomOrder(6) = "cerna"
' EN (nezapomente zmenit hodnotu byteColumnSort =1 !)
' arrCustomOrder(1) = "yellow"
' arrCustomOrder(2) = "red"
' arrCustomOrder(3) = "green"
' arrCustomOrder(4) = "blue"
' arrCustomOrder(5) = "brown"
' arrCustomOrder(6) = "black"
' DE (nezapomente zmenit hodnotu byteColumnSort =2 !)
' arrCustomOrder(1) = "gelb"
' arrCustomOrder(2) = "rot"
' arrCustomOrder(3) = "grune"
' arrCustomOrder(4) = "blau"
' arrCustomOrder(5) = "braune"
' arrCustomOrder(6) = "schwarz"
' radit podle indexu pole arrMain (zde CESKY )
byteColumnSort = 3
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' PRO KONTROLU !
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
On Error Resume Next '
Application.DisplayAlerts = False '
Sheets("Check and delete").Delete '
Application.DisplayAlerts = True '
On Error GoTo 0 '
'
Sheets.Add '
ActiveSheet.Name = "Check and delete" '
Cells(1, 1) = "Neserazene pole" '
Cells(1, 2) = "Serazene pole dle uzivatelskeho seznamu" '
Cells(1, 3) = "Uzivatelsky seznam" '
Columns("A:C").AutoFit '
For i = LBound(arrMain, 1) To UBound(arrMain, 1) '
Cells(i + 1, 1) = arrMain(i, byteColumnSort) '
Next i '
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' Zavola funkci pro razeni 2D pole
If Array_2D_CustomSort(arrMain, arrCustomOrder, byteColumnSort) Then
Sheets("Check and delete").Activate
For i = LBound(arrMain, 1) To UBound(arrMain, 1)
Cells(i + 1, 2) = arrMain(i, byteColumnSort)
Next i
For i = LBound(arrCustomOrder) To UBound(arrCustomOrder)
Cells(i + 1, 3) = arrCustomOrder(i)
Next i
MsgBox "Konec"
Else
MsgBox "Chyba"
End If
End Sub
Function Array_2D_CustomSort(arrMain() As Variant, arrCustomOrder() As Variant, byteColumnSort As Byte) As Boolean
' Tento priklad pouziva 2D pole
' 1, Neserazene pole (arrMain)
' 2, Uzivatelske pole (arrCustomOrder)
' 3, Cislo rozmeru neserazeneho pole pro setrizeni (byteColumnSort)
' pouziva bubble-sort metodu
' verze: 1.0 28.9.2007 Autor: Premysl Lazecky
Dim arrTemp() As Variant ' pomocne pole k serazeni
Dim i As Integer, j As Integer, k As Integer
Dim intNextWriteposition As Integer ' uchovava posledni hodnotu pro zapis
Dim bolContain As Boolean
On Error GoTo errtitle
' Predimenzovani pole
ReDim arrTemp(LBound(arrMain, 1) To UBound(arrMain, 1), LBound(arrMain, 2) To UBound(arrMain, 2))
' razeni podle uzivatelskeho seznamu
For i = LBound(arrCustomOrder) To UBound(arrCustomOrder)
For j = LBound(arrMain, 1) To UBound(arrMain, 1)
' kdyz hodnota v hlavnim poli (v rozmeru ktery je zadan - byteColumnSort
' odpovida uzivatelskemu seznamu, je hodnota presunuta do prvniho
' volneho indexu pomocneho pole
If arrMain(j, byteColumnSort) = arrCustomOrder(i) Then
' udrzuje posledni volny index pomocneho pole
intNextWriteposition = intNextWriteposition + 1
' prepise vsechny data do pomocneho pole
For k = LBound(arrTemp, 2) To UBound(arrTemp, 2)
arrTemp(intNextWriteposition, k) = arrMain(j, k)
Next k
End If
Next j
Next i
' Zkontroluje zda pole Temp ma stejny pocet polozek jako hlavni pole
' Protoze nektere polozky, ktere obsahuje Hlavni pole nemuseji odpovidat
' polozkam v uzivatelskem razeni, vsechny tyto polozky budou presunuty na
' konec pole arrTemp
If intNextWriteposition < UBound(arrMain, 1) Then
For i = LBound(arrMain) To UBound(arrMain)
bolContain = False
For j = LBound(arrCustomOrder, 1) To UBound(arrCustomOrder, 1)
If arrMain(i, byteColumnSort) = arrCustomOrder(j) Then
bolContain = True
Exit For
End If
Next j
' pokud promenna "bolContain" = False, bude polozka presunuta na
' posledni volny index pole arrTemp"
If Not bolContain Then
intNextWriteposition = intNextWriteposition + 1
For k = LBound(arrTemp, 2) To UBound(arrTemp, 2)
arrTemp(intNextWriteposition, k) = arrMain(i, k)
Next k
End If
Next i
End If
' kopiruje pomocne pole do hlavniho pole
' nechtel jsem pouzit API funkce
For j = LBound(arrMain, 1) To UBound(arrMain, 1)
For k = LBound(arrTemp, 2) To UBound(arrTemp, 2)
arrMain(j, k) = arrTemp(j, k)
Next k
Next j
Erase arrTemp
Array_2D_CustomSort = True
Exit Function
errtitle:
Array_2D_CustomSort = False
Erase arrTemp
End Function
Komentáře
Přehled komentářů
You revealed this really well.
thesis page https://topswritingservices.com masters dissertation writing services https://helpwithdissertationwriting.com
How to fritter away Google
(DavidJug, 25. 12. 2022 1:03)That means you'll perceive some stylish features and have access to additional channels where you can win visibility, without having to designate nous of some complicated, manual migration process. https://googlec5.com
cialis generic cialiswithdapoxetine.com
(cialis without a doctor prescription, 27. 12. 2021 19:38)
generic cialis https://cialiswithdapoxetine.com/
Im happy I now registered
(Jerrold, 19. 11. 2021 22:16)
Upadłość Konsumencka Sanok Prawo to zostało stworzone, aby dać
ludziom, którzy są przytłoczeni przez ich długów szansę, aby zacząć od nowa z czystym kontem.
Ubieganie się o upadłość konsumencką w Sanoku jest skomplikowanym procesem, więc zaleca się, aby skorzystać z
usług prawnika, aby upewnić się, że postępujesz zgodnie
z prawem ścisłych wytycznych. - Upadłość Konsumencka Sanok
cialis online cialiswithdapoxetine.com
(cialis with dapoxetine overnight to, 29. 10. 2021 18:00)
buy cialis usa https://cialiswithdapoxetine.com/
cialis price cialiswithdapoxetine.com
(cheap cialis, 6. 10. 2021 15:50)
https://cialiswithdapoxetine.com/ buy cialis usa
tadalafil dosis
(Rosita, 11. 9. 2021 16:56)
Good way of telling, and pleasant article to get infokrmation concerning my presentation subject matter, which i am
ging tto preseht in school.
https://harborbaystorage.net/
tadalafil dosis
elitadalafill
(tadalafil 40 mg daily, 8. 4. 2021 12:49)tadalafil 40 https://elitadalafill.com/ 40 mg tadalafil
vegavardenafil
(vardenafil sublingual under tongue, 4. 4. 2021 17:49)vardenafil tablets https://vegavardenafil.com/ generic vardenafil 20mg
writing an argumentative essay
(Mckinley, 2. 2. 2021 8:17)
I really like whuat you guys are usually up too. This tyupe of clever
work annd coverage! Keep up the excellent works guys I've added yoou
guys to my blogroll.
https://www.tabletennisdaily.com/forum/member.php?94500-danaobrien1999
Preserve 5% now together with your lower prrice
writing an argumentative essay
writing an argumentative essay
razeni podle barvy bunky nebo pisma, excek2000
(bluk, 31. 7. 2016 17:47)Zdravim. Myslite, ze by sla vytvorit funkce nebo kod, ktery by mi pomohl radit viz nadpis? Prolezl jsem cely cesky internet a prd, pac novejsi excely jiz tuto funkci implicitne maji. Dekuji za pripadnou reakci.
amazing college essay n65tgk
(EugeneCex, 5. 4. 2023 22:57)