如何从xll调用xlcOnTime

基本上试图在C ++中复制下面的VBA代码我不希望我的Excel加载项返回一个数组(而是我需要一个UDF来更改其他单元格),但是调用Excel4(xlcOnTime,&timer2,2&now,cmd )在系统计时器function中有一个返回码2,即无法设置Excel的计时器。 任何想法? 我试图限制我的加载项1和C + +代码。 我可以通过两个加载项来解决这个问题,一个用C ++,一个用VBA,但是不用。

namespace { UINT timer1 = 0; XLOPER timer2; XLOPER now; }; // //this function is xlfRegister as ApplicationOnTime // int __stdcall application_on_time() { XLOPER ret; XLOPER ref; XLOPER value; //define the destination cells to be changed ref.xltype = xltypeSRef; ref.val.sref.count = 1; ref.val.sref.ref.rwFirst = 10; ref.val.sref.ref.rwLast = 12; ref.val.sref.ref.colFirst = 10; ref.val.sref.ref.colLast = 20; //the values value.xltype = xltypeMulti; value.val.array.columns = 2; value.val.array.rows = 3; value.val.array.lparray = new XLOPER[6]; (value.val.array.lparray[0]).xltype = xltypeNum; (value.val.array.lparray[0]).val.num = 9991; (value.val.array.lparray[1]).xltype = xltypeNum; (value.val.array.lparray[1]).val.num = 9992; (value.val.array.lparray[2]).xltype = xltypeNum; (value.val.array.lparray[2]).val.num = 9993; (value.val.array.lparray[3]).xltype = xltypeNum; (value.val.array.lparray[3]).val.num = 9994; (value.val.array.lparray[4]).xltype = xltypeNum; (value.val.array.lparray[4]).val.num = 9995; (value.val.array.lparray[5]).xltype = xltypeNum; (value.val.array.lparray[5]).val.num = 9996; //set the value to the cell int xlret = Excel4(xlSet, &ret, 2, &ref, &value); printf("xlret is %d", xlret); return 0; } //xlfRegister as a command TestUserCommand, to be //called from a button on Excel, with VBA code //Application.run("TestUserCommand") int __stdcall test_user_command() { LPXLOPER now = new XLOPER; LPXLOPER cmd = new XLOPER; cmd->xltype = xltypeStr; cmd->val.str = XLUtil::MakeExcelString("ApplicationOnTime"); Excel4(xlfNow, now, 0, NULL); timer2.xltype = xltypeInt; timer2.val.num = 0; int xlret = Excel4(xlcOnTime, &timer3, 2, now, cmd); //xlret is 0, the ApplicationOnTime command would be triggered //and the cells K11:U13 value get set as expected printf("xlret is %d", xlret); return 0; } //xlfRegister as a function TestUserFunction, to be //called from a cell formula on Excel //=TestUserFunction(1) char * __stdcall test_user_function(xloper *pxl) { static bool first = true; if (first) { timer2.xltype = xltypeInt; timer2.val.num = 0; first = false; } if (timer1 > 0) { UINT tmp = timer1; timer1 = 0; KillTimer(NULL, tmp); } Excel4(xlfNow, &now, 0, NULL); //set the system timer to triggers the MyTimerProc, //and MyTimerProc is triggered successfully but no luck //in setting the second timer that is excel //inside MyTimerProc timer1 = SetTimer(NULL, 0, 1, (TIMERPROC)MyTimerProc); return 0; } //this is the procedure referred to in the SetTimer call void CALLBACK MyTimerProc(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime) { if (timer1 > 0) { UINT tmp = timer1; timer1 = 0; KillTimer(NULL, tmp); } LPXLOPER12 cmd = new XLOPER12; cmd->xltype = xltypeStr; cmd->val.str = (XCHAR *)XLUtil::MakeExcelString("ApplicationOnTime"); now.val.num = now.val.num + 10.0 / (60.0 * 60.0 * 24.0); int xlret = Excel4(xlcOnTime, &timer2, 2, &now, cmd); //xlret is 2, indicates invalid function, no luck. the ApplicationOnTime //command won't be triggered //try to call the application_on_time function to set the values to cell //to no effect application_on_time(); } 

我敢肯定,原因是你不能调用线程以外的任何Excel4函数调用线程。 因为你从TIMERPROC里面调用,你可能在事件线程或其他时间线程中。 这当然是一个巨大的痛苦,但这是事实。