Всем добрый день! Поискав на форуме не нашел ничего про преобразование диапазона чисел в регулярные выражения. Если у кого-то есть - буду благодарен. Ну а пока, решил сделать его сам. В процессе наткнулся на задачку, к которой не могу найти подход. Нужно разбить диапазон чисел по разрядам: Единицы должны переходить в десятки, десятки в сотни. Потом в обратную сторону до конечного значения. Итак:
Например есть диапазон: 778 - 877 (99 значений) Необходимо его разбить следующим образом:
778-779 (2 значения) - диапазон до изменения второго разряда (десятки) (меняется с 7 на 8, так как единица обнуляется после значения 9. следующее число будет уже 780)
780-799 (19 значений) - диапазон до изменения первого разряда (после 799 идет 800: первый разряд переходит с 7 на 8 )
Так, как нам не нужен диапазон 9хх (у нас край диапазона - 877 см. условие), то идем в обратную сторону:
800-869 - (69 значений) - диапазон до изменения второго разряда (десятки) (после 869 идет 870) 870-877 - (7 значений) - диапазон до конца.
Вот такая интересная нетривиальная задачка. На входе - диапазон значений ( в одной ячейке ОТ в другой ДО), на выходе - 4 диапазона в ячейках В идеале - инструмент должен быть универсальный - диапазоны могут быть четырехзначные, пятизначные и т.п
Я начал диапазоны в массивы заносить, потом пытался сравнивать..в итоге запутался окончательно! ) Может есть какая-то готовая математическая функция? Может похожая? я сам адаптирую ее
Если есть любители поломать голову - буду благодарен
Т.е. дан ряд идущих подряд упорядоченных по возрастанию чисел, и признак окончания очередного диапазона - это момент перехода с 6 на 7 или с 7 на 8 в любом разряде кроме первого? Если так, то не понимаю, в чём нетривиальность задачи.
Ну, в принципе верно. Только переход с 6 на 7 или 7 на 8 - это в данном конкретном примере. А в общем случае признак - изменение на единицу сначала единиц, потом десяток, потом сотен
В общем пока алгоритм вижу такой. Объявляете массив чисел. В него записываете все числа, которые нужно разбить на диапазоны. Потом циклом проходите по всему этому массиву и сравниваете разряды в текущем элементе массива с разрядами предыдущего элемента массива. Если в результе сравнения выполнилось условие окончания текущего диапазоны и начала следующего, то начинаете записываете текущий элемент массива в новый столбец / новую строку таблицы Excel. Для разделения числа на разряды можно использовать такой способ:
Код
x = 12345 ' число, которое разбиваем на разряды
Do While (x >= 10)
y = x - Int(x / 10) * 10
MsgBox (y)
x = Int(x / 10)
Loop
MsgBox (x)
Function SplitDigitRange(mi&, ma&, Optional r% = 1, Optional dr% = 1, Optional s$ = "") As String
Dim v&, i&, u&
If Int(Log(ma) / Log(10)) < r Then dr = -1
i = Int(mi / 10 ^ r) * 10 ^ r: u = i + 10 ^ r - 1:
u = IIf(u < ma, u, Int(ma / 10 ^ (r - 1)) * 10 ^ (r - 1) - IIf(r = 1, 0, 1)): If mi = ma Then u = ma
s = s & ", " & mi & "-" & u
If r + dr = 0 Or u = ma Then SplitDigitRange = Right(s, Len(s) - 2) Else SplitDigitRange = SplitDigitRange(u + 1, ma, r + dr, dr, s)
End Function
Пример вызова SplitDigitRange
Код
Sub Split()
Debug.Print SplitDigitRange(112, 53741)
End Sub
Equio - спасибо. Ваш способ делить длинное число на цифры оригинальнее моего. Взял на вооружение, спасибо! Подход по сравнению массивов я и думал реализовать, но запутался в самом процессе(( Ігор Гончаренко, Спасибо за функцию! Однако, она возвращает одно лишнее значение. На уменьшение нужно идти на один шаг раньше
Вот диапазон, который я вставил: 778-877 Результат функции: То, что выделил жирным - лишняя итерация В обратную сторону на единицу шаг не нужен. Остальное все супер. Можно это как-то поправить? или нарушится логика функции и лучше потом уже из текстового результата это лишнее значение вырезать? "778-779, 780-799, 800-799, 800-869, 870-877"
Function SplitDigitRange(mi&, ma&, Optional r% = 1, Optional dr% = 1, Optional s$ = "") As String
Dim u&, r1%
If mi >= ma Then SplitDigitRange = Right(s, Len(s) - 2): Exit Function
u = Int(mi / 10 ^ r) * 10 ^ r + 10 ^ r - 1: r1 = r: If u >= ma Then dr = -1
Do While (u > ma And r1 > 0) Or u < mi
r1 = r1 - 1: u = Int(ma / 10 ^ r1) * 10 ^ r1 - IIf(r1 = 0, 0, 1)
Loop
s = s & ", " & mi & "-" & u
If r + dr = 0 Then SplitDigitRange = Right(s, Len(s) - 2) Else SplitDigitRange = SplitDigitRange(u + 1, ma, r + dr, dr, s)
End Function
Sub Split1()
Debug.Print SplitDigitRange(778, 877)
End Sub
Ігор Гончаренко, не получается в обратную сторону если вести другой интервал: 501-699 dubug: 501-509, 510-599, 600-689, 690-699 - жирный шрифт - лишнее В сторону уменьшения от идет через десятки. Здесь нужен последний интервал - 600-699. Последнее значение, после которого 6 переходит в 7