我正在Delphi 10 / Seattle编写一个程序来控制Excel 2013.我需要根据列进行排序。该列有标题。当我的代码编译时,实际的SORT命令会给出错误'无法将类型(错误)的变体转换为类型(布尔)。'简而言之,我有一个参数错误,但我无法确定WHICH参数。我已经完成了MS语法(下面列出的URL),但找不到任何错误。这是一个显示问题的工作示例。我DID生成我自己的类型库,它在USES子句中。
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, ComObj, Excel_TLB;
..
procedure TForm1.Button2Click(Sender: TObject);
var
oExcel : ExcelApplication;
RawDataSheet :_Worksheet;
myChart: Shape;
begin
oExcel := CreateOleObject('Excel.Application') as ExcelApplication;
oExcel.Visible[LOCALE_USER_DEFAULT] := True;
// Add a New Workbook, with a single sheet
oExcel.Workbooks.Add(EmptyParam, LOCALE_USER_DEFAULT);
// Get the handle to the active Sheet, and insert some dummy data
RawDataSheet := oExcel.ActiveSheet as _Worksheet;
RawDataSheet.Range['A1', 'F10'].value2 := 10;
RawDataSheet.Sort.SortFields.Clear;
// Now actually do the sort...
// SYNTAX at https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.namedrange.sort.aspx
RawDataSheet.UsedRange[LOCALE_USER_DEFAULT].Sort (
RawDataSheet.Range['A1:A10', EmptyParam], xlAscending, // Key1, Order1
EmptyParam, EmptyParam, xlAscending, // key2, Type_, Order2
EmptyParam, xlAscending, // key3, Order3
xlYes, EmptyParam, False, xlSortRows, // Header, OrderCustom, MatchCase, Orientation
xlPinYin, EmptyParam, EmptyParam, EmptyParam); // Sort, Data Option1, Data Option2, Data Option3
end;
答案 0 :(得分:1)
有多个违规参数。他们错误的是他们不喜欢EmptyParam
,尽管我们应该为未使用的可选参数传递它。
由于两个原因很难找到哪一个。一个是,当你使用后期绑定时,你提供参数的方式非常正常。另一个是误导性的错误信息:
...带有消息的EVariantTypeCastError'无法转换类型的变体 (错误)进入类型(布尔)'。
EmptyParam
是设置为varError
的变体,因此第一部分建议我们应该怀疑EmptyParam
。转换为布尔值失败,那么我们要寻找的是为可选的布尔参数传递的EmptyParam
。不幸的是有none,甚至没有像布尔一样的东西。事实上,任何一个'DataOption'枚举都会导致上述错误消息。
这是一种可能有助于找到可行解决方案的系统方法:
EmptyParam
填写所有剩余参数,进行测试,然后将调用调整为早期绑定。这是我的工作样本:
procedure TForm1.Button1Click(Sender: TObject);
var
oExcel : ExcelApplication;
RawDataSheet :_Worksheet;
begin
oExcel := CreateOleObject('Excel.Application') as ExcelApplication;
oExcel.Visible[LOCALE_USER_DEFAULT] := True;
// Add a New Workbook, with a single sheet
oExcel.Workbooks.Add(EmptyParam, LOCALE_USER_DEFAULT);
// Get the handle to the active Sheet, and insert some dummy data
RawDataSheet := oExcel.ActiveSheet as _Worksheet;
RawDataSheet.Range['A1', 'F1'].value2 := 'head';
RawDataSheet.Range['A2', 'F2'].value2 := 8;
RawDataSheet.Range['A3', 'F3'].value2 := 17;
RawDataSheet.Range['A4', 'F4'].value2 := 4;
RawDataSheet.Range['A5', 'A5'].value2 := 10;
RawDataSheet.Range['B5', 'F5'].Value2 := 11;
RawDataSheet.Range['A6', 'F6'].value2 := 7;
RawDataSheet.Range['A7', 'F7'].value2 := 1;
RawDataSheet.Range['A8', 'F8'].value2 := 2;
RawDataSheet.Range['A9', 'A9'].value2 := 10;
RawDataSheet.Range['B9', 'B9'].value2 := 11;
RawDataSheet.Range['C9', 'F9'].value2 := 9;
RawDataSheet.Range['A10', 'F10'].value2 := 10;
RawDataSheet.Sort.SortFields.Clear;
// Now actually do the sort...
// SYNTAX at https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.namedrange.sort.aspx
RawDataSheet.UsedRange[LOCALE_USER_DEFAULT].Sort
(RawDataSheet.Range['A1', 'A10'], xlAscending,
RawDataSheet.Range['B1', 'B10'], EmptyParam, xlAscending,
RawDataSheet.Range['C1', 'C10'], xlAscending,
xlYes, NULL, False, xlSortColumns,
xlPinYin, xlSortNormal, xlSortNormal, xlSortNormal);
end;
最后,我很高兴Type
参数没有抱怨传递EmptyParam
,因为我不明白它是什么。
老答案如下:
我使用IDispatch / Invoke路由测试了你的参数,后期绑定,尽管失去了一些性能和类型安全性,但它通常具有更高的工作概率。没有一个是错的,我也测试了其他键。虽然参数没有错误,但如果使用早期绑定,excel会抛出错误。这是一个有效的例子:
procedure TForm1.Button1Click(Sender: TObject);
var
oExcel : ExcelApplication;
RawDataSheet :_Worksheet;
V: OleVariant; // Range
begin
oExcel := CreateOleObject('Excel.Application') as ExcelApplication;
oExcel.Visible[LOCALE_USER_DEFAULT] := True;
// Add a New Workbook, with a single sheet
oExcel.Workbooks.Add(EmptyParam, LOCALE_USER_DEFAULT);
// Get the handle to the active Sheet, and insert some dummy data
RawDataSheet := oExcel.ActiveSheet as _Worksheet;
RawDataSheet.Range['A1', 'F1'].value2 := 'head';
RawDataSheet.Range['A2', 'F2'].value2 := 8;
RawDataSheet.Range['A3', 'F3'].value2 := 17;
RawDataSheet.Range['A4', 'F4'].value2 := 4;
RawDataSheet.Range['A5', 'A5'].value2 := 10;
RawDataSheet.Range['B5', 'F5'].Value2 := 11;
RawDataSheet.Range['A6', 'F6'].value2 := 7;
RawDataSheet.Range['A7', 'F7'].value2 := 1;
RawDataSheet.Range['A8', 'F8'].value2 := 2;
RawDataSheet.Range['A9', 'A9'].value2 := 10;
RawDataSheet.Range['B9', 'B9'].value2 := 11;
RawDataSheet.Range['C9', 'F9'].value2 := 9;
RawDataSheet.Range['A10', 'F10'].value2 := 10;
RawDataSheet.Sort.SortFields.Clear;
{
// Now actually do the sort...
// SYNTAX at https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.namedrange.sort.aspx
RawDataSheet.UsedRange[LOCALE_USER_DEFAULT].Sort (
RawDataSheet.Range['A1:A10', EmptyParam], xlAscending, // Key1, Order1
EmptyParam, EmptyParam, xlAscending, // key2, Type_, Order2
EmptyParam, xlAscending, // key3, Order3
xlYes, EmptyParam, False, xlSortRows, // Header, OrderCustom, MatchCase, Orientation
xlPinYin, EmptyParam, EmptyParam, EmptyParam); // Sort, Data Option1, Data Option2, Data Option3
}
V := RawDataSheet.Range['A1', 'F10'];
V.Sort(RawDataSheet.Range['A1:A10', EmptyParam], xlAscending,
RawDataSheet.Range['B1', 'B10'], EmptyParam, xlAscending,
RawDataSheet.Range['C1', 'C10'], xlAscending,
xlYes, EmptyParam, False, xlSortColumns,
xlPinYin, EmptyParam, EmptyParam, EmptyParam);
end;
答案 1 :(得分:0)
我认为您与所需参数存在一些不匹配。你应该试试
RawDataSheet.UsedRange.Sort (RawDataSheet.Range['A1:A10'], xlAscending, // Key1, Order1
EmptyParam, xlAscending, // key2, Type_, Order2
EmptyParam, xlAscending, // key3, Order3
xlYes, EmptyParam, EmptyParam, xlSortRows, // Header, OrderCustom, MatchCase, Orientation
EmptyParam, EmptyParam, EmptyParam, EmptyParam); // Sort, Data Option1, Data Option2, Data Option3
删除所有不清楚的参数并将其替换为Emptyparam,甚至" true"或"假"有时可能不清楚,有时我不得不使用" wordbool(1)"或者" msotrue"在Delphi代码中而不是真正的