SQLite UDF - VBA Callback
Unfortunately, you can't use a VB6/VBA function as a callback directly as VB6 only generates stdcall
functions rather than the cdecl
functions SQLite expects.
You will need to write a C dll to proxy the calls back and forth or recompile SQLite to to support your own custom extension.
After recompiling your dll to export the functions as stdcall
, you can register a function with the following code:
'Create FunctionPublic Declare Function sqlite3_create_function Lib "SQLiteVB.dll" (ByVal db As Long, ByVal zFunctionName As String, ByVal nArg As Long, ByVal eTextRep As Long, ByVal pApp As Long, ByVal xFunc As Long, ByVal xStep As Long, ByVal xFinal As Long) As Long'Gets a valuePublic Declare Function sqlite3_value_type Lib "SQLiteVB.dll" (ByVal arg As Long) As SQLiteDataTypes 'Gets the typePublic Declare Function sqlite3_value_text_bstr Lib "SQLiteVB.dll" (ByVal arg As Long) As String 'Gets as StringPublic Declare Function sqlite3_value_int Lib "SQLiteVB.dll" (ByVal arg As Long) As Long 'Gets as Long'Sets the Function ResultPublic Declare Sub sqlite3_result_int Lib "SQLiteVB.dll" (ByVal context As Long, ByVal value As Long)Public Declare Sub sqlite3_result_error_code Lib "SQLiteVB.dll" (ByVal context As Long, ByVal value As Long)Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)Public Property Get ArgValue(ByVal argv As Long, ByVal index As Long) As Long CopyMemory ArgValue, ByVal (argv + index * 4), 4End PropertyPublic Sub FirstCharCallback(ByVal context As Long, ByVal argc As Long, ByVal argv As Long) Dim arg1 As String If argc >= 1 Then arg1 = sqlite3_value_text_bstr(ArgValue(argv, 0)) sqlite3_result_int context, AscW(arg1) Else sqlite3_result_error_code context, 666 End IfEnd SubPublic Sub RegisterFirstChar(ByVal db As Long) sqlite3_create_function db, "FirstChar", 1, 0, 0, AddressOf FirstCharCallback, 0, 0 'Example query: SELECT FirstChar(field) FROM TableEnd Sub