2010-12-07 11 views
3

Ich habe einige Applescript Code zu Scripting Bridge verschieben, um einige Cocoa Hooks ohne die Notwendigkeit für Applescript-ObjC zu nutzen.Portierung Applescript zu Scripting Bridge: kann Wert des Bereichs in Excel 2008 nicht erhalten

Mit Excel 2008 mit Applescript, um den Wert einer Reihe bekommen ist einfach:

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 

Aber in Scripting-Brücke, ich bin die Zellen von einem Arbeitsblatt ein Problem, das auf einem Bereich basierend bekommen. Das Folgende habe ich bisher.

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]; 

Das Problem kommt mit der letzten Zeile, wenn ich tatsächlich die Zellen aus valueSheet, dass die zurück SBElementArray nicht null ist, aber es enthält auch keine Gegenstände. Das gleiche gilt für die Zellen in targetSheet auch.

Dokumentation, um dies zu tun, in der Nähe, wie ich aus all meinen Recherchen sagen kann, existiert nicht und ich habe dies so weit wie möglich gemacht.

Antwort

1

Gelöst.

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 

Es scheint der Trick den Bereich Zeichenfolge in die name Eigenschaft des Excel2008Range gesetzt ist. Der einzige Fallstrick, den ich bei der Arbeit daran gefunden habe, ist, niemals die formulaR1c1 des Bereichs zu füllen - wie in [NSDictionary dictionaryWithObjectsAndKeys:rangeName, @"formulaR1c1", nil] - weil das den Bereich mit dem Wert der Range-Zeichenfolge füllen wird.

Im Nachhinein das macht tatsächlich Sinn, wenn in beide Apple die Syntax des exakt gleichen Befehls zu lesen ...

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

... und objc-appscript ...

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

In In beiden Fällen wird der Wert des Bereichs gewonnen, indem mit seinem Namen eine Reihe von Werten erhalten wird. Aber mit Scripting Bridge, in der Nähe, wie ich sagen kann, hat der Name explizit bei der Erstellung des Bereichs Objekt angewendet werden.

Ich bin sicher, es gibt eine bessere Möglichkeit, dies zu erreichen (gibt es normalerweise), aber zumindest funktioniert das.