Option Explicit
Option Private Module
'====================================================================================================
Const nMax& = 100000000
'====================================================================================================
Sub Test_IfClassic()
Dim t!, n&, p&
t = Timer
For n = 1 To nMax
If n = 1 Then
p = p + 1
ElseIf n = 10 Then
p = p + 1
ElseIf n = 100 Then
p = p + 1
ElseIf n = 1000 Then
p = p + 1
ElseIf n = 10000 Then
p = p + 1
ElseIf n = 100000 Then
p = p + 1
ElseIf n = 1000000 Then
p = p + 1
ElseIf n = 10000000 Then
p = p + 1
ElseIf n = 100000000 Then
p = p + 1
End If
Next n
Debug.Print "IfClassic", Timer - t, p
End Sub
'====================================================================================================
Sub Test_IfMonster()
Dim t!, n&, p&
t = Timer
For n = 1 To nMax
If n = 1 Then
p = p + 1
Else
If n = 10 Then
p = p + 1
Else
If n = 100 Then
p = p + 1
Else
If n = 1000 Then
p = p + 1
Else
If n = 10000 Then
p = p + 1
Else
If n = 100000 Then
p = p + 1
Else
If n = 1000000 Then
p = p + 1
Else
If n = 10000000 Then
p = p + 1
Else
If n = 100000000 Then
p = p + 1
End If
End If
End If
End If
End If
End If
End If
End If
End If
Next n
Debug.Print "IfMonster", Timer - t, p
End Sub
'====================================================================================================
Sub Test_IfGoTo()
Dim t!, n&, p&
t = Timer
For n = 1 To nMax
If n = 1 Then p = p + 1: GoTo nx
If n = 10 Then p = p + 1: GoTo nx
If n = 100 Then p = p + 1: GoTo nx
If n = 1000 Then p = p + 1: GoTo nx
If n = 10000 Then p = p + 1: GoTo nx
If n = 100000 Then p = p + 1: GoTo nx
If n = 1000000 Then p = p + 1: GoTo nx
If n = 10000000 Then p = p + 1: GoTo nx
If n = 100000000 Then p = p + 1
nx:
Next n
Debug.Print "IfGoTo", Timer - t, p
End Sub
'====================================================================================================
Sub Test_Case()
Dim t!, n&, p&
t = Timer
For n = 1 To nMax
Select Case n
Case Is = 1: p = p + 1
Case Is = 10: p = p + 1
Case Is = 100: p = p + 1
Case Is = 1000: p = p + 1
Case Is = 10000: p = p + 1
Case Is = 100000: p = p + 1
Case Is = 1000000: p = p + 1
Case Is = 10000000: p = p + 1
Case Is = 100000000: p = p + 1
End Select
Next n
Debug.Print "Case", Timer - t, p
End Sub
'====================================================================================================
Выводы
Скорости примерно равны (кроме монстра )
Краткая запись Select Case очень выгодно смотрится в примере и является отличным вариантом Также можно использовать переход по метке (он незначительно быстрее и на 1 строку короче), но это не все одобряют (вкусовщина)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
При множестве условий If труднее читается. Select Case предпочтительнее. Переход по метке не одобряю и не применяю (почти). Не надо структуру (последовательность) нарушать.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: Вариант с переходом по метке мне нравится больше остальных
ровно до того случая когда это не приведет к катастрофическим последствиям. Забыл указать или не на ту метку отправил. 2 структура If then else end if грамотными редакторами автоматически распознается и не только контролируется на целостность но и позволяет для удобства схлопнуть блок. Естественно мы о нее блоке в одну строку как в примере. Я вот в ущерб длине кода всегда использую
БМВ: ровно до того случая когда это не приведет к катастрофическим последствиям
я этих страшилок наслушался за 5 лет и чёт не было ничего страшного. Даже меньше, чем при обычном программировании, т.к. метки редкие и их хорошо видно слева Дядь Миш, меточный холивар по ссылке из #3, а тут — просто сравнение скоростей
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
интересно как))) а что делать, например, если в процессе выполнения макроса мы что-то спрашиваем у пользователя через диалог и там есть красный крестик и/или кнопка отмены? Я уже молчу про кучу проверок, которые нужно проводить и выходить при несоблюдении условий...)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Михаил игнорирует exit sub, но использует goto. Отчего такая нелюбовь к exit sub ? Например в Си, там нужно перед выходом почистить память, поэтому goto-->delete x-->return. В vba можно сразу exit sub
А чем ненормален exit sub? P.S. В том же С/С++ , C#.NET нет понятия exit sub. Там в любом месте можно выйти из функции/процедуры, используя return. Это нормально)
bedvit: Михаил игнорирует exit sub, но использует goto
а ты покури формулы с его — и не такое кодить начнёшь Го в тему с метками — я ща примерчик накидаю о "полезности меток"
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Михаил не игнорирует, а просто считает код более читаемым логичным без меток там, где без них можно обойтись. Уже раз писал, что несмотря на то что в VBS допускается описывать функцию или процедуру по ходу основного кода
Код
Call sub1
Sub sub1()
Call sub11
WScript.Echo "sub1"
End Sub
WScript.Echo "main1"
Sub sub11()
WScript.echo "sub11"
End Sub
WScript.Echo "main2"
и это делает код не всегда читаемым когда посреди основного кода возникает описание подпрограммы. По этой причине, чтоб шанса не было так сделать, для чуть более крупного скрипта я всегда делал основную процедура именно отдельной процедурой, вынося за её пределы определения переменных? если они нужны глобально, и описание констант.
Пишу код и понимаю, что в данном случае Select Case уже не поможет, а с меткой всё также легко и коротко
Код
Sub File_CopyKillRename(Optional fCopy As Boolean, Optional fKill As Boolean, Optional fRename As Boolean)
Dim tx$
If fCopy + fKill + fRename <> -1 Then Stop
If fCopy Then tx = "Copy": GoTo nx
If fKill Then tx = "Kill" Else tx = "Rename"
nx: 'other code
End Sub
UPD: далее БМВ показал, как это сделать легко и просто
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: Пишу код и понимаю, что в данном случае Select Case
Select case нет, а If...Then никто не отменял
Код
Sub File_CopyKillRename(Optional fCopy As Boolean, Optional fKill As Boolean, Optional fRename As Boolean)
Dim tx$
If fCopy + fKill + fRename <> -1 Then Stop
If fCopy Then tx = "Copy" Else If fKill Then tx = "Kill" Else tx = "Rename"
End Sub
"Все гениальное просто, а все простое гениально!!!"
Nordheim: If fCopy Then tx = "Copy" Else If fKill Then tx = "Kill" Else tx = "Rename"
понятно, что так можно, но это уже беспредел какой-то Я в такую кишку могу завернуть только 2 последовательные проверки — больше совесть не позволяет
Как выиграть немного времени при нескольких проверках
Код
If x>5 And x<10 Then ' классика (всегда проверяются оба условия
If x>5 Then If x< 10 Then ' быстрее (второе условие проверяется только при истине первого
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄