Страницы: 1
RSS
Передача\вызов переменной, обрабатываемой в Private Sub Worksheet_Change
 
Добрый день!

В свойствах Листа имею код следующего вида:
Код
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?
Изменено: RazorBaze - 30.04.2018 07:24:37 (приложил файл примера с работающим кодом и пояснениями к вопросу)
 
с сообщением Procedure too large люди справляются делением процедуры на фрагменты  
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
и в Вашем файле не возникает ситуация Procedure too large
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Я надеялся что в файле кто-то поможет мне вынести в отдельный модуль (или процедуру - не принципиально) выделенный комментарием кусок кода.
Потому что у меня не получается это сделать из-за связи этого куска с редактируемой ячейкой (ставшей причиной Worksheet_Change).

Этот кусок (с точки зрения связи с редактируемой ячейкой) НИЧЕМ не отличается от сотен других кусков, которые я не стал помещать в файл.
Все вместе, они вызывают ошибку "too large".
Изменено: RazorBaze - 30.04.2018 08:17:10
 
Call z0(A1)
'вот здесь пример переноса, который я МОГУ осилить.
'см. Module1.

осильте так:
z0 zChange
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Жесть какая-то. 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
На тему сокращения объема кода за счет выноса его части в процедуры:
- для начала почитайте о них (о процедурах), о типах параметров и чем они между собой отличаются
 
Цитата
RazorBaze написал: Я пытаюсь решить проблему путём ПЕРЕДАЧИ переменных
НЕ предлагайте введения циклов и прочих агрегаторов...
Так Вам 'шашечки' или ехать? Опишите лучше саму задачу, а не то, как Вы ее (неправильно) пытаетесь решить.
Согласие есть продукт при полном непротивлении сторон
 
А можно просто чтобы я скачал файл с готовым вынесенным в отдельную процедуру куском когда, который в файле выделил? Если бы я мог написать сам, или понять из того, что могло быть прочитано, я бы не просил помощи.
Это же не диссертация, Господи Иисусе. Или у всех приступ понедельника?

Iгор Гончаренко, похоже на мои попытки перенести одну из переменных из Worksheet_Change в отдельный модуль. Не получилось.

Iгор Гончаренко, спасибо: на первый взгляд всё равно непонятно, так что насчёт понедельника думаю Вы тоже правы))
Конструкцию в предыдущем сообщении Вы указали действительно буквально: просто я прежде работал только с "Call". Шаг влево\шаг вправо - уже не воспринимаю.
Изменено: RazorBaze - 30.04.2018 09:42:16
 
Вы же написали, что умеете ПРАВИЛЬНО объявлять переменные.
Цитата
RazorBaze написал: Товарищ  vikttur  в  своё время...
Что не получилось? Объявите переменную ГЛОБАЛЬНО (ссылка есть в той теме) и используйте ее где хотите
Согласие есть продукт при полном непротивлении сторон
 
у Вас - да, а вообще, не понимаю в чем проблема
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Посмотрел файл - зачем для такого простого действа столько кода не понял, и нет желания понимать...
По вопросу - нет никакой проблемы передать в другую процедуру собственно сам диапазон, и пусть она (процедура) делает с ним что угодно.
Если нужно из неё (процедуры) получить что-то назад в вызывающую - можно обойтись и без глобальных переменных, просто передайте локальную:
Код
'в листе:
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
 
Hugo, это очень похоже именно на то, что было нужно.
Большое Вам спасибо!
Изменено: RazorBaze - 30.04.2018 18:49:31
Страницы: 1
Наверх