VBA передает пользовательские элементы управления в качестве параметров - PullRequest
2 голосов
/ 11 декабря 2019

Я хочу, чтобы .Caption метки пользовательской формы был изменен с помощью Sub, который находится в другом модуле.

  Private Sub UserForm_Activate()

    Dim Vs_Label as string
    Label_S.Caption = "something"

    Call ChangeLabel(Vs_Label)
    Label_S.Caption = Vs_Label

    Call ChangeLabel(Label_S.Caption)
  end

  Sub ChangeLabel(Vs_Label)
    Vs_Label = "something else"
  end

При первом вызове процедуры возвращается Vs_Label = "что-то другое". Во второй раз, когда процедура вызывается, она возвращает Label_S.Capiton = "что-то".

Может кто-нибудь объяснить мне, что здесь происходит?

1 Ответ

3 голосов
/ 11 декабря 2019
Sub ChangeLabel(Vs_Label)

Во-первых, давайте проясним ситуацию, сделав все модификаторы и типы явными.

Public Sub ChangeLabel(ByRef Vs_Label As Variant)

Нам дана локальная переменная с именем Vs_Label, чья начальнаязначение равно vbNullString.

Dim Vs_Label as String
Label_S.Caption = "something"

В этот момент Vs_Label по-прежнему vbNullString, а Label_S.Caption это "что-то".

Call ChangeLabel(Vs_Label)

Теперь мы передаем переменный указатель Vs_Label в процедуру, которая присваивает его «чему-то еще». Обратите внимание, что это будет эквивалентный и, возможно, более чистый код:

ChangeLabel Vs_Label

После возврата этого оператора Vs_Label - это "somethign else", а Label_S.Caption - все еще "что-то".

Label_S.Caption = Vs_Label

Теперь и Vs_Label, и Label_S.Caption содержат «что-то еще».

Call ChangeLabel(Label_S.Caption)

Этот вызов теперь другой: мы непередавая ссылку на переменную, но выражение члена.

Таким образом, выражение члена получает оценку («что-то еще») и ссылку на это значение (которое не содержит вызывающая сторонаon to) передается процедуре, которая присваивает ей «что-то другое» (без изменений), ... и затем ссылка отбрасывается: 2-й вызов не имеет никакого эффекта.

Итак, в концепроцедуры Vs_Label и Label_S.Caption оба являются «чем-то другим».

Чтобы Caption метки был «чем-то», в конце этого кода вы бынужно иметь другой код.

Поместите точку останова в верхней части процедуры (F9), запустите код,и используйте F8, чтобы пройти и проверить ваши метки и переменные по ходу дела: вы обнаружите, что этот код не имеет никакого отношения к тому, почему метка говорит «что-то».

Проверьте, какой экземпляр формы вы 'Вы работаете с двумя местами, которые ищете, и убедитесь, что оба места работают с одним и тем же экземпляром объекта. Обработчик Activate будет запускаться каждый раз, когда форма активируется - если форма не отображается как модальное диалоговое окно, то это может быть несколько раз за экземпляр.

...