
Swap X and Y of an array
I am modifying an ADSI/ASP script that I did not write, and my boss has asked me to sort the array held within. I used the "Quicksort" code I found on this site, which works great, however, the original array is backwards  what should show up as columns ends up as rows and vice versa.<BR><BR>Is there a painless way to create a new array from the old array, reversing the values, and then quicksorting the new array? There is too much code on the original array to begin rearranging things there...<BR><BR>Or, alternatively, is there an ADSI call (using the WinNT provider) that will sort by an attribute so that the original array is sorted corectly? (it currently doesn't sort) I am BRAND NEW to ADSI... I'm trying to work with print queues...

Is this a 2D array?
That you got from RecordSet.GetRows?<BR><BR>If so, you just need to change what your definition of columns and rows is!<BR><BR>If you've been doing:<BR><BR>If ar(row,0) > ar(otherRow,0) Then...<BR><BR>Change it to<BR><BR>If ar(0,row) > ar(0,otherRow) Then ...<BR><BR>Just swap column and array usage in all the array indices. <BR><BR>GetRows *always* returns an array where you access individual cells via<BR><BR>ar( columnNumber, rowNumber )<BR><BR>and if the quicksort code is expecting<BR><BR>ar( rowNumber, columnNumber )<BR><BR>well...you see the point?<BR><BR>

RE: Is this a 2D array?
It is a 2D array, but it didn't come from a recordset. (Otherwise I think I could just sort the recordset first, right? Since my final goal is to sort the listing.)<BR><BR>'First get a list of printqueues from the WinNT ADSI provider:<BR><BR> Set objPrinters = GetObject("WinNT://" & strComputer & ",computer")<BR> objPrinters.filter = Array("PrintQueue")<BR><BR> ' then iterate through all the (shared) printers to get the total number<BR> iTotal = 0<BR> For Each objPrinter In objPrinters<BR> iTotal = iTotal + 1<BR> Next<BR> iRevStart = iTotal  iEnd + 1<BR> iRevEnd = iTotal  iStart + 1<BR><BR> If iEnd <= iTotal Then bShowNext = TRUE<BR><BR> iPrinters = 0<BR> i = 1<BR> For Each objPrinter In objPrinters<BR><BR> If i > iRevEnd Then Exit For<BR><BR> If i > iRevStart Then<BR> iPrinters = iPrinters + 1<BR><BR> 'then populate the array with data (these vars are defined earlier<BR> ReDim Preserve rgPrinters(ADSI_PRINTER_ATTRIBUTES, iPrinters)<BR> rgPrinters(ADSI_PRINTER_STATUS, iPrinters) = objPrinter.Status<BR> rgPrinters(ADSI_PRINTER_NAME, iPrinters) = objPrinter.Name<BR> 'continues with each attribute .....<BR> <BR> i = i + 1<BR> Next<BR><BR>'<BR><BR>So should I be swapping in this file or in the quicksort file? (I must just not be able to see the forest for the trees here...)

Yuck!
Let's see if we can improve that code *and* set it up for proper sorting!<BR><BR>Set objPrinters = GetObject("WinNT://" & strComputer & ",computer")<BR>objPrinters.filter = Array("PrintQueue")<BR><BR>ReDim rgPrinters(ADSI_PRINTER_ATTRIBUTES, 1000) ' arbitrary size<BR>count = 1<BR><BR>For Each objPrinter In objPrinters<BR> count = count + 1<BR> If count > UBound( rgPrinters, 2 ) Then<BR> ReDim Preserve rgPrinters(ADSI_PRINTER_ATTRIBUTES, count+100) ' arbitrary size<BR> End If<BR> rgPrinters(ADSI_PRINTER_STATUS, iPrinters) = objPrinter.Status<BR> rgPrinters(ADSI_PRINTER_NAME, iPrinters) = objPrinter.Name<BR> 'continues with each attribute .....<BR>Next<BR><BR>' cut array back to asused size<BR>ReDim Preserve rgPrinters(ADSI_PRINTER_ATTRIBUTES, count)<BR><BR>' *now* quicksort that array...<BR>...<BR>%><BR><BR>HOWEVER... I don't see what you mean about the columns and rows being reversed. They are *correct* in that rgPrinters array!<BR><BR>Are you *sure* that objPrinter is not a Recordset object???<BR><BR>It *feels* like it, since it has the .Filter property. <BR><BR>Did you ever try doing a .Sort on it??<BR><BR>

Yes, Yuck is the word....
No, I am not sure that it is not a Recordset, I just know that I didn't get a recordset using ADO where I could use a nice ORDER BY clause. I tried a .Sort and a .SortKey, errored on both:<BR><BR>The error occurred in Microsoft VBScript runtime errorError Code: 1B6 <BR>Description: Object doesn't support this property or method <BR>Note: Get ADSI Printers <BR><BR>I'm combing MS's site to see what the WinNT ADSI provider will support... not coming up with much...

Okay...I was just hoping...
I don't use ADSI (yet) so I was just hoping.<BR><BR>No biggy.<BR><BR>So now you have this nice array of printers to sort.<BR><BR>How big is it???? Maximum expected size, that is.<BR><BR>And explain again what is wrong with the quicksort you are using? It is sorting on the columns instead of the rows, is that it?<BR><BR>

I was hoping also... but it seems no dice...
We have somewhere in the neighborhood of 175 printers. I want to sort the list by printer location. <BR><BR>The quicksort code I cut and pasted from 4guys which I'll paste and can also be found here:<BR>http://www.4guysfromrolla.com/webtech/0127993.shtml<BR><BR>I expected to get a result where each row is one printer, and each column is one attribute, and that this would sort all printers (rows) by a specified attribute (column), like this (sort on column 2):<BR><BR>PrintQueue3 Floor25 HPLJ4<BR>PrintQueue2 Floor26 HPLJ4<BR>PrintQueue1 Floor27 HPLJ4<BR><BR>Instead the result I got was that each row was all the attribute values, and each column represented one printer, and what it did was sort by column, so it sorted the rows (of attributes) by the attribute values of one printer (column), like this (sort on column 2):<BR><BR>Floor25 Floor26 Floor27 <BR>HPLJ4 HPLJ4 HPLJ4<BR>PrintQueue3 PrintQueue2 PrintQueue1<BR><BR>It doesn't make sense to me... I'm going to run a test using good old sql and getrows and see what happens... (as more hairs go gray...)<BR><BR><BR>QUICKSORT CODE:<BR><BR><%@ Language="VBScript" %><BR><%<BR>Option Explicit<BR>Response.Write "<HTML><HEAD></HEAD><BODY BGCOLOR=""WHITE"">"<BR><BR><BR>Sub SwapRows(ary,row1,row2)<BR> '== This proc swaps two rows of an array <BR> Dim x,tempvar<BR> For x = 0 to Ubound(ary,2)<BR> tempvar = ary(row1,x) <BR> ary(row1,x) = ary(row2,x)<BR> ary(row2,x) = tempvar<BR> Next<BR>End Sub 'SwapRows<BR><BR>Sub QuickSort(vec,loBound,hiBound,SortField)<BR><BR> Dim pivot(),loSwap,hiSwap,temp,counter<BR> Redim pivot (Ubound(vec,2))<BR><BR> '== Two items to sort<BR> if hiBound  loBound = 1 then<BR> if vec(loBound,SortField) > vec(hiBound,SortField) then Call SwapRows(vec,hiBound,loBound)<BR> End If<BR><BR> '== Three or more items to sort<BR> <BR> For counter = 0 to Ubound(vec,2)<BR> pivot(counter) = vec(int((loBound + hiBound) / 2),counter)<BR> vec(int((loBound + hiBound) / 2),counter) = vec(loBound,counter)<BR> vec(loBound,counter) = pivot(counter)<BR> Next<BR><BR> loSwap = loBound + 1<BR> hiSwap = hiBound<BR> <BR> do<BR> '== Find the right loSwap<BR> while loSwap < hiSwap and vec(loSwap,SortField) <= pivot(SortField)<BR> loSwap = loSwap + 1<BR> wend<BR> '== Find the right hiSwap<BR> while vec(hiSwap,SortField) > pivot(SortField)<BR> hiSwap = hiSwap  1<BR> wend<BR> '== Swap values if loSwap is less then hiSwap<BR> if loSwap < hiSwap then Call SwapRows(vec,loSwap,hiSwap)<BR><BR><BR> loop while loSwap < hiSwap<BR> <BR> For counter = 0 to Ubound(vec,2)<BR> vec(loBound,counter) = vec(hiSwap,counter)<BR> vec(hiSwap,counter) = pivot(counter)<BR> Next<BR> <BR> '== Recursively call function .. the beauty of Quicksort<BR> '== 2 or more items in first section<BR> if loBound < (hiSwap  1) then Call QuickSort(vec,loBound,hiSwap1,SortField)<BR> '== 2 or more items in second section<BR> if hiSwap + 1 < hibound then Call QuickSort(vec,hiSwap+1,hiBound,SortField)<BR><BR>E nd Sub 'QuickSort<BR><BR>Sub PrintArray(vec,lo,hi,mark)<BR> '====<BR> '== Print out an array from the lo bound ==<BR> '== to the hi bound. Highlight the column ==<BR> '== whose number matches parm mark ==<BR> '====<BR><BR> Dim i,j<BR> Response.Write "<table border=""1"" cellspacing=""0"">"<BR> For i = lo to hi<BR> Response.Write "<tr>"<BR> For j = 0 to Ubound(vec,2)<BR> If j = mark then <BR> Response.Write "<td bgcolor=""FFFFCC"">"<BR> Else <BR> Response.Write "<td>"<BR> End If<BR> Response.Write vec(i,j) & "</td>"<BR> Next<BR> Response.Write "</tr>"<BR> Next<BR> Response.Write "</table>"<BR>End Sub 'PrintArray<BR><BR><BR><BR>Randomize<BR><BR>D im x(9,5),z,y<BR>Const col = 0<BR><BR><BR>For z = 0 to 9<BR> For y = 0 to 5<BR> x(z,y) = int(Rnd*1000)<BR> If (Rnd < 0.5) then x(z,y) = x(z,y)1000<BR> Next<BR>Next<BR><BR><BR>Response.Write "Here is a jumbled array:<BR>"<BR>Call PrintArray(x,0,9,col)<BR><BR>Call QuickSort(x,0,9,col)<BR><BR>Response.Write "<BR>Now the array is sorted!<BR>"<BR>Call PrintArray(x,0,9,col)<BR><BR>Response.Write "</BODY></HTML>"<BR>%><BR><BR><BR>

Same result using ADO and SQL
I get the same result using ADO to pull records from a SQL table using GetRows... The quicksort puts things backwords.<BR><BR>Can someone else check this? Are my expectations of what this code should be incorrect?<BR>

*EXACTLY* what I told you!
Look at this code, for example:<BR><BR>Sub SwapRows(ary,row1,row2) <BR> '== This proc swaps two rows of an array <BR> Dim x,tempvar <BR> For x = 0 to Ubound(ary,2) <BR> tempvar = ary(row1,x) <BR> ary(row1,x) = ary(row2,x) <BR> ary(row2,x) = tempvar <BR> Next <BR>End Sub 'SwapRows <BR><BR>That code does *NOT* swap rows in a standard VBScript 2D array!<BR><BR>The author of the code should be shot for reversing columns and rows!<BR><BR>It swaps *columns* of a standard VBS 2D array. <BR><BR>Like I said, you need to swap *ALL* column and array usage in that quicksort code!<BR><BR>For this routine:<BR><BR>Sub SwapRows(ary,row1,row2) <BR> '== This proc swaps two rows of an array <BR> Dim x,tempvar <BR> For x = 0 to Ubound(ary,1) <BR> tempvar = ary(x,row1) <BR> ary(x,row1) = ary(x,row2) <BR> ary(x,row2) = tempvar <BR> Next <BR>End Sub 'SwapRows <BR><BR>Note that I changed which UBOUND was used, too! All UBOUND usage in that code must swap from UBOUND(xx,1) to UBOUND(xx,2) and vice versa.<BR><BR>FINALLY...<BR><BR>Truthfully, this is a pretty crappy sort. Because although QuickSort itself is fast, this code suffers because it has to swap rows using that silly SUB that has to swap individual elements.<BR><BR>There are several ways to improve performance, but I'll let you get this code working first before we talk about them.<BR><BR>

Where'd you get the code from?
If it's from 4Guys, maybe we can get Scott to put up a caveat about the rows and columns being reversed from a standard VBS 2D arrangement.<BR><BR>
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

