将 Applescript 移植到 Scripting Bridge:无法获取 Excel 2008 中的范围值
我需要将一些 Applescript 代码移动到 Scripting Bridge 以利用一些 Cocoa 挂钩,而不需要 Applescript-ObjC。
将 Excel 2008 与 Applescript 结合使用,获取范围的值很容易:
set myList to GetValuesFromColumnRange("A", 1, 100)
on GetValuesFromColumnRange(ColumnLetter, FirstRow, LastRow) -- (string, integer, integer) as list
set theList to {}
tell application "Microsoft Excel"
set theRange to ColumnLetter & FirstRow & ":" & ColumnLetter & LastRow
set AppleScript's text item delimiters to {return}
set theList to (get value of range theRange as list)
set AppleScript's text item delimiters to {""}
end tell
set theList to ConvertItemizedListToValueList(theList) of me -- Note this dependency due to how MSE2008 returns the data
return theList
end GetValuesFromColumnRange
但在 Scripting Bridge 中,我在根据范围获取工作表的单元格时遇到问题。以下是我到目前为止所拥有的。
Excel2008Application *excelApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Excel"];
Excel2008Workbook *workbook = excelApp.activeWorkbook;
SBElementArray *sheets = [workbook sheets];
Excel2008Sheet *targetSheet;
int thisSheet = 0;
int lastSheet = [sheets count];
for (thisSheet = 0; thisSheet < lastSheet; thisSheet++) {
Excel2008Sheet *currentSheet = [sheets objectAtIndex:thisSheet];
NSString *currentSheetName = currentSheet.name;
if ([currentSheetName isEqualToString:@"Metadata"]) {
targetSheet = currentSheet;
[targetSheet retain];
}
}
Excel2008Range *range = [[[excelApp classForScriptingClass:@"range"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:@"A1:A10", @"formulaR1c1", nil]];
[[targetSheet ranges] addObject:range];
range = [[targetSheet ranges] lastObject]; // not null; stated class in log: MicrosoftExcelRange
Excel2008Sheet *valueSheet = range.worksheetObject; // supposed to be new worksheet based upon values within the range; not null; stated class in log: MicrosoftExcelSheet
[valueSheet retain];
SBElementArray *valueCells = [valueSheet cells]; // not null, but count is 0
[valueCells retain];
问题出现在最后一行,当我实际从 valueSheet
获取单元格时,返回的 SBElementArray
不为 null,但它也不包含任何对象。获取 targetSheet
中的单元格也是如此。
从我所有的搜索中可以看出,执行此操作的文档并不存在,我已尽我所能。
I have a need to move some Applescript code to Scripting Bridge to take advantage of some Cocoa hooks without the need for Applescript-ObjC.
Using Excel 2008 with Applescript, getting the value of a range is easy:
set myList to GetValuesFromColumnRange("A", 1, 100)
on GetValuesFromColumnRange(ColumnLetter, FirstRow, LastRow) -- (string, integer, integer) as list
set theList to {}
tell application "Microsoft Excel"
set theRange to ColumnLetter & FirstRow & ":" & ColumnLetter & LastRow
set AppleScript's text item delimiters to {return}
set theList to (get value of range theRange as list)
set AppleScript's text item delimiters to {""}
end tell
set theList to ConvertItemizedListToValueList(theList) of me -- Note this dependency due to how MSE2008 returns the data
return theList
end GetValuesFromColumnRange
But in Scripting Bridge, I'm having a problem getting the cells of a worksheet based on a range. The following is what I have so far.
Excel2008Application *excelApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Excel"];
Excel2008Workbook *workbook = excelApp.activeWorkbook;
SBElementArray *sheets = [workbook sheets];
Excel2008Sheet *targetSheet;
int thisSheet = 0;
int lastSheet = [sheets count];
for (thisSheet = 0; thisSheet < lastSheet; thisSheet++) {
Excel2008Sheet *currentSheet = [sheets objectAtIndex:thisSheet];
NSString *currentSheetName = currentSheet.name;
if ([currentSheetName isEqualToString:@"Metadata"]) {
targetSheet = currentSheet;
[targetSheet retain];
}
}
Excel2008Range *range = [[[excelApp classForScriptingClass:@"range"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:@"A1:A10", @"formulaR1c1", nil]];
[[targetSheet ranges] addObject:range];
range = [[targetSheet ranges] lastObject]; // not null; stated class in log: MicrosoftExcelRange
Excel2008Sheet *valueSheet = range.worksheetObject; // supposed to be new worksheet based upon values within the range; not null; stated class in log: MicrosoftExcelSheet
[valueSheet retain];
SBElementArray *valueCells = [valueSheet cells]; // not null, but count is 0
[valueCells retain];
The problem comes with the last line, when I actually get the cells from valueSheet
, in that the returned SBElementArray
isn't null, but it also doesn't contain any objects. The same goes for getting the cells in targetSheet
as well.
Documentation to do this, near as I can tell from all my searching, does not exist and I've taken this about as far as I can.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决了。
看来诀窍是将范围字符串设置到
Excel2008Range
的name
属性中。我在处理此问题时发现的一个陷阱是永远不要填充范围的formulaR1c1
— 如[NSDictionary DictionaryWithObjectsAndKeys:rangeName, @"formulaR1c1", nil]
—因为这将使用范围字符串的值填充范围。中完全相同的命令的语法时,这实际上是有意义的
事后看来,当阅读 Applescript ... 和 objc-appscript
...在这两种情况下,范围的值都是通过获取带有其名称的值范围来获得的。但对于 Scripting Bridge,据我所知,名称必须在创建范围对象时显式应用。
我确信有更好的方法来实现这一点(通常有),但至少这是有效的。
Solved.
It seems the trick is to set the range string into the
name
property of theExcel2008Range
. The one pitfall I had found while working on this is to never populate theformulaR1c1
of the range—as in[NSDictionary dictionaryWithObjectsAndKeys:rangeName, @"formulaR1c1", nil]
—because that will populate the range with the value of the range string.In hindsight this actually makes sense when reading the syntax of the exact same command in both Applescript...
...and objc-appscript...
In both cases the value of the range is gained by getting a range of values with its name. But with Scripting Bridge, near as I can tell, the name has to be applied explicitly upon creation of the range object.
I'm sure there is a better way of accomplishing this (there usually is), but at least this works.