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

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >

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

  • Many enterprises are working with an IT architecture that's evolved over time. As business needs evolve, IT must decide whether to modernize incrementally, or all at once. Each approach has its benefits and drawbacks. Identity Management is key to modernizing IT; it plays a crucial role in migrating to cloud apps like Office 365 or HR information systems, building web and mobile apps, and opening developer access to business systems. Read how Okta's modern approach to identity management helps business lower …

  • Analytics in the cloud democratize the ability of developers and non-technical business users alike to put ever-expanding data universes to work. Download this eBook to learn how to plan and build a cloud-based enterprise analytics platform, tune that environment to meet changing business requirements, and maximize the TCO benefits of moving analytics to the cloud.

Most Popular Programming Stories

More for Developers

RSS Feeds

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