Я написал алгоритм, который сортирует целочисленные значения в порядке возрастания, но сохраняет соответствующую информацию в смежных ячейках, отсортированную в соответствии с ней. Он использует Arr в качестве моментального снимка сортируемой ячейки, строит массив индексов значений (TagIndex), если они были отсортированы в порядке возрастания, затем применяет TagIndex к этому и соседним ячейкам.Операторы неравенства терпят неудачу при сравнении вариантов
Например, он должен принять это ...
----------------------------------
| 5/14/12 | 87 | 91 | 102 |
| 12/8/11 | 96 | 81 | 93 |
| 9/30/10 | 75 | 101 | 74 |
| 4/26/08 | 107 | 95 | 64 |
----------------------------------
... и сортировать по второй колонке крайней левой, чтобы превратить его в это:
----------------------------------
| 9/30/10 | 75 | 101 | 74 |
| 5/4/12 | 87 | 91 | 102 |
| 12/8/11 | 96 | 81 | 93 |
| 4/26/08 | 107 | 95 | 64 |
----------------------------------
Вот код:
Dim cell as Range
Dim Arr, TempArr, BoundVal As Variant
For Each cell In ActiveSheet.ListObjects("Table2").ListColumns(targetColumn).DataBodyRange
Arr = Split(cell.Value, Chr(10))
ReDim TagIndex(0 To UBound(Arr)) As Variant
For i = 0 To UBound(Arr)
BoundVal = Arr(i) 'starts with first value and index
TagIndex(i) = i 'as defaults
For j = 0 To UBound(Arr)
If Arr(j) < BoundVal Then 'if sorter finds a smaller value,
BoundVal = Arr(j) 'flags it...
TagIndex(i) = j '...and its index as smaller,
End If 'keeps looking,
Next j 'leaves For loop with the smallest,
Arr(TagIndex(i)) = 201 'and moves it up out of reach so sorter won't
Next i 'flag it anymore (none of the values go above 200)
For j = leftBoundColumn To rightBoundColumn
TempArr = Split(Cells(cell.Row, j).Value, Chr(10))
For i = 0 To UBound(TempArr)
Arr(i) = TempArr(TagIndex(i))
Next i
Cells(cell.Row, j).Value = Join(Arr, Chr(10))
Next j
Next cell
Этот код работал с dandy сначала, но у меня было две отдельные версии: одна для сортировки целых чисел и другая для сортировки даты - и хотел, чтобы они обрабатывали оба. Для этого я попытался объявить BoundVal как вариант в новом. Когда результаты оказались неустойчивыми, острое использование MsgBox'es показало, что он не прошел логические тесты у оператора <, пытаясь сказать мне «Нет» для 96 < 201 и «Да» для 107 < 75 (но нет для 117/107, как и должно).
Если я вернусь к объявлению BoundVal как целого, он начнет нормально работать для целых чисел, но при попытке использовать его в датах дает ошибку типа «Несоответствие».
Есть ли какая-то фундаментальная проблема при сравнении Arr (j) < BoundVal? Оба варианта, оба из нисходящих строк. Есть идеи?
Просто потому, что вы объявляете переменную, которая будет вариантом, не означает, что она остается такой же, как во время выполнения. Просто проверьте его самостоятельно: 'Dim varTMP As Variant', затем установите его в 20 в следующей строке' varTMP = 20' и, наконец, спросите, какой тип переменной является 'Debug.Print TypeName (varTMP)'. Вы получите ответ «Целое число». Итак, возможно, вы хотите включить еще несколько текстовых полей, чтобы проверить, что вы сравниваете друг с другом ... – Ralph
Спасибо, это проблема. Но BoundVal = CVar (Arr (i)) не преуспевает в изменении BoundVal к варианту. Как еще это можно сделать? –