powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Функция - как аргумент процедуры
14 сообщений из 14, страница 1 из 1
Функция - как аргумент процедуры
    #35446546
profts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может ли название функции быть аргументом процедуры и вызываться из этой процедуры.

Например:

Sub qqq (name_function as string)

x = name_function

End Sub
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35446577
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
profts,
может, если эта функция является public членом класса. См. функцию CallByName().
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35446614
AndreyMp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно, а зачем? Сам же и запутаешься. Все равно функция тебе что то вернет, то и передашь в процедуру.
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35446683
profts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дело в том, что процедура имеет еще несколько аргументов и в общей сложности запускается 30 раз, так вот в зависимости от параметров должна вызываться определенная функция (всего их 5). Поэтому название функции тоже решил сделать аргументом. Только в приведенном выше примере функция не вызывается, а переменной x присваивается название функции как строка. Вот с этим и проблема. Не могу понять как синтаксически оформить данную строку.
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35446774
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Синтаксически — никак. Можешь сделать класс с этими функциями в качестве членов, создать из этого класса объект и юзать функцию CallByName применительно к этому объекту. Только учти, что она тормозная.
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35446813
profts
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо. Придется наверно поискать другой способ.
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35446965
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
profts,
другой способ - это правильно. Кстати, один - ниже.


AntonariyСинтаксически — никак.Ну уж, ну уж :) Ссылка на экземпляр объекта вполне заменяет указатель на функцию. Синтаксически можно оформить достаточно красиво:
Код: plaintext
1.
2.
3.
4.
5.
'Интерфейсный класс IMyFunc
Option Explicit

Public Function Invoke(ParamArray Args() As Variant) As Variant

End Function
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
'Вспомогательный модуль
Option Explicit

Public Sub PrintArgs(FuncName As String, ParamArray Args() As Variant)
 Dim i As Long
 Debug.Print FuncName,
 If Not IsMissing(Args( 0 )) Then
    For i = LBound(Args( 0 )) To UBound(Args( 0 ))
       Debug.Print Args( 0 )(i),
    Next i
 End If
 Debug.Print
End Sub
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
'Класс MyFunc1
Option Explicit

Implements IMyFunc

Private Function IMyFunc_Invoke(ParamArray Args() As Variant) As Variant
 PrintArgs "MyFunc1", Args()
End Function
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
'Класс MyFunc2
Option Explicit

Implements IMyFunc

Private Function IMyFunc_Invoke(ParamArray Args() As Variant) As Variant
 PrintArgs "MyFunc2", Args()
End Function
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
'Использование вышепреведённых классов в модуле формы
Option Explicit

Private m_MyFuncs As VBA.Collection

Private Function MyFunc(FuncName As String) As IMyFunc
 Set MyFunc = m_MyFuncs(FuncName)
End Function

Private Sub Command1_Click()
 'Создаём и заполняем список своих функций
 Set m_MyFuncs = New VBA.Collection
 m_MyFuncs.Add New MyFunc1, "MyFunc1"
 m_MyFuncs.Add New MyFunc2, "MyFunc2"
 
 'Вызываем функции по имени
 MyFunc("MyFunc1").Invoke  1 ,  2 ,  3 
 MyFunc("MyFunc2").Invoke  4 , "xyz"
End Sub
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35447310
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прикольно, но по сути
Код: plaintext
1.
 m_MyFuncs.Add New MyFunc1, "MyFunc1"
 m_MyFuncs.Add New MyFunc2, "MyFunc2"
ничем не отличается от
Код: plaintext
1.
2.
3.
Select case FuncName
    Case "MyFunc1": MyFunc1
    Case "MyFunc2": MyFunc2
End Select
И слишком громоздко для пяти функций.
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35447336
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторСинтаксически можно оформить достаточно красиво:
И, кстати, это — не синтаксически. Это — архитектурно. Лесенка Case'ов и CallByName — тоже архитектурно.
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35447836
cxxcxc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Antonariyничем не отличается от Select caseОтличие есть: динамический подход против статического. Набор функций можно создать, изменить, удалить в процессе выполнения программы; этот набор сам по себе может являться параметром какой-нибудь процедуры, если понадобится такой функционал.

"Фишка" здесь всё-таки в другом. Мы идём на поводу у формулировки задачи "Может ли название функции быть аргументом процедуры и вызываться из этой процедуры". Уж больно формулировка антропоцентрическая - человеку легче всего представить, что функция идентифицируется именем, ну и, следовательно, в процедуру надо передавать строковый параметр. Но почему бы функцию не идентифицировать ссылкой на экземпляр класса, членом которого она является? Тогда отпадёт необходимость переводить так или иначе в процессе выполнения программы (через ассоциативный массив (коллекцию), Select Case, или CallByName(), которая дёргает метод IDsipatch::Invoke(), который внутри себя опять-таки содержит то же самое) строку в адрес функции. В итоге:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Sub qqq(name_function As IMyFunc)
 x = name_function.Invoke
End Sub

Sub Test1()
 qqq New MyFunc1
 qqq New MyFunc2
End Sub
При желании можно избавиться и от New при вызове qqq:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Private Function MyFunc1() As MyFunc1
 Static mf1 As New MyFunc1
 Set MyFunc1 = mf1
End Function

Private Function MyFunc2() As MyFunc2
 Static mf2 As New MyFunc2
 Set MyFunc2 = mf2
End Function

Sub Test2()
 qqq MyFunc1
 qqq MyFunc2
End Sub
Синтаксически? ;)
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35447838
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"cxxcxc" читать как "Бенедикт"
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35448194
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктОтличие есть: динамический подход против статического.
Код: plaintext
1.
'Класс MyFunc1
'Класс MyFunc2
Вот только обидно, что создавать классы динамически COM пока не умеет. ;)

БенедиктНо почему бы функцию не идентифицировать ссылкой на экземпляр класса, членом которого она является?Это мне напомнило еще один вариант, не идущий на поводу.)) Сама функция (указатель) может быть аргументом. AddressOf + CallWindowProc = гораздо шустрее замутов с интерфейсами. И динамику можно прикрутить на таком же уровне.

БенедиктСинтаксически? ;)Хмм?
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35450511
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyВот только обидно, что создавать классы динамически COM пока не умеет. ;)

Это мне напомнило еще один вариант, не идущий на поводу.)) Сама функция (указатель) может быть аргументом. AddressOf + CallWindowProc = гораздо шустрее замутов с интерфейсами. И динамику можно прикрутить на таком же уровне.Я не понял фразу про классы (хотя поворачивал и рассматривал её и так, и эдак). Одним из VB-шных способов для вызова функции по адресу как раз и является динамическое создание экземпляра COM-объекта с единственным методом (помимо IDispatch-евых) через CreateStdDispatch(), затем вызов этого метода.

Адрес функции - фи, низкий полёт :), уровень ассемблера, Си и PowerBasic. Передача ссылки на интерфейс - о да, это уже C++, Java, VB и т. п. :)

Чтобы вызов CallWindowProc (со всеми минусами этого решения) был гораздо быстрей вызова метода при раннем связывании - это спорно. Можно проверить, но завтра начинается отпуск, и для небольшого количества вызовов это не важно.
...
Рейтинг: 0 / 0
Функция - как аргумент процедуры
    #35451228
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктЯ не понял фразу про классы Я говорил про создание класса как реализацию интерфейса в противоположность созданию объекта как экземпляра класса.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Функция - как аргумент процедуры
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]