Я не уверен, как оптимизировать код, прикрепленный ниже, в какую-то форму цикла, и я надеюсь, что кто-то сможет проиллюстрировать, как лучше всего решить эту проблему.
По сути, я унаследовал электронную таблицу с несколькими модулями 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, действительно ли действительно быстрее или оптимальнее сводить такие вещи в циклы, или мне следует искать в другом месте для дальнейшей оптимизации электронной таблицы? Превращение длинных фрагментов рекурсивного кода в минимальные циклы, безусловно, приятно (!), но я не знаю, действительно ли это нужно делать для повышения скорости и стабильности, или это действительно имеет мало значимого влияния.
И прочитайте Как избежать использования Select в Excel VBA
@TimStack точно в точку. Я искал ссылку на эту статью.
Трудно сказать, что делает ваш код, исходя из того, что вы предоставляете, но есть несколько способов сделать хотя бы эту часть более эффективной.
Первый — использовать конструкцию 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
также является открытой дверью для ошибок.
Согласен ... но пытаюсь делать это шаг за шагом, так как ОП сказал, что он новичок в кодировании.
Большое спасибо @ rohrl77. Как я только что описал в другом месте, по какой-то причине, когда я удаляю «Выбрать», это приводит к «Ошибке времени выполнения 438: объект не поддерживает это свойство или метод», но обе точки все еще действительно полезный совет и очень ценный-большое спасибо! :)
или просто используйте 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
Но почему вы думаете, что ОП хочет этого избежать? Может быть, он хочет выбрать Shapes, чтобы увидеть, что копируется, и я делаю первый Case, чтобы избежать этого ))
Ответы приходят так быстро, большое спасибо за всю информацию и идеи! @TimStack Я не знаю, связано ли это с какими-то другими плохими практиками, но удаление «выбрать» на самом деле нарушает это для меня, я получаю «Ошибка времени выполнения« 438 »- объект не поддерживает это свойство или метод». Я прочитаю ссылку о том, как избежать выбора, и включу ее в другое место, когда смогу поблагодарить.
@DmitrijHolkin Большое спасибо, я попробую и отчитаюсь - я достаточно новичок, поэтому еще не понимаю случаи, но мне придется прочитать :)
@DmitrijHolkin, вам не нужно использовать ужасный Select
, чтобы увидеть это..
@Turtle, вам нужно заменить функцию Select
, а не удалить слово. Использование Select
является плохой практикой и необходимо только в очень редких случаях, поэтому старайтесь избегать его использования. Снова прочитайте эта тема
@TimStack Спасибо, Тим, я буквально только что читал эту ветку, когда ты ответил :) К сожалению, для меня это действительно не работает; Я неправильно сформулировал то, что пытался сказать ранее, но замена «выбрать» на «копировать» в этом случае для меня не работает. Так, например, [ ActiveSheet.Shapes.Range(Array("Group1")).Copy ] выдает ошибку. По какой-то причине работает [ ActiveSheet.Shapes.Range(Array("Group1")).Select с последующим Selection.Copy ]. Есть идеи, почему это может быть связано с какой-то другой плохой практикой в коде?
Select
, посмотрите, поможет ли это вам
@DmitrijHolkin Просто в подтверждение того, что я очень ценю ваше предложение, однако необходимость вводить число не совсем подходила для данной ситуации. Это очень полезно как конкретный пример того, как можно использовать регистр - большое спасибо :)
@TimStack Спасибо за ссылку и дальнейшие идеи. К сожалению, я не смог заставить его работать на меня, группировка выглядела многообещающе, однако я группировал вещи, которые уже были сгруппированы, я думаю, я все еще получал сообщение об ошибке. Мне нужно добиться некоторого прогресса в более важных функциях, но я обязательно вернусь к этому, когда у меня будет время. Спасибо еще раз :)
Выбор регистра полезен в любой ситуации, так как вы можете делать все, что хотите, например, проверить логическое значение Select Case True
, а затем case Range("Links").Value = "" : ActiveSheet.Shapes.Range(Array("Group1")).Group.Copy
На первый взгляд, вам способ лучше использовать операторы elseif вместо вложенных операторов if.