Страницы: 1
RSS
Как передать аргумент в событие при программном создании формы?
 
Здравствуйте. Изучаю пример с форумов
Код
ub MakeForm()
    Dim TempForm As Object    'VBComponent
    Dim NewButton As Msforms.CommandButton
    Dim Line As Integer
    Dim TheForm
    Application.VBE.MainWindow.Visible = False
    ' Создание диалогового окна UserForm
    Set TempForm = ThisWorkbook.VBProject. _
                   VBComponents.Add(3)    'vbext_ct_MSForm
    With TempForm
        .Properties("Caption") = "Временная форма"
        .Properties("Width") = 200
        .Properties("Height") = 100
    End With
    ' Добавление элемента управления CommandButton
    Set NewButton = TempForm.Designer.Controls _
                    .Add("forms.CommandButton.1")
    With NewButton
        .Caption = "Щелкни!"
        .Left = 60
        .Top = 40
    End With

    With TempForm.CodeModule
        Line = .CountOfLines
        .InsertLines Line + 1, "Sub CommandButtonl_Click()"
        .InsertLines Line + 2, "MsgBox ""Привет!"""
        .InsertLines Line + 3, "Unload Me"
        .InsertLines Line + 4, "End Sub"
    End With
    ' Отображение диалогового окна UserForm
    VBA.UserForms.Add(TempForm.Name).Show
    ' Удаление диалогового окна UserForm
    ThisWorkbook.VBProject.VBComponents.Remove TempForm
End Sub
Что если при нажатии на кнопку формы требуется удалить эту форму?
Код
With TempForm.CodeModule
        Line = .CountOfLines
        .InsertLines Line + 1, "Sub CommandButtonl_Click()"
        .InsertLines Line + 2, "ThisWorkbook.VBProject.VBComponents.Remove TempForm"
        .InsertLines Line + 3, "End Sub"
    End With
Но это не будет работать, поскольку не понятно, как в создаваемое событие Sub CommandButtonl_Click()  передать параметр TempForm.
Пробовал другое решение: "ThisWorkbook.VBProject.VBComponents.Remove Me", ошибка - type mismatch. Хотя вроде бы Me - ссылка на родителя, а для кнопки это форма.
Пробовал помещать строку "ThisWorkbook.VBProject.VBComponents.Remove Me" в создаваемые для формы события Unload и Terminate - ошибок нет, но форма не удаляется.
Изменено: zenija2007 - 07.05.2018 09:07:29
 
А создать процедуру удаления формы в другом модуле и вызвать ее по Application.OnTime ?
 
Dima S,
попытался. попробовал вызвать процедуру основного кода, потом добавил ее прямо в код формы. в итоге в форме получился такой код:
Код
Option Explicit

Sub Button1_Click()
Application.OnTime Now + TimeValue("00:00:05"), "DelForms(Me)"
Unload Me
End Sub
Sub DelForms(nf As Object)
ThisWorkbook.VBProject.VBComponents.Remove nf
End Sub
но при попытке вызвать процедуру DelForms в обоих случаях пишет, что не может выполнить. Ошибку в упор не вижу.
Не удается выполнить макрос "DelForms(Me)". Возможно, этот макрос отсутствует в текущей книге, либо все макросы отключены.
Изменено: zenija2007 - 07.05.2018 12:38:50
 
Цитата
zenija2007 написал:
разработчики наверное сами не понимали, что делали
Я думаю они все отлично понимали. Только не уверен, что Вы правильно все используете. Как минимум так должно быть:
Код
Application.OnTime Now + TimeValue("00:00:01"), "'DelForms " & Me.Name & "'"
чтобы передать аргумент в OnTime.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дмитрий Щербаков,
исправил, но ошибка точно такая же - и при обращении к процедуре основного кода, и при создании процедуры в форме.
Не удается выполнить макрос "DelForms(UserForm1)". Возможно, этот макрос отсутствует в текущей книге, либо все макросы отключены.
Основной код находится в модуле Module1, хотя вряд ли это на что то влияет.
Изменено: zenija2007 - 07.05.2018 12:53:57
 
Значит он действительно отсутствует. Вы его, наверное, разместили внутри самой формы, а не в стандартном модуле? И непонятно - так же в скобках пишет UserForm? Не должен, если использовать тот код, который я привел.
Изменено: Дмитрий Щербаков - 07.05.2018 12:56:00
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
zenija2007 написал:
Основной код находится в модуле Module1
основной - это какой? В стандартном модуле должен находиться как минимум вызываемый, иначе он действительно не будет найден. Ну а вызывающий, естественно, внутри формы - чтобы быть привязанным к событию нажатия кнопки. Но это, судя по всему, работает без проблем, раз ошибку описанную получаете.
В общем оптимальным вариантом было бы увидеть файл, в котором проблема возникает.
Изменено: Дмитрий Щербаков - 07.05.2018 12:59:07
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дмитрий Щербаков,
загрузил файл. весь скрипт находится в модуле Module1, процедура для удаления формы находится там же, но доступ к ней  Application.Ontime получить не может. Такая же процедура с чуть изменным именем добавляется непосредственно в форму, и доступ к ней получить также не удается. В приведенном вами примере было написано Me.Name, а это и есть имя формы.
Главная процедура в самом низу nform().
Изменено: zenija2007 - 08.05.2018 04:52:57
 
как я понимаю, подобное никто не делал, и ответа не знает. зато написать с умным видом нерабочий совет - это завсегда. разочарован в местных гуру. далеко не первый случай.
Изменено: zenija2007 - 11.05.2018 04:57:07
 
Если Вы думаете, что Ваша задача кому-то очень интересна кроме Вас и, вместо шашлыков на природе тут все только и думают как Вам помочь, Вы глубоко заблуждаетесь.
Цитата
zenija2007 написал: разочарован в местных гуру
на слабо тут брать не нужно - не прокатит. Кому станет интересно тот поможет, а разочаровываться и исправлять нужно свои кривые руки.
Цитата
Дмитрий Щербаков написал: И непонятно - так же в скобках пишет UserForm?
а Вы упорно пытаетесь эти скобки впихнуть в строку. Ну и прочее.
Вариант
Запоминаем индекс создаваемой формы в коллекции ThisWorkbook.VBProject.VBComponents в ее-же свойстве Tag.
При удалении формы передаем значение этого свойства в процедуру удаления (см.файл)
Изменено: Sanja - 11.05.2018 09:04:15
Согласие есть продукт при полном непротивлении сторон
 
Виталий, такой интересный нюанс. Код формы получается такой
Код
Sub Button1_Click()
Application.OnTime Now + TimeValue("00:00:01"), "'DelForm " & Me.Tag & "'"
Unload Me
End Sub
Option Explicit

И, соответственно, не работает.
 
Привет Андрей. Такой нюанс возникает из-за включенного Tools-Options-Editor-Require Variable Declaration.
Лечится или ее отключением или изменением в строке
Код
    nf.CodeModule.InsertLines 1, _
    "Sub " & nb.Name & "_Click()" & vbNewLine & _
    "Application.OnTime Now + TimeValue(""00:00:01""), ""'DelForm "" & Me.Tag & ""'""" & vbNewLine & _
    "Unload Me" & vbNewLine & _
    "End Sub"
nf.CodeModule.InsertLines 1, _ ......
единицы на двойку (тройку, ...),  короче НЕ на единицу  :) . Что-бы первой строкой вставляло
Код
Option Explicit
Изменено: Sanja - 11.05.2018 10:48:35
Согласие есть продукт при полном непротивлении сторон
 
Цитата
zenija2007 написал:
и ответа не знает. зато написать с умным видом нерабочий совет - это завсегда.
А Вы, извиняюсь, не охренели, случаем? Вы для начала научитесь переписывать коды как Вам предлагают, матчасть чуть изучить, а потом волну гнать. Вот это что?
Код
"Application.OnTime Now + TimeValue(""00:00:01""), ""DelForm("" & Me & "")"""

почему опять скобки? Где апострофы, которые там быть обязаны в случае передачи аргументов? Посмотрите на мой код из сообщения #4 и найдите отличия. Далее. Т.к. передаем мы уже тип String - то почему у Вас в DelForm записан Object? Тип объекта мы вряд ли сможем передать, поэтому выкручиваться надо иначе.
А потом Вы еще удивляетесь, почему не работает.
Вот такой код у меня работает без проблем:
Код
'Параметры - Параметры центра правления безопасностью - Параметры макросов - Галочка Доверять. Иначе не даст доступ.
Function NewForm(nm As String, w As Integer, h As Integer) As Object 'создает новую форму
    Dim nf
    Application.VBE.MainWindow.Visible = False
    Set nf = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
    With nf
        .Properties("Caption") = nm
        .Properties("Width") = w
        .Properties("Height") = h
    End With
    Set NewForm = nf
End Function
Sub DelForm(nf)
    ThisWorkbook.VBProject.VBComponents.Remove ThisWorkbook.VBProject.VBComponents.Item(TypeName(nf))
End Sub
Sub NewButton(nf As Object, nm As String, l As Integer, t As Integer) 'создает кнопку. Привязать обязательно обработчик
    Dim nb As Msforms.CommandButton
    Set nb = nf.Designer.Controls.Add("forms.CommandButton.1", "Button1")
    With nb
        .Caption = nm
        .Left = l
        .Top = t
    End With
    With nf.CodeModule
        Line = .CountOfLines
        .InsertLines Line + 1, "Sub " & nb.Name & "_Click()"
        .InsertLines Line + 2, "Application.OnTime Now + TimeValue(""00:00:01""), ""'DelForm "" & Me.name & ""'""" 'также пробовал DelForms - результат тот же
        .InsertLines Line + 3, "Unload Me" 'тут работает, а DelForm (Me) выдает ошибку
        .InsertLines Line + 4, "End Sub"
    End With
End Sub
Sub nform()
    Dim nf As Object
    Set nf = NewForm("Новая форма", 200, 100)
    NewButton nf, "Кнопочка", 60, 40
    VBA.UserForms.Add(nf.Name).Show
    'ThisWorkbook.VBProject.VBComponents.Remove nf
    Application.VBE.MainWindow.Visible = True 'при разработке
End Sub
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Страницы: 1
Наверх