Private Sub Worksheet_Change (ByVal zChange As Range)
(более 5000 строк)
End Sub
Сегодня получил ошибку "Procedure too large" при попытке запуска. Узнал об ограничении.
Суть кода в том, что если я изменяю на листе ячейку из определённой колонки (например, из колонки "1"), то такая ячейка будет обработана (назовём её "zCell"). В частности - на основе данных этой изменённой ячейки, будет рассчитан ряд переменных:
Код
zCellUPRng As Range
- все ячейки колонки "1" ВЫШЕ zCell.
zCellDNRng As Range
- все ячейки колонки "1" НИЖЕ zCell.
zArrUPRowS(1 To zCellUPRng.Count)
- массив номеров строк, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.
zArrUPValueS(1 To zCellUPRng.Count)
- массив значений, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.
после этого, я разбиваю их на все ДОПУСТИМЫЕ значения (которые перед этим ограничиваю),
и составляю из них следующие списки:
Dim zArrUP8(1 To zCellUPRng.Count)
- список номеров строк, значения ячеек которых = 8 (всего 8 списков, от 1 до 8);
получаю я его следующим образом:
For i = 1 to zCellUPRng.Count
If zArrUPValueS(i) = 8 _
Then
zArrUP8(i) = zArrUPRowS(i)
Else
End If
Next i
и далее происходит ещё много-много чего.
Таким образом, я столкнулся с проблемой перегрузки процедуры.
Пожалуйста: НЕ предлагайте введения циклов и прочих агрегаторов, вроде "With": ни один из них для меня не новость.
Я пытаюсь решить проблему путём ПЕРЕДАЧИ переменных, в связи с чем и возник мой ВОПРОС.
Товарищ vikttur в своё время пролил мне свет на то, как можно передавать переменные между процедурами, и\или из одного модуля в другой - за что ему отдельное спасибо, ибо с тех пор качество моей жизни значительно улучшилось))) Однако в случае Worksheet_Change у меня возникли трудности.
Насколько я понимаю данную процедуру, весь "перенос" сводится к работе с командой "Call". Например, в отдельном модуле определяем:
Код
Sub z_Call1(zAnotherCell As Range)
Set zAnotherCell = Cells(1, 1)
End Sub
- тогда в Private Sub Worksheet_Change я бы написал:
Код
Dim zAnotherCell As Range
Call z_Call1(zAnotherCell)
Здесь команда "Call" позволила бы мне оперировать свойствами ячейки (1, 1).
Но как мне быть в случае Worksheet_Change, когда отдельным модулям необходимо оперировать свойствами ИЗМЕНЯЕМОЙ ячейки - ???..
Как, например, мне перенести в отдельный модуль процесс создания одного из упомянутых выше списков:
Код
Dim zArrUP8(1 To zCellUPRng.Count)
- список номеров строк, значения ячеек которых = 8 (всего 8 списков, от 1 до 8);
получаю я его следующим образом:
For i = 1 to zCellUPRng.Count
If zArrUPValueS(i) = 8 _
Then
zArrUP8(i) = zArrUPRowS(i)
Else
End If
Next i
- ведь вместе с ним нужно будет перенести и прочие переменные!
Код
zArrUPValueS(1 To zCellUPRng.Count)
- массив значений, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.
zArrUPRowS(1 To zCellUPRng.Count)- массив номеров строк, соответствующих ячейкам из zCellUPRng;
такой же - для zCellDNRng.
zCellUPRng As Range - все ячейки колонки "1" ВЫШЕ zCell.
- и так вплоть до "zCell", с изменения которой и началось выполнение Worksheet_Change.
Ведь это бесконечный цикл какой-то, разве нет? Может, есть какой-то пример, как люди справлялись с "Procedure too large", ИМЕННО в случае Worksheet_Change?
Я надеялся что в файле кто-то поможет мне вынести в отдельный модуль (или процедуру - не принципиально) выделенный комментарием кусок кода. Потому что у меня не получается это сделать из-за связи этого куска с редактируемой ячейкой (ставшей причиной Worksheet_Change).
Этот кусок (с точки зрения связи с редактируемой ячейкой) НИЧЕМ не отличается от сотен других кусков, которые я не стал помещать в файл. Все вместе, они вызывают ошибку "too large".
Жесть какая-то. 5000 строк в модуле листа... Слайд-шоу? На тему вопроса в выложенном файле:
Код
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Columns(1), Target) Is Nothing Then Exit Sub
MsgBox Me.Range("A1:A" & Target.Row).AddressLocal(0, 0)
End Sub
На тему сокращения объема кода за счет выноса его части в процедуры: - для начала почитайте о них (о процедурах), о типах параметров и чем они между собой отличаются
А можно просто чтобы я скачал файл с готовым вынесенным в отдельную процедуру куском когда, который в файле выделил? Если бы я мог написать сам, или понять из того, что могло быть прочитано, я бы не просил помощи. Это же не диссертация, Господи Иисусе. Или у всех приступ понедельника?
Iгор Гончаренко, похоже на мои попытки перенести одну из переменных из Worksheet_Change в отдельный модуль. Не получилось.
Iгор Гончаренко, спасибо: на первый взгляд всё равно непонятно, так что насчёт понедельника думаю Вы тоже правы)) Конструкцию в предыдущем сообщении Вы указали действительно буквально: просто я прежде работал только с "Call". Шаг влево\шаг вправо - уже не воспринимаю.
Посмотрел файл - зачем для такого простого действа столько кода не понял, и нет желания понимать... По вопросу - нет никакой проблемы передать в другую процедуру собственно сам диапазон, и пусть она (процедура) делает с ним что угодно. Если нужно из неё (процедуры) получить что-то назад в вызывающую - можно обойтись и без глобальных переменных, просто передайте локальную:
Код
'в листе:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim s$
If Not Intersect(Target, Range("A1:A100")) Is Nothing Then
Call z1(Target, s)
End If
MsgBox s
End Sub
'в модуле:
Sub z1(zx As Range, str As String)
Dim i&
For i = 1 To zx.Row
str = str & vbNewLine & i
Next
str = Mid(str, 3)
End Sub