无法使用Delphi排序Excel工作

时间:2016-11-21 14:39:36

标签: excel delphi

我正在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;

2 个答案:

答案 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代码中而不是真正的