I am confused by the name of your procedure: "SortGridByColumn" implies for me that the entire grid is sorted so that the cells in the given column are ordered; I would expect that complete rows are exchanged so that each cell in each row keeps its horizontal neighbour. (This is already available in TStringGrid as method SortColRow(IsColumn: Boolean; index:Integer).
Your code, however, sorts only the cells in the given column, all other cells are not touched. If this really is your intention you could do this alternatively by copying the column to be sorted into a TStringList which has sorting capabilities. You'll have to provide a custom compare function because you want to have blank cells at the end of the column after sorting.
The attached project demonstrates all cases:
- Button1 triggers your function "SortGridByColumn".
- Button2 triggers TStringGrid.SortByColRow and sorts the entire grid
- Button3 uses the auxiliary TStringList for sorting.
All the non-blank cells in this demo grid have an object attached; it is the same integer shown as cell text cast to a pointer. When you click into the grid the Cells[] text and the Objects[] are read from the clicked cell and displayed by two labels - both labels should always display the same. Note that all sorting methods tested keep Cells[] and Objects[] together. In case of SortByColRow this is because the grid stores Cells[] and Objects[] as elements of the same internal record (TCellProps) and thus stay together automatically when the cell records are rearranged during sorting. In case of the aux stringlist, the Assign method also copies the pointers along with the texts into the destination list.