Option Explicit
Option Private Module
'====================================================================================================
Sub Tester()
Dim rng As Range
Dim x, arrR() As Range
Dim tx$, t!, tt!, i&
tt = Timer
t = Timer
tx = GetAddress()
Debug.Print "GetAddress:", Format$(Timer - t, "0.000 sec") ' 0.42 = 6% всего времени работы
t = Timer
arrR = FILE_RangesFromAddress(tx)
Debug.Print "Get Ranges:", Format$(Timer - t, "0.000 sec") ' 0.12 = 2%
t = Timer
Set rng = FILE_UnionArray(arrR)
Debug.Print "Smart Union:", Format$(Timer - t, "0.000 sec") ' 5.97 = 92%
Debug.Print "PRDX time total:", Format$(Timer - tt, "0.000 sec"), rng.Count ' 6.51 187 468 (18,1 sec by bedvit)
rng.Select
End Sub
'====================================================================================================
Sub PrepareSheet() ' запустить 1 раз, чтобы тестировать на одинаковых данных. Удалить диапазон (и сохранить) перед отправкой на Планету для уменьшения размера файла
Dim i&, j&, t#, a&(1 To 10000, 1 To 25)
t = Timer
For i = 1 To 10000
For j = 1 To 25
a(i, j) = Int(Rnd * 2000)
Next
Next
Cells(1, 1).Resize(10000, 25) = a
End Sub
'====================================================================================================
Private Function GetAddress() As String ' 0.4 sec
Dim rng As Range
Dim arr, arrAdr() As String
Dim t!, r&, c&, i&
Set rng = Range("A1:Y10000")
arr = rng.Value2: i = -1
ReDim arrAdr(UBound(arr, 1) * UBound(arr, 2))
For c = 1 To UBound(arr, 2)
For r = 1 To UBound(arr, 1)
If arr(r, c) < 1500 Then i = i + 1: arrAdr(i) = rng(r, c).Address(0, 0, xlA1)
Next r
Next c
ReDim Preserve arrAdr(i)
GetAddress = Join(arrAdr, ",")
End Function
'====================================================================================================
Sub SimpleSelect() ' 297 sec (5 min) with 18 860 elements
Dim rng As Range, gr As Range
Dim arr, t!, r&, c&
t = Timer
Set rng = Range("A1:Y1000")
arr = rng.Value2
For c = 1 To UBound(arr, 2)
For r = 1 To UBound(arr, 1)
If arr(r, c) < 1500 Then
If gr Is Nothing Then
Set gr = rng(r, c)
Else
Set gr = Union(gr, rng(r, c))
End If
End If
Next r
Next c
Debug.Print "Simple select:", Format$(Timer - t, "0.000 sec"), gr.Count
End Sub
'====================================================================================================
Option Explicit
Option Private Module
'====================================================================================================
Function FILE_RangesFromAddress(ByVal txAdr$, Optional sh As Worksheet) As Range()
Dim arr() As Range
Dim l&, n&, i&, p&, m&
If sh Is Nothing Then Set sh = ActiveSheet
If InStr(txAdr, "$") Then txAdr = Replace$(txAdr, "$", "")
l = Len(txAdr): If l < 256 Then ReDim arr(0): Set arr(0) = sh.Range(txAdr): GoTo fin
m = l - 256
ReDim arr(l \ 200): n = -1
Do
i = InStrRev(txAdr, ",", p + 256)
n = n + 1: Set arr(n) = sh.Range(Mid$(txAdr, p + 1, i - p - 1))
p = i
If p > m Then
n = n + 1: Set arr(n) = sh.Range(Right$(txAdr, l - p))
ReDim Preserve arr(n): GoTo fin
End If
Loop
fin: FILE_RangesFromAddress = arr
End Function
'====================================================================================================
'====================================================================================================
' Функция объединяет все диапазоны переданного массива в один диапазон, который и возвращает
Function FILE_UnionArray(arrRng() As Range) As Range
Dim i&, j&
Do
j = -1
For i = 0 To UBound(arrRng) Step 30
j = j + 1
Set arrRng(j) = FILE_UnionSmart(arrRng, i)
Next i
ReDim Preserve arrRng(j)
If j < 30 Then Set FILE_UnionArray = FILE_UnionSmart(arrRng): Exit Function
Loop
End Function
'----------------------------------------------------------------------------------------------------
' Функция для "умного" объединения диапазонов из переданного массива с помощью Union
' Основной смысл — объединять по 30 диапазонов за раз (максимум для Union). Реже вызов Union = выше скорость
' Функция получает массив диапазонов и индекс элемента, с которого нужно начать объединения (первый элемент массива с индексом 0 - по умолчанию)
' Функция постарается максимально "забить" Union всеми 30ю аргументами-диапазонами, а, если их меньше, то всеми оставшимися
Function FILE_UnionSmart(arrRng() As Range, Optional iStart&) As Range
Dim n&
n = UBound(arrRng) - iStart + 1 ' количество элементов от стартового и до конца массива
If n >= 30 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22), arrRng(iStart + 23), arrRng(iStart + 24), arrRng(iStart + 25), arrRng(iStart + 26), arrRng(iStart + 27), arrRng(iStart + 28), arrRng(iStart + 29)): Exit Function
If n < 15 Then
If n = 1 Then Set FILE_UnionSmart = arrRng(iStart): Exit Function
If n = 2 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1)): Exit Function
If n = 3 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2)): Exit Function
If n = 4 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3)): Exit Function
If n = 5 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4)): Exit Function
If n = 6 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5)): Exit Function
If n = 7 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6)): Exit Function
If n = 8 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7)): Exit Function
If n = 9 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8)): Exit Function
If n = 10 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9)): Exit Function
If n = 11 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10)): Exit Function
If n = 12 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11)): Exit Function
If n = 13 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12)): Exit Function
If n = 14 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13)): Exit Function
Else
If n = 15 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14)): Exit Function
If n = 16 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15)): Exit Function
If n = 17 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16)): Exit Function
If n = 18 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17)): Exit Function
If n = 19 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18)): Exit Function
If n = 20 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19)): Exit Function
If n = 21 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20)): Exit Function
If n = 22 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21)): Exit Function
If n = 23 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22)): Exit Function
If n = 24 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22), arrRng(iStart + 23)): Exit Function
If n = 25 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22), arrRng(iStart + 23), arrRng(iStart + 24)): Exit Function
If n = 26 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22), arrRng(iStart + 23), arrRng(iStart + 24), arrRng(iStart + 25)): Exit Function
If n = 27 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22), arrRng(iStart + 23), arrRng(iStart + 24), arrRng(iStart + 25), arrRng(iStart + 26)): Exit Function
If n = 28 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22), arrRng(iStart + 23), arrRng(iStart + 24), arrRng(iStart + 25), arrRng(iStart + 26), arrRng(iStart + 27)): Exit Function
If n = 29 Then Set FILE_UnionSmart = Union(arrRng(iStart), arrRng(iStart + 1), arrRng(iStart + 2), arrRng(iStart + 3), arrRng(iStart + 4), arrRng(iStart + 5), arrRng(iStart + 6), arrRng(iStart + 7), arrRng(iStart + 8), arrRng(iStart + 9), arrRng(iStart + 10), arrRng(iStart + 11), arrRng(iStart + 12), arrRng(iStart + 13), arrRng(iStart + 14), arrRng(iStart + 15), arrRng(iStart + 16), arrRng(iStart + 17), arrRng(iStart + 18), arrRng(iStart + 19), arrRng(iStart + 20), arrRng(iStart + 21), arrRng(iStart + 22), arrRng(iStart + 23), arrRng(iStart + 24), arrRng(iStart + 25), arrRng(iStart + 26), arrRng(iStart + 27), arrRng(iStart + 28)): Exit Function
End If
MsgBox "UNcorrect ranges!", vbCritical, "UnionSmart"
Err.Raise xlErrNA
End Function
'====================================================================================================
Итог: на диапазоне в 250 000 ячеек (25 столбцов * 10 000 строк) при подходящих условию (< 1500) 187 468 (75%) ячейках мой вариант с временем 6,51 сек быстрее конкурента со временем 18,1 сек почти в 3 раза (2,78)
Выводы
Можно с уверенностью говорить о том, что при росте объёмов, выигрыш будет увеличиваться, причём не линейно, а гораздо быстрее, а значит функцию резки адреса нужно обязательно использовать для любых задач, связанных с Union Для прочих задач по работе с диапазонами, использование функции также ничем навредить не может и будет только лучше
Очевидно, что укрупнение строк "нарезкой" позволяет многократно сократить количество вызовов Union'ов, т.к. 92% всего времени работы (в моей процедуре, но у bedvit'а примерно также) занимает именно он Принцип передачи всех 30ти (максимум) аргументов в Union (также с целью минимального количества его вызовов) реализован с обоих сторон, но по-разному
Ну и финалочка — причина, по которой, собственно, более 5 лет назад Владимир (ZVI), а потом и bedvit разрабатывали способ быстрого выделения: процедура выделения (сбор диапазона в один) по-старинке на объёме в 10 раз меньшем тестового (18 860 ячеек из 25 тыс) работает 5 минут Причём время работы растёт не линейно и при выделении, скажем 50 тысяч ячеек вы и за ночь можете не дождаться …
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Но вот и поясни свой алгоритм, посмотри как подробно ZVI или я описывал в своих темах. За счет чего достигнул выигрыша, что для этого использовал, что сильнее всего повлияло на прирост скорости и т.д. Народ и подтянется
ты либо не читаешь, что я пишу, любо прикалывешься
Цитата
bedvit: поясни свой алгоритм, посмотри как подробно ZVI или я описывал в своих темах
и посмотри, насколько также всем плевать, кроме единиц типа меня. Я в таких темах не жду ажиотажа и тебе не советую
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: ты либо не читаешь, что я пишу, любо прикалывешься
Я тебе говорю серьезно, ты проделал серьезную работу, придумал алгоритм быстрее вот и поделись с народом (не со мной), чем он лучше предыдущих, как его можно использовать.
Цитата
Jack Famous написал: насколько также всем плевать, кроме единиц типа меня.
кому плевать, а кто почитает и будет пользоваться. Может через месяц, может через год, для этого и форум. даже Нобелевку могут дать через 50 лет, а ты ждешь признания сразу же
bedvit: ты проделал серьезную работу, придумал алгоритм быстрее вот и поделись с народом
«Моя борьба»
Я подробно сравнил несколько вариантов нарезки между собой, сравнил с быстрейшими аналогами (твоими), с привычными вариантами простого кода, на разных объёмах и условиях — всё это оформил в сравнительно-аналитическую таблицу с процентами и прочими условными форматированиями Что ещё тут можно поделать, друг?
Это как, если бы я был механиком и пытался объяснить на графиках простому водителю, что резинки на лопатках вентилятора положительно влияют на ресурс двигателя, при этом не снижают мощности и уменьшают расход бензина (придумал только что и не понимаю, о чём говорю ). Ему же пофиг на то, КАК ЭТО РАБОТАЕТ, главное, что ЭТО ХОРОШО и МИНУСОВ НЕТ, то есть выбирать ВООБЩЕ НЕ НАДО — бери и пользуйся, как говорится (я ж всё оформил в 3 функции: 1 резка и 2 для Union'а)
А кто в теме, тот поймёт, что "под капотом"
Больше скорости
есть ещё одна идея по ускорению — объединять отдельные ячейки, стоящие рядом, в один диапазон и получать вместо адреса/диапазона A1;B2;A2;B1 диапазон A1:B2. Тут уже всё не так очевидно и железобетонно, как с резкой. Придётся задействовать регулярки, сортировку и, возможно, словари — это нехилые ресурсы, оправдать использование которых может только достаточное количество стоящих рядом ячеек и на большом объёме Не знаю, займусь ли, но пока мысли вот такие…
На данный момент моя душенька спокойна - я всё оттестировал и показал Теперь могу спокойно тестировать аналог Split'а Anchoret, на мой взгляд, не дотянул строковый вариант, не пробовал извлечение регулярками и вообще свернул с верного пути "разделения" на путь "сделать, как оригинальный Split" со всеми аргументами, хотя я не помню, когда вообще использовал больше первых двух…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄