sorting - 通过 Delphi 在 OpenOffice Calc 中排序
问题描述
我花了几个小时试图在 Delphi 的 OpenOffice Calc 中对数据进行排序。我尝试按照基本(来自“OpenOffice.org Macros Explained”*)或 C# 中的示例进行操作,但仍然没有结果。数据根本不会改变。我究竟做错了什么?也许问题出在数据类型上?
* https://www.pitonyak.org/OOME_3_0.pdf,第 488 页。
最小的可重现示例:
program OpenOfficeCalcSortingIssue;
{$APPTYPE CONSOLE}
uses
System.SysUtils, Variants, ComObj, ActiveX;
var
StarOffice: OleVariant;
SODesktop: OleVariant;
SOCalc: OleVariant;
CalcSheets: OleVariant;
CalcSheet: OleVariant;
SortFields: OleVariant;
SortDescriptor: OleVariant;
begin
CoInitialize(nil);
try
try
StarOffice:=CreateOleObject('com.sun.star.ServiceManager');
SODesktop:=StarOffice.CreateInstance('com.sun.star.frame.Desktop');
SOCalc:=SODesktop.LoadComponentFromURL('private:factory/scalc', '_blank', 0, VarArrayCreate([0, -1], varVariant));
CalcSheets:=SOCalc.GetSheets;
CalcSheet:=CalcSheets.GetByIndex(0);
CalcSheet.GetCellByPosition(0, 0).SetValue(2);
CalcSheet.GetCellByPosition(0, 1).SetValue(1);
CalcSheet.GetCellByPosition(0, 2).SetValue(4);
CalcSheet.GetCellByPosition(0, 3).SetValue(3);
SortFields:=VarArrayCreate([0, 0], varVariant);
SortFields[0]:=StarOffice.Bridge_GetStruct('com.sun.star.util.SortField');
SortFields[0].Field:=0;
SortFields[0].SortAscending:=True;
SortDescriptor:=VarArrayCreate([0, 0], varVariant);
SortDescriptor[0]:=StarOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
SortDescriptor[0].Name:='SortFields';
SortDescriptor[0].Value:=SortFields;
CalcSheet.GetCellRangeByName('A1:A4').Sort(SortDescriptor);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
finally
CoUninitialize;
end;
end.
解决方案
像往常一样,在将问题暴露给世界后不久就出现了解决方案:-)我从互联网深处找到了一个例子。希望偶然发现这个问题的人可以更轻松地搜索关于 SO 的这个主题。答案是:SortFields 不仅仅是一个变体数组。它是一个“值对象”,必须像这样设置:
ValueObject:=StarOffice.Bridge_GetValueObject;
ValueObject.Set('[]com.sun.star.table.TableSortField', SortFields);
在我发现的示例中,注释为“您必须指定将哪种类型的序列传输到 SortFields 属性”。
所以整个代码应该是:
StarOffice:=CreateOleObject('com.sun.star.ServiceManager');
SODesktop:=StarOffice.CreateInstance('com.sun.star.frame.Desktop');
SOCalc:=SODesktop.LoadComponentFromURL('private:factory/scalc', '_blank', 0, VarArrayCreate([0, -1], varVariant));
CalcSheets:=SOCalc.GetSheets;
CalcSheet:=CalcSheets.GetByIndex(0);
CalcSheet.GetCellByPosition(0, 0).SetValue(2);
CalcSheet.GetCellByPosition(0, 1).SetValue(1);
CalcSheet.GetCellByPosition(0, 2).SetValue(4);
CalcSheet.GetCellByPosition(0, 3).SetValue(3);
SortFields:=VarArrayCreate([0, 0], varVariant);
SortFields[0]:=StarOffice.Bridge_GetStruct('com.sun.star.table.TableSortField');
SortFields[0].Field:=0;
SortFields[0].IsAscending:=True;
ValueObject:=StarOffice.Bridge_GetValueObject;
ValueObject.Set('[]com.sun.star.table.TableSortField', SortFields);
SortDescriptor:=VarArrayCreate([0, 0], varVariant);
SortDescriptor[0]:=StarOffice.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
SortDescriptor[0].Name:='SortFields';
SortDescriptor[0].Value:=ValueObject;
CalcSheet.GetCellRangeByName('A1:A4').Sort(SortDescriptor);
推荐阅读
- c# - 单元测试在 VSTS Build 上查找 roslyn 二进制文件的位置错误
- ios - 如何在 Xcode IB 中为 ARSCNView 设置首选渲染 API
- javascript - 将单页应用程序集成到 WordPress
- php - 在mysqli中添加所有重复值
- google-app-maker - 如何在 AppMaker 中导出数据库的架构
- selenium - 如何在量角器框架中使用 chrome 选项?
- r - 在 R 中打开 .bcp 文件
- bluej - 如何定义默认和非默认构造函数,以及 mutator 和 accessor 方法
- mysql - 前 6 名的 SQL 计数值
- wpf - 如何在 WPF 应用程序中以编程方式插入文本时调整文本框的大小?