2014-11-17 3 views
0

내 머리 (및 다른 Excel 프로그래밍 사이트의 다른 머리도)를 두드려서 Userform에 콤보 박스를 가져 와서 행을 정렬했습니다. 소스 스프레드 시트)를 알파 순서로 표시합니다.Excel에서 2D Bubblesort의 런타임 오류 VBA 배열

이상적으로는 2 차원 정렬이 필요하지만이 시점에서 작동하는 하나에 만족합니다.

현재, 아래로 떨어졌다 콤보 상자가 부분적으로 읽어

(마이너스 표시하지 않고 필요하지 않은 총알 포인트) :

  • 확대 MRKPayoutPlan
  • 척 PSERSFuture
  • 척 PSERSCurrent는

내가 원하는 것은 :

012 3,516,
  • 척 PSERSCurrent
  • 척 PSERSFuture
  • 줌 MRKPayoutPlan

첫번째 순서는 행 소스 시트에 나타나는 순서로부터 유도된다.

이 시점에서 런타임 오류 '13', 유형 불일치 오류가 발생합니다. 두 필드는 모두 텍스트 필드입니다 (이름은 성입니다. 다른 하나는 분류 코드입니다. 먼저 이름순으로 정렬하려고합니다).

다음은 VBA 코드의 두 가지 관련 섹션입니다. 누군가 내가이 문제를 해결할 수 있다면 최소한 가상의 맥주를 살 것입니다. Excel VBA가 가장 안락한 지역이 아닙니다. 다른 앱에서도이 작업을 수행 할 수 있지만 클라이언트 사양은이 모든 것이 Excel에서만 실행되어야한다는 것입니다. 미리 감사드립니다.

Private Sub UserForm_Initialize() 
    fPath = ThisWorkbook.Path & "\" 
    currentRow = 4 

    sheetName = Sheet5.Name 
    lastRow = Sheets(sheetName).Range("C" & Rows.Count).End(xlUp).Row 


    Dim rngUID As Range 
    Dim vList 

    Set rngUID = Range("vUID") 

    With rngUID 
     vList = Application.Index(.Cells, .Parent.Evaluate("ROW(" & .Address & ")"), Array(7, 1)) 
    End With 
    vList = BubbleSort2D(vList, 2, 1) 

    With ComboBox1 
     .ColumnCount = 2 
     .ColumnWidths = "100;100" 
     .List = vList 
    End With 

    PopulateControls 
End Sub 

Public Function BubbleSort2D(Strings, ParamArray SortColumns()) 
    Dim tempItem 
    Dim a      As Long 
    Dim e      As Long 
    Dim f      As Long 
    Dim g      As Long 
    Dim i      As String 
    Dim j      As String 
    Dim m()     As String 
    Dim n 
    Dim x As Long 
    Dim y As Long 
    Dim lngColumn As Long 


    e = 1 
    n = Strings 
    Do While e <> -1 

     For a = LBound(Strings) To UBound(Strings) - 1 
      For y = LBound(SortColumns) To UBound(SortColumns) 
       lngColumn = SortColumns(y) 
       i = n(a, lngColumn) 
       j = n(a + 1, lngColumn) 
       f = StrComp(i, j) 
       If f < 0 Then 
        Exit For 
       ElseIf f > 0 Then 
        For x = LBound(Strings, 2) To UBound(Strings, 2) 
         tempItem = n(a, x) 
         n(a, x) = n(a + 1, x) 
         n(a + 1, x) = tempItem 
        Next x 
        g = 1 
        Exit For 
       End If 
      Next y 
     Next a 
     If g = 1 Then 
      e = 1 
     Else 
      e = -1 
     End If 

     g = 0 
    Loop 
    BubbleSort2D = n 
End Function 
+0

어떻게 두 번째 차원에서 정렬해야합니까? 모든 데이터가 하위 벡터에 남아 있습니까? – cheezsteak

+0

성, 분류 (예 : Smith A101, Smith A201, Thompson C100). 콤보 박스가 두 필드를 모두 보여줄 필요가 있기 때문에 하나의 이름으로 갈 수있는 최대 4 ~ 5 개의 분류가 있기 때문에 이름 정렬 만하면된다. 정렬되지 않은 배열로 채워지면 모든 것이 제대로 작동하지만 약 2000 개의 행이 있으면 필요한만큼 작동하지 않습니다. – Craig

+0

질문을 편집하여 정렬되지 않은 2D 배열과 정렬 된 2D 배열의 모습을 보여줄 수 있습니까? 그냥 작은 3x3 블록? – cheezsteak

답변

0

여기는 VBA source의 버블 정렬입니다.

Public Sub BubbleSort(ByRef sequence As Variant, _ 
     ByVal lower As Long, ByVal upper As Long) 

    Dim upperIt As Long 
    For upperIt = upper To lower + 1 Step -1 

     Dim hasSwapped As Boolean 
     hasSwapped = False 

     Dim bubble As Long 
     For bubble = lower To upperIt - 1 

      If sequence(bubble) > sequence(bubble + 1) Then 

       Dim t as Variant 
       t = sequence(bubble) 

       sequence(bubble) = sequence(bubble + 1) 
       sequence(bubble + 1) = t 
       hasSwapped = True 

      End If 

     Next bubble 

     If Not hasSwapped Then Exit Sub 

    Next upperIt 

End Sub 

단일 문자 대신 자신이 무엇인지 지정하는 변수 이름을 사용하면 더 쉽게 읽을 수 있습니다.

2D 정렬의 경우. 하지마. 각 배열을 개별적으로 정렬 한 다음 같은 방법으로 배열 배열을 정렬하십시오. 열을 비교하기 위해 추상화를 제공해야합니다. 동시에 둘 다 정렬하려고하지 마십시오. 나는 그게 좋은 생각 인 시나리오를 생각할 수 없다. 어떤 이유로 요소가 2D 배열에서 하위 배열을 변경할 수있는 경우이를 1 배열로 평면화하고 정렬 한 다음 다시 2D 배열로 분할합니다.

솔직히 나는 당신의 특정 문제를 이해하고 있습니다. 1D 시퀀스에서 1D 시퀀스로 이동하므로 2D 배열은 불필요한 복잡성이라고 생각합니다.

대신
If sequence(bubble) > sequence(bubble +1) Then '... 

첫 번째 인수가 두 번째로 교환 할 필요가있는 경우 True을 반환하는 사용자 정의 비교 함수

ComboBoxItemCompare(sequence(bubble), sequence(bubble + 1)) 

로 대체, 비교 문을 수정 거품 정렬 루틴을 사용 .