Почему .autoFill вызывает сбой Excel? - PullRequest
1 голос
/ 11 июня 2019

У меня есть электронная таблица, вот ее фрагмент:

enter image description here

В идеале, когда я добавляю дату в colC, различные столбцы автоматически заполняютдаты до последней строки с датой закрытия.Вот мой код (в нем также есть сортировка, которая работает нормально);Часть, после которой я определяю lastDrag, - вот где проблема, я думаю:

Private Sub Worksheet_Change(ByVal Target As Range)
'On Error Resume Next

Dim firstRow As Long
Dim insRow As Long
Dim lastRow As Long

If Not Intersect(Target, Range("A:AC")) Is Nothing Then

    With ActiveWorkbook.ActiveSheet

        lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row

        .Sort.SortFields.Clear

        .Sort.SortFields.Add(Range("AC1:AC" & lastRow), _
            xlSortOnCellColor, xlDescending, , xlSortNormal).SortOnValue.Color = RGB(191, 191, 191)

        ' ^^ sorts the "gray" (closed) exchanges at the bottom)

        .Sort.SortFields.Add Key:=.Range("AC1:AC" & lastRow), _
            SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal

        ' ^^ sorts closed files by file close date

        .Sort.SortFields.Add Key:=.Range("C1:C" & lastRow), _
            SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

        ' ^^ sorts open files by RQ close date
        ' THIS IS WHERE CONDITIONS SHOULD BE
        ' IF no id has been entered, sort by...
        ' IF id has been entered, sort by...

        .Sort.SortFields.Add(Range("K1:K" & lastRow), _
            SortOn:=xlSortOnCellColor, Order:=xlDescending, DataOption:=xlSortNormal).SortOnValue.Color = xlNone

        ' ^^ makes sure that the non-colored rows are sorted??

        With .Sort
            .SetRange Range("A1:AC" & lastRow)
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With

        lastDrag = .Cells(.Rows.Count, "C").End(xlUp).Row

        Range("D2").Select
        Selection.AutoFill Destination:=Range("D2:D" & lastDrag), Type:=xlFillDefault
'        ^^ this seems to work but it loops forever...


    End With

End If

End Sub

В настоящее время кажется, что Excel автоматически заполняется снова и снова, пока не произойдет сбой.Почему?

Есть ли способ получить его для автозаполнения столбцов D, E, H, J и т. Д. (Т. Е. Группы несмежных столбцов) - все в одном кадре?У меня было что-то вроде Range("D2,E2,H2..." & lastDrag)...

Ответы [ 2 ]

2 голосов
/ 11 июня 2019
Private Sub Worksheet_Change(ByVal Target As Range)

Это событие рабочего листа вызывается каждый раз при изменении рабочего листа ... независимо от того, вызвано ли оно пользователем ... или вашим собственным кодом.Вам нужно установить EnableEvents на False, чтобы предотвратить повторный вход, и вернуться к True, как только вы закончите - независимо от того, возникла ошибка или нет:

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo ErrHandler
    Application.EnableEvents = False

    '...code...

CleanExit:
    Application.EnableEvents = True
    Exit Sub
ErrHandler:
    Stop 'debug me
    Resume CleanExit
End Sub

Когда вы вызываетеиз другой процедуры, новая процедура помещает в стек вызовов ;Когда эта процедура завершается, она выталкивается / удаляется из стека вызовов.Обычно это не проблема, но если все становится рекурсивным и неконтролируемым, в конечном итоге стек вызовов не может стать более глубоким, и время выполнения VBA резко возрастает ... в этом случае удаление приложения хоста (Excel) с ним.

1 голос
/ 11 июня 2019

Подумайте о том, что делает ваш код - как только в столбцах A обнаружено изменение: AC, ваш код запускается, чтобы что-то сделать.И когда он что-то делает, он делает это в столбцах A: AC, создавая непрерывный цикл, который в конечном итоге может привести к сбою.После того, как вы обнаружили событие рабочего листа, и прежде чем начать манипулирование данными, вы должны указать Excel прекратить обнаруживать новые события, пока код не будет завершен.

Вам необходимо добавить Application.EnableEvents = False сразу после оператора IFи снова включите его Application.EnableEvents = True непосредственно перед выходом из подпрограммы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...