2010-12-07 84 views
3

我需要将一些Applescript代码移动到Scripting Bridge以利用一些Cocoa钩子而无需Applescript-ObjC。将Applescript移植到脚本桥:无法在Excel 2008中获取范围值

使用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 

但在脚本桥,我在得到基于一系列工作表的单元格的问题。以下是我目前为止的内容。

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不为空,但它也没有包含任何对象。获取targetSheet中的单元格也是一样。

从我所有的搜索结果中可以看出,这样做的文档不存在,而且我尽可能地将其采用。

回答

1

已解决。

NSString *rangeName = @"A1:A10"; 

Excel2008Range *range = [[[excelApp classForScriptingClass:@"range"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:rangeName, @"name", nil]]; 
[[targetSheet ranges] addObject:range]; 

Excel2008Range *currentRange; 
if ([[[targetSheet ranges] objectWithName:rangeName] exists]) { 
    currentRange = [[targetSheet ranges] objectWithName:rangeName]; 
} 

NSLog(@"[currentRange.value get] = %@", [currentRange.value get]); 
// result: ((key),(1),(2),(3),(4),(5),(6),(7),(8),(9)) = NSArray 

看来,关键是要在范围内的字符串设定为Excel2008Rangename财产。我在处理这个问题时发现的一个缺陷是永远不会填充范围的formulaR1c1(如[NSDictionary dictionaryWithObjectsAndKeys:rangeName, @"formulaR1c1", nil]),因为它会使用范围字符串的值填充范围。

事后该读两个AppleScript的完全相同的命令的语法时,实际上是有意义的......

tell application "Microsoft Excel" 
    set theValues to get value of range "A1:A10" 
end tell 

...和objc-appscript ...

NSString *rangeString = @"A1:A10" 
MEApplication *microsoftExcel = [MEApplication applicationWithName: @"Microsoft Excel"]; 
MEReference *cells = [[[microsoftExcel ranges] byName:rangeString] value]; 
NSArray *cellValues = [cells getItem]; 

在两种情况下,范围的值都是通过获取其名称的一系列值来获得的。但是对于Scripting Bridge,据我所知,名称在创建范围对象时显式应用。

我确定有更好的方法来完成这个(通常是),但至少这是有效的。