精华内容
下载资源
问答
  • excel自定义函数
    2022-06-18 20:03:24

    自定义函数

    假定你想要为Excel编写自定义函数,但是这个自定义函数用vba写起来比较麻烦,还有一种做法就是编写一个dll。我们准备用熟悉的C/C++来编写dll,此时我们打开VS,写下了一个自定义函数Foo,头文件定义如下

    #ifndef TEST_H
    #define TEST_H
    
    #pragma once
    
    #include <Windows.h>
    
    #ifdef TESTDLL_EXPORT
    # define TESTDLL_API __declspec(dllexport)
    #else
    # define TESTDLL_API __declspec(dllimport)
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    	TESTDLL_API int WINAPI Foo();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif // !TEST_H
    
    

    这里大部分都是模板代码,需要注意的是Foo的声明。Foo的calling convetion是WINAPI,也就是__stdcall,vba中自定义c函数必须是WINAPI

    我们在再来看vba中如何声明该函数

    Declare Function Foo Lib "libpath" () As Long
    

    这里有3点需要注意

    1. Foo有返回值,所以声明为Function
    2. libpath为dll的路径,可以是绝对路径,也可以是相对路径,这到后面再介绍
    3. 返回值为Long不是Integer

    C/C++导出函数名称

    我们知道,c/c++编译器通常会对函数名进行修饰,其中两个原因是因为函数可以重载,还有为了区分不同的调用约定。这就导致dll中的导出函数名称和我们编写的函数名字不一样。为了能够让VBA找到导出函数,我们一般可以在声明VBA函数时指定Alias

    假设c中有如下函数

    void WINAPI Foo(int i);
    

    对于32位和64位平台,导出函数名称不一样。[1]

    32位

    导出函数名字位_Foo@4,所以函数声明为

    Declare Sub Foo Lib "libpath" Alias "_Foo@4" (ByVal i As Long)
    

    64位

    Declare PtrSafe Foo Lib "libpath" (ByVal i As Long)
    

    注意,这里我们使用了PtrSafe关键字,因为在64位Office下面,函数声明需要PtrSafe关键字。

    数据类型

    下表给出VBAC/C++中常见的数据类型的对应关系

    VBAC/C++说明
    BooleanVARIANT_BOOLvba中的True=-1,False=0
    VARIANT_BOOL实际为short的typedef
    Integershort
    Longint
    Doubledouble
    StringBSTRBSTR是OLE的数据类型,是一个带长度前缀的字符串
    VariantVARIANT
    ArraySAFEARRAY

    String

    vba中的String是Unicode string,对于常见的Win32 API,通常接受LPCWSTRLPCSTR两种字符指针,分别是utf-16和ANSI的字符串。

    String -> LPCWSTR、const wchar_t*或BSTR

    这种比较简单,我们使用StrPtr函数,直接获取String的指针即可,因为String本质上是一个BSTR

    Declare Sub Foo Lib "libpath" (ByVal str As Long)
    
    void WINAPI Foo(BSTR);
    // void WINAPI Foo(LPCWSTR);
    // void WINAPI Foo(const wchar_t*);
    

    注意,vba的文档中找不到StrPtr

    String -> LPCSTR 或 const char*

    String是utf-16编码的,如果我们声明vba中的函数接受String,且c中的函数接受const char*,那么vba就会根据系统当前的locale,将utf-16转换为ANSI字符串。显然这个过程可能是有损的,通常不建议这么做。还有中方法就是再vba中将字符串转换为utf-8数组后,再传递给c函数。

    Declare Sub Foo Lib "libpath" (ByVal str As String)
    
    void WINAPI Foo(const char*);
    // void WINAPI Foo(LPCSTR);
    

    ARRAY

    要传递vba的数组到c/c++函数中,可以使用以下两种方法[2]

    指向第一个元素的指针

    Declare Sub Foo Lib "libpath" (ByRef anArray As Long, ByVal size As Long)
    
    Dim anArray() As Long
    Foo anArray(0), UBound(anArray) + 1
    
    void WINAPI Foo(const int* anArray, int size);
    

    SAFEARRAY指针

    Delcare Sub Foo Lib "libpath" (ByRef anArray() As Long)
    
    Dim anArray() Long
    Foo anArray
    
    void WINAPI Foo(SAFEARRAY** ppArray);
    

    vba函数命名

    vba函数的名字不能同Excel中已经存在的名字相冲突,比如单元格的名字。所以F2这样的名字是非法,在调用时你会得到#REF!错误。

    Dll路径

    Declare时我们需要指定dll的路径,显然我们不想要硬编码路径。一种方法是我们修改PATH变量,加入dll所在的目录。这个动作可以在打开插件的工作簿时完成,代码如下

    Private Declare PtrSafe Function SetEnvironmentVariableW Lib "Kernel32" (ByVal name As LongPtr, ByVal value As LongPtr) As Long
    
    Private Sub Workbook_Open()
    	Dim newPath As String
    	newPath = "path to dll" & Environ("PATH")
    	' TODO Warn if changing PATH fails
    	Debug.Print SetEnvironmentVariableW(StrPtr("PATH"), StrPtr(newPath))
    End Sub
    

    References

    [1] Decorated names
    [2] How To Pass Arrays Between Visual Basic and C

    更多相关内容
  • Excel自定义函数智能提示插件及示例
  • EXCEL自定义函数

    千次阅读 2021-01-04 16:54:36
    这里,简单说明一下如何创建自定义函数。 创建自定义函数 1、在打开的EXCEL中,按alt+F11键,打开VB 脚本开发窗口 2、右键点选文件名,插入模块 3、编写代码 代码: Function aaa(ByVal rng As Range) ...

    序言

    EXCEL中有不少函数,但还是不能满足要求,比如:需要把某个字符串字符倒过来的函数就没有。这里,简单说明一下如何创建自定义函数。

    创建自定义函数

    1、在打开的EXCEL中,按alt+F11键,打开VB 脚本开发窗口

    2、右键点选文件名,插入模块

    3、编写代码

    代码:

    Function aaa(ByVal rng As Range)
     
        aaa = VBA.StrReverse(rng.Value)
     
    End Function
    

    4、保存,关闭窗口,至此,函数已定义完成。

     

    自定义函数的使用

    假设我们要对一个字符串进行翻转,翻转后的值写入到另一列。

    1、选中将要输入的一个单元格,点fx函数按钮

    可以看到自定义函数显示出来,如果没有显示,可以点选“或选择类别”组合框查找。

    2、选中自定义函数后,点“确定”按钮。在输入值项(这里定义的值名称为Rng,实际可改成其他的易记变量)点选要翻转的单元格:

    3、然后再点确定按钮,则字符串被翻转

    C2单元格为输出值,使用公式:aaa(B2)

    B2单元格为原值

    扩展:

    这个函数也可以像其他函数一样,通过点按单元格右下角小方块,实现快速格式填充,完成一整列的操作。

    参考:

    https://support.microsoft.com/zh-cn/office/%e5%9c%a8-excel-%e4%b8%ad%e5%88%9b%e5%bb%ba%e8%87%aa%e5%ae%9a%e4%b9%89%e5%87%bd%e6%95%b0-2f06c10b-3622-40d6-a1b2-b6748ae8231f?ui=zh-cn&rs=zh-cn&ad=cn

    展开全文
  • 列举了VB6开发EXCEL自定义函数加载宏,这是一本不错的资源
  • 但是问题来了,为啥这样设置自定义函数不行呢? Function qiuhe1(a, b) qiuhe1 = a + b End Function Function qiuhe111() '自定义函数正常 qiuhe111 = 100 End Function Function qiuhe112() '这...

    1目标问题:

    为什么VBA里,function可以运行的代码,在EXCEL用自定义函数,会返回错误值?

    例子1

    • 比如下面这段代码,在VBA里运行的好好的
    • 在excel里 用= 自定义函数运行,就返回错误值,而且也不允许,去改变其他单元格得值,为啥呢,比如像这种    Cells(3, 6) = "aaa"   也运行不了

    2 先说结论

    • EXCEL和VBA:自定义函数,其实受限制很多,远比不了VBA
    • 为啥在VBA里,点运行,好好的代码,在EXCEL里用 = 自定义函数名的方法调用,发现返回格子错误值?而且很多操作也不执行?因为那是在VBA里运行,是在VBA得环境下才能运行了,现在在 excel 自定义公式,当然可能不行
    • 能在VBA里执行的,不一定可以在EXCEL作为自定义函数执行,尤其是两者有些语法有差异,有的函数甚至不互通,差异更大
    • 自定义函数,是运行在EXCEL环境里得,语法受到EXCEL公式得语法限制,比如像这种    Cells(3, 6) = "aaa"   是运行不了得,因为这cells() 就不是excel得内置公式啊
    • 自定义函数,不要用EXCEL保留词。比如 function sum111() ,这样VBA写对了函数,在EXCEL运行还是会报错!!!
    • 也就是说,自定义公式,虽然是用VBA写得,但是必须得能在EXCEL里运行,得符合EXCEL得语法,不符合得就运行不了,或者返回值报错
    • 其他一些报错的可能:
    • 需要写成function 不能写成过程sub
    • 必须新建模块,否则,调用不到,工作表里定义的 函数

    3  自定义函数返回值的情况

    • 下面这些VBA函数,虽然都可以作为自定义函数在EXCEL里用,但各有不同
    • 没用返回值得,EXCEL里自定义函数,EXCEL里会返回0
    • 有返回值得,会返回自定义函数得返回值
    Function testA1()
    '如果没用返回值,就相当于testA1返回了空值 null none,EXCEL调用为自定义函数会返回0
    '但是自定义函数要在EXCEL写法为  =testa1() 不能写成 =testa1否则会报错
    End Function
    
    
    Function testA2()
    '如果没用返回值,就相当于testA2返回了空值 null none,EXCEL调用为自定义函数会返回0
        b = 100
    End Function
    
    
    Function testA3()
    '有返回值,EXCEL调用为自定义函数会testA3得返回值
        testA3 = 100
    End Function

    自定义函数,不要用EXCEL保留词。比如 function sum111() ,这样VBA写对了函数,在EXCEL运行还是会报错!!!

    • 用 sum111 怎么都不对
    • 改成 test111就OK

    4 这3个自定义函数都会返回错误值,因为单元格的语法是VBA的,不符合EXCEL公式语法

    '下面3个报错都因为,EXCEL里指定范围得写法和VBA不同
    Function testB1()
       Cells(3, 6) = "testB1"
    End Function
    
    
    Function testB2()
       Range("f5") = "testB2"
    End Function
    
    
    Function testB3()
       [f7] = "testB3"
    End Function

    5 可以正常运行,且返回值正确的 自定义函数

    • 难道没有用VBA写得自定义函数,直接改变EXCEL内容得方法? 有,但是不能像VBA那么方便,用rang() 或者cells() 语法随便改
    • 自定义函数写在那个单元格,其实就是改变了单元格了吧!因为自定义函数也是 EXCEL函数的一种,必须符合EXCEL公式的各种限制,而EXCEL公式本身也不提供,函数返回值之外得直接修改 EXCEL单元格得办法!
    
    '这个没问题,因为这里没涉及到excel里得操作
    
    Function testB4()
       Debug.Print "testB4"
    
    End Function
    
    
    '可以带参数,参数可以直接在EXCEL自定义函数时指定为其他单元格
    Function testB5(a, b)
       testB5 = (a + b)
    End Function
    
    
    Function testB6(a As Integer, b As Integer) As Integer
       testB6 = (a + b)
    
    End Function
    

    6  如果希望自定义函数能返回多个值呢?

    • 自定义函数 只能和 系统自带函数一样,只能改变1个单元格得内容?一般的是
    • 能同时改变多个格子嘛?像VBA一样?像VBA一样肯定不行
    • 普通公式肯定不行,只有数值公式可以,那也就意味着自定义函数当数组公式用就可以!
    • 但是在EXCEL输入 testc1(), 要横向选2个单元格,整体输入数组公式,ctrl+ shift +enter 输入

    Function testC1(a, b)
    
    Dim c1()
    ReDim c1(1 To 2)
    
    c1(1) = a + b
    c1(2) = a - b
    
    testC1 = c1()
    
    End Function
    
    

    7 那其他改动呢? 自定义函数能做的大概就是EXCEL的函数那些吧


     

    展开全文
  • 在VSTO中如何利用C#创建EXCEL自定义函数
  • Excel 自定义函数

    2018-06-01 17:35:00
    打开excel,在菜单栏选择开发工具,点击Visual Basic(或按Alt+F11),打开 Visual Basic 编辑窗口。 2 在编辑窗口中菜单栏选择插入-模块命令,插入一个新的模块1。...V为函数名称,abc为...
    1. 打开excel,在菜单栏选择开发工具,点击Visual Basic(或按Alt+F11),打开 Visual Basic 编辑窗口。

      Excel怎样自定义函数
    2. 2

      在编辑窗口中菜单栏选择插入-模块命令,插入一个新的模块1。

      Excel怎样自定义函数
    3. 3

      在右边的模块1窗口中输入如下代码:

      Function V(a, b, C)

      V = a * (b + c) / 3

      End Function

      V为函数名称,abc为该函数的三个元素。

      Excel怎样自定义函数
    4. 4

      然后关闭编辑器窗口,返回到工作表,接下来就可利用这个函数了。

      Excel怎样自定义函数
    5. 5

      在N1单元格中输入公式=V(K1,L1,M1),表示计算的是K1*(L1+M1)/3的结果。

      Excel怎样自定义函数
    6. 6

      把公式向下拉,就可以算出其他单元格的结果,把公式里的元素改变,可计算指定单元格的结果。

      Excel怎样自定义函数
    7.  

    展开全文
  • 浅谈Excel开发:四 Excel 自定义函数

    千次阅读 2018-09-23 12:04:39
    我们知道,Excel中有很多内置的函数,比如求和,求平均,字符串操作函数,金融函数等等。在有些时候,结合业务要求,这些函数可能不能满足我们的需求,比如我想要一个函数能够从WebService上
  • VSTO用VISUALBASIC2010编写EXCEL自定义函数(加载项)[归纳].pdf
  • 使用VBA开发自定义函数,可以弥补Excel内置函数的不足,简化函数公式,但是需要注意实现同样功能,自定义函数的效率远远不如内置函数,所以不要试图重新发明轮子。
  • VBA Excel 自定义函数不能调用成功的问题的解决方法问题以及解决方案的列举(持续更新中) 问题以及解决方案的列举(持续更新中) 自定义函数是自动化各种Excel重复操作的重要函数,我们可以用它实现各种自己的奇葩...
  • Excel自定义函数:字符串相似度

    热门讨论 2010-09-27 14:35:41
    自己开发的Excel函数,可以判定两个字符串的相似度。
  • VBA_Excel自定义函数大全,很有用的哦。
  • excel 自定义函数 (vb)

    千次阅读 2019-07-25 12:35:27
    Function ss(s) Dim a As String, b As Long, c As Long, d As Long, e As Long, f As Integer, res As Double a = CStr(s) b = InStr(1, a, “.”) f = 65 If b > 0 Then e = Mid(a, b + 1) ...
  • excel自定义函数

    2008-07-23 17:14:06
    excel自定义函数
  • EXCEL自定义倒序函数

    2021-01-04 17:34:35
    EXCEL自定义倒序函数,可对字符串进行翻转
  • Excel 自定义函数与宏在线路数据中的开发应用 林永强 中铁隧道集团有限公司第一工程处 河南新乡 453000 摘 要 本文通过介绍Excel 中的自定义函数及编写宏就如何建立线路数据信息查询系统形成独特的模板 文件线路数据...
  • Excel自定义函数_身份证号码校验
  • #资源达人分享计划#
  • excel-自定义函数及使用

    千次阅读 2021-10-19 10:46:03
    编写自定义函数 打开一个excel文件,在某个sheet上,选择Visual Basic 然后在新打开的vb页面上新建模块。这个test.xlsx就是我之前打开的excel文件。 函数编写规则 参考Office支持 自定义函数以Function语句开始,...
  • 自定义函数_搜索excel自定义函数157个
  • 目录 本文使用的版本:Excel 2013 1、打开脚本编辑框 2、插入模块,编写代码 ... 4、给Excel单元插入自定义函数 5、给函数增加自定义说明 6、设置该自定义函数Excel上通用 附录: ...
  • Excel自定义函数.rar

    2019-09-26 11:09:28
    Excel自定义函数.rar,自定义函数就是用户创建的用于满足特定需求的函数,是对于Excel内置工作表函数的一个补充。本示例文件内容包括:对比自定义函数的效率、两种参数传递方式示例、返回数组的函数示例和自定义...
  • xlwings是python对excel操作的一个第三方库,融合了pandas数据分析工具,比其他的python操作excel 好用。xlwings自定义函数和宏。
  • EXCEL中我们是可以设置自定义函数来进行运算数据的,方便我们下次直接使用我们已经定义好的函数,让我们开始吧: 1、首先打开EXCEL表格 2、然后点击开发工具,选择Visual Basic 3、右击VBAPorject选择插入,再...
  • 一、Excel自定义格式:快速输入性别。 目的:在单元格中输入1显示“男”,输入0显示“女”。 方法: 1、选定目标单元格,快捷键Ctrl+1打开【设置单元格格式】对话框。 2、单击【数字】选项卡【分类】中的...
  • Excel自定义函数使用正则表达式详解

    千次阅读 2019-02-21 14:12:26
    Excel自定义函数使用正则表达式详解

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,039
精华内容 15,615
关键字:

excel自定义函数

友情链接: sigg2012.rar