简体   繁体   中英

VBA passing userform controls as parameters

I want to have the .Caption of a userform label modified by a Sub which is located in another module.

  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

The 1st time the procedure is called, it returns Vs_Label = "something else". The 2nd time the procedure is called it returns Label_S.Capiton = "something".

Can someone explain to me what is happening here?

Sub ChangeLabel(Vs_Label)

First, let's make things clearer by making all the modifiers and types explicit.

Public Sub ChangeLabel(ByRef Vs_Label As Variant)

We're given a local variable named Vs_Label , whose initial value is vbNullString .

 Dim Vs_Label as String Label_S.Caption = "something"

At this point Vs_Label is still vbNullString , and Label_S.Caption is "something".

 Call ChangeLabel(Vs_Label)

Now we're passing the Vs_Label variable pointer to the procedure, which assigns it to "something else". Note that this would be equivalent, and arguably cleaner code:

ChangeLabel Vs_Label

After this statement returns, Vs_Label is "somethign else", and Label_S.Caption is still "something".

 Label_S.Caption = Vs_Label

Now both Vs_Label and Label_S.Caption contain "something else".

 Call ChangeLabel(Label_S.Caption)

This call is different now: we're not passing in a variable reference, but a member expression.

So the member expression gets evaluated ("something else"), and a reference to that value (which the caller isn't holding on to) is passed to the procedure, which assigns it to "something else" (no change), ...and then the reference is discarded: the 2nd call has no effect whatsoever.

So at the end of the procedure both Vs_Label and Label_S.Caption are both "something else".

In order for the Caption of the label to be "something", at the end of that code, you'd need to have different code.

Place a breakpoint near the top of the procedure (F9), run the code, and use F8 to step through and inspect your labels and variables as you go: you'll find that this code has nothing to do with why the label says "something".

Verify what instance of the form you're working with, in the two places you're looking - and make sure both places are working with the same object instance. The Activate handler will run every time the form is activated - if the form isn't being shown as a modal dialog, then this could be multiple times per instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM