VBA: ByRef - не изменяются значения вызывающей процедуры

Автор noname6171, 27 января 2017, 22:34

noname6171

Если я изменяю значение элементов контроля формы напрямую из процедуры Show_uf_1, все работает.
Для сокращения кода хотел выделить повторяющиеся фрагменты в процедуру FillBarDateTime - не работает.

FillBarDateTime вызывается, получает значения, выполняется, считает новые значения - все как задумано, но они не связаны со значениями вызывающей процедуры, не изменяют их. Например изменение sDate не изменяет uf_1.f_Common.l_CommonFirstDate.Caption. Обойти проблему не сложно прямым присвоением в Show_uf_1. Хотелось бы докопаться до сути, на будущее. В чем косяк?

Заранее спасибо.

Код
Sub Show_uf_1()

    uf_1.Show

    With uf_1
        .f_Common.l_BarsWorked.Caption = 0 ' работает
        .f_Common.l_BarsMax.Caption = CommonLastBar
       
        .f_Common.tb_CommonLastBar.Value = CommonLastBar
    End With
   
    Call FillBarDateTime(1, uf_1.f_Common.tb_CommonFirstBar.Value, uf_1.f_Common.l_CommonFirstDate.Caption, _
        uf_1.f_Common.l_CommonFirstTime.Caption) ' не работает
    Call FillBarDateTime(P, uf_1.f_Common.tb_CommonLastBar.Value, uf_1.f_Common.l_CommonLastDate.Caption, _
        uf_1.f_Common.l_CommonLastTime.Caption)
   
    uf_1.f_Common.tb_CommonFirstBar.Value = CStr(CommonFirstBar) ' работает
    uf_1.f_Common.l_CommonFirstDate.Caption = Worksheets("Data").Cells(CommonFirstBar, 3)
    s = Worksheets("Data").Cells(CommonFirstBar, 4)
    uf_1.f_Common.l_CommonFirstTime.Caption = Mid(s, 1, 2) & ":" & Mid(s, 3, 2) & ":00"
       
End Sub

Sub FillBarDateTime(n As Long, ByRef sBarNum As String, ByRef sDate As String, ByRef sTime As String)

    Dim s As String
   
    sBarNum = CStr(n)
    sDate = Worksheets("Data").Cells(n, 3)
    s = Worksheets("Data").Cells(n, 4)
    sTime = Mid(s, 1, 2) & ":" & Mid(s, 3, 2) & ":00"

End Sub
[свернуть]

Администратор

Да, не работает так. Не знаю, почему не работает.
Можно такой вариант использовать. Я использую свои контролы, а не те, которые вы указали в сообщении.
Слово "ByRef" можно явно не указывать, т.к. это слово используется по умолчанию в VBA (в других языках программирования не так).

Private Sub CommandButton1_Click()
    Call meth(Me.TextBox1)
    Call meth(Me.TextBox2)
End Sub

Private Sub meth(txt As MSForms.TextBox)
    txt.Text = "text"
End Sub

noname6171

Спасибо! Помогло. Переделал по аналогии с Вашим примером.

Как я это понял, нельзя передавать по ссылке свойство элемента контроля. Изменение значения в вызываемой процедуре не меняет свойство самого элемента контроля.

Но если передать по ссылке сам элемент контроля, то обращаясь к его свойству в вызываемой процедуре, мы можем изменить это свойство элемента контроля.

Итоговый рабочий вариант:
Спойлер


Sub Show_uf_1()


        uf_1.Show

        With uf_1
            .f_Config.l_Instr.Caption = Worksheets("Data").Cells(1, 1)
            .tb_NN.Value = NN
            .tb_Step.Value = Step
            .tb_Comissions.Value = Comissions
            .tb_Intervals.Value = Intervals
           
            .f_Common.l_BarsWorked.Caption = 0
            .f_Common.l_BarsMax.Caption = CommonLastBar
           
            Call FillBarDateTime(CommonFirstBar, .f_Common.tb_CommonFirstBar, .f_Common.l_CommonFirstDate, .f_Common.l_CommonFirstTime)
            Call FillBarDateTime(CommonLastBar, .f_Common.tb_CommonLastBar, .f_Common.l_CommonLastDate, .f_Common.l_CommonLastTime)
        End With

End Sub



Sub FillBarDateTime(n As Long, sBarNum As MSForms.TextBox, sDate As MSForms.Label, sTime As MSForms.Label)

    Dim s As String
   
   
        sBarNum.Text = CStr(n)
        sDate.Caption = Worksheets("Data").Cells(n, 3)
        s = Worksheets("Data").Cells(n, 4)
        sTime.Caption = Mid(s, 1, 2) & ":" & Mid(s, 3, 2) & ":00"

End Sub



[свернуть]