Бесконечный цикл при попытке удалить стиль таблицы программно, но когда цикл возобновляется вручную, он работает

#excel #vba

Вопрос:

название в основном резюмирует мою проблему. Я изо всех сил пытаюсь найти виновника здесь.

Подпрограмма переходит в бесконечный цикл при автоматическом запуске, но при попытке отладки и пошагового выполнения она работает так, как задумано.

Что я делаю не так?

 Sub insert_custom_table(ByVal table_range As Range)
    Dim target_worksheet As Worksheet
    Set target_worksheet = table_range.Parent
    
    Dim table_style As TableStyle
    
    Do While table_style Is Nothing
        On Error Resume Next
        
        With target_worksheet.Parent
            Set table_style = .TableStyles("tablestyle_df")
            
            If table_style Is Nothing Then
                Set table_style = .TableStyles.Add("tablestyle_df")
            Else
                table_style.Delete
                Set table_style = Nothing
            End If
        End With

        On Error GoTo 0
    Loop

' rest of code

End Sub
 

Комментарии:

1. Старайтесь избегать использования циклов While, используя для каждого цикла и для цикла при обработке большого набора данных. Раньше я сталкивался с проблемой бесконечного цикла, когда работать в одиночку нормально, но в сочетании с другой процедурой, а затем с бесконечным циклом. Для циклической работы лучше всего в большинстве случаев

2. Я не понимаю твоей логики. Почему вы вообще делаете петлю? Если я вас правильно понял, вы хотите удалить и (повторно)создать стиль таблицы с именем "tablestyle_df" ?

3. @FunThomas, да, я хочу быть уверенным, что в стиль таблицы не было внесено никаких изменений вручную, поэтому я каждый раз воссоздаю его заново.

4. @холлсон: Да, я понимаю это, но почему петля?

5. @Фунтомас: Я включил туда цикл, потому что по какой-то причине я получал ошибку при попытке удалить существующий стиль таблицы (видимый при повторении всех), но при ручном возобновлении кода после ошибки стиль таблицы, у которого была проблема с удалением, фактически был удален. Я пытался убедиться, что объект в конечном итоге будет назначен, подумал, что, возможно, код выполнялся слишком быстро или что-то в этом роде, но вместо этого по какой-то причине он вошел в бесконечный цикл, хотя, если я разорву бесконечный цикл и возобновлю код, он будет выполнен просто отлично.

Ответ №1:

Ваш цикл while не имеет смысла, вам не о чем зацикливаться. Если вы просто хотите удалить существующий стиль таблицы, просто сделайте это.

TableStyles это коллекция, и в коллекции вы можете получить доступ к элементу либо через номер индекса, либо через имя (очень похоже на Worksheets -коллекцию рабочей книги). Если вы знаете это имя, вы можете просто написать

 .TableStyles("tablestyle_df").delete
 

Теперь единственная небольшая проблема заключается в том, что это вызовет ошибку во время выполнения (ошибка 9 — Индекс вне диапазона), если стиль не существует. Просто проигнорируйте эту ошибку, заключив заявление (но только это единственное заявление!!!) с оговоркой On Error Resume Next -. Если стиль не существует, вам не нужно удалять его. Так что все, что вам нужно, это

 With target_worksheet.Parent
    On Error Resume Next      ' Ignore the error if delete fails because style does not exist
    .TableStyles("tablestyle_df").delete
    On Error Goto 0
    Set table_style = .TableStyles.Add("tablestyle_df")
End With
 

Комментарии:

1. Просто скопируйте вставку из предыдущего комментария, я включил туда цикл, потому что по какой-то причине я получал ошибку при попытке удалить существующий стиль таблицы (видимый при повторении всех), но при ручном возобновлении кода после ошибки стиль таблицы, у которого была проблема с удалением, фактически был удален. Я пытался убедиться, что объект в конечном итоге будет назначен, подумал, что, возможно, код выполнялся слишком быстро или что-то в этом роде, но вместо этого по какой-то причине он вошел в бесконечный цикл, хотя, если я разорву бесконечный цикл и возобновлю код, он будет выполнен просто отлично.

2. Поскольку ваш код поглощает все ошибки, неясно, что именно происходит. Вы попадете в бесконечный цикл, когда удаление завершится неудачно. Все еще не вижу никаких причин для зацикливания.

3. Когда я удаляю ошибку «игнорировать» и снова запускаю код на своем исходном фрагменте кода, существующий объект стиля таблицы назначается правильно и не является ничем. Когда код вводится в . фаза удаления, я получаю -2147417848 Метод «Удаление» объекта «Табличный стиль» по какой-то причине не удалена ошибка. Когда я возобновляю код и он переходит на другую итерацию цикла, ошибка не отображается. Но когда он работает на полном автомате, он входит в бесконечный цикл. Это то, что я пытаюсь понять, но повторение всех стилей таблиц и удаление одного с соответствующим именем, похоже, работает.

Ответ №2:

Старайтесь избегать циклов While без определенного конца. По неизвестным причинам table_style никогда не может не быть ничего, что вызвало бы бесконечное зацикливание.

Вместо этого перефразируйте свой цикл, чтобы иметь определенное начало и конец:

 Sub insert_custom_table(ByVal table_range As Range)
    Dim target_worksheet As Worksheet
    Set target_worksheet = table_range.Parent
    
    Dim table_style As TableStyle
    
    For Each table_style In target_worksheet.Parent.TableStyles
        If table_style.Name <> "tablestyle_df" Then table_style.Delete
    Next table_style

' rest of code

End Sub
 

Комментарии:

1. Спасибо, кажется, это работает! Я был так упрям, что заставил объект назначить в конечном итоге в цикле, но не подумал просто перебрать все стили таблиц и удалить тот, где имя совпадает. Спасибо, иногда более простые решения являются лучшими 🙂

2. Это приведет к удалению всех стилей таблиц, кроме "tablestyle_df" — это то, что вы хотите?

3. Я просто заменил знак «не равно» на «равно», так как хотел полностью воссоздать стиль таблицы.

4. Решение работало в течение нескольких запусков, и теперь я получаю -2147417848 Метод «Удаления» объекта «Табличный стиль» снова не удался, что, черт возьми, происходит.