Как создать новый лист с несколькими кнопками управления (OLEObject)?

Я работаю над кодом, который имеет две командные кнопки:

1) ВХОД ПОЛЬЗОВАТЕЛЯ

2) Выполнить

При нажатии кнопки ВВОД ПОЛЬЗОВАТЕЛЯ появляется пользовательская форма. На основе входных данных UserForm формат рабочего листа корректируется, и пользователь вводит данные в рабочий лист по запросу. Кнопка «Выполнить» выполняет вычисления и заполняет остальную часть листа, а затем отображает результаты в виде графика ИЛИ открывает новый лист, который затем содержит те же две кнопки.

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

Dim obj As Object
Dim Code As String
Dim obj2 As Object
Dim code2 As String

    With Sec_Delay

        Set obj = .OLEObjects.Add(classType:="Forms.CommandButton.1", _
                                Link:=False, DisplayAsIcon:=False, Left:=279, _
                                Top:=210.75, Width:=109.5, Height:=24)
        obj.Name = "ButtonTest"
        obj.Object.Caption = "USER INPUT"

        Code = "Sub ButtonTest_Click()" & vbCrLf & _
            "UF_input.Show" & vbCrLf & _
            "End Sub"

        Set obj2 = .OLEObjects.Add(classType:="Forms.CommandButton.2", _
                                Link:=False, DisplayAsIcon:=False, Left:=277.5, _
                                Top:=236.25, Width:=111, Height:=24)
        obj2.Name = "Execute2Test"
        obj2.Object.Caption = "Execute"

        code2 = "Sub Execute2Test_Click()" & vbCrLf & _
                "Cells(8,1) = 1" & vbCrLf & _
                "End Sub"

        With .Parent.VBProject.VBComponents(.CodeName).CodeModule
            .insertlines .CountOfLines + 1, Code
        End With
    End With

Этот код находится внутри моей подпрограммы, которая создает новый лист. Новый лист называется «Sec_Delay» и имеет только одну командную кнопку. Я поднял код для первой командной кнопки откуда-то еще в stackoverflow, поэтому я не знаком с тем, что делает последняя часть:

    With .Parent.VBProject.VBComponents(.CodeName).CodeModule
        .insertlines .CountOfLines + 1, Code
    End With

Но в основном я понимаю, как работает OLEObject. Я просто не понимаю, как сделать вторую командную кнопку для нового листа.

Как я могу создать вторую командную кнопку? Почему Forms.CommandButton.2 ничего не делает? Что вообще означает ".1"? Возможно ли иметь два объекта OLEObject в одной подпрограмме?


person Dives    schedule 26.04.2018    source источник


Ответы (1)


Ты почти там...

Forms.CommandButton.1 - это имя класса для элемента управления: он определяет, какой тип элемента управления создается, и вы не должны изменять значение, иначе Excel не распознает его.

Последняя часть кода добавляет обработчики событий для кнопок в модуль кода листа: после создания листа вы можете просмотреть код в редакторе VB.

Dim obj As Object
Dim Code As String
Dim obj2 As Object
Dim code2 As String

With Sec_Delay

    Set obj = .OLEObjects.Add(classType:="Forms.CommandButton.1", _
                            Link:=False, DisplayAsIcon:=False, Left:=279, _
                            Top:=210.75, Width:=109.5, Height:=24)
    obj.Name = "ButtonTest"
    obj.Object.Caption = "USER INPUT"

    Code = "Sub ButtonTest_Click()" & vbCrLf & _
        "UF_input.Show" & vbCrLf & _
        "End Sub"

    'edit: use "Forms.CommandButton.1" again
    Set obj2 = .OLEObjects.Add(classType:="Forms.CommandButton.1", _
                            Link:=False, DisplayAsIcon:=False, Left:=277.5, _
                            Top:=236.25, Width:=111, Height:=24)
    obj2.Name = "Execute2Test"
    obj2.Object.Caption = "Execute"

    code2 = "Sub Execute2Test_Click()" & vbCrLf & _
            "Cells(8,1) = 1" & vbCrLf & _
            "End Sub"

    With .Parent.VBProject.VBComponents(.CodeName).CodeModule
        .insertlines .CountOfLines + 1, Code
        .insertlines .CountOfLines + 1, code2 '<< added
    End With
End With

РЕДАКТИРОВАТЬ: если вы хотите вызвать код, который находится в модуле листа, из обычного модуля, вам необходимо включить имя модуля в вызов.

Sub TestCall()
    Sheet1.Tester
End Sub

... и убедитесь, что вы используете кодовое имя листа, а не имя вкладки:

введите описание изображения здесь

person Tim Williams    schedule 26.04.2018
comment
Спасибо @Tim, что сработало! Я пытаюсь настроить кнопку Execute2Test для запуска того же кода с первой кнопки, которая называется ExecuteButton_Click (). Однако, когда я набираю "Call ExecuteButton_Click", я получаю сообщение об ошибке: Sub или Function not defined. Но он определен как Public Sub ExecuteButton_Click() на листе 1. Как мне заставить его запускать этот код, который находится на листе 1? Я думал, что если называть его Public Sub, на него можно будет ссылаться где угодно. - person Dives; 27.04.2018
comment
Попробуйте Sheet1.ExecuteButton_Click (или другое кодовое имя для модуля Sheet1). Модуль кода Sheet1 представляет объект Worksheet, поэтому вам необходимо соответствующим образом определить область видимости ваших вызовов. - person Tim Williams; 27.04.2018
comment
Когда я пытаюсь это сделать, он все еще говорит «Требуется объект». Следующее, что я попробовал, - это превратил весь математический код в его собственную подпрограмму, так что ExecuteButton_Click имеет только одну строку кода Call MathCode. Затем я попытался вызвать Sheet1.MathCode, MathCode и Sheet1.ExecuteButton_Click в OLEObject, но ничего не помогло. Все они возвращают одну и ту же ошибку. - person Dives; 27.04.2018
comment
Если вы получили требуемый объект, возможно, вы используете неправильное имя модуля листа: убедитесь, что оно соответствует тому, что отображается в дереве в редакторе VB. - person Tim Williams; 27.04.2018
comment
Кто-то сказал мне, что вы не можете ссылаться на код из другого модуля рабочего листа. Это правда? Он порекомендовал мне поместить весь свой код в обычный модуль, а затем вызвать подпрограммы в модуле рабочего листа. Это вызвало различные ошибки, которые я не мог понять. Я не понимаю, почему я не могу просто позвонить своей подписке куда угодно, ведь она общедоступна. - person Dives; 27.04.2018
comment
Нет проблем со ссылкой на код из модуля рабочего листа (в той же книге), если вы префикс его с кодовым именем модуля листа (как в моем примере выше). Сделать Sub Public просто означает, что он видим: это не позволяет вам игнорировать требования к области видимости. В моем примере Tester - это метод Sheet1, поэтому вы должны называть его как Sheet1.Tester - person Tim Williams; 27.04.2018