Сообщество программистов Autodesk в СНГ

ADN Club => Inventor API => Тема начата: R.I.Chernov от 03-02-2015, 16:18:36

Название: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 03-02-2015, 16:18:36
Доброго времени суток, уважаемые форумчане! Я снова в тупике и снова прошу Вашей помощи!
Ситуация такая, у меня есть переменная "varia", которая может принимать значение от 1 до 20, и есть двадцать процедур с именами "proc_1" , "proc_2"..."proc_20" . В определенный  момент у меня срабатывает одна из двадцати процедур, в зависимости от значения переменной "varia". Ну т.е. если varia= 16, то должна сработать процедура proc_16. Подскажите пожалуйста, можно ли скомбинировать необходимое имя, чтобы условно вызвать процедуру с именем "proc_" & varia, вместо того, чтобы писать 20 условий в "if..then..else"

п.с. Прошу, не судите мой вопрос слишком строго, просто  программист я такой себе : ) Я с радостью разобрался бы сам, а не перекладывал бы свои заботы на Ваши плечи, если бы смог найти, где про это почитать :(

(update)
изменил название переменной с "const" на "varia" дабы не позориться :)
п.п.с. Я программирую в VBA. Но буду признателен за пример в любом из языков, а то даже, что гуглить не знаю толком :)
Название: Re: Комбинирование имени процедуры
Отправлено: Виктор Чекалин от 03-02-2015, 16:58:36
R.I.Chernov,
не совсем по теме, но называть переменную именем const, т.е. constant, т.е. постоянная величина - не очень хорошая практика :-)

А по теме. Нагуглилось вот такое
Код - Text [Выбрать]
  1. Sub callSomeProc(i as Integer)
  2.    Application.Run "proc_" & i
  3. End Sub
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 03-02-2015, 17:20:03
не совсем по теме, но называть переменную именем const, т.е. constant, т.е. постоянная величина - не очень хорошая практика :-)
))))))))))))))) Согласен. Помему-то это первый пришедший в голову вариант замены истинного имени переменной kolvo_verikalnih_stoek_osnovnogo_karkasa :)
Ну такие описки лишний раз показывают мой "профессионализм" в данной сфере.

А по теме. Нагуглилось вот такое
Код - Text [Выбрать]
  1. Sub callSomeProc(i as Integer)
  2.    Application.Run "proc_" & i
  3. End Sub

Не захотело работать :( Я не указал выше, что я ищу код для VBA.
Название: Re: Комбинирование имени процедуры
Отправлено: Александр Ривилис от 03-02-2015, 17:24:29
Не захотело работать :( Я не указал выше, что я ищу код для VBA.
Небось у процедуры еще и параметры есть?
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 03-02-2015, 17:30:03
Небось у процедуры еще и параметры есть?
Вы будете смеяться, но я сомневаюсь, что полностью понял смысл вашего вопроса, так как терминами владею из рук вон плохо. :(

Вобщем я проводил тест вышеуказанного кода на таком вот примере:
Sub callSomeProc(i As Integer)
i = 2
Application.Run "msg_" & i
End Sub

Public Sub msg_1()
Debug.Print "msg_1"
End Sub

Public Sub msg_2()
Debug.Print "msg_2"
End Sub
Название: Re: Комбинирование имени процедуры
Отправлено: Виктор Чекалин от 03-02-2015, 17:30:44
Не захотело работать  Я не указал выше, что я ищу код для VBA.
Так я для VBA и писал. Но не проверял, так как совсем не пишу на VBA.
А на что ругается?
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 03-02-2015, 17:36:54
Так я для VBA и писал. Но не проверял, так как совсем не пишу на VBA.
А на что ругается?
Я чуть выше код привел, у меян не получилось запустить процедуру callSomeProc
Я попытался заменить на такой вот код:
Sub callSomeProc
dim i As Integer
i = 2
Application.Run "msg_" & i
End Sub
Тогда он пишет что переменная "apllication" не задана.
Ну в смысле пишет "Variable not defined" и обводит слово Application ... может я как-то не так это понимаю
Название: Re: Комбинирование имени процедуры
Отправлено: Александр Ривилис от 03-02-2015, 18:03:09
Ну в смысле пишет "Variable not defined" и обводит слово Application ...
А если ThisApplication вместо Application?
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 03-02-2015, 19:32:34
А если ThisApplication вместо Application?
Я щас не могу проверить - домой с работы еду. Но сегодня копался в браузере объектов, не нашел у ThisApplication метода run, правда не помню, попробовал ли ThisApplication в коде написать. Я нашел в браузере свойство VBA.Thisapplication но им также не получилось воспользоваться, и метода run у него тоже не было. Да и вобще, я не нашел ни одного метода run через поиск в объектом бразере. В родном  help VBA по запросу "run" находятся статьи, но я не смог в них найти решения :(
Название: Re: Комбинирование имени процедуры
Отправлено: Виктор Чекалин от 03-02-2015, 19:47:50
R.I.Chernov, нашел еще функцию CallByName (http://support.microsoft.com/kb/186143). Можно ее попробовать, если она доступна в VBA для Inventor.
Название: Re: Комбинирование имени процедуры
Отправлено: Александр Ривилис от 03-02-2015, 19:56:48
И еще статья Владимира Ананьева: http://adndevblog.typepad.com/manufacturing/2012/07/run-vba-macro-using-inventor-api.html
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 03-02-2015, 21:35:23
нашел еще функцию CallByName (http://support.microsoft.com/kb/186143). Можно ее попробовать, если она доступна в VBA для Inventor.

Нашел в браузере данную функцию, доступ к ней осуществляется: Interaction.CallByName. В help VBA по этой функции написано приблизительно тоже самое что и в данной статье (если не меньше) :
http://www.excelworld.ru/stuff/vba_function/system/callbyname/24-1-0-87
Но эта функция дает возможность обращаться к объектам, свойствам и методам какого либо объекта объектной  модели программы (извиняюсь за тавтологию). А процедура вроде бы не является таковой. Я так понял, что эта функция для решения обсуждаемой нами задачи не подходит.
Если я ошибаюсь, то, пожалуйста , поправьте меня.

(update)
Попробовал достучаться до модуля по принципу: MyProject.MyModule.MyFunction (имена проекта, модуля и функции внутри модуля)
Т.е. 

Код - Text [Выбрать]
  1. Call Interaction.CallByName(MyProject.MyModule, MyFunction, VbMethod)

Но он пишет мне "type mismatch" и выделяет в строке MyModule.
Название: Re: Комбинирование имени процедуры
Отправлено: Алексей Кулик от 03-02-2015, 23:52:35
На VBA, да еще и под Inventor... Это будет треш ))) Пинайте, если че :)
Как вариант, писал на VBA под Excel, но технология, по-моему, неизменна:
Код - Visual Basic [Выбрать]
  1. Option Explicit
  2.  
  3. Public Sub Proc1(param As Integer, msgTitle As String)
  4.   MsgBox "Proc1 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  5. End Sub
  6.  
  7. Public Sub Proc2(param As Integer, msgTitle As String)
  8.   MsgBox "Proc2 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  9. End Sub
  10.  
  11. Public Sub Proc3(param As Integer, msgTitle As String)
  12.   MsgBox "Proc3 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  13. End Sub
  14.  
  15. Public Sub Proc4(param As Integer, msgTitle As String)
  16.   MsgBox "Proc4 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  17. End Sub
  18.  
  19. Public Sub Proc5(param As Integer, msgTitle As String)
  20.   MsgBox "Proc5 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  21. End Sub
  22.  
  23. Public Sub TestToRun()
  24. Dim sTitle As String
  25.   sTitle = "Call from TestToRun"
  26. Dim iCount As Integer
  27.  
  28.   iCount = CInt(InputBox("Enter proc number", sTitle, "0"))
  29.  
  30.   Select Case iCount
  31.     Case 1:
  32.       Proc1 iCount, sTitle
  33.     Case 2:
  34.       Proc2 iCount, sTitle
  35.     Case 3:
  36.       Proc3 iCount, sTitle
  37.     Case 4:
  38.       Proc4 iCount, sTitle
  39.     Case 5:
  40.       Proc5 iCount, sTitle
  41.     Case Else:
  42.       MsgBox "Do not defun proc!", vbOKOnly + vbCritical + vbApplicationModal
  43.   End Select
  44. End Sub

---
Добавлено: при использовании функций, как мне кажется, тоже мало что изменится:
Код - Visual Basic [Выбрать]
  1. Option Explicit
  2.  
  3. Public Function Proc1(param As Integer, msgTitle As String) As Integer
  4.   MsgBox "Proc1 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  5.   Proc1 = param
  6. End Function
  7.  
  8. Public Function Proc2(param As Integer, msgTitle As String) As Integer
  9.   MsgBox "Proc2 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  10.   Proc2 = param ^ 2
  11. End Function
  12.  
  13. Public Function Proc3(param As Integer, msgTitle As String) As Integer
  14.   MsgBox "Proc3 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  15.   Proc3 = param ^ 3
  16. End Function
  17.  
  18. Public Function Proc4(param As Integer, msgTitle As String) As Integer
  19.   MsgBox "Proc4 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  20.   Proc4 = param ^ 4
  21. End Function
  22.  
  23. Public Function Proc5(param As Integer, msgTitle As String) As Integer
  24.   MsgBox "Proc5 " + CStr(param), vbOKOnly + vbCritical + vbApplicationModal, msgTitle
  25.   Proc5 = param ^ 5
  26. End Function
  27.  
  28. Public Sub TestToRun()
  29. Dim sTitle As String
  30.   sTitle = "Call from TestToRun"
  31. Dim iCount As Integer
  32. Dim iRes As Integer
  33.  
  34.   iCount = CInt(InputBox("Enter proc number", sTitle, "0"))
  35.  
  36.   Select Case iCount
  37.     Case 1:
  38.       iRes = Proc1(iCount, sTitle)
  39.     Case 2:
  40.       iRes = Proc2(iCount, sTitle)
  41.     Case 3:
  42.       iRes = Proc3(iCount, sTitle)
  43.     Case 4:
  44.       iRes = Proc4(iCount, sTitle)
  45.     Case 5:
  46.       iRes = Proc5(iCount, sTitle)
  47.     Case Else:
  48.       MsgBox "Do not defun proc!", vbOKOnly + vbCritical + vbApplicationModal
  49.   End Select
  50.   MsgBox "iRes = " + CStr(iRes), vbOKOnly + vbCritical + vbApplicationModal
  51.  
  52. End Sub
Название: Re: Комбинирование имени процедуры
Отправлено: Алексей Романов от 04-02-2015, 07:42:26
Подскажите пожалуйста, можно ли скомбинировать необходимое имя, чтобы условно вызвать процедуру с именем "proc_" & varia, вместо того, чтобы писать 20 условий в "if..then..else"
Примерно так:
Код - Visual Basic [Выбрать]
  1. Public Sub callSomeProc()
  2.  
  3. Dim i As Integer: i = 2
  4. Dim name As String: name = "msg_" & i
  5.  
  6. Dim invVBAProject As InventorVBAProject
  7. For Each invVBAProject In ThisApplication.VBAProjects
  8.     If invVBAProject.name = "Проект_приложений" Then Exit For
  9. Next
  10.  
  11. Dim invModule As InventorVBAComponent
  12. Set invModule = invVBAProject.InventorVBAComponents.Item("Module4")
  13.  
  14. Dim invSub As InventorVBAMember
  15. Set invSub = invModule.InventorVBAMembers.Item(name)
  16. Call invSub.Execute
  17.  
  18. End Sub
  19.  
  20. Public Sub msg_1()
  21. MsgBox "msg_1"
  22. End Sub
  23.  
  24. Public Sub msg_2()
  25. MsgBox "msg_2"
  26. End Sub
  27.  
  28.  
Название: Re: Комбинирование имени процедуры
Отправлено: Виктор Чекалин от 04-02-2015, 07:42:57
Попробовал достучаться до модуля по принципу: MyProject.MyModule.MyFunction (имена проекта, модуля и функции внутри модуля)
Т.е. 

Код - Text: [Выделить]
Call Interaction.CallByName(MyProject.MyModule, MyFunction, VbMethod)

Но он пишет мне "type mismatch" и выделяет в строке MyModule.

Первым параметром надо передать объект, в котором находится вызываемая функция. Если процедуры находятся в том же самом модуле, откуда эти процедуры вызывается, то первым параметром должно стоять Me.

Алексей Кулик, думаю это не совсем то, чего хотел автор.
вместо того, чтобы писать 20 условий в "if..then..else"
Идея и состоит в том, чтобы вызвать процедуру, имя которой сформировано динамически.
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 04-02-2015, 11:07:17
Первым параметром надо передать объект, в котором находится вызываемая функция. Если процедуры находятся в том же самом модуле, откуда эти процедуры вызывается, то первым параметром должно стоять Me.
Ну не знаю... В моем примере процедура находилась в другом модуле (MyProject.MyModule). С другой стороны, я пробовал на простом примере, что если даже процедура находится в текущем модуле, то обратиться к ней можно не только написав ее имя например Call ProcName, но и написав полный ее путь: Call ProjName.ModuleName.ProcName.
Я попробовал использовать "Me" : Call Interaction.CallByName(Me, MyFunction, VbMethod) ... на что VBA мне ответило : "Invalid use of Me keyword". Так что пока тупик ...
П.С. Спасибо всем за советы и идеи, но проверять их работоспособность оперативно не получается, так как я не знаю половины используемых в них операторов :)
Приходится подолгу разбираться. Поэтому отвечаю "небыстро" :(
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 04-02-2015, 11:12:20
И еще статья Владимира Ананьева: http://adndevblog.typepad.com/manufacturing/2012/07/run-vba-macro-using-inventor-api.html

Спасибо! Но если честно, то я не понял, чем она может помочь в обсуждаемом нами вопросе... не подскажете, что я пропустил?
Название: Re: Комбинирование имени процедуры
Отправлено: Виктор Чекалин от 04-02-2015, 11:34:58
чем она может помочь в обсуждаемом нами вопросе... не подскажете, что я пропустил?
В ней приведено примерно то же, что и в ответе Алексея Романова (http://adn-cis.org/forum/index.php?topic=1823.msg7158#msg7158).
А именно, нужно найти метод по имени и выполнить его с помощью Call.
Код - Text [Выбрать]
  1. VBA version
  2.  
  3. Private Sub Command1_Click()
  4.   Dim oA As Inventor.Application
  5.   Set oA = GetObject(, "Inventor.Application")
  6.  
  7.   Dim oP As Inventor.InventorVBAProject
  8.  
  9.   For Each oP In oA.VBAProjects
  10.     If oP.Name = "ApplicationProject" Then
  11.       Dim oC As Inventor.InventorVBAComponent
  12.       For Each oC In oP.InventorVBAComponents
  13.         If oC.Name = "Module1" Then
  14.           Dim oM As Inventor.InventorVBAMember
  15.           For Each oM In oC.InventorVBAMembers
  16.             If oM.Name = "MyFunction" Then
  17.               Dim oO As Variant
  18.               Call oM.Execute(oO)
  19.             End If
  20.           Next oM
  21.         End If
  22.       Next oC
  23.     End If
  24.   Next
  25.  
  26. End Sub
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 04-02-2015, 11:51:50
На VBA, да еще и под Inventor... Это будет треш ))) Пинайте, если че :)
Чуть выше уже заметили, что это не совсем то, что я ищу.

Цитата: R.I.Chernov от 03-02-2015, 16:18:36
    вместо того, чтобы писать 20 условий в "if..then..else"

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

То бишь имя вызываемой процедуры должно состоять из какой-то неизменной части и переменной константы, что-то вроде "Proc_number_" & VariablePart

(update)
П.С. Забыл поблагодарить, на вашем примере я наконец таки разобрался с принципом работы оператора "Select Case". :)
Название: Re: Комбинирование имени процедуры
Отправлено: R.I.Chernov от 04-02-2015, 13:17:51
Примерно так:
*****

Не стал дублировать код :) Спасибо Алексей, это именно то, что я искал! Спасибо всем, кто принимал участие в обсуждении, вы очень помогли. Лично мне,  "суперпрограммисту", наш диалог добавил знаний не только в данном вопросе, но и еще во многих других :)

П.С. От себя добавлю пояснение для таких же "подкованных" как я парней. В коде Алексея нужно вместо "Проект_приложений" и "Module4" написать имя проекта, в котором находится модуль с процедурой, и имя самого модуля соответственно.