我正在编写一个简单的函数,例如:
Function myFunction() As Variant
'Some rules
End Function
对于上述功能,是否可以像使用API调用一样分配 Alias ?
显然这不是正确的语法,但你明白了:
Function myFunction() Alias myFunc As Variant
'Some rules
End Function
这将允许我使用任一名称:
Sub Test()
Debug.Print myFunction
Debug.Print myFunc
End Sub
答案 0 :(得分:22)
我不明白为什么你需要为VBA功能提供VBA别名。
API别名用于引用DLL中的函数或其他对象, 如果它的名字"给出名字"无法在需要它的模块中使用。
别名 - 表示正在调用的过程具有另一个过程 DLL中的名称。当外部过程名称为时,这很有用 与关键字相同。您还可以在DLL过程具有时使用Alias 与公共变量,常量或任何其他过程相同的名称 相同的范围。如果DLL中有任何字符,别名也很有用 DLL命名约定不允许使用过程名称。 (Source)功能
...但是要回答你的问题,确定你可以为一个函数创建一个替代名称,只需稍微修改你的代码:
你的职能:
Function myFunction() As Variant 'Some rules End Function
指定一个替代名称:
Function myFunc() As Variant myFunc = myFunction End Function
这将允许您使用任一名称:
Sub Test() Debug.Print myFunction Debug.Print myFunc End Sub
(当我说我不明白为什么你需要这样做时,我以为你没有像我这样的记忆!现在我理解你的理由,为相同的函数赋予多个名称!)
什么,还没有记住所有自定义VBA功能的名称和语法,除了1000个内置函数,过程和对象之外,以及看似无限列表的属性,方法和类名?
我也不是。
在VBA中编码时有助于触发内存的功能 属性/方法列表 。
开始输入功能名称或程序,然后按 Ctrl + J ,您将获得自定义和内置函数,方法,程序等的列表。**
我注意到您的示例函数名称都以" my
"开头。这可能只是为了说明目的,但是,这样的特定命名约定也可以通过在“属性/方法”对话框中将函数分组在一起来帮助。
您还可以添加说明到UDF(用户定义函数),这在工作表上输入函数名称时会出现:
请参阅: How to put a 'Tooltip' on a user-defined function
比说明更进一步,注册用户定义的功能不仅可以创建功能的描述,还可以提供有关每个功能的详细信息。 功能参数及其数据类型;您甚至可以指定 快捷键 ,添加指向自定义" 帮助 的链接&#34 ;文件/页面,甚至为UDF分配 类别 。
这些扩展属性显示在 Insert Function
对话框中,只需点击公式栏左侧的按钮,或点击 Shift + F3 :
Excel没有用于编辑参数描述的内置界面,因此需要VBA。很难找到相关文档。
代码&有关注册用户定义函数的信息 - :
我还没有尝试过,但我可以看到它是如何非常方便的,特别是因为它可以很容易进一步定制,可能还有项目特定的功能列表和其他信息。
可以在功能区中添加一个按钮,单击该按钮会显示VBA过程/功能列表,使用XML和VBA从按钮显示用户表单。还可以选择保存程序列表到文本文件。
您已经可以从Developers选项卡上的Macros按钮看到工作簿中的过程。但是,“宏”对话框中仅显示模块和工作表中的无参数子例程。带参数的函数和子程序不会显示。此列中描述的代码显示工作簿中的所有子例程和函数。
更多信息和完整代码 here 。
通过以编程方式操作VBA编辑器(VBE),您可以在VBA中编写读取或修改其他VBA项目,模块和过程的代码,并可用于自动执行与开发相关的任务。这称为 extensibility ,因为它扩展了编辑器 - 您可以使用VBA代码创建新的VBA代码。您可以使用这些功能编写创建,更改或删除VBA模块和代码过程的自定义过程。
令人惊讶的Chip Pearson再次完成了这项工作,详细说明和完整的代码此处,可扩展性为您提供了一些有趣的事情。
芯片页面上的部分代码列表(here):
这些方法使用 VBA可扩展性 [library](http://www.exceltoolset.com/setting-a-reference-to-the-vba-extensibility-library-by-code/)(参考),并要求以编程方式访问VBA项目,这是一个安全设置在Excel的选项中。有关详细信息,请参见芯片页面。
Chip的网页上还提供了Customizing Menus with VBA上提供的优质信息和代码,这有助于简化开发人员拥有工作。
看似"被遗忘的" VBA的功能,如果 控制的功能,甚至拦截内置命令。这也可以用来使开发人员受益(尤其是内存不佳的开发人员!)...来自Microsoft的更多信息和示例 here 。
答案 1 :(得分:1)
简单的VBA示例(无类)
当您称自己为 TheNotSoGuru 时,请尝试以下相对简单的方法:您必须编写别名定义,而不是像alias
定义那样的 API 。在一个用户定义别名()函数。
调用测试程序
这将向您展示如何使用 ONE 用户定义的alias
函数调用别名;第一个参数是您的别名Name as string,其他参数定义原始函数本身的可能参数:
Option Explicit ' declaration head of your code module
Sub Test()
Debug.Print "0) Original Function", myFunction
Debug.Print "1) alias(""(myFunc1"")", alias("myFunc1")
Debug.Print "2) alias(""(myFunc2"")", alias("myFunc2") ' too less arguments
Debug.Print "2) alias(""(myFunc2"",false)", alias("myFunc2", False)
End Sub
示例功能
第一个例子需要无参数; 第二个例子演示了一个错误的以及一个正确的别名函数调用 - 原始函数出现了一个布尔参数(True
或False
)的输入。
Function myFunction() As Variant
'Some rules
'...
'return result
myFunction = "Result from myFunction"
End Function
Function myFunctionWithOneArgument(Optional ByVal b As Boolean = True) As String
'Some rules
If b Then
myFunctionWithOneArgument = "result from myFunctionWithOneArgument " & "okay"
Else
myFunctionWithOneArgument = "result from myFunctionWithOneArgument " & "without comment"
End If
End Function
=============== Alias()函数的示例
您有责任将别名定义插入别名函数中。 它允许您甚至通过引发450错误和#34;错误的参数数量来强制输入正确数量的参数..."通过错误处理。如果发生错误,消息框将显示错误消息。
Function alias(ByVal sFunc, Optional arg1, Optional arg2, Optional arg3)
On Error GoTo oops ' error handler
Select Case sFunc & "" ' check your own aliases as string values
Case "myFunc1", "1" ' your alias Definition(s)
alias = myFunction ' return original function myFunction
Case "myFunc2", "One" ' see above
' defines if one argument is needed here:
If IsMissing(arg1) Then Err.Raise (450) ' too less arguments if arg1 is missing
alias = myFunctionWithOneArgument(arg1)
Case Else
alias = "Unknown function alias " & sFunc
End Select
EverythingOkay: Exit Function
oops:
MsgBox "Function: " & sFunc & vbNewLine & vbNewLine & _
"Error No: " & Err.Number & vbNewLine & _
Err.Description, vbExclamation, "Error - Wrong number of arguments"
Err.Clear
End Function
答案 2 :(得分:0)
通过相似性搜索别名
A)简介
您对1/22的评论:"问题不在于我有意想故意调出别名,这是一个忘记我可能拥有的问题将一个函数命名为开头(即
verifyRange
vsverifyRng
)。如果我知道我开始使用别名,那么我就不需要调用别名了。但是你的解决方案确实有效,而且经过深思熟虑。"
由于您在上述引用评论中的示例:当您略微修改了您的初始问题时,我考虑了另一种解决方案,并将其添加为独立新答案:< / p>
►您可以利用所谓的
SoundEx
搜索来基于语音算法对程序名称进行分组。
方法: Soundex代码标识一组类似的声音术语,名称或...►过程名称。如果您将此与通过所有现有程序/功能的 VBIDE 列表的循环相结合(不要忘记设置参考),您就可以获得最多列出的别名。
示例结果
1/1 Project(s): "VBAProject" (D:\Excel\test.xlsm)
**Project name: "VBAProject" ** (Host Project)
++SoundEx("verifyRange")="V616"
-- Found -- Procedure/Function name(s) --------- ------------------
[Prc: Sub] verifyRng in Std Module modTest1 Line#: 2/[Body: 3]
[Prc: Sub] verifyRange in Std Module modSortDict Line#: 6/[Body: 6]
注意:此方法根据人类语音的六个语音分类构建精简字母数字代码(双唇,唇形) ,牙齿,牙槽嵴,腭和声门),去除人声和一些出现的&#39; H&#39; W&#39; W&#39;和&#39; Y&#39 ;;代码由第一个大写字母和后面三个数字组成(如果没有找到辅音,则填充0
)。 BTW起源可以追溯到1800年代后期用于索引美国人口普查记录。
<强>链接强>
Find the word which I closest to the particular string? http://www.creativyst.com/Doc/Articles/SoundEx1/SoundEx1.htm#JavaScriptCode https://en.wikipedia.org/wiki/Soundex
Soundex示例
要演示soundex编码,请尝试以下相同结果的示例调用:
Sub testSoundEx()
Dim i As Integer
Dim a()
a = Array("verifyRange", "verifyRng", "vrfRanges")
Debug.Print "Proc name", "SoundEx Code": Debug.Print String(50, "-")
For i = LBound(a) To UBound(a)
Debug.Print a(i), SoundEx(a(i))
Next i
End Sub
SoundEx功能
Function SoundEx(ByVal s As String) As String
' Site: https://stackoverflow.com/questions/19237795/find-the-word-which-i-closest-to-the-particular-string/19239560#19239560
' Source: Developed by Richard J. Yanco
' Method: follows the Soundex rules given at http://home.utah-inter.net/kinsearch/Soundex.html
Dim Result As String, c As String * 1
Dim Location As Integer
s = UCase(s) ' use upper case
' First character must be a letter
If Len(Trim(s)) = 0 Then
Exit Function
ElseIf Asc(Left(s, 1)) < 65 Or Asc(Left(s, 1)) > 90 Then
SoundEx = ""
Exit Function
Else
' (1) Convert to Soundex: letters to their appropriate digit,
' A,E,I,O,U,Y ("slash letters") to slashes
' H,W, and everything else to zero-length string
Result = Left(s, 1)
For Location = 2 To Len(s)
Result = Result & Category(Mid(s, Location, 1))
Next Location
' (2) Remove double letters
Location = 2
Do While Location < Len(Result)
If Mid(Result, Location, 1) = Mid(Result, Location + 1, 1) Then
Result = Left(Result, Location) & Mid(Result, Location + 2)
Else
Location = Location + 1
End If
Loop
' (3) If category of 1st letter equals 2nd character, remove 2nd character
If Category(Left(Result, 1)) = Mid(Result, 2, 1) Then
Result = Left(Result, 1) & Mid(Result, 3)
End If
' (4) Remove slashes
For Location = 2 To Len(Result)
If Mid(Result, Location, 1) = "/" Then
Result = Left(Result, Location - 1) & Mid(Result, Location + 1)
End If
Next
' (5) Trim or pad with zeroes as necessary
Select Case Len(Result)
Case 4
SoundEx = Result
Case Is < 4
SoundEx = Result & String(4 - Len(Result), "0")
Case Is > 4
SoundEx = Left(Result, 4)
End Select
End If
End Function
SoundEx()
调用的辅助函数此辅助函数返回基于语音分类的字母代码(请参阅上面的注释):
Private Function Category(c) As String
' Returns a Soundex code for a letter
Select Case True
Case c Like "[AEIOUY]"
Category = "/"
Case c Like "[BPFV]"
Category = "1"
Case c Like "[CSKGJQXZ]"
Category = "2"
Case c Like "[DT]"
Category = "3"
Case c = "L"
Category = "4"
Case c Like "[MN]"
Category = "5"
Case c = "R"
Category = "6"
Case Else 'This includes H and W, spaces, punctuation, etc.
Category = ""
End Select
End Function
►您的问题的解决方案 - 按别名获取函数的示例调用
B)记忆问题或如何慢慢记忆
您可以使用以下示例调用通过语法listProc {function name string}
搜索过程/函数别名,例如listProc "verifyRange"
您在Visual Basic编辑器(VBE)的立即窗口中获得了所有找到的别名的精简列表:
Sub Test()
listProc "verifyRange" ' possibly gets verifyRange AND verifyRng via SoundEx "V616"
'listProc "verify" ' possibly gets nothing, as SoundEx "V610" has no fourth consonant
'listProc '[ displays ALL procedures without SoundEx Filter ]
End Sub
注意:请注意,SoundEx代码(例如&#34; V616&#34; verifyRange
)的长度限制为四个字母数字字符。
如果您正在寻找&#34;验证&#34;只有(= 3个辅音V + r + f),你会得到&#34; V610&#34;而没有发现&#34; verifyRange&#34;或&#34; verifyRng&#34; (V + R + F + R)。
在这种情况下,您应该搜索一对变体。
=============================
主要程序listProc
=====================
Sub listProc(Optional ByVal sFuncName As String)
' Purpose: display procedures using a SoundEx Filter
' Call: 0 arguments or empty argument - ALL procedures without filter
' 1 argument (not empty) - procedures found via SoundEx
' Note: requires reference to Microsoft Visual Basic for Applications Extensibility 5.3
' Declare variables to access the macros in the workbook.
Dim VBAEditor As VBIDE.VBE ' VBE
Dim objProject As VBIDE.VBProject ' Projekt
Dim objComponent As VBIDE.VBComponent ' Modul
Dim objCode As VBIDE.CodeModule ' Codeblock des Moduls
' Declare other miscellaneous variables.
Dim sProcName As String
Dim sndx As String, sndx2 As String
Dim pk As vbext_ProcKind ' proc kind (Sub, Function, Get, Let)
Dim strPK As String, sTyp As String
Dim iLine As Integer, iBodyLine As Integer, iStartLine As Integer
Dim i As Integer
Dim bShow As Boolean ' show procedure name
Dim bSoundEx As Boolean
If Len(Trim(sFuncName)) > 0 Then bSoundEx = True ' show alle procedures!
' ========================================
' Get the project details in the workbook.
' ========================================
Set VBAEditor = Application.VBE
Set objProject = VBAEditor.ActiveVBProject
' Set objProject = VBAEditor.VBProjects("MyProcject") ' 1-based, project name or item number
For i = 1 To VBAEditor.VBProjects.Count ' show name, filename, buildfilename (DLL)
Debug.Print i & "/" & _
VBAEditor.VBProjects.Count & " Project(s): """ & _
VBAEditor.VBProjects(i).Name & """ (" & VBAEditor.VBProjects(i).filename & ")"
Next i
' get SoundEx of Function name
sndx2 = SoundEx(sFuncName)
' ==================
' ? PROJECT NAME
' ==================
' objProject.Type ...vbext_pt_HostProject 100 Host-Project
' ...vbext_pt_StandAlone 101 Standalone-Project
Debug.Print "**Project name: """ & objProject.Name & """ ** (" & _
IIf(objProject.Type = 100, "Host Project", "Standalone") & ")"
If bSoundEx Then Debug.Print "++SoundEx(""" & sFuncName & """)=""" & sndx2 & """" & _
vbNewLine & "-- Found -- Procedure/Function name(s)"
' Iterate through each component (= Module) in the project.
For Each objComponent In objProject.VBComponents ' alle MODULE
' Find the code module for the project (Codeblock in current component/=module).
Set objCode = objComponent.CodeModule
' =============
' ? MODULE NAME
' =============
If objCode.CountOfLines > 0 And Not bSoundEx Then
Debug.Print " *** " & _
sModType(objComponent.Type) & " ** " & objComponent.Name & " ** "
End If
' Scan through the code module, looking for procedures.
' Durch alle Codezeilen des jeweiligen Moduls gehen
iLine = 1
Do While iLine < objCode.CountOfLines ' alle Zeilen durchackern (1/End ...)
' =================
' Get Procedurename ' !! SETZT AUTOMATISCH >> pk << !!
' =================
sProcName = objCode.ProcOfLine(iLine, pk) ' jede nächste Zeile auf Prozedurbeginn checken
If sProcName <> "" Then ' ohne Declaration head
' -----------------
' Found a procedure
' -----------------
' a) Get its details, and ...
strPK = pk ' 0-Prc|1-Let/2-Set/3-Get Werte abfangen !!!
'' iStartLine = objCode.ProcStartLine(sProcName, strPK) ' here = iLine !!
iBodyLine = objCode.ProcBodyLine(sProcName, strPK) ' Zeilennr mit Sub/Function/L/S/Get
sTyp = sPrcType(objCode.Lines(iBodyLine, 1)) ' Sub|Fct|Prp
' b) Check Soundex
If bSoundEx Then
sndx = SoundEx(sProcName)
If sndx = sndx2 Or UCase(sProcName) = UCase(sFuncName) Then
bShow = True
Else
bShow = False
End If
Else
bShow = True
End If
' ==============
' c) ? PROC NAME
' --------------
If bShow Then
Debug.Print " " & "[" & sPK(strPK) & ": " & sTyp & "] " & _
sProcName & IIf(bSoundEx, " in " & sModType(objComponent.Type) & " " & objComponent.Name, "") & vbTab, _
"Line#: " & iLine & "/[Body: " & iBodyLine & "]"
End If
' -------------------------------------------
' d) Skip to the end of the procedure !
' => Add line count to current line number
' -------------------------------------------
iLine = iLine + objCode.ProcCountLines(sProcName, pk)
Else
' This line has no procedure, so => go to the next line.
iLine = iLine + 1
End If
Loop
Next objComponent
' Clean up and exit.
Set objCode = Nothing
Set objComponent = Nothing
Set objProject = Nothing
End Sub
3主要程序的助手功能listProc
这些辅助函数会向过程和模块返回其他信息:
Function sPK(ByVal prockind As Long) As String
' Purpose: returns short description of procedure kind (cf ProcOfLine arguments)
Dim a(): a = Array("Prc", "Let", "Set", "Get")
sPK = a(prockind)
End Function
Function sPrcType(ByVal sLine As String) As String
' Purpose: returns procedure type abbreviation
If InStr(sLine, "Sub ") > 0 Then
sPrcType = "Sub" ' sub
ElseIf InStr(sLine, "Function ") > 0 Then
sPrcType = "Fct" ' function
Else
sPrcType = "Prp" ' property (Let/Set/Get)
End If
End Function
Function sModType(ByVal moduletype As Integer) As String
' Purpose: returns abbreviated module type description
Select Case moduletype
Case 100
sModType = "Tab Module"
Case 1
sModType = "Std Module"
Case 2
sModType = "CLS Module"
Case 3
sModType = "Frm Module"
Case Else
sModType = "?"
End Select
End Function