Создание цикла для замены нескольких вложенных операторов if при работе с группами объектов в Excel

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

По сути, я унаследовал электронную таблицу с несколькими модулями VBA, записанными с помощью средства записи макросов и/или написанными кем-то, не имеющим опыта работы с VBA, и она работает очень медленно. Я просматривал и уменьшал множество избыточных разделов типа «вложенных если» в циклы for в попытке оптимизировать и ускорить процесс, однако я также очень неопытен и сам не кодер, как вы, вероятно, догадались!

If Range("Link1").Value = "" Then
    Application.CutCopyMode = False

    GoTo Finale:
Else

If Range("Link2").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1")).Select
    Selection.Copy
Else

If Range("Link3").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1", "Group2")).Select
    Selection.Copy
Else

If Range("Link4").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3")).Select
    Selection.Copy
Else

If Range("Link5").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4")).Select
    Selection.Copy
Else

If Range("Link6").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4", "Group5")).Select
    Selection.Copy
Else

If Range("Link7").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4", "Group5", "Group6")).Select
    Selection.Copy
Else

If Range("Link8").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4", "Group5", "Group6", "Group7")).Select
    Selection.Copy
Else

    ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4", "Group5", "Group6", "Group7", "Group8")).Select
    Selection.Copy

End If

End If

End If

End If

End If

End If

End If

End If

Код имеет дело с копированием 8 групп «вещей» (в данном случае, каждая из которых содержит текстовые поля и графику) и проверяет, заполнена ли ссылка, копируя предыдущие группы, когда находит незаполненную ссылку. Таким образом, идея заключается в том, что копируются только заполненные группы.

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

На первый взгляд, вам способ лучше использовать операторы elseif вместо вложенных операторов if.

Tim Stack 12.06.2019 10:31

И прочитайте Как избежать использования Select в Excel VBA

Tim Stack 12.06.2019 10:32

@TimStack точно в точку. Я искал ссылку на эту статью.

rohrl77 12.06.2019 10:33
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
0
3
114
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Трудно сказать, что делает ваш код, исходя из того, что вы предоставляете, но есть несколько способов сделать хотя бы эту часть более эффективной.

Первый — использовать конструкцию ElseIf. Это избавляет вас от необходимости выполнять множество вложенных операторов if.

Во-вторых, вы хотите по возможности избегать использования Select.

Вот пример того, что вы можете сделать для рефакторинга кода:

If Range("Link2").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1")).Copy
ElseIf Range("Link3").Value = "" Then
    ActiveSheet.Shapes.Range(Array("Group1", "Group2")).Copy
Elseif ...

Отсутствие указанной рабочей книги и -листа, а также ссылка на ActiveSheet также является открытой дверью для ошибок.

Tim Stack 12.06.2019 10:39

Согласен ... но пытаюсь делать это шаг за шагом, так как ОП сказал, что он новичок в кодировании.

rohrl77 12.06.2019 10:40

Большое спасибо @ rohrl77. Как я только что описал в другом месте, по какой-то причине, когда я удаляю «Выбрать», это приводит к «Ошибке времени выполнения 438: объект не поддерживает это свойство или метод», но обе точки все еще действительно полезный совет и очень ценный-большое спасибо! :)

Turtle 12.06.2019 10:55

или просто используйте Select Case

Application.ScreenUpdating = False
Select Case Range("Links").Value
        Case "1": ActiveSheet.Shapes.Range(Array("Group1")).Group.Copy
        Case "2": ActiveSheet.Shapes.Range(Array("Group1", "Group2")).Group.Copy
        Case "3": ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3")).Group.Copy
        Case "4": ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4")).Group.Copy
        Case "5": ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4", "Group5")).Group.Copy
        Case "6": ActiveSheet.Shapes.Range(Array("Group1", "Group2", "Group3", "Group4", "Group5", "Group6")).Group.Copy
        Case Else: Application.CutCopyMode = False: GoTo Finale
    End Select
Application.ScreenUpdating = True

куда

Range("Links").Value - это только одна ячейка, где вы вводите желаемый номер

Постарайтесь помочь ОП избежать использования Select

Tim Stack 12.06.2019 10:45

Но почему вы думаете, что ОП хочет этого избежать? Может быть, он хочет выбрать Shapes, чтобы увидеть, что копируется, и я делаю первый Case, чтобы избежать этого ))

Dmitrij Holkin 12.06.2019 10:46

Ответы приходят так быстро, большое спасибо за всю информацию и идеи! @TimStack Я не знаю, связано ли это с какими-то другими плохими практиками, но удаление «выбрать» на самом деле нарушает это для меня, я получаю «Ошибка времени выполнения« 438 »- объект не поддерживает это свойство или метод». Я прочитаю ссылку о том, как избежать выбора, и включу ее в другое место, когда смогу поблагодарить.

Turtle 12.06.2019 10:52

@DmitrijHolkin Большое спасибо, я попробую и отчитаюсь - я достаточно новичок, поэтому еще не понимаю случаи, но мне придется прочитать :)

Turtle 12.06.2019 10:52

@DmitrijHolkin, вам не нужно использовать ужасный Select, чтобы увидеть это..

Tim Stack 12.06.2019 11:19

@Turtle, вам нужно заменить функцию Select, а не удалить слово. Использование Select является плохой практикой и необходимо только в очень редких случаях, поэтому старайтесь избегать его использования. Снова прочитайте эта тема

Tim Stack 12.06.2019 11:20

@TimStack Спасибо, Тим, я буквально только что читал эту ветку, когда ты ответил :) К сожалению, для меня это действительно не работает; Я неправильно сформулировал то, что пытался сказать ранее, но замена «выбрать» на «копировать» в этом случае для меня не работает. Так, например, [ ActiveSheet.Shapes.Range(Array("Group1")).Copy ] выдает ошибку. По какой-то причине работает [ ActiveSheet.Shapes.Range(Array("Group1")).Select с последующим Selection.Copy ]. Есть идеи, почему это может быть связано с какой-то другой плохой практикой в ​​​​коде?

Turtle 12.06.2019 11:28
Этот ответ содержит два варианта использования Select, посмотрите, поможет ли это вам
Tim Stack 12.06.2019 12:21

@DmitrijHolkin Просто в подтверждение того, что я очень ценю ваше предложение, однако необходимость вводить число не совсем подходила для данной ситуации. Это очень полезно как конкретный пример того, как можно использовать регистр - большое спасибо :)

Turtle 13.06.2019 15:44

@TimStack Спасибо за ссылку и дальнейшие идеи. К сожалению, я не смог заставить его работать на меня, группировка выглядела многообещающе, однако я группировал вещи, которые уже были сгруппированы, я думаю, я все еще получал сообщение об ошибке. Мне нужно добиться некоторого прогресса в более важных функциях, но я обязательно вернусь к этому, когда у меня будет время. Спасибо еще раз :)

Turtle 13.06.2019 15:47

Выбор регистра полезен в любой ситуации, так как вы можете делать все, что хотите, например, проверить логическое значение Select Case True, а затем case Range("Links").Value = "" : ActiveSheet.Shapes.Range(Array("Group1")).Group.Copy

Dmitrij Holkin 13.06.2019 17:42

Другие вопросы по теме