2016-03-07 2 views
2

У меня есть довольно борьба с каким-то кодом, который работал нормально. В одном из своих подлодок, я прячу кучу строк (1599, чтобы быть точным), то UNHIDE те, которые мне нужны, как правило, около 200. Отъезд код:Код VBA прекращает выполнение без ошибок после скрытия строк

Private Sub HideUnneededRows(numberToShow As Integer) 
Dim thisSheet As Worksheet 
Dim allHideableRows As String, rowsToShow As String 
Dim firstRow As Integer 
Dim secondRow As Integer 
Dim lastRow As Integer 
Dim lastRowToShow As Integer 

    Set thisSheet = ThisWorkbook.Sheets(1) 

    firstRow = thisSheet.Range("mass1").row 
    secondRow = firstRow + 1 
    lastRow = firstRow - 1 + maxNumberOfRows 
    lastRowToShow = firstRow - 1 + numberToShow '//numberToShow is usually 200 

    '//THIS NEXT LINE RUNS, BUT STOPS EXECUTING AFTER THE ACTION IS PERFORMED 
    Range("A" + CStr(secondRow) + ":A" + CStr(lastRow)).EntireRow.Hidden = True 
    Range("A" + CStr(secondRow) + ":A" + CStr(lastRowToShow)).EntireRow.Hidden = False 

End Sub 

Все хорошо и хорошо до кода скрывает строки (сначала «Range» («A» + ....). Скрытые «строки». Он выполняет действие hide просто отлично, но затем не достигает следующей строки кода, которая должна была бы скрывать другой набор строк. Вещи, которые я пробовал:

  • жесткого кодирования строки диапазона (т.е. Range("A25:A1623") вместо Range("A" + CStr(secondRow) + ":A" + ....))
  • Выполнение этих двух скрыть действия через Rows объекта (т.е. Rows("25:1623").Hidden = True)
  • Распаковка эти две скрыть строки в свое собственное событие button_click в новом модуле, чтобы узнать, было ли это что-то в этом модуле в настоящее время в

Все они дали e xact same result - код останавливает выполнение после того, как строки 1599 будут скрыты.

Помогите ?!

+2

Я использовал ваш код, чтобы скрыть более 26 000 строк, и он отлично работал. Я заметил, что лист (ы) был пересчитан (по крайней мере частично, потому что у меня есть некоторые из моих собственных UDF, отмеченных как «Неустойчивые»). Возможно, попробуйте отключить события и обновления экрана до скрыть (и снова включить). – PeterT

+0

@PeterT Спасибо за ваши комментарии. Код может быть дополнительно модифицирован и оптимизирован.Надеемся, что основная проблема решена в вопросе PO. С уважением, –

+0

@PeterT YOU WIN !! Отключение событий не исправить, но отключить «ScreenUpdating» исправлена ​​проблема. Почему это сработало? Почему во многих перерасчетах (у меня было приблизительно 4800 ячеек с условным форматированием) причиной смерти кода? – BGeorge

ответ

1

следующие фрагменты кода, используемые для отладки цели прекрасно работает (скрыть/показать строки)

Private Sub HideUnneededRows() 
Dim thisSheet As Worksheet 
Dim allHideableRows As String, rowsToShow As String 
Dim firstRow As Integer 
Dim secondRow As Integer 
Dim lastRow As Integer 
Dim lastRowToShow As Integer 

'for debugging purpose 
numberToShow = 200 
maxNumberOfRows = 300 
'-------------------- 

    Set thisSheet = ThisWorkbook.Sheets(1) 

    'firstRow = thisSheet.Range("mass1").Row 
    ' for debugging purpose 
    firstRow = 1 
    secondRow = firstRow + 1 
    lastRow = firstRow - 1 + maxNumberOfRows 
    lastRowToShow = firstRow - 1 + numberToShow '//numberToShow is usually 200 

    '//THIS NEXT LINE RUNS, BUT STOPS EXECUTING AFTER THE ACTION IS PERFORMED 
    Range("A" + CStr(secondRow) + ":A" + CStr(lastRow)).EntireRow.Hidden = True 
    Range("A" + CStr(secondRow) + ":A" + CStr(lastRowToShow)).EntireRow.Hidden = False 

End Sub 

Проверьте все свои «магические числа», как maxNumberOfRows переменной (набор 300 для отладки цели: откуда приходит/объявлен?) и firstRow из этого «таинственного» диапазона «mass1».

Примечание: в VBA коде, конкатенация строк, как правило, делаются с амперсанд «&», но этот синтаксис будет работать отлично, а также:

Range("A" + CStr(secondRow) + ":A" + CStr(lastRow)) 

Надеется, что это позволит решить проблему.

+1

Я сделал тест, похожий на Alex's, и он выглядит правильно. Я бы тщательно проверил выполнение кода шаг за шагом и проверил значения, сделанные firstRow, secondRow, lastRow и lastRowToShow. Вероятно, ваш ответ есть. – Michele

+0

@Michele Спасибо за ваши комментарии. Он должен работать в образце ПО с разъяснением, относящимся к тем «магическим числам», которые я упомянул (что именно эти переменные хранят в пошаговом исполнении). С наилучшими пожеланиями, –

+0

@AlexBell Именно поэтому я так смущен. Я использую один и тот же код в некоторых других книгах, и он отлично работает. Мы используем систему управления версиями здесь, и этот код отлично работает на более старой версии. Я не могу понять, что может вызвать проблему сейчас. – BGeorge

0

Похоже, вы со стороны C#/Java - используя +, чтобы объединить строки, в VBA, используйте амперсанд &.

Предполагая, что maxNumberOfRows является глобальной переменной или функцией, попробуйте ниже.

Private Sub HideUnneededRows(numberToShow As Integer) 
    Dim firstRow As Long, secondRow As Long 
    Dim lastRow As Long, lastRowToShow As Long 
    Dim lCalcMode As Long 

    firstRow = ThisWorkbook.Names("mass1").RefersToRange.Row 
    secondRow = firstRow + 1 
    lastRow = firstRow - 1 + maxNumberOfRows 
    lastRowToShow = firstRow - 1 + numberToShow '//numberToShow is usually 200 

    lCalcMode = Application.Calculation 
    Application.ScreenUpdating = False 
    Application.Calculation = xlCalculationManual 
    Rows(secondRow & ":" & lastRow).Hidden = True 
    Rows(secondRow & ":" & lastRowToShow).Hidden = False 
    Application.Calculation = lCalcMode 
    Application.ScreenUpdating = True 
End Sub 

Измененные строки, относящиеся к типу данных Long (экономия Excel сделать преобразование).

+0

Спасибо за ваш ответ. Виновен в качестве обвиняемого Я со стороны C#. Полезно знать об амперсанде! Для моего образовательного преимущества, зачем менять тип данных to 'Long' из' Integer'? Я почти исключительно использую 'Integer' во всем моем коде, поэтому было бы полезно знать. – BGeorge

+0

Еще один совет для проверки имени типа данных - в непосредственном окне используйте'? TypeName() ', чтобы найти имя типа данных (полезно если не вариант). например '? TypeName (Range (« A1 »). Row)' – PatricK

+0

Range («A» + CStr (secondRow) + «: A» + CStr (lastRow)) будет отлично работать в современном Excel VBA. С наилучшими пожеланиями, –

0

Благодаря @PeterT решение моей проблемы состояло в том, чтобы отключить обновление экрана перед запуском кода, а затем включить его после завершения кода. Новый код такой:

Private Sub HideUnneededRows(numberToShow As Integer) 
Dim thisSheet As Worksheet 
Dim firstRow As Integer 
Dim secondRow As Integer 
Dim lastRow As Integer 
Dim lastRowToShow As Integer 

    Set thisSheet = ThisWorkbook.Sheets(1) 

    firstRow = thisSheet.Range("mass1").row 
    secondRow = firstRow + 1 
    lastRow = firstRow - 1 + maxNumberOfRows 
    lastRowToShow = firstRow - 1 + numberToShow '//numberToShow is usually 200 

    '//Turn off ScreenUpdating 
    Application.ScreenUpdating = False 
    '//THIS NEXT LINE WAS GIVING ME TROUBLES 
    Range("A" + CStr(secondRow) + ":A" + CStr(lastRow)).EntireRow.Hidden = True 
    Range("A" + CStr(secondRow) + ":A" + CStr(lastRowToShow)).EntireRow.Hidden = False 
    '//Turn ScreenUpdating back on 
    Application.ScreenUpdating = True 

End Sub 
Смежные вопросы