Možnosti navigácie pre SharePoint Online

Dôležité : Tento článok je strojovo preložený, prečítajte si vyhlásenie. Anglickú verziu tohto článku nájdete tu a môžete ju použiť ako referenciu.

Tento článok popisuje, ako zlepšiť časy načítania SharePointu Online použitím štruktúrovanej navigácie a navigácie riadenej vyhľadávaním.

Globálna navigácia a dotazy, ktoré sú potrebné na vytvorenie štrukturálnej navigácie, môžu spôsobiť, že vaše stránky sa v SharePointe Online načítavajú pomalšie. Je to preto, že všetky tieto dotazy odosielajú požiadavku na iný SQL server. Pre každú lokalitu a podlokality, ktoré máte, sa na SQL server odosielajú ďalšie dotazy. Tento problém sa týka aj predlôh. Toto má v konečnom dôsledku vplyv aj na globálnu navigáciu.

Niektoré lokality SharePointu vyžadujú veľkú a zložitú štruktúru. Použitie predinštalovanej štrukturálnej navigácie, ktorá používa obsah prostredníctvom dotazov, môže spôsobiť zhoršenie časov načítavania vzhľadom na väčší počet vrstiev. Každá z vrstiev podlokalít tiež vytvára ďalší dotaz.

Existujú dva hlavné typy navigácie predinštalované v SharePointe spolu s tretím, prispôsobeným prístupom riadeným vyhľadávaním. Každá z možností má svoje výhody a nevýhody, ako je uvedené v nasledujúcej tabuľke.

Štruktúrovaná navigácia

Spravovaná navigácia

Navigácia riadená vyhľadávaním

Výhody

  • Jednoduchá konfigurácia

  • Spracovanie zabezpečením

  • Pri pridávaní lokalít sa aktualizuje automaticky

Výhody

  • Jednoduchá údržba

Výhody

  • Spracovanie zabezpečením

  • Pri pridávaní lokalít sa aktualizuje automaticky

  • Rýchle časy načítania a lokálne uložená navigačná štruktúra

Nevýhody:

  • Pri zložitejšej štruktúre lokality môže byť zhoršený výkon

Nevýhody:

  • Aktualizácia podľa štruktúry lokality nie je automatická

Nevýhody:

  • Žiadna možnosť jednoducho meniť poradie lokalít

  • Vyžaduje sa prispôsobenie predlohy (potrebné technické zručnosti)

Ak máte stránky s množstvom podlokalít a používate štrukturálnu navigáciu, môže to vašu stránku výrazne spomaliť. Najvhodnejšia možnosť pre vašu lokalitu bude závisieť od požiadaviek vašej lokality a vašich technických kapacitách. Ak ste pripravení používať vlastnú predlohu a máte v organizácii kapacity na to, aby ste mohli zachovať prípadné zmeny v predvolenej predlohe SharePointu Online, možnosť riadená vyhľadávaním poskytne najlepšie možnosti používania. Ak chcete využiť jednoduchú strednú cestu medzi predinštalovanou štrukturálnou navigáciou a vyhľadávaním, potom je spravovaná navigácia veľmi užitočnou možnosťou. Údržbu spravovanej navigácie možno vykonávať prostredníctvom konfigurácie, nevyžaduje súbory na prispôsobenie kódu a je výrazne rýchlejšia ako predinštalovaná štrukturálna navigácia.

Ďalším spôsobom je reštrukturalizácia existujúcej lokality spolu so znížením počtu položiek navigácie a požadovaných podlokalít. To je potrebné pretlo, výkon štrukturálnej navigácie je optimálny len v prípade, že štruktúra lokality a navigácia nie je priveľmi komplikovaná.

Tento článok porovnáva rôzne prístupy využité v ukážkovej kolekcii lokalít. Príklad kolekcie lokalít má 11 podlokalít a každá podlokalita obsahuje aspoň štyri ďalšie podlokality.

Snímka obrazovky zobrazujúca lokality a podlokality

Použitie štrukturálnej navigácie v SharePointe Online

Toto je predinštalovaný typ navigácie, ktorý sa používa v predvolenom nastavení a vo väčšine podmienok je najvhodnejším a najjednoduchším riešením. Ak nemá štrukturálna navigácia spracovávať zložitú štruktúru viacerých podlokalít či viacerých úrovní podlokalít, jej výkon je optimálny. Medzi hlavné výhody tohto prístupu patrí fakt, že je spracovaná zabezpečením, pri pridávaní nových lokalít sa automaticky aktualizuje a nevyžaduje žiadne úpravy predlohy lokality. Netechnický používateľ môže jednoducho pridávať položky, skrývať ich a spravovať navigáciu zo stránky s nastaveniami.

Zapnutie štrukturálnej navigácie v SharePointe Online

Ilustrácia výkonu štandardného riešenia SharePointu Online so štrukturálnou navigáciou a zapnutou možnosťou zobrazovania podlokalít. Nižšie sa nachádza snímka obrazovky znázorňujúca nastavenia zobrazené na stránke Nastavenie lokality > Navigácia.

Snímka obrazovky zobrazujúca podlokality

Analýza výkonu štrukturálnej navigácie v SharePointe Online

Ak chcete analyzovať výkon lokality SharePoint, použite kartu Sieť v nástrojoch vývojára F12 v Internet Exploreri.

Snímka obrazovky zobrazujúca kartu Sieť vo vývojárskych nástrojoch F12

Na karte Sieť kliknite na stránku s príponou .aspx, ktorá sa práve nahráva, a potom kliknite na kartu Podrobnosti.

Snímka obrazovky zobrazujúca kartu podrobností

Kliknite na položku Hlavičky odpovedí.

Snímka obrazovky s kartou Podrobnosti

V hlavičkách odpovede vracia Sharepoint užitočné diagnostické informácie. Jednou z najužitočnejších je údaj SPRequestDuration    čo je údaj o trvaní spracovania požiadavky na serveri, uvedený v milisekundách.

V nasledujúcej snímke obrazovky nastavení štrukturálnej navigácie možnosť Zobraziť podlokality nie je začiarknutá. Znamená to, že v globálnej navigácii sa nachádza len prepojenie na kolekciu lokalít:

Snímka obrazovky zobrazujúca časy načítania ako trvanie požiadavky

Kľúč SPRequestDuration    obsahuje hodnotu 245 milisekúnd. Tá predstavuje čas, ktorý bol potrebný na vrátenie požiadavky. Keďže na lokalite sa nachádza len jedna položka navigácie, ide o dobrú ukážku výkonu SharePointu Online pri nenáročnej navigácii. Na ďalšej snímke obrazovky sa zobrazuje, ako pridanie podlokality ovplyvňuje tento kľúč.

Snímka obrazovky zobrazujúca trvanie požiadavky 2502 ms

Pridanie podlokality výrazne zvýšilo čas potrebný na vrátenie požiadavky na stránku.

Medzi výhody používania bežnej štruktúrovanej navigácie patrí fakt, že je možné jednoducho meniť poradie, skrývať lokality, pridávať stránky, spracovanie výsledkov zabezpečením a skutočnosť, že sa neodchyľujete od podporovaných predlôh používaných v SharePointe Online. Ak starostlivo vytvoríte štruktúru lokality a minimalizujete množstvo podlokalít v kolekcii lokalít, štrukturálna navigácia bude pracovať optimálne.

Použitie spravovanej navigácie a spravovaných metaúdajov v SharePointe Online

Spravovaná navigácia predstavuje ďalšie predinštalované riešenie, ktoré môžete použiť na to, aby ste vytvorili rovnaký typ funkcií, aký poskytuje štrukturálna navigácia.

Výhodou použitia spravovaných metaúdajov je podstatne vyššia rýchlosť získavania údajov oproti získavaniu obsahu prostredníctvom dotazov a následnému vytváraniu navigácie lokality. Napriek tejto rýchlostnej výhode však neexistuje spôsob, ako spracovať výsledky zabezpečením, takže ak používateľ nemá prístup k danej lokalite, prepojenie sa zobrazí, no bude viesť k chybovému hláseniu.

Implementácia spravovanej navigácie a jej výsledky   

Na lokalite TechNet existuje niekoľko článkov o podrobnostiach spravovanej navigácie. Prezrite si napríklad tému Prehľad spravovanej navigácie na SharePoint Serveri 2013.

Ak chcete implementovať spravovanú navigáciu, potrebujete mať v ukladacom priestore výrazov povolenia správcu. Nastavením výrazov s URL adresami, ktoré sa zhodujú so štruktúrou kolekcie lokalít, môže spravovaná navigácia nahradiť štrukturálnu. Príklad:

Snímka obrazovky s príkladom Podlokalita1

Nasledujúci príklad zobrazuje výkon zložitej navigácie pri použití spravovanej navigácie.

Snímka obrazovky s príkladom hodnoty SPRequestDuration

Použitie spravovanej navigácie konzistentne zlepšuje výkon v porovnaní so získavaním obsahu prostredníctvom dotazov, ktoré využíva štrukturálna navigácia.

Používanie skriptovania na strane klienta riadeného vyhľadávaním

Pomocou funkcie vyhľadávania môžete využívať indexy, ktoré sú vytvorené na pozadí pomocou priebežného vyhľadávania nového obsahu. To znamená, že nie sú potrebné intenzívne dotazy na obsah. Výsledky hľadania sa zhromažďujú z indexu vyhľadávania a sú upravené zabezpečením. Je to rýchlejšie, než použitie bežných dotazov na obsah. Použitie vyhľadávania v štrukturálnej navigácii výrazne zrýchli čas načítania stránky, obzvlášť v prípade, že štruktúra vašej lokality je zložitá. Hlavnou výhodou tohto prístupu oproti spravovanej navigácii je skutočnosť, že môžete využiť spracovanie bezpečnosťou.

Súčasťou tohto prístupu je tvorba vlastnej predlohy a nahradenie predinštalovaného kódu navigácie vlastným HTML kódom. Ak chcete nahradiť kód navigácie v súbore seattle.html, postupujte podľa nasledujúcich pokynov.

V tomto príklade otvoríte súbor seattle.html a nahradíte celý prvok s parametrom id = "DeltaTopNavigation" vlastným HTML kódom.

Príklad: Nahradenie predinštalovaného kódu navigácie v predlohe

  1. Prejdite na stránku Nastavenie lokality.

  2. Otvorte galériu predlôh kliknutím na položku Strany predlohy.

  3. Tu môžete prehľadávať knižnicu a stiahnuť súbor seattle.master.

  4. Upravte kód pomocou textového editora a odstráňte blok kódu zobrazený na nasledujúcej snímke obrazovky.

    Uloženie súborov do cloudu
  5. Odstráňte kód medzi značkami < SharePoint: AjaxDelta id = "DeltaTopNavigation" > a < \SharePoint:AjaxDelta > a nahraďte ho nasledujúcim zlomkom:

    <div id="loading">
      <!--Replace with path to loading image.-->
      <div style="background-image: url(''); height: 22px; width: 22px; ">
      </div>
    </div>
    <!-- Main Content-->
    <div id="navContainer" style="display:none">
        <div data-bind="foreach: hierarchy" class="noindex ms-core-listMenu-horizontalBox">
            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                <span class="menu-item-text" data-bind="text: item.Title">
                </span>
            </a>
            <ul id="menu" data-bind="foreach: $data.children" style="padding-left:20px">
                <li class="static dynamic-children">
                    <a class="static dynamic-children menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                        <span aria-haspopup="true" class="additional-background ms-navedit-flyoutArrow dynamic-children">
                            <span class="menu-item-text" data-bind="text: item.Title">
                            </span>
                        </span>
                    </a>
                    <ul id="menu" data-bind="foreach: children; visible: children.length>0" class="dynamic" >
                        <li class="dynamic">
                            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                                <span class="menu-item-text" data-bind="text: item.Title">
                                </span>
                            </a>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
  6. Nahradiť URL v načítanie obrázok ukotvenie značku na začiatku, s prepojením na načítanie obrázka v rámci kolekcie lokalít. Po vykonaní zmien, premenujte súbor a nahrajte ho do galérie predlôh. Tým sa vygeneruje nový .Master môžete súbor.

  7. Tento HTML kód predstavuje základné značky, ktoré sa vyplnia výsledkami vyhľadávania vrátenými z kódu JavaScriptu. Bude potrebné upraviť nasledujúci kód a zmeniť v ňom hodnotu var root = “site collection URL ako je uvedené v nasledujúcom zlomku kódu:

    var root = “https://spperformance.sharepoint.com/sites/NavigationBySearch”;

    Celý súbor JavaScriptu vyzerá takto:

    //Models and Namespaces
    var SPOCustom = SPOCustom || {};
    SPOCustom.Models = SPOCustom.Models || {}
    SPOCustom.Models.NavigationNode = function () {
    
        this.Url = ko.observable("");
        this.Title = ko.observable("");
        this.Parent = ko.observable("");
    
    };
    
    var root = "https://spperformance.sharepoint.com/sites/NavigationBySearch";
    var baseUrl = root + "/_api/search/query?querytext=";
    var query = baseUrl + "'contentClass=\"STS_Web\"+path:" + root + "'&trimduplicates=false&rowlimit=300";
    
    var baseRequest = {
        url: "",
        type: ""
    };
    
    
    //Parses a local object from JSON search result.
    function getNavigationFromDto(dto) {
        var item = new SPOCustom.Models.NavigationNode();
        if (dto != undefined) {
    
            var webTemplate = getSearchResultsValue(dto.Cells.results, 'WebTemplate');
    
            if (webTemplate != "APP") {
                item.Title(getSearchResultsValue(dto.Cells.results, 'Title')); //Key = Title
                item.Url(getSearchResultsValue(dto.Cells.results, 'Path')); //Key = Path
                item.Parent(getSearchResultsValue(dto.Cells.results, 'ParentLink')); //Key = ParentLink
            }
    
        }
        return item;
    }
    
    function getSearchResultsValue(results, key) {
    
        for (i = 0; i < results.length; i++) {
            if (results[i].Key == key) {
                return results[i].Value;
            }
        }
        return null;
    }
    
    //Parse a local object from the serialized cache.
    function getNavigationFromCache(dto) {
        var item = new SPOCustom.Models.NavigationNode();
    
        if (dto != undefined) {
    
            item.Title(dto.Title);
            item.Url(dto.Url);
            item.Parent(dto.Parent);
        }
    
        return item;
    }
    
    /* create a new OData request for JSON response */
    function getRequest(endpoint) {
        var request = baseRequest;
        request.type = "GET";
        request.url = endpoint;
        request.headers = { ACCEPT: "application/json;odata=verbose" };
        return request;
    };
    
    /* Navigation Module*/
    function NavigationViewModel() {
        "use strict";
        var self = this;
        self.nodes = ko.observableArray([]);
        self.hierarchy = ko.observableArray([]);;
        self.loadNavigatioNodes = function () {
            //Check local storage for cached navigation datasource.
            var fromStorage = localStorage["nodesCache"];
            if (false) {
                var cachedNodes = JSON.parse(localStorage["nodesCache"]);
    
                if (cachedNodes && timeStamp) {
                    //Check for cache expiration. Currently set to 3 hrs.
                    var now = new Date();
                    var diff = now.getTime() - timeStamp;
                    if (Math.round(diff / (1000 * 60 * 60)) < 3) {
    
                        //return from cache.
                        var cacheResults = [];
                        $.each(cachedNodes, function (i, item) {
                            var nodeitem = getNavigationFromCache(item, true);
                            cacheResults.push(nodeitem);
                        });
    
                        self.buildHierarchy(cacheResults);
                        self.toggleView();
                        addEventsToElements();
                        return;
                    }
                }
            }
            //No cache hit, REST call required.
            self.queryRemoteInterface();
        };
    
        //Executes a REST call and builds the navigation hierarchy.
        self.queryRemoteInterface = function () {
            var oDataRequest = getRequest(query);
            $.ajax(oDataRequest).done(function (data) {
                var results = [];
                $.each(data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results, function (i, item) {
    
                    if (i == 0) {
                        //Add root element.
                        var rootItem = new SPOCustom.Models.NavigationNode();
                        rootItem.Title("Root");
                        rootItem.Url(root);
                        rootItem.Parent(null);
                        results.push(rootItem);
                    }
                    var navItem = getNavigationFromDto(item);
                    results.push(navItem);
                });
                //Add to local cache
                localStorage["nodesCache"] = ko.toJSON(results);
    
                localStorage["nodesCachedAt"] = new Date().getTime();
                self.nodes(results);
                if (self.nodes().length > 0) {
                    var unsortedArray = self.nodes();
                    var sortedArray = unsortedArray.sort(self.sortObjectsInArray);
    
                    self.buildHierarchy(sortedArray);
                    self.toggleView();
                    addEventsToElements();
                }
            }).fail(function () {
                //Handle error here!!
                $("#loading").hide();
                $("#error").show();
            });
        };
        self.toggleView = function () {
            var navContainer = document.getElementById("navContainer");
            ko.applyBindings(self, navContainer);
            $("#loading").hide();
            $("#navContainer").show();
    
        };
        //Uses linq.js to build the navigation tree.
        self.buildHierarchy = function (enumerable) {
            self.hierarchy(Enumerable.From(enumerable).ByHierarchy(function (d) {
                return d.Parent() == null;
            }, function (parent, child) {
                if (parent.Url() == null || child.Parent() == null)
                    return false;
                return parent.Url().toUpperCase() == child.Parent().toUpperCase();
            }).ToArray());
    
            self.sortChildren(self.hierarchy()[0]);
        };
    
    
        self.sortChildren = function (parent) {
    
            // sjip processing if no children
            if (!parent || !parent.children || parent.children.length === 0) {
                return;
            }
    
            parent.children = parent.children.sort(self.sortObjectsInArray2);
    
            for (var i = 0; i < parent.children.length; i++) {
                var elem = parent.children[i];
    
                if (elem.children && elem.children.length > 0) {
                    self.sortChildren(elem);
                }
            }
        };
    
        // ByHierarchy method breaks the sorting in chrome and firefix 
        // we need to resort  as ascending
        self.sortObjectsInArray2 = function (a, b) {
            if (a.item.Title() > b.item.Title())
                return 1;
            if (a.item.Title() < b.item.Title())
                return -1;
            return 0;
        };
    
    
        self.sortObjectsInArray = function (a, b) {
            if (a.Title() > b.Title())
                return -1;
            if (a.Title() < b.Title())
                return 1;
            return 0;
        }
    }
    
    //Loads the navigation on load and binds the event handlers for mouse interaction.
    function InitCustomNav() {
        var viewModel = new NavigationViewModel();
        viewModel.loadNavigatioNodes();
    }
    
    function addEventsToElements() {
        //events.
        $("li.dynamic-children").mouseover(function () {
            var position = $(this).position();
            $(this).find("ul").css({ width: 125, left: position.left + 10, top: 50 });
    
        })
            .mouseout(function () {
                $(this).find("ul").css({ width: 0, left: -99999, top: 0 });
            });
    }
    
    _spBodyOnLoadFunctionNames.push("InitCustomNav");
    

    Súhrn kódu je uvedené vyššie v tejto funkcii $(document).ready jQuery je viewModel objekt, vytvorili a potom loadNavigationNodes() funkcie na daný objekt sa nazýva. Táto funkcia buď načíta predtým vytvorené navigačnej hierarchii uložené v lokálne úložisko HTML5 klienta prehliadača alebo ho zavolá funkcia queryRemoteInterface().

    QueryRemoteInterface() vytvorí žiadosť s funkciou getRequest() s parametrom dotazu uviedli v skript a potom vráti údaje zo servera. Tieto údaje je v podstate pole všetkých lokalít v kolekcii lokalít vyjadrenými objekty prenos údajov s rôzne vlastnosti. Tieto údaje sa potom analyzovaný do predtým definované SPO.Models.NavigationNode objektov, ktoré použiť Knockout.js vytvoriť pozorovať vlastnosti na použitie údajov záväzné hodnoty do HTML, ktorý sme definovali v staršej verzii. Objekty sa vráťte do poľa typu výsledkov. Toto pole je rozložený do JSON pomocou Knockout a uložené v ukladací priestor pre zlepšenie výkonu v budúcnosti stránka načíta lokálneho prehliadača.

  8. Potom výsledky sú priradené k self.nodes poľa a hierarchie je postavené z objektov pomocou linq.js priradenie výstupu do poľa self.heirarchy. Toto pole je objekt, ktorý súvisí s HTML. Je to vo funkcii toggleView() pri prechode na vlastný objekt ko.applyBinding() funkcie. To potom spôsobí hierarchie pole do previazať s nasledujúci HTML:

    <div data-bind=”foreach: hierarchy” class=”noindex ms-core-listMenu-horizontalBox”>

    Nakoniec obsluhy udalostí pre mouseenter a mouseexit sa pridajú do najvyššej úrovne v rámci navigácie postupovať podlokality drop-down menu, čo sa deje vo funkcii addEventsToElements() .

    Výsledky navigácie sú zobrazené na nasledujúcej snímke obrazovky:

    Snímka obrazovky zobrazujúca výsledky navigácie

    V našom príklade zložitej navigácie pri celkom novom načítaní bez ukladania do lokálnej vyrovnávacej pamäte vidieť, že čas strávený na serveri sa skrátil oproti kontrolnej vzorke s prístupom štrukturálnej navigácie na hodnoty podobné prístupu spravovanej navigácie.

    Snímka obrazovky s hodnotou SPRequestDuration 301

    Významnou výhodou tohto prístupu je skutočnosť, že vďaka použitiu lokálneho ukladacieho priestoru HTML5 sa navigácia pre používateľa uloží lokálne a použije pri nasledujúcom načítaní stránky.

Použitím vyhľadávania API pre štrukturálnu navigáciu získavame výrazne vyšší výkon, správna realizácia a prispôsobenie však vyžadujú isté technické zručnosti. V príklade implementácie sú lokality usporiadané rovnako, ako v predinštalovanej štrukturálnej navigácii, t. j. v abecednom poradí. Ak by ste poradie chceli zmeniť, vytvorenie a údržba tohto riešenia by boli zložitejšie. Tento prístup by tiež vyžadoval odklon od podporovaných predlôh. Ak sa nebude vykonávať údržba prispôsobenej predlohy, vaša lokalita nebude mať k dispozícii aktualizácie a zlepšenia predlôh poskytované spoločnosťou Microsoft.

Vyššie uvedený kód obsahuje nasledujúce závislosti:

Aktuálna verzia LinqJS neobsahuje ByHierarchy priečkami vyššie uvedený kód a preruší navigácia kód. Ak chcete vyriešiť tento problém, pridajte nasledujúci postup do súboru Linq.js pred riadok "vyrovnať: funkcia ()".

ByHierarchy: function(firstLevel, connectBy, orderBy, ascending, parent) {
     ascending = ascending == undefined ? true : ascending;
     var orderMethod = ascending == true ? 'OrderBy' : 'OrderByDescending';
     var source = this;
     firstLevel = Utils.CreateLambda(firstLevel);
     connectBy = Utils.CreateLambda(connectBy);
     orderBy = Utils.CreateLambda(orderBy);
    
     //Initiate or increase level
     var level = parent === undefined ? 1 : parent.level + 1;

    return new Enumerable(function() {
         var enumerator;
         var index = 0;

        var createLevel = function() {
                 var obj = {
                     item: enumerator.Current(),
                     level : level
                 };
                 obj.children = Enumerable.From(source).ByHierarchy(firstLevel, connectBy, orderBy, ascending, obj);
                 if (orderBy !== undefined) {
                     obj.children = obj.children[orderMethod](function(d) {
                         return orderBy(d.item); //unwrap the actual item for sort to work
                     });
                 }
                 obj.children = obj.children.ToArray();
                 Enumerable.From(obj.children).ForEach(function(child) {
                     child.getParent = function() {
                         return obj;
                     };
                 });
                 return obj;
             };

        return new IEnumerator(

        function() {
             enumerator = source.GetEnumerator();
         }, function() {
             while (enumerator.MoveNext()) {
                 var returnArr;
                 if (!parent) {
                     if (firstLevel(enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }

                } else {
                     if (connectBy(parent.item, enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }
                 }
             }
             return false;
         }, function() {
             Utils.Dispose(enumerator);
         })
     });
 },

Poznámka : Vyhlásenie týkajúce sa strojového prekladu: Tento článok bol preložený počítačovým systémom bez zásahu človeka. Poskytovaním týchto strojových prekladov umožňuje spoločnosť Microsoft aj používateľom, ktorí nehovoria po anglicky, využívať obsah o produktoch, službách a technológiách spoločnosti Microsoft. Článok bol preložený strojovo, môže preto obsahovať chyby týkajúce sa slovnej zásoby, syntaxe alebo gramatiky.

Rozšírte svoje zručnosti
Preskúmať školenie
Buďte medzi prvými, ktorí získajú nové funkcie
Pridajte sa k insiderom pre Office

Boli tieto informácie užitočné?

Ďakujeme za vaše pripomienky!

Ďakujeme vám za pripomienky. Pravdepodobne vám pomôže, ak vás spojíme s pracovníkom podpory pre Office.

×