Sort list based on text/numeric/date-time in any column

This code is based on the articls
"Sorting the list based on text in any column" &
"Sorting list on Numeric Column".

The follwing code combines both articals and adds a new sort type Date/Time sort.

#include          // MFC Ole
#include         // Ole TimeData something...

Add function

// Compare two string by their column types
//
// returns:
//    Zero if the strings are identical,
//    < 0 if cstL is less than cstR,
//    > 0 if cstL is greater than cstR.
//
int CMyListCtrl::CmpItems(CString cstL, CString cstR, int nCol)
{
   switch (nCol) {
      //Date time column(s)
      //***********************
      case 0:

         COleDateTime odtL;
         COleDateTime odtR;
         odtL.ParseDateTime(cstL);
         odtR.ParseDateTime(cstR);
         COleDateTimeSpan spanElapsed = odtL - odtR;
         if (spanElapsed.GetStatus() == COleDateTimeSpan::invalid ) {
            // Invalid Date time.
            ASSERT(FALSE);
            return(0);
         }
         return((int)spanElapsed.GetTotalSeconds());
      }

      //Numbers column(s)
      //***********************
      case 1:
      case 4:
         return(atoi(cstL) - atoi(cstR));

      // Strings column(s)
      //***********************
      //***********************
      default:
         return (cstL.Compare(cstR));
   }
}

Modified lines ==> /*!!!*/
bool CMyListCtrl::SortNumericItems( int nCol, BOOL bAscending,int low/*=0*, int high/*=-1* )
{
	if( nCol >= ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount() )
		return FALSE;

	if( high == -1 ) high = GetItemCount() - 1;

	int lo = low;
	int hi = high;
	CString midItem;

	if( hi <= lo )
	      return FALSE;

	midItem = GetItemText( (lo+hi)/2, nCol );

	// loop through the list until indices cross
	while( lo <= hi )
	{
 		// rowText will hold all column text for one row
 		CStringArray rowText;

 		// find the first element that is greater than or equal to
 		// the partition element starting from the left Index.
  
		if( bAscending )
  			//while( ( lo < high ) && (atoi(GetItemText(lo, nCol)) < midItem ) )
			/*!!!*  while( ( lo < high ) && ( CmpItems( GetItemText(lo, nCol) , midItem, nCol) < 0 ) )
   				++lo;
 		else
  			//while( ( lo < high ) && (atoi(GetItemText(lo, nCol)) > midItem ) )
			/*!!!*  while( ( lo < high ) && ( CmpItems( GetItemText(lo, nCol) , midItem, nCol) > 0 ) )
   			++lo;

 		// find an element that is smaller than or equal to
 		// the partition element starting from the right Index.
 		if( bAscending )
  			//while( ( hi > low ) && (atoi(GetItemText(hi, nCol)) > midItem ) )
			/*!!!*  while( ( hi > low ) && ( CmpItems(GetItemText(hi, nCol) , midItem, nCol ) > 0 ) )
   				--hi;
 		else
  			//while( ( hi > low ) && (atoi(GetItemText(hi, nCol)) < midItem ) )
			/*!!!*  while( ( hi > low ) && ( CmpItems(GetItemText(hi, nCol) , midItem, nCol ) < 0 ) )
   			--hi;

 		// if the indexes have not crossed, swap
 		// and if the items are not equal
 		if( lo <= hi )
 		{
			// swap only if the items are not equal
			//if(atoi(GetItemText(lo, nCol)) != atoi(GetItemText(hi, nCol)) )
			/*!!!*  if( CmpItems (GetItemText(lo, nCol) , GetItemText(hi, nCol), Col  ) != 0) {
	   			// swap the rows
	   			LV_ITEM lvitemlo, lvitemhi;

	   			int nColCount = ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
	   			rowText.SetSize( nColCount );

	   			int i;
	   			for( i=0; i < nColCount; i++)
	      			rowText[i] = GetItemText(lo, i);

	   			lvitemlo.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
	   			lvitemlo.iItem = lo;
	   			lvitemlo.iSubItem = 0;
	   			lvitemlo.stateMask = LVIS_CUT | LVIS_DROPHILITED |
	      					LVIS_FOCUSED |  LVIS_SELECTED |
	      					LVIS_OVERLAYMASK | LVIS_STATEIMAGEMASK;
	   			lvitemhi = lvitemlo;
	   			lvitemhi.iItem = hi;

	   			GetItem( &lvitemlo );
	   			GetItem( &lvitemhi );

	   			for( i=0; i< nColCount; i++)
	      			SetItemText(lo, i, GetItemText(hi, i) );

	   			lvitemhi.iItem = lo;
	   			SetItem( &lvitemhi );

	   			for( i=0; i< nColCount; i++)
	      			SetItemText(hi, i, rowText[i]);

	   			lvitemlo.iItem = hi;
	   			SetItem( &lvitemlo );
	  		}

	  		++lo;
	  		--hi;
	 	}
	}

	// If the right index has not reached the left side of array
	// must now sort the left partition.
	if( low < hi )
 		SortNumericItems( nCol, bAscending , low, hi);

	// If the left index has not reached the right side of array
	// must now sort the right partition.
	if( lo < high )
 		SortNumericItems( nCol, bAscending , lo, high );

	return TRUE;
}



Comments

  • Lots of bugs....

    Posted by Legacy on 11/08/2000 12:00am

    Originally posted by: Goetz Hasselberg

    I was looking for a clue to solve my problems with sorting of ListCtrls.
    Your code seemed to do exactly what I needed, so I copied it and put it into my application but it's full of bugs!
    There are some struggles with variable-names that are written with underscores here and without underscores there aswell as brackets right in the middle of the case-construct.
    Ok, all in all it helped my to solve my problems, but please(!): Releasing correct code would have been much more helpful!

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Salesforce has been recognized by Gartner as a leader in this report for three years in a row. This graphic was published by Gartner, Inc. as part of a larger research document and should be evaluated in the context of the entire document. The Gartner document is available upon request from Salesforce.com. Gartner does not endorse any vendor, product or service depicted in its research publications, and does not advise technology users to select only those vendors with the highest ratings. Gartner research …

  • Get an in-depth look at the services and tools that the #1 cloud platform for creating next-gen apps offers to help you build apps faster. You'll learn how Salesforce gives you a competitive advantage with Platform as a Service like no other. Details include: Salesforce's Multitenant Cloud Infrastructure and Database App Builder that lets anyone build apps fast Force.com for building employee-facing apps Heroku for beautiful and engaging customer-facing apps

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date