2016-04-13 6 views
2

Ich bin neu in APPS für OFFICEReusing Kreisobjekt in Excel.run für Anwendungen für Büro

Ich bin ein einfacher Code, in dem ich Validate Excel-Daten zu versuchen. So Anstatt Verschachtelung Dinge in ctx.sync() immer wieder, ich schreibe Code wie folgt aus: -

 // **json** object used beneath is somewhat like: 
     {"Field":[ 
      {"FieldName":"Field1", "FieldDesc":"Field 1 desc", "MappedTo":"B2", "IsMandatory":"true", "LOV":"1,2,3"}]} 

     // **LOV** in above json data means:- the field data can only be among the values given. 

     //********** MY PIECE OF CODE************** 

     var fieldData = ""; 
     $.each(json, function (index, field) { 
      range = ctx.workbook.worksheets.getActiveWorksheet().getRange(field.MappedTo + ":" + field.MappedTo); 
      range.load('text'); 
      ctx.sync(); 
      fieldData = range.text; 

      if(field.IsMandatory == true && (fieldData == "" || fieldData == null)) 
      { 
       headerValidation = headerValidation + "Data is required for Field : " + field.FieldDesc + "\n"; 
      } 
      else if(field.LOV != "") 
      { 
       if($.inArray(fieldData, field.LOV.split(',')) == -1) 
       { 
        headerValidation = headerValidation + "Data not among LOV for Field : " + field.FieldDesc + "\n"; 
       } 
      } 

      range = null; 
     }); 

Wie man sehen kann, muss ich immer wieder Range-Objekt lesen. Also benutze ich das Bereichsobjekt jedes Mal mit einer anderen Adresse und rufe zuerst "load()" und dann "ctx.sync()" auf.

Wenn ich langsam debuggen, die Dinge in Ordnung funktionieren aber Anwendung auf laufende i häufige Fehler bekommen und dann: -

*

Die Eigenschaft ‚Text‘ nicht zur Verfügung steht. Bevor Sie den Wert der Eigenschaft lesen, rufen Sie die load-Methode für das enthaltende Objekt auf und rufen Sie "context.sync()" im zugehörigen Anfragekontext auf.

*

Bitte leite mich, wie ich damit umgehen kann? Ist meine Vorgehensweise auch korrekt?

Antwort

3

In Bezug auf was falsch ist, ist der Fehler neben Ihrer ctx.sync() -Anweisung. Sie müssen es

ctx.sync() 
    .then(function() { 
     fieldData = range.text; 
     ... 
    }); 

sein und ich würde die .catch (function (Fehler) {...}) am Ende, auch nicht vergessen.

Soweit die Variable wiederverwenden oder nicht, spielt es keine Rolle. Wenn Sie "range = ctx.workbook ...." ausführen, erstellen Sie tatsächlich eine globale Bereichsvariable, was als schlechte Praxis angesehen wird. Besser zu tun "var range = ctx.workbook ....". Und Sie müssen sich keine Sorgen darüber machen, dass Sie am Ende auf null setzen.

Eine Sache zu beachten ist, dass, da Sie dies in einer for-each-Schleife tun, beachten Sie, dass die Anzahl der gleichzeitigen .sync() s ist begrenzt (irgendwo um 50-60, glaube ich) . Daher müssen Sie möglicherweise Ihren Algorithmus anpassen, wenn Sie eine große Anzahl von Feldern haben möchten.

Schließlich können Sie diesen Code viel effizienter machen, indem Sie alle Ihre Bereichsobjekte simultan auflösen, sie alle gleichzeitig laden und dann eine einzige ".sync" ausführen.

var ranges = []; 
$.each(json, function (index, field) { 
    var range = ctx.workbook.worksheets.getActiveWorksheet().getRange(field.MappedTo + ":" + field.MappedTo); 
    range.load('text'); 
    ranges.push(range); 
}); 
ctx.sync() 
    .then(function() { 
     // iterate through the read ranges and do something 
    }) 

hoffe, das hilft,

~ Michael Zlatkovsky, Entwickler auf Office-Extensibility Team, MSFT

+0

Hey, das war wirklich sehr hilfreich sein. Danke .. Was, wenn ich nur etwas in eine Zelle schreiben muss. Sagen wir bei Zelle B2, ich möchte "XYZ" schreiben. In diesem Fall mache ich einen Bereich von B2 Zelle und setze seine Values ​​Eigenschaft und rufe ctx.sync() auf. Das ist es . Hier habe ich im "then()" Teil nichts zu tun. Recht? –

+0

Richtig, das "Dann" ist nur dann, wenn man nachträglich etwas verketten muss. Aber Sie sollten immer noch ein .catch haben, entweder dort oder irgendwo weiter stromaufwärts, wenn Sie das Versprechen zurückgeben. –