XLL插件开发-Excel SDK函数问题
XLL add-in Development - Excel SDK function issue
目前我正在使用Excel SDK 2010开发Excel 2010加载项(.xll)。不幸的是,微软的文档很少(或者我只是还没有找到)。我的加载项加载在Excel中,它的菜单出现了,我可以从菜单中调用一个函数,它确实会被执行。在里面,我试图收集所有的Sheet名称,但每次调用函数都会得到不同的结果。返回的XLOPER
中存在正确的图纸名称,但它们被不断变化的"奇怪"字符包围。
有问题的代码:
LPXLOPER12 GetWorkbook(void){
LPXLOPER12 workbooksheets=new XLOPER12,xworkbookname = new XLOPER12;
memset(xworkbookname,0,sizeof(XLOPER12));
memset(workbooksheets,0,sizeof(XLOPER12));
Excel12f(xlfGetDocument,xworkbookname,1,TempInt12(88));
Excel12f(xlfGetWorkbook,workbooksheets,2,TempInt12(1),xworkbookname);
// at this point I expect xworkbookname->val.str to contain the workbook name
// but instead it has garbage before and after
return 0;
}
您在这里仍然没有提供太多信息,但我猜。
由于计算机使用数字,因此必须有一个表示文本的约定。C编程语言使用的一种约定是说"文本的第一个字符在第一个内存位置,文本继续,直到您找到值为0的字节/单词"。既然你是用C写的,我想这就是你所期望的。
但微软最初并不是用C语言开发Excel的。他们是用Pascal语言开发的。Pascal使用的约定是"第一个内存位置包含文本的长度,实际文本从第二个内存位置开始,按照长度指定的内存位置。没有终止0。"
例如,MSDN网站上实际上有很多可用的文档http://msdn.microsoft.com/en-us/library/aa730920%28v=office.12%29.aspx
特别是,它们有一个图形(和示例代码),显示了在Pascal字符串和C字符串之间转换时需要使用的例程。
正如AnotherParker所暗示的,xlfGetWorkbook以长度前缀字符串的形式返回工作表名称,因此要在函数中使用它,需要将其转换为Null分隔字符串。
此外,xlfGetWorkbook在工作表名称前面加上[]括号中的Workbook名称,因此需要去掉它才能获得实际的工作表名称。
这里是一个完整的C语言工作示例,不使用任何风格的Framework,它在Activesheet的第一列中输出Sheet名称。
int __stdcall ListSheetsD (void)
{
static XLOPER12 xWorkbook;
XLOPER12 xRef, xNumParm, xAutoFit, xFalse, xlCell[10], xlArray;
int rc, i, iSheets;
size_t fullnamelen, sheetnamelen;
wchar_t *fullname, *sheetname;
XCHAR *ptr;
OLECHAR buffer[100];
OLECHAR *function = L"ListSheetsD";
xNumParm.xltype = xltypeNum;
xNumParm.val.num = 1;
rc = Excel12 ( xlfGetWorkbook, (LPXLOPER12)&xWorkbook, 1, (LPXLOPER12)&xNumParm);
if ( rc != xlretSuccess )
{
swprintf ( buffer, 100, L"xlfGetWorkbook. rc=%d", rc );
MessageBox (NULL, buffer, function, MB_OK | MB_SETFOREGROUND );
}
//Get Number of Sheets
iSheets = xWorkbook.val.array.columns;
for ( i = 0; i < iSheets; i++ )
{
if ( i < 10 )
{
//Pickup Sheet Name (format: [Book.xls]Sheet1) & set it up as a Null Delimited String
fullnamelen = xWorkbook.val.array.lparray[i].val.str[0];
fullname = (wchar_t *) malloc ( (fullnamelen + 2) * sizeof (wchar_t) );
memcpy (fullname, (xWorkbook.val.array.lparray[i].val.str + 1),
(fullnamelen) * sizeof(wchar_t));
fullname[fullnamelen] = L' ';
//Extract Sheet Name (format: Sheet1) & set it up as a Length Prefixed String
sheetname = (wchar_t *) malloc ( (fullnamelen + 2) * sizeof (wchar_t) );
ptr = wcschr (fullname, L']');
sheetnamelen = wcslen (ptr);
wcscpy ( sheetname, ptr );
sheetname[0] = sheetnamelen;
//Setup Output Row
xlCell[i].xltype = xltypeStr;
xlCell[i].val.str = sheetname;
free (fullname);
}
}
if ( i > 10 ) i = 10;
xlArray.xltype = xltypeMulti;
xlArray.val.array.rows = i;
xlArray.val.array.columns = 1;
xlArray.val.array.lparray = &xlCell[0];
xRef.xltype = xltypeSRef;
xRef.val.sref.count = 1;
xRef.val.sref.ref.rwFirst = 0;
xRef.val.sref.ref.rwLast = i - 1;
xRef.val.sref.ref.colFirst = 0;
xRef.val.sref.ref.colLast = 0;
rc = Excel12 ( xlSet, 0, 2, (LPXLOPER12)&xRef, (LPXLOPER12)&xlArray );
if ( rc != xlretSuccess )
{
swprintf ( buffer, 100, L"xlSet. Error=%d", rc );
MessageBox (NULL, buffer, function, MB_OK | MB_SETFOREGROUND );
}
rc = Excel12 (xlFree, NULL, 2, &xWorkbook, &xlArray );
if ( rc != xlretSuccess )
{
swprintf ( buffer, 100, L"xlFree. rc=%d", rc );
MessageBox (NULL, buffer, function, MB_OK | MB_SETFOREGROUND );
}
rc = Excel12 ( xlcSelect, 0, 1, (LPXLOPER12)&xRef );
if ( rc != xlretSuccess )
{
swprintf ( buffer, 100, L"xlcSelect. rc=%d", rc );
MessageBox (NULL, buffer, function, MB_OK | MB_SETFOREGROUND );
}
xAutoFit.xltype = xltypeNum;
xAutoFit.val.num = 3;
xFalse.xltype = xltypeBool;
xFalse.val.xbool = 0;
rc = Excel12 ( xlcColumnWidth, 0, 4, &xNumParm, (LPXLOPER12)&xRef, &xFalse, &xAutoFit );
if ( rc != xlretSuccess )
{
swprintf ( buffer, 100, L"xlcColumnWidth. rc=%d", rc );
MessageBox (NULL, buffer, function, MB_OK | MB_SETFOREGROUND );
}
return 1;
}
尝试http://xll.codeplex.com.它会让你的生活更轻松。
- 类C++中的函数问题(LNK2019和LNK1120错误)
- 返回不停止函数,递归函数问题?(编程练习,动态规划,Levenshtein 回溯)
- 变分模板递归构造函数问题
- C++函数问题中的数组分配
- C++中嵌套在另一个 LinkedList 中的 LinkedList 整数上的回调函数问题
- C++重载构造函数问题
- 二叉搜索树析构函数问题
- C++ vector<pair<int,int>> std::all_of() 函数问题(重定向到头文件)
- 迷宫构造函数问题 [线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)]
- C++函数问题中的 IF 语句
- 函数问题,未定义的引用错误
- C++ 指针无效函数问题
- C++函数问题 = 帮助我理解基本概念
- 由于基于接口的编程,遇到 C++ 虚拟模板函数问题
- C++二进制树递归析构函数问题
- 构造函数问题<无法读取内存>
- 构造函数问题
- C 时间函数问题
- 另一个类中的类的构造函数问题
- C与C++函数问题