Opsyen navigasi untuk SharePoint Online

Penting: Artikel ini diterjemahkan oleh mesin, lihatlah notis penafian. Sila dapatkan versi Bahasa Inggeris artikel ini di sini sebagai rujukan anda

Artikel ini menerangkan cara untuk meningkatkan masa pemuatan halaman untuk SharePoint Online dengan menggunakan navigasi berstruktur dan navigasi dipacu carian.

Navigasi global dan pertanyaan yang diperlukan untuk membina navigasi berstruktur boleh menjadikan halaman anda memuatkan lebih perlahan dalam SharePoint Online. Ini adalah kerana setiap pertanyaan ini menghantar permintaan lain untuk SQL server. Untuk setiap laman dan sublaman yang anda miliki, lebih banyak permintaan dibuat untuk SQL server. Isu ini juga mempengaruhi halaman induk. Ini bermakna navigasi sejagat juga dipengaruhi.

Sesetengah laman SharePoint memerlukan struktur kompleks dan besar. Menggunakan navigasi berstruktur keluar kotak, yang menggunakan kandungan oleh pertanyaan, boleh menyebabkan masa pemuatan halaman perlahan disebabkan berbilang Laman lapisan. Setiap lapisan sublaman juga mencipta pertanyaan lain.

Terdapat dua opsyen navigasi keluar kotak utama dalam SharePoint serta ketiga, pendekatan tersuai, dipacu carian. Setiap opsyen mempunyai kebaikan dan keburukan seperti yang dinyatakan dalam Jadual berikut.

Navigasi berstruktur

Navigasi terurus

Navigasi berpandukan carian

Pakar:

  • Mudah untuk mengkonfigurasikan

  • Memotong Keselamatan

  • Mengemas kini sebagai Laman ditambah secara automatik

Pakar:

  • Mudah untuk mengekalkan

Pakar:

  • Memotong Keselamatan

  • Mengemas kini sebagai Laman ditambah secara automatik

  • Fast memuatkan struktur navigasi masa dan cache tempatan

Keburukan:

  • Boleh melaksanakan buruk dengan struktur laman kompleks

Keburukan:

  • Tidak secara automatik dikemas kini untuk menunjukkan struktur laman

Keburukan:

  • Tiada keupayaan mudah tertib Laman

  • Memerlukan penyesuaian halaman induk (kemahiran teknikal diperlukan)

Jika anda mempunyai laman dengan banyak sublaman dan anda menggunakan navigasi berstruktur, ia mungkin memperlahankan halaman anda memuat secara nyata. Opsyen yang paling sesuai untuk laman anda akan bergantung pada keperluan laman anda dan keupayaan teknikal anda. Jika anda yakin untuk menggunakan halaman induk tersuai dan mempunyai keupayaan beberapa dalam organisasi untuk mengekalkan perubahan yang mungkin berlaku dalam halaman induk lalai untuk SharePoint Online, kemudian opsyen dipacu carian yang akan menghasilkan pengalaman pengguna yang terbaik. Jika anda ingin tanah tengah ringkas antara keluar kotak navigasi berstruktur dan carian, kemudian navigasi terurus ialah pilihan yang sangat baik. Opsyen navigasi terurus boleh diselenggarakan melalui konfigurasi, melibatkan kod penyesuaian fail dan ia secara nyata lebih pantas daripada navigasi berstruktur keluar kotak.

Pendekatan lain adalah menyusun Laman sedia ada dan mengurangkan bilangan item dan navigasi sublaman yang diperlukan. Ini adalah kerana navigasi berstruktur melaksanakan juga selagi struktur laman dan navigasi bukan terlalu rumit.

Artikel ini membandingkan pelbagai pendekatan dalam koleksi laman contoh. Contoh koleksi laman mempunyai sublaman 11 dan setiap sub laman mempunyai sekurang-kurangnya empat sublaman tambahan.

Petikan skrin menunjukkan laman dan sub laman

Menggunakan navigasi berstruktur dalam SharePoint Online

Ini ialah navigasi keluar kotak yang digunakan secara lalai dan penyelesaian yang paling mudah dan sesuai dalam kebanyakan keadaan. Melainkan terdapat struktur kompleks berbilang sublaman atau aras banyak sublaman, navigasi berstruktur melaksanakan juga. Kelebihan utama pendekatan ini adalah ia memotong Keselamatan, mengemas kini secara automatik apabila laman baru ditambah dan tidak memerlukan sebarang penyesuaian halaman induk. Pengguna bukan teknikal boleh juga mudah menambah item, menyembunyikan item dan menguruskan navigasi dari halaman seting.

Menghidupkan navigasi berstruktur dalam SharePoint Online

Untuk menggambarkan cara prestasi dalam penyelesaian SharePoint Online standard dengan navigasi berstruktur dan tunjukkan subsites opsyen dihidupkan. Di bawah adalah pada petikan skrin seting yang ditemui pada halaman Seting Laman > navigasi.

Petikan skrin menunjukkan sublaman

Menganalisis prestasi navigasi berstruktur dalam SharePoint Online

Untuk menganalisis prestasi halaman SharePoint menggunakan tab rangkaian alat pembangun F12 dalam Internet Explorer.

Petikan skrin menunjukkan alat pembangun F12 tab Rangkaian

Pada tab rangkaian , klik pada halaman .aspx yang sedang dimuatkan dan kemudian klik pada tab butiran .

Petikan skrin menunjukkan tab butiran

Klik pengepala respons.

Petikan skrin tab Butiran

SharePoint mengembalikan beberapa maklumat diagnostik yang berguna dalam pengepala respons kerjanya. Salah satu yang paling berguna adalah SPRequestDuration    adalah nilai dalam milisaat, bagi tempoh permintaan mengambil proses pada pelayan.

Dalam skrin berikut petikan menunjukkan sublaman tidak ditandakan untuk navigasi berstruktur. Ini bermakna bahawa terdapat hanya Laman koleksi pautan dalam navigasi sejagat:

Petikan skrin menunjukkan masa memuatkan sebagai tempoh permintaan

Kekunci SPRequestDuration    mempunyai nilai 245 milisaat. Ini mewakili masa ia mengambil untuk mengembalikan permintaan. Memandangkan terdapat hanya satu item navigasi pada laman, ini adalah aras yang baik untuk cara SharePoint Online melaksanakan tanpa berat navigasi. Petikan skrin berikut menunjukkan cara menambah dalam sublaman yang mempengaruhi kekunci ini.

Petikan skrin menunjukkan tempoh permintaan 2502 ms

Menambah sublaman yang telah meningkatkan masa yang diambil untuk mengembalikan permintaan halaman.

Kelebihan menggunakan navigasi berstruktur yang biasa ialah anda boleh dengan mudah mengatur tertib, Sembunyikan Laman, tambah halaman, hasil ialah memotong Keselamatan, dan anda tidak menyeleweng dari halaman induk disokong yang digunakan dalam SharePoint Online. Jika anda struktur laman anda dengan teliti dan meminimumkan jumlah sublaman dalam koleksi laman anda kemudian navigasi berstruktur melaksanakan juga.

Menggunakan navigasi terurus dan metadata terurus dalam SharePoint Online

Navigasi terurus adalah opsyen keluar kotak lain yang anda boleh gunakan untuk mencipta jenis sama kefungsian sebagai navigasi berstruktur.

Kelebihan menggunakan metadata terurus adalah adalah lebih cepat untuk mendapatkan data daripada menggunakan kandungan oleh pertanyaan untuk membina navigasi laman. Walaupun ia adalah lebih cepat terdapat tiada cara untuk Keselamatan trim hasil jadi jika pengguna tidak mempunyai capaian ke Laman yang diberikan, pautan masih akan menunjukkan tetapi akan menghala ke mesej ralat.

Cara untuk melaksanakan navigasi terurus dan hasil   

Terdapat beberapa artikel TechNet mengenai butiran navigasi terurus, contohnya, lihat gambaran keseluruhan navigasi terurus dalam SharePoint Server 2013.

Untuk melaksanakan navigasi terurus, anda perlu mempunyai keizinan pentadbir stor istilah. Dengan menyediakan istilah dengan URL yang sepadan dengan struktur koleksi laman, navigasi terurus boleh digunakan untuk menggantikan navigasi berstruktur. Contohnya:

Petikan skrin contoh Sublaman1

Contoh berikut menunjukkan prestasi navigasi kompleks yang menggunakan navigasi terurus.

Petikan skrin contoh SPRequestDuration

Menggunakan navigasi terurus secara konsisten meningkatkan prestasi berbanding kandungan dengan pendekatan navigasi berstruktur pertanyaan.

Menggunakan dipacu carian pihak klien penskripan

Menggunakan carian anda boleh memanfaatkan indeks yang dibina di latar yang menggunakan rangkak berterusan. Ini bermakna terdapat pertanyaan kandungan tiada berat. Hasil carian ditarik daripada indeks carian dan hasil ialah memotong Keselamatan. Ini adalah lebih pantas daripada menggunakan pertanyaan kandungan yang biasa. Menggunakan carian untuk navigasi berstruktur, terutamanya jika anda mempunyai struktur laman yang kompleks, akan mempercepatkan halaman memuatkan masa jauh. Kelebihan utama ini atas navigasi terurus ialah anda mendapat manfaat daripada pemangkasan Keselamatan.

Pendekatan ini melibatkan mencipta halaman induk tersuai dan menggantikan Kod keluar kotak navigasi dengan HTML tersuai. Ikuti prosedur ini untuk menggantikan Kod navigasi dalam seattle.html fail.

Dalam contoh ini, anda akan membuka fail seattle.html dan gantikan unsur seluruh id = "DeltaTopNavigation" dengan kod HTML yang tersuai.

Contoh: Untuk menggantikan Kod keluar kotak navigasi dalam halaman induk

  1. Navigasi ke halaman Seting Laman .

  2. Membuka Galeri halaman induk dengan mengklik Halaman induk.

  3. Dari sini, anda boleh menavigasi melalui pustaka dan memuat turun fail seattle.master.

  4. Mengedit kod yang menggunakan editor teks dan memadamkan blok kod dalam petikan skrin berikut.

    Petikan skrin kod DeltaTopNavigation untuk dipadamkan
  5. Mengalih keluar kod antara yang < SharePoint:AjaxDelta id = "DeltaTopNavigation" > < \SharePoint:AjaxDelta > tag dan menggantikannya dengan cebisan berikut:

    <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. Menggantikan URL dalam muat imej penambat tag pada permulaan, dengan pautan kepada imej dimuatkan dalam koleksi laman anda. Selepas anda membuat perubahan, menamakan semula fail dan kemudian memuat naiknya ke galeri halaman induk. Ini menjana fail .master baru.

  7. HTML ini adalah penanda asas yang akan diisikan dengan hasil carian yang dikembalikan dari kod JavaScript. Anda perlu mengedit kod berikut untuk mengubah nilai untuk var root = “site collection URL seperti yang ditunjukkan dalam cebisan berikut:

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

    Fail JavaScript seluruh adalah seperti berikut:

    //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");
    

    Ringkaskan kod yang ditunjukkan di atas dalam fungsi $(document).ready jQuery terdapat objek viewModel yang dicipta dan kemudian loadNavigationNodes() berfungsi pada objek yang dipanggil. Fungsi ini sama ada memuatkan hierarki navigasi sebelum ini dibina yang disimpan di Storan setempat HTML5 pelayar klien ia panggilan atau fungsi queryRemoteInterface().

    QueryRemoteInterface() membina permintaan menggunakan fungsi getRequest() dengan parameter pertanyaan yang ditakrifkan terdahulu dalam skrip dan kemudian mengembalikan data dari pelayan. Data ini adalah asasnya tatasusunan semua laman dalam koleksi laman yang diwakili sebagai objek pemindahan data dengan pelbagai sifat. Data ini kemudian dihuraikan ke objek sebelum ini tertakrif SPO.Models.NavigationNode yang menggunakan Knockout.js untuk mencipta akibat sifat untuk digunakan dengan data yang terikat nilai HTML yang kita takrifkan terdahulu. Objek kemudian meletakkan dalam tatasusunan hasil. Tatasusunan ini ialah dihuraikan ke JSON menggunakan kalah mati dan disimpan di storan pelayar tempatan untuk prestasi dipertingkatkan pada pemuatan halaman akan datang.

  8. Seterusnya, hasil yang diperuntukkan kepada tatasusunan self.nodes dan hierarki dibina keluar dari objek yang menggunakan linq.js memperuntukkan output tatasusunan yang self.heirarchy. Tatasusunan ini adalah objek yang terikat HTML. Ini selesai dalam fungsi toggleView() dengan pemberian objek diri ke fungsi ko.applyBinding() . Ini kemudian menyebabkan tatasusunan hierarki yang terikat kepada HTML berikut:

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

    Akhirnya, pengendali peristiwa untuk mouseenter dan mouseexit ditambahkan navigasi aras atas untuk mengendalikan menu juntai bawah sublaman yang dilakukan dalam fungsi addEventsToElements() .

    Hasil navigasi boleh dilihat dalam skrin petikan di bawah:

    Petikan skrin hasil navigasi

    Dalam contoh kami kompleks navigasi halaman segar muat tanpa menunjukkan cache setempat masa yang dihabiskan pada pelayan mempunyai telah memotong ke bawah dari navigasi berstruktur aras untuk mendapatkan hasil yang sama seperti pendekatan navigasi terurus.

    Petikan skrin SPRequestDuration 301

    Satu manfaat utama pendekatan ini ialah yang menggunakan Storan setempat HTML5, navigasi disimpan secara setempat untuk pengguna kali seterusnya mereka memuatkan halaman.

Kami menggunakan peningkatan prestasi utama daripada menggunakan carian API untuk navigasi berstruktur; Walau bagaimanapun, ia mengambil masa beberapa keupayaan teknikal untuk melaksanakan dan menyesuaikan kefungsian ini. Dalam contoh pelaksanaan, Laman disusun dengan cara yang sama sebagai navigasi berstruktur keluar kotak; tertib abjad. Jika anda inginkan menyimpang daripada Perintah ini, ia akan lebih rumit untuk membangunkan dan mengekalkan. Juga, pendekatan ini memerlukan anda menyimpang dari halaman induk yang disokong. Jika halaman induk tersuai tidak dikekalkan, laman anda akan terlepas keluar pada kemas kini dan pembaikan yang Microsoft menjadikan halaman induk.

Kod di atas mempunyai kebergantungan berikut:

Versi semasa LinqJS mengandungi kaedah ByHierarchy yang digunakan dalam kod di atas dan akan memutuskan kod navigasi. Untuk membaikinya, menambahkan kaedah berikut fail Linq.js sebelum baris "Flatten: fungsi ()".

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);
         })
     });
 },

Nota: Notis Penafian Penterjemahan Mesin: Artikel ini telah diterjemah oleh sistem komputer tanpa campur tangan manusia. Microsoft menawarkan penterjemahan mesin ini untuk membantu pengguna-pengguna yang tidak bertutur dalam Bahasa Inggeris supaya dapat menikmati kandungan mengenai produk, perkhidmatan dan teknologi Microsoft. Artikel ini mungkin mengandungi ralat perbendaharaan kata, sintaks atau tatabahasa kerana ia diterjemahkan oleh mesin.

Kembangkan kemahiran anda
Jelajahi latihan
Dapatkan ciri baru terlebih dahulu
Sertai Office Insiders

Adakah maklumat ini membantu?

Terima kasih atas maklum balas anda!

Terima kasih atas maklum balas anda! Nampaknya ia mungkin akan membantu untuk menyambungkan anda kepada salah seorang daripada ejen sokongan Office kami.

×