演習 - ワークシートおよびアドイン コマンドを操作する

完了

この演習では、以前に作成したテーブルのヘッダー行を固定して、ワークシートを下にスクロールしてもヘッダー行が表示されるようにする方法を説明します。 また、ワークシートの保護のオンとオフを切り替える方法についても説明します。

テーブルのヘッダーの固定

テーブルがとても長く、行を参照するためにスクロールしなければならない場合、ヘッダー行が画面の外に移動して見えなくなることがあります。 このセクションでは、以前に作成したテーブルのヘッダー行を固定して、ワークシートを下にスクロールしてもヘッダー行が表示されるようにします。

表のヘッダー行を固定する

  1. ファイル ./src/taskpane/taskpane.html を開きます。

  2. [create-chart] ボタンの <button> 要素を見つけ、その行の後に次のマークアップを追加します。

    <button class="ms-Button" id="freeze-header">Freeze Header</button><br/><br/>
    
  3. ファイル ./src/taskpane/taskpane.js を開きます。

  4. Office.onReady() メソッド呼び出しで次の行を見つけます。

    document.getElementById("create-chart").onclick = createChart;
    

    その直後に、次のコードを追加します。

    document.getElementById("freeze-header").onclick = freezeHeader;
    
  5. 次の関数をファイルの最後に追加します。

    async function freezeHeader() {
      await Excel.run(async (context) => {
    
        // TODO1: Queue commands to keep the header visible when the user scrolls.
    
        await context.sync();
      })
      .catch(function (error) {
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
          console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
      });
    }
    
  6. freezeHeader() 関数で、TODO1 を次のコードに置き換えます。:

    const currentWorksheet = context.workbook.worksheets.getActiveWorksheet();
    currentWorksheet.freezePanes.freezeRows(1);
    

    注:

    • Worksheet.freezePanes コレクションは、ワークシートのスクロール操作時に、ワークシート上でピン留めつまり固定される一式のペインのことです。
    • メソッドは freezeRows() パラメーターとして、ピン留めする行の数を先頭から受け取ります。 最初の行をピン留めするには、1 を渡します。
  7. 変更内容がプロジェクトに保存されていることを確認します。

アドインをテストする

  1. ローカル Web サーバーが既に実行されていて、アドインが既に Excel に読み込まれている場合は、手順 2 に進みます。 そうでない場合は、ローカル Web サーバーを起動し、アドインのサイドロードを行います。

    • Excel でアドインをテストするには、プロジェクトのルート ディレクトリから次のコマンドを実行します。 ローカル Web サーバーが (まだ実行されていない場合) 起動し、アドインが読み込まれた Excel が開きます。

      npm start
      
    • Excel on the web でアドインをテストするには、プロジェクトのルート ディレクトリから次のコマンドを実行します。 このコマンドを実行すると、ローカル Web サーバーが起動します (まだ実行されていない場合)。

      npm run start:web
      

      アドインを使用するには、Excel on the web で新しいドキュメントを開き、「Office on the web で Office アドインをサイドロードする」の手順に従ってアドインをサイドロードします。

  2. アドインの作業ウィンドウをまだ開いていない場合は、[ホーム] タブで [作業ウィンドウ​​の表示] を選択します。

  3. このチュートリアルに以前追加したテーブルがワークシートに存在する場合は、それを削除します。

  4. 作業ウィンドウで、[テーブルの作成] を選択します。

  5. 作業ウィンドウで、[ヘッダーの固定] を選択します。

  6. ヘッダー以降の行が画面の外に出て見えなくなるまでワークシートを十分下にスクロールしても、表のヘッダーが最上部に表示されていることを確認します。

Excel のチュートリアルで設定されたヘッダーの固定のスクリーンショット。

ワークシートの保護

このセクションでは、リボンに別のボタンを追加します。このボタンをクリックすると、ワークシートの保護のオン/オフが切り替わるように定義した関数が実行されるようにします。

2 つ目のリボン ボタンを追加するようにマニフェストを構成する

  1. マニフェスト ファイル ./manifest.xml を開きます。

  2. <Control> 要素を見つけます。 この要素では、アドインの起動に使用している [ホーム] リボンの [作業ウィンドウの表示] ボタンを定義しています。 ここでは、[ホーム] リボンの同じグループに 2 つ目のボタンを追加します。

    Control 終了タグ (</Control>) と Group 終了タグ (</Group>) の間に、次のマークアップを追加します。

    <Control xsi:type="Button" id="<!--TODO1: Unique (in manifest) name for button -->">
        <Label resid="<!--TODO2: Button label -->" />
        <Supertip>
          <Title resid="<!-- TODO3: Button tool tip title -->" />
          <Description resid="<!-- TODO4: Button tool tip description -->" />
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="<!-- TODO5: Specify the type of action-->">
          <!-- TODO6: Identify the function.-->
        </Action>
    </Control>
    
  3. マニフェスト ファイルに追加した XML 内で TODO1 を文字列に置き換えて、このマニフェスト ファイル内で一意の ID をボタンに割り当てます。 このボタンでは、ワークシートの保護のオン/オフを切り替える予定なので、ToggleProtection を使用することにします。 完了すると、Control 要素の開始タグは次のようになります。

    <Control xsi:type="Button" id="ToggleProtection">
    
  4. その次の 3 つの TODO では、resid プロパティを設定します (このプロパティ名は、リソース ID の略号です)。 リソースは文字列です。これら 3 つの文字列は、この後の手順で作成します。 ここでは、そのリソースに ID を割り当てる必要があります。 ボタンの labelToggle Protection と表示されるようにしますが、この文字列の IDProtectionButtonLabel にする必要があります。そのため、Label 要素は次のようになります。

    <Label resid="ProtectionButtonLabel" />
    
  5. SuperTip 要素では、このボタンのツール ヒントを定義します。 ツール ヒントのタイトルはボタンのラベルと同じにする必要があるため、リソース ID には同じ ProtectionButtonLabel を使用することにします。 ツール ヒントの説明は、Click to turn protection of the worksheet on and off にします。 ただし、IDProtectionButtonToolTip にする必要があります。 したがって、完了すると、SuperTip 要素は次のようになります。

    <Supertip>
      <Title resid="ProtectionButtonLabel" />
      <Description resid="ProtectionButtonToolTip" />
    </Supertip>
    

    注:

    運用アドインでは、異なる 2 つのボタンに同じアイコンを使用することは避けたいところですが、このチュートリアルでは説明を簡単にするために同じアイコンを使用します。 そのため、この新しい IconControl マークアップは、単に既存の Icon から Control 要素をコピーします。

  6. 既にマニフェストに存在している元の Control 要素の内側にある Action 要素では、その要素のタイプが ShowTaskpane に設定されていますが、新しいボタンで作業ウィンドウを開く予定はありません。このボタンでは、この後の手順で作成するカスタム関数を実行する予定です。 そのため、TODO5 は、カスタム関数をトリガーするボタンのアクションの種類である に置き換えます。 Action 要素の開始タグは次のようになります。

    <Action xsi:type="ExecuteFunction">
    
  7. 元の Action 要素には、作業ウィンドウ ID を指定する子要素と、作業ウィンドウで開かれるページの URL を指定する子要素があります。 ただし、Action タイプの ExecuteFunction 要素には、実行を制御する関数の名前を指定する子要素を 1 つ含めます。 その関数は、toggleProtection という名前にして、この後の手順で作成します。 そのために、TODO6 を次のマークアップに置き換えます。

    <FunctionName>toggleProtection</FunctionName>
    

    Control マークアップの全体は、次のようになりました。

    <Control xsi:type="Button" id="ToggleProtection">
        <Label resid="ProtectionButtonLabel" />
        <Supertip>
          <Title resid="ProtectionButtonLabel" />
          <Description resid="ProtectionButtonToolTip" />
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="ExecuteFunction">
          <FunctionName>toggleProtection</FunctionName>
        </Action>
    </Control>
    
  8. マニフェストの Resources セクションまで下にスクロールします。

  9. bt:ShortStrings 要素の子として、次のマークアップを追加します。

    <bt:String id="ProtectionButtonLabel" DefaultValue="Toggle Worksheet Protection" />
    
  10. bt:LongStrings 要素の子として、次のマークアップを追加します。

    <bt:String id="ProtectionButtonToolTip" DefaultValue="Click to protect or unprotect the current worksheet." />
    
  11. ファイルを保存します。

シートを保護する関数を作成する

  1. .\commands\commands.js ファイルを開きます。

  2. action() 関数の直後に次の関数を追加します。 関数に args パラメーターを指定し、その関数の最後の行で args.completed を呼び出します。 ExecuteFunction タイプのすべてのアドイン コマンドでは、これが要件になります。 これにより、関数が終了したことと、UI が再度応答可能になることを Office ホスト アプリケーションに通知します。

    async function toggleProtection(args) {
      await Excel.run(async (context) => {
    
        // TODO1: Queue commands to reverse the protection status of the current worksheet.
    
        await context.sync();
      })
      .catch(function (error) {
        console.log("Error: " + error);
        if (error instanceof OfficeExtension.Error) {
          console.log("Debug info: " + JSON.stringify(error.debugInfo));
        }
      });
      args.completed();
    }
    
  3. 次の行を、ファイルの最後に追加します。

    Office.actions.associate("toggleProtection", toggleProtection);
    
  4. toggleProtection() 関数で、TODO1 を次のコードに置き換えます。 このコードでは、標準の切り替えパターンで、ワークシート オブジェクトの protection プロパティを使用します。 TODO2 については、次のセクションで説明します。

    const sheet = context.workbook.worksheets.getActiveWorksheet();
    
    // TODO2: Queue command to load the sheet's "protection.protected" property from
    //        the document and re-synchronize the document and task pane.
    
    if (sheet.protection.protected) {
      sheet.protection.unprotect();
    } else {
      sheet.protection.protect();
    }
    

ドキュメントのプロパティを作業ウィンドウのスクリプト オブジェクトにフェッチするコードを追加する

これまでに作成した各関数では、Office ドキュメントに 書き込む コマンドをキューに入れました。 各関数は、キューに登録されたコマンドを実行対象の文書に送信する context.sync() メソッドの呼び出しで終了します。 ただし、最後の手順で追加したコードでは、sheet.protection.protected プロパティを呼び出しています。このことが、これまでに作成した関数とは大きく異なります。sheet オブジェクトは、この作業ウィンドウのスクリプトに存在する単なるプロキシ オブジェクトなので、 ドキュメントの実際の保護の状態を認識できません。そのため、その protection.protected プロパティでは実際の値が保持できません。 まず、ドキュメントから保護の状態をフェッチする必要があり、その状態を使用して sheet.protection.protected の値を設定します。 そのようにした場合にのみ、例外がスローされることなく sheet.protection.protected を呼び出せるようになります。 このフェッチ処理には、3 つの手順があります。

  1. コードで読み取る必要があるプロパティをロードする (つまりフェッチする) コマンドをキューに登録します。
  2. コンテキスト オブジェクトの sync() メソッドを呼び出します。このメソッドは、キューに登録されたコマンドを実行対象のドキュメントに送信して、要求された情報を返します。
  3. sync() メソッドは非同期であるため、フェッチされたプロパティをコードで呼び出す前に、そのメソッドが完了していることを確認します。

こうした手順は、コードで Office ドキュメントから情報を読み取る必要がある場合には必ず完了する必要があります。

  1. toggleProtection() 関数で、TODO2 を次のコードに置き換えます。

    sheet.load('protection/protected');
    await context.sync();
    

    注:

    • すべての Excel オブジェクトに load() メソッドがあります。 読み取る必要のあるオブジェクトのプロパティは、コンマ区切りの名前の文字列としてパラメーターで指定します。 この場合、読み取る必要のあるプロパティは、protection プロパティのサブプロパティです。 サブプロパティはその他のコードの場合とほとんど同じ方法で参照しますが、"." 記号の代わりにスラッシュ ('/') 記号を使用する点が異なります。
    • を読み取sheet.protection.protectedるトグル ロジックが、 が完了sheet.protection.protectedし、ドキュメントからフェッチされる正しい値が割り当てられるまでsync実行されないようにするには、演算子の後に配置するawait必要があります。

    作業が完了すると、関数の全体は次のようになります。

    async function toggleProtection(args) {
        await Excel.run(async (context) => {
          const sheet = context.workbook.worksheets.getActiveWorksheet();
          sheet.load('protection/protected');
    
          await context.sync();
    
          if (sheet.protection.protected) {
              sheet.protection.unprotect();
          } else {
              sheet.protection.protect();
          }
    
          await context.sync();
        })
        .catch(function (error) {
          console.log("Error: " + error);
          if (error instanceof OfficeExtension.Error) {
            console.log("Debug info: " + JSON.stringify(error.debugInfo));
          }
        });
        args.completed();
    }
    
  2. プロジェクトに行ったすべての変更が保存されていることを確認します。

アドインをテストする

  1. Excel も含めて、すべての Office アプリケーションを閉じます。

  2. キャッシュ フォルダーの内容を削除して、Office キャッシュを削除します。 これは、ホストから古いバージョンのアドインを完全に削除するために必要です。

    • Windows の場合: %LOCALAPPDATA%\Microsoft\Office\16.0\Wef\

    • macOS の場合: ~/Library/Containers/com.Microsoft.OsfWebHost/Data/

      注:

      そのフォルダーが存在しない場合は、次のフォルダーを確認し、見つかった場合はフォルダーの内容を削除します。

      • {host} が Office ホスト (例: Excel) の ~/Library/Containers/com.microsoft.{host}/Data/Library/Caches/
      • {host} が Office ホスト (例: Excel) の ~/Library/Containers/com.microsoft.{host}/Data/Library/Application Support/Microsoft/Office/16.0/Wef/
      • com.microsoft.Office365ServiceV2/Data/Caches/com.microsoft.Office365ServiceV2/
  3. ローカル Web サーバーが既に実行されている場合は、コマンド プロンプトに次のコマンドを入力して停止します。

    npm stop
    
  4. マニフェスト ファイルが更新されているため、更新されたマニフェスト ファイルを使用してアドインを再度サイドロードする必要があります。 ローカル Web サーバーを起動し、アドインのサイドロードを行います。

    • Excel でアドインをテストするには、プロジェクトのルート ディレクトリから次のコマンドを実行します。 ローカル Web サーバーが (まだ実行されていない場合) 起動し、アドインが読み込まれた Excel が開きます。

      npm start
      
    • Excel on the web でアドインをテストするには、プロジェクトのルート ディレクトリから次のコマンドを実行します。 このコマンドを実行すると、ローカル Web サーバーが起動します (まだ実行されていない場合)。

      npm run start:web
      

      アドインを使用するには、Excel on the web で新しいドキュメントを開き、「Office on the web で Office アドインをサイドロードする」の手順に従ってアドインをサイドロードします。

  5. Excel の [ホーム] タブで、[ワークシート保護を切り換える] ボタンを選択します。 次のスクリーンショットに示すように、リボンのほとんどのコントロールは無効化 (淡色表示) されます。

    ワークシート保護がオンになっている Excel のリボンのスクリーンショット。

  6. セルの内容を変更する場合は、そのセルを選択します。 Excel にワークシートが保護されていることを示すエラー メッセージが表示されます。

  7. もう一度 [ワークシート保護を切り換える] ボタンを選択すると、コントロールが再有効化され、再びセルの値を変更できるようになります。

概要

この演習では、以前に作成したテーブルのヘッダー行を固定して、ワークシートを下にスクロールしてもヘッダー行が表示されるようにする方法を学習しました。 また、ワークシートの保護のオンとオフを切り替える方法についても学習しました。

自分の知識をテストする

1.

ブック内の次のワークシートが表示されるのは、次のうちどのオプションですか?

2.

アドインのマニフェストで定義されている Office アプリケーションのリボンのボタンから JavaScript 関数を呼び出すには、次のうちどの操作を行う必要がありますか?