Снова спешу обратиться к вашему профессиональному сообществу. Благодаря вашей помощи, есть в наличии UDF (низкий поклон Александру «ikki»). Предыстория, если интересно, тут. Функция помогает находить вертикальные блоки символов в массиве: указывается номер строки и она возвращает номер столбца, где заданный блок символов «сидит» в буквальном смысле сверху на строке.
Функция работает как часы, «вылавливая» блоки одинакового содержания, например, «ДДДДДД» или «НННН» (высота задаётся отдельно, в зависимости от кол-ва символов). Однако, когда возникла необходимость поискать блоки разного наполнения – «ДДННН», «НННДДД», «вуНННННН», «ДДуНННН» - то что-то, как говориться, в двигателе забарахлило… Думал, переменной s непосредственно указывать «состав» символов, чтобы Split создавал искомый массив. Тщетно. Очевидно, тропинка решения ведёт в циклы с присвоением значений, где, собственно, всё колдовство и происходит. Но поскольку механизм этой функции мне пока ещё непонятен, ищу подсказку у «сильных мира сего» - где можно что-нибудь «подкрутить»? Пусть даже переменную высоты блока х придётся задавать отдельно для каждого набора блока, лишь бы функция «научилась» находить блоки с разным составом символов.
Как говорил Джигарханян из «Место встречи…»: «какие будут мнения, господа хорошие?»
[vba]
Код
Function f(r As Range, n&, Optional x = 7, Optional s = "Д;Н") Dim a(), b&(), j&, k&, jj&, xx, ss$, ff As Boolean If x > r.Rows.Count Or x > n Then f = CVErr(xlErrValue): Exit Function a = r.Rows(n - x).Resize(x).Value
xx = Split(s, ";") For jj = 0 To UBound(xx) ss = ";" & xx(jj): xx(jj) = "" For j = 1 To x: xx(jj) = xx(jj) & ss: Next Next
ReDim b(1 To Application.Caller.Columns.Count): j = 1: k = 0 Do While j <= UBound(a, 2) And k < UBound(b) ss = "": ff = False For jj = 1 To x: ss = ss & ";" & a(jj, j): Next For jj = 0 To UBound(xx) If ss = xx(jj) Then ff = True: Exit For Next If ff Then k = k + 1: b(k) = j j = j + 1 Loop f = b End Function
[/vba]
Добрый день!
Снова спешу обратиться к вашему профессиональному сообществу. Благодаря вашей помощи, есть в наличии UDF (низкий поклон Александру «ikki»). Предыстория, если интересно, тут. Функция помогает находить вертикальные блоки символов в массиве: указывается номер строки и она возвращает номер столбца, где заданный блок символов «сидит» в буквальном смысле сверху на строке.
Функция работает как часы, «вылавливая» блоки одинакового содержания, например, «ДДДДДД» или «НННН» (высота задаётся отдельно, в зависимости от кол-ва символов). Однако, когда возникла необходимость поискать блоки разного наполнения – «ДДННН», «НННДДД», «вуНННННН», «ДДуНННН» - то что-то, как говориться, в двигателе забарахлило… Думал, переменной s непосредственно указывать «состав» символов, чтобы Split создавал искомый массив. Тщетно. Очевидно, тропинка решения ведёт в циклы с присвоением значений, где, собственно, всё колдовство и происходит. Но поскольку механизм этой функции мне пока ещё непонятен, ищу подсказку у «сильных мира сего» - где можно что-нибудь «подкрутить»? Пусть даже переменную высоты блока х придётся задавать отдельно для каждого набора блока, лишь бы функция «научилась» находить блоки с разным составом символов.
Как говорил Джигарханян из «Место встречи…»: «какие будут мнения, господа хорошие?»
[vba]
Код
Function f(r As Range, n&, Optional x = 7, Optional s = "Д;Н") Dim a(), b&(), j&, k&, jj&, xx, ss$, ff As Boolean If x > r.Rows.Count Or x > n Then f = CVErr(xlErrValue): Exit Function a = r.Rows(n - x).Resize(x).Value
xx = Split(s, ";") For jj = 0 To UBound(xx) ss = ";" & xx(jj): xx(jj) = "" For j = 1 To x: xx(jj) = xx(jj) & ss: Next Next
ReDim b(1 To Application.Caller.Columns.Count): j = 1: k = 0 Do While j <= UBound(a, 2) And k < UBound(b) ss = "": ff = False For jj = 1 To x: ss = ss & ";" & a(jj, j): Next For jj = 0 To UBound(xx) If ss = xx(jj) Then ff = True: Exit For Next If ff Then k = k + 1: b(k) = j j = j + 1 Loop f = b End Function
Решение найдено на форуме planetaexel (ссылка на тему почему-то не получается, но она там с таким же названием). Надеюсь, кому-нибудь пригодиться!
Тему можно закрывать.
Решение найдено на форуме planetaexel (ссылка на тему почему-то не получается, но она там с таким же названием). Надеюсь, кому-нибудь пригодиться!mick-77
Сообщение отредактировал mick-77 - Среда, 24.09.2014, 08:07