none
Sorting array with VBS RRS feed

  • Question

  • I am reading data from file to array with For Next loop. I get the data to array but when I try to pass this unsorted array to bubblesort function I get type mismatch error. I don't understand why.

    'This causes type mismatch

    arrTestArray = BubbleSort(arrTestArray)

    Function BubbleSort(arrValues)

        Dim j, k, Temp
        For j = 0 To UBound(arrValues) - 1
            For k = j + 1 To UBound(arrValues)
                If (arrValues(j) > arrValues(k)) Then
                    Temp = arrValues(j)
                    arrValues(j) = arrValues(k)
                    arrValues(k) = Temp
                End If
            Next
        Next
     BubbleSort = arrValues
    End Function

    Friday, June 13, 2014 2:52 PM

Answers

  • There is a bug in the logic.  THe bounds are Ubound and LBound - not UBound -1

    Try it this way:

    arrTestArray = Array("a5","a4","a3","a2","a1")
    
    BubbleSort arrTestArray
    for i = 0 to 4
      WScript.Echo arrTestArray(i)
    Next
    Function BubbleSort(arrValues)
    
         Dim j, k, Temp
         For j = LBound(arrValues) To UBound(arrValues)
             For k = j + 1 To UBound(arrValues)
                 If (arrValues(j) > arrValues(k)) Then
                     Temp = arrValues(j)
                     arrValues(j) = arrValues(k)
                     arrValues(k) = Temp
                 End If
             Next
         Next
     End Function 
    You need to retrieve LBound for the initializer as arrays can be bounded however we want.  Office arrays are "1" based.


    ¯\_(ツ)_/¯

    • Marked as answer by DamonWH Friday, June 13, 2014 3:57 PM
    Friday, June 13, 2014 3:34 PM

All replies

  • What are you passing to the function as arrValues?



    -- Bill Stewart [Bill_Stewart]

    Friday, June 13, 2014 3:16 PM
    Moderator
  • While line of code generates the error?
    What is the contents of arrTestArray? Strings? Numbers? Objects? Arrays?
    Friday, June 13, 2014 3:19 PM
  • This works correctly:

    arrTestArray = Array(5,4,3,2,1)
    
    BubbleSort arrTestArray
    MsgBox arrTestArray(0)
    Function BubbleSort(arrValues)
    
         Dim j, k, Temp
         For j = 0 To UBound(arrValues) - 1
             For k = j + 1 To UBound(arrValues)
                 If (arrValues(j) > arrValues(k)) Then
                     Temp = arrValues(j)
                     arrValues(j) = arrValues(k)
                     arrValues(k) = Temp
                 End If
             Next
         Next
     End Function 

    Try it to see that it reverse the array correctly.

    It will work with simple strings but not with objects.


    ¯\_(ツ)_/¯

    Friday, June 13, 2014 3:30 PM
  • There is a bug in the logic.  THe bounds are Ubound and LBound - not UBound -1

    Try it this way:

    arrTestArray = Array("a5","a4","a3","a2","a1")
    
    BubbleSort arrTestArray
    for i = 0 to 4
      WScript.Echo arrTestArray(i)
    Next
    Function BubbleSort(arrValues)
    
         Dim j, k, Temp
         For j = LBound(arrValues) To UBound(arrValues)
             For k = j + 1 To UBound(arrValues)
                 If (arrValues(j) > arrValues(k)) Then
                     Temp = arrValues(j)
                     arrValues(j) = arrValues(k)
                     arrValues(k) = Temp
                 End If
             Next
         Next
     End Function 
    You need to retrieve LBound for the initializer as arrays can be bounded however we want.  Office arrays are "1" based.


    ¯\_(ツ)_/¯

    • Marked as answer by DamonWH Friday, June 13, 2014 3:57 PM
    Friday, June 13, 2014 3:34 PM
  • One other note that can confuse people.  Passing an array will always pass it by value.  Alter any object in a subroutine will alter the original object.  Simple values will only be altered if we add the ByVal keyword.

    ¯\_(ツ)_/¯

    Friday, June 13, 2014 3:36 PM
  • Thanks man! This seems to be working.
    Friday, June 13, 2014 3:56 PM
  • This would be so much easier choice for me but I cannot use it. Sorting with one line of code!

    Dim AL
    Set AL = CreateObject("System.Collections.ArrayList")
    AL.Add C
    AL.Add B
    AL.Add A
    AL.Sort

    My script needs to run in WinPE. I don't have dotnet framework there so I need to do this hard way.





    • Edited by DamonWH Friday, June 13, 2014 4:05 PM
    Friday, June 13, 2014 4:02 PM
  • There is a bug in the logic.  THe bounds are Ubound and LBound - not UBound -1
    Good catch. I would also note that in VBScript LBound is always 0.

    -- Bill Stewart [Bill_Stewart]

    Friday, June 13, 2014 5:35 PM
    Moderator
  • There is a bug in the logic.  THe bounds are Ubound and LBound - not UBound -1

    Good catch. I would also note that in VBScript LBound is always 0.

    -- Bill Stewart [Bill_Stewart]

    Except when it is an Office array then it is 1.

    In Office it is easier to use "Count" as it is both length and UBound because of one based arrays and collections.

    Office VB arrays created with Dim are zero based.


    ¯\_(ツ)_/¯

    Friday, June 13, 2014 5:53 PM
  • I should also note that in Office VBA and in VB6 we can do this:

    Dim someArray(1 To 10)Dim someArray(-3 To 12)
    Dim someArray(-10 To -1)This is where the need for LBound comes from. If you generate an array like this in Office and pass it to VBScript then you need to use LBound.

    The misuse of UBound -1 is a takeoff on using Length for the limit.

    for I = 0 to A.Length -1

    which would be better stated like this:

    i=0
    while(i < a.length)
        ....
       i = i - 1
    wend

    Of course VBScript doesn't not have an array length function.


    ¯\_(ツ)_/¯

    Friday, June 13, 2014 6:02 PM
  • Correct, other flavors of VB (VBA, VB6) let you use a different array lower bound (hence needed LBound function). But in VBScript LBound is always 0. Doesn't hurt to use it in VBScript anyway; just a note.


    -- Bill Stewart [Bill_Stewart]

    Friday, June 13, 2014 6:17 PM
    Moderator
  • Correct, other flavors of VB (VBA, VB6) let you use a different array lower bound (hence needed LBound function). But in VBScript LBound is always 0. Doesn't hurt to use it in VBScript anyway; just a note.


    -- Bill Stewart [Bill_Stewart]

    I agree.  I usually use 0 but we need to be mindful that when mixing systems it can fool us.  LBound never fails.

    In this instance it was tipical error #1 - the use of UBound(..) - 1 and trying to alter an array incorrectly.

    I still doubt the original error.


    ¯\_(ツ)_/¯

    Friday, June 13, 2014 6:21 PM