Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从xll调用xlcOnTime 基本上试图在C++中复制下面的VBA代码 但是在系统计时器函数中调用Excel4(xlcOnTime,&timer2,2,&now,cmd)的返回代码为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(); }_Excel_Xll - Fatal编程技术网

如何从xll调用xlcOnTime 基本上试图在C++中复制下面的VBA代码 但是在系统计时器函数中调用Excel4(xlcOnTime,&timer2,2,&now,cmd)的返回代码为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(); }

如何从xll调用xlcOnTime 基本上试图在C++中复制下面的VBA代码 但是在系统计时器函数中调用Excel4(xlcOnTime,&timer2,2,&now,cmd)的返回代码为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(); },excel,xll,Excel,Xll,我很确定原因是除了调用线程外,不能从其他线程调用任何Excel4函数。因为您是从TimerRoc内部回调,所以您可能处于事件线程或其他时间线程中。诚然,这是一个巨大的痛苦,但这就是事实。 < P>问题是,C++代码与VBA代码不是完全等价的。在VBA中,通过Excel计时器运行命令 Application.OnTime 它使用Excel实时自动调用。在C++中,你有< /P> Excel4(xlcOnTime, &timer2, 2, &now, cmd); 这是XLL接口函

我很确定原因是除了调用线程外,不能从其他线程调用任何Excel4函数。因为您是从TimerRoc内部回调,所以您可能处于事件线程或其他时间线程中。诚然,这是一个巨大的痛苦,但这就是事实。

< P>问题是,C++代码与VBA代码不是完全等价的。在VBA中,通过Excel计时器运行命令

Application.OnTime
它使用Excel实时自动调用。在C++中,你有< /P>
Excel4(xlcOnTime, &timer2, 2, &now, cmd);
这是XLL接口函数
xlcOnTime
。Excel对XLL函数调用的限制非常严格;只能在特定上下文中调用它们。例如,
xlcOnTime
可以从用户定义的Excel命令调用,但不能从Windows计时器回调调用

<>你需要做的是在C++中使用完全等价的VBA代码,这意味着在C++中使用自动化。有几个例子说明如何使用Excel在C++中使用MSDN和其他源中的自动化。他们经常使用
AutoWrap
函数来调用自动化,所以您需要

AutoWrap(DISPATCH_METHOD, &result, pXlApp, L"OnTime", 1, COleVariant("ApplicationOnTime"));
自动化调用没有与xlc函数相同的限制,因此Excel将接受从Windows计时器回调发出的此类调用,并且将运行
applicationantime
命令