Приветствую! Я правильно понимаю, что [ни при каких обстоятельствах] НЕЛЬЗЯ объявить переменнуюпо условию?
Код
Код
Sub t()
Dim n&
If n = 1 Then
Dim p&
Static pp&
End If
Debug.Print TypeName(p), TypeName(pp) ' всегда выдаст Long Long
End Sub
Может, можно с помощью # (как при проверке разрядности для API) или типа того?…
Практического смысла мало - можно было бы сократить время работы, НЕ вызывая словари, регулярки и прочие "тяжёлые" объекты, если они не понадобятся в коде далее (определяется условиями в процессе выполнения кода), но это решается статическими переменными с проверкой на инициализацию
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
не совсем так. Есть операторы прекомпиляции. Например, можно назначить разный тип одной переменной в зависимости от разрядности системы:
Код
Sub DiffVariableType()
#If Win64 Then
Dim n as long
#Else
Dim n as longlong
#End If
End Sub
другой вопрос, что условия здесь ограничены переменными окружения по сути. Т.е. нельзя будет по факту изменить тип внутри цикла по условию другой переменной.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
правильно я понимаю, что обычными условиями решить, объявлять переменную или нет — не получится? Только ограниченным списком условий и то только выбрать ТИП, но никак не решить, ВВОДИТЬ ПЕРЕМЕННУЮ или нет? Мне это нужно просто чтобы объявлять или не объявлять переменную внутри одной процедуры
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous, как уже написал выше - по условию никак. В том плане, что по такому условию, которые ты привел в первом сообщении. Только зарезервированные для перкомпиляции типы переменных.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
#Const ALEXEY = True ' Менять здесь
#If ALEXEY Then
Dim a As Long
#Else
Dim b As Range
#End If
Sub Test()
#If ALEXEY Then
Debug.Print TypeName(a)
Dim c
'...
#Else
Debug.Print TypeName(b)
Dim d
'...
#End If
End Sub
Локальные переменные можно задавать и обычным способом
Код
Sub Test1()
Dim n&
n = 1 ' или вызов функции, меняющей n: Call Fn(n)
If n = 1 Then
Dim ЧегоНибудь
' И дальше весь код здесь
'...
Else
Dim ЧегоНибудьДругое
'И дальше весь код здесь
'...
End If
End Sub
Правильно ли понимаю: где бы ни была объявлена в процедуре переменная, память она кушает сразу, при запуске процедуры? И столько, сколько потребуется для указанного (или Variant) типа
Jack Famous, Алексей, ну сам вопрос как бред, ибо : если, как рекомендовано и ты используешь, все переменные должны быть определены, то определять все равно надо. На этапе предкомпиляции выявится или отсутствие определения или дублирование. Не могу гарантироватm на 100, но логика мне подсказывает, что если теле процедуры появилось определение переменной, то независимо от номера строки переменная будет определена с самого начала процедуры, и естеcвенно доходит ли код до нее или не доходит, уже не важно.
ZVI, приветствую, Владимир! Вот это штуку вы показали! Большое спасибо! Действительно, при таком вызове переменные b и d остаются НЕ ОПРЕДЕЛЕНЫ
Цитата
ZVI: Локальные переменные можно задавать и обычным способом … If n = 1 Then Dim ЧегоНибудь
а в таком случае (как я в шапке и показал) все переменные будут ОБЪЯВЛЕНЫ вне зависимости от "внутренних" условий процедуры/функции
ZVI, правильно ли я понимаю, что без "внешнего" определения переменных и условий (перед первой процедурой модуля) никак более НЕ ВВОДИТЬ переменную (исходя только из внутренних условий процедуры) — не получится?
Цитата
vikttur: где бы ни была объявлена в процедуре переменная, память она кушает сразу, при запуске процедуры? И столько, сколько потребуется для указанного (или Variant) типа
с использованием "условной" константы уровня модуля типа #Const ALEXEY = True — можно ВЫБОРОЧНО вводить переменные, во всех остальных все вводимые "по условию" переменные это тоже самое, что ввести их без условия
Ну и помним (указал в шапке), что влиять на выделение памяти и экономно (увеличивая скоростьпри многократном вызове функций с ними) использовать переменные можно, объявив их статичными и вводя/меняя только по мере надобности
Самое частое:
Код
…
Static RE As RegExp, fStatic As Boolean
If Not fStatic Then
fStatic = True
Set RE = New RegExp ' важно что "New" только тут, а не "Static RE As New RegExp"
RE.Global = True
RE.Pattern = "/d"
End If
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Добрый день, Виктор. Да, правильно. Кроме тех, что объявлены в условном компилировании.
P.S. Для выполнения кода он автоматически компилируется, если ранее не был скомпилирован. При этом резервируется память, в том числе, под все переменные как глобальные, так и локальные. При этом из #If Cond #Else #End If компилируются только то, что определено условием Cond .
очень легко сказать "бред" (вообще не понимаю, зачем тогда заходить в тему) и не пытаться выяснить, зато Владимир ZVI показал, в каких условиях это всё-таки возможно
Цитата
БМВ: На этапе предкомпиляции выявится или отсутствие определения или дублирование
а вопрос про "используем или нет"
Цитата
БМВ: если теле процедуры появилось определение переменной, то будет определена с самого начала
тесты показывают тоже самое (как и на твоём скрине)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
БМВ написал: переменная будет определена с самого начала процедуры
Здравствуйте, коллеги! Давно такой кворум не собирался. Я всегда объявляю переменные в начале макроса, но это дело вкуса. Некоторые любят объявление перед первым использованием (что гарантирует, что в предыдущих строках макроса эта переменная не была задействована).
Правильно. По коду - вместо If Not fStatic Then лучше If RE Is Nothing Then без всяких лишних дел Вообще, экономить на переменных - это явный перебор: - память они сами по себе отъедают никакую. - глобальные переменные можно очищать, а локальные создаются и живут только на время выполнения процедуры/функции.
Непонятно, в чем проблема, которую нужно решать. И проблема ли это? Скорее, вопрос познавательный, как я понял.
sokol92, приветствую! Я тоже объявляю всё сначала - проще править и вообще видеть всю картину Однако, как мы выяснили, положение никак не влияет на "видимость" и, где бы не была переменная объявлена, жрёт она на момент запуска процедуры
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: это медведю всегда "ЗАЧЕМ???" подавай
естественно, ибо не первый случай когда вопрос как , раскручивается до зачем и от этого идет совершенно иное решение. Что касаемо цели там или , то "экономия" имен переменных понятно что не удел. Экономия памяти за счет неопределенных переменных может дать обратный результат , когда именно этого байта не хватит при определенных условиях, которых не было при тестах.