VBA的调试输出只有简单的Debug.Print,在接触过C语言之后,很喜欢printf那种形式的打印输出,无奈一直觉得C语言太难了,没能深入去学习。
后来接触了go语言后,觉得这种语言学起来还算简单,也很像C语言。所以在学习一段时间后,就想着能不能用go语言封装dll给VBA使用,前面讲到的那些关于指针、数据类型的东西,主要就是为了做dll:
在了解了VBA的数据类型后,我们才能把VBA的数据传递到dll中,并正确的解析数据,这里简单介绍一下封装go语言的Sprintf函数。
效果:

1、函数声明
func Sprintf(format string, a ...interface{}) string 这个是go语言的Sprintf函数,可以按c语言的Sprintf函数来理解,第1个参数好处理,关键是后面的可变参数,因为它是允许任意类型和任意数量的:
所以,VBA里的函数声明为:
Public Sub Printf(format As Variant, ParamArray args() As Variant)
End Subformat是string,为了方便统一处理,都按Variant类型来传递。
封装Sprintf的目的就是为了能得到一个格式化的字符串,VBA的String和go语言里的string是不一样的,所以dll传出来的string需要转换,API声明:
Public Declare Function gosprintf Lib "godllForVBA32.dll" (ByVal pFormat As Long, ByVal pVBAVariant As Long, ByVal nCount As Long) As MyString
Type MyString
pUCS2 As Long
Len As Long
End Type为了方便处理,我是在go语言里把String转换为了VBA里的编码,这样在VBA里不需要再次转码了。
2、go实现:
go语言里的函数:
func Sprintf(pformat, pParamArray, nCount int32) (ptr unsafe.Pointer, lenth int)参数pformat, pParamArray接收VBA传入的指针,nCount直接接收数值,函数返回VBA的String及长度。
实现过程:
3、编译
go.exe build -v -x -buildmode=c-archive -o c\go.a生成.a和.h 2个文件
struct Sprintf_return __stdcall gosprintf(GoInt p0, GoInt p1, GoInt p2) {
return Sprintf(p0, p1, p2);
}EXPORTS
gosprintf
cfreegcc.exe c\stdcall.c c\go.def c\go.a -shared -lwinmm -lWs2_32 -o go.dll -Wl,--enable-stdcall-fixup,--out-implib,go.libgo语言的具体实现因为和VBA代码相关性不大,就不展开讲。